adk-typescript
Version:
TypeScript port of Google's Agent Development Kit (ADK)
190 lines (189 loc) • 6.14 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseAgent = void 0;
const Event_1 = require("../events/Event");
const CallbackContext_1 = require("./CallbackContext");
const InvocationContext_1 = require("./InvocationContext");
/**
* Abstract base class for all agents.
*/
class BaseAgent {
/**
* Creates a new agent.
*
* @param name The name of the agent
* @param options Options for the agent
*/
constructor(name, options = {}) {
/** The sub-agents of this agent */
this.subAgents = [];
// Validate agent name - it should be a valid identifier
if (!/^[a-zA-Z0-9_]+$/.test(name)) {
throw new Error('Agent name must contain only alphanumeric characters and underscores');
}
this.name = name;
this.description = options.description;
// Set the parent agent if provided
if (options.parentAgent) {
this.setParentAgent(options.parentAgent);
}
}
/**
* Invokes the agent with the given context.
*
* @param invocationContext The invocation context
* @returns An async generator of events
*/
async *invoke(invocationContext) {
// Set the agent in the invocation context
invocationContext.agent = this;
// Run before-agent callback if present
const beforeEvent = this.handleBeforeAgentCallback(invocationContext);
if (beforeEvent) {
yield beforeEvent;
if (invocationContext.endInvocation) {
return;
}
}
// Run the agent implementation based on invocation mode
if (invocationContext.live) {
yield* this.runLiveImpl(invocationContext);
}
else {
yield* this.runAsyncImpl(invocationContext);
}
// Run after-agent callback if present
const afterEvent = this.handleAfterAgentCallback(invocationContext);
if (afterEvent) {
yield afterEvent;
}
}
/**
* Gets the root agent of the agent tree.
*
* @returns The root agent
*/
get rootAgent() {
return this.parentAgent ? this.parentAgent.rootAgent : this;
}
/**
* Finds an agent by name in the entire agent tree.
*
* @param name The name of the agent to find
* @returns The agent if found, undefined otherwise
*/
findAgent(name) {
if (this.name === name) {
return this;
}
for (const subAgent of this.subAgents) {
const found = subAgent.findAgent(name);
if (found) {
return found;
}
}
return undefined;
}
/**
* Finds a sub-agent by name among direct children.
*
* @param name The name of the sub-agent to find
* @returns The sub-agent if found, undefined otherwise
*/
findSubAgent(name) {
return this.subAgents.find(agent => agent.name === name);
}
/**
* Sets the parent agent of this agent.
*
* @param parentAgent The parent agent
*/
setParentAgent(parentAgent) {
if (this.parentAgent) {
// Remove from current parent's sub-agents
const index = this.parentAgent.subAgents.indexOf(this);
if (index !== -1) {
this.parentAgent.subAgents.splice(index, 1);
}
}
this.parentAgent = parentAgent;
// Add to new parent's sub-agents if not already there
if (parentAgent && !parentAgent.subAgents.includes(this)) {
parentAgent.subAgents.push(this);
}
}
/**
* Adds a sub-agent to this agent.
*
* @param agent The sub-agent to add
* @returns This agent for method chaining
*/
addSubAgent(agent) {
if (agent.parentAgent && agent.parentAgent !== this) {
throw new Error(`Agent ${agent.name} already has a different parent: ${agent.parentAgent.name}`);
}
agent.setParentAgent(this);
return this;
}
/**
* Creates a new invocation context for this agent.
*
* @param parentContext The parent invocation context
* @returns A new invocation context
*/
createInvocationContext(parentContext) {
const branch = parentContext.branch ?
`${parentContext.branch}.${this.name}` :
this.name;
return new InvocationContext_1.InvocationContext({
...parentContext,
agent: this,
branch
});
}
/**
* Handles the before-agent callback.
*
* @param invocationContext The invocation context
* @returns The event if the callback returns content, undefined otherwise
*/
handleBeforeAgentCallback(invocationContext) {
if (!this.beforeAgentCallback) {
return undefined;
}
const callbackContext = new CallbackContext_1.CallbackContext(invocationContext);
const content = this.beforeAgentCallback(callbackContext);
if (!content) {
return undefined;
}
return new Event_1.Event({
author: this.name,
content,
invocationId: invocationContext.invocationId,
branch: invocationContext.branch
});
}
/**
* Handles the after-agent callback.
*
* @param invocationContext The invocation context
* @returns The event if the callback returns content, undefined otherwise
*/
handleAfterAgentCallback(invocationContext) {
if (!this.afterAgentCallback) {
return undefined;
}
const callbackContext = new CallbackContext_1.CallbackContext(invocationContext);
const content = this.afterAgentCallback(callbackContext);
if (!content) {
return undefined;
}
return new Event_1.Event({
author: this.name,
content,
invocationId: invocationContext.invocationId,
branch: invocationContext.branch
});
}
}
exports.BaseAgent = BaseAgent;