Recursive agents update
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ztimson/ai-utils",
|
||||
"version": "1.6.13",
|
||||
"version": "1.7.0",
|
||||
"description": "AI Utility library",
|
||||
"author": "Zak Timson",
|
||||
"license": "MIT",
|
||||
|
||||
+19
-13
@@ -19,6 +19,13 @@ const PDF_OCR_PAGE_THRESHOLD = 12; // above this many pages, OCR scanned pages i
|
||||
export type AnthropicConfig = {proto: 'anthropic', token: string | string[]};
|
||||
export type OpenAiConfig = {proto: 'openai', host?: string, token: string | string[]};
|
||||
|
||||
export type AgentRef = {
|
||||
name: string;
|
||||
description?: string;
|
||||
delegate?: boolean;
|
||||
fn: () => Agent | null | Promise<Agent | null>;
|
||||
}
|
||||
|
||||
export type Agent = {
|
||||
name: string;
|
||||
description?: string;
|
||||
@@ -29,7 +36,7 @@ export type Agent = {
|
||||
skills?: Skill[] | null;
|
||||
tools?: AiTool[] | null;
|
||||
mcp?: McpServer[] | null;
|
||||
agents?: string[] | null;
|
||||
agents?: AgentRef[] | null;
|
||||
}
|
||||
|
||||
export type LLMFile = {
|
||||
@@ -106,8 +113,8 @@ export type LLMRequest = {
|
||||
skills?: Skill[];
|
||||
/** MCP servers to connect and expose as tools */
|
||||
mcp?: McpServer[];
|
||||
/** Subagents exposed as delegatable/wrapped tools */
|
||||
agents?: Agent[];
|
||||
/** Subagents exposed as delegatable/wrapped tools, resolved lazily via their `fn` */
|
||||
agents?: AgentRef[];
|
||||
/** Attach files to request */
|
||||
files?: LLMFile[];
|
||||
/** @internal recursion guard for nested agent delegation */
|
||||
@@ -265,22 +272,21 @@ class LLM {
|
||||
};
|
||||
}
|
||||
|
||||
private setupAgent(agents: Agent[] = [], allAgents: Agent[], history: LLMMessage[], aborts: ((keep?: boolean) => void)[], depth = 0, delegateState: {resp: string | null}): AiTool[] {
|
||||
return agents.map(a => {
|
||||
const toolName = `${a.delegate ? '' : 'sub'}agent_${snakeCase(a.name)}`;
|
||||
private setupAgent(stubs: AgentRef[] = [], history: LLMMessage[], aborts: ((keep?: boolean) => void)[], depth = 0, delegateState: {resp: string | null}): AiTool[] {
|
||||
return stubs.map(stub => {
|
||||
const toolName = `${stub.delegate ? '' : 'sub'}agent_${snakeCase(stub.name)}`;
|
||||
return {
|
||||
name: toolName,
|
||||
description: `${a.delegate ? 'Delegate to ' : ''}Subagent: ${a.description || a.name}`,
|
||||
description: `${stub.delegate ? 'Delegate to ' : ''}Subagent: ${stub.description || stub.name}`,
|
||||
args: clean<any>({
|
||||
context: !a.delegate ? {type: 'string', description: 'Summary of related messages, samples, files, etc...', required: true} : undefined,
|
||||
context: !stub.delegate ? {type: 'string', description: 'Summary of related messages, samples, files, etc...', required: true} : undefined,
|
||||
instructions: {type: 'string', description: 'Detailed instructions for subagent to complete', required: true},
|
||||
}),
|
||||
fn: async (args: any, stream: any, ai: any, id?: string) => {
|
||||
if(depth >= MAX_AGENT_DEPTH) return 'Max agent delegation depth exceeded';
|
||||
|
||||
const nested = (a.agents || [])
|
||||
.map(name => allAgents.find(x => x.name === name))
|
||||
.filter((x): x is Agent => !!x && x.name !== a.name);
|
||||
const a = await stub.fn();
|
||||
if(!a) return `Agent "${stub.name}" could not be resolved`;
|
||||
|
||||
const q = a.delegate ? '' : `${args.instructions}${args.context ? `\n\n<context>${args.context}</context>` : ''}`;
|
||||
|
||||
@@ -297,7 +303,7 @@ ${a.system}`,
|
||||
mcp: a.mcp || undefined,
|
||||
skills: a.skills || undefined,
|
||||
tools: a.tools || undefined,
|
||||
agents: nested,
|
||||
agents: a.agents || [],
|
||||
_agentDepth: depth + 1,
|
||||
} as any);
|
||||
aborts.push(request.abort);
|
||||
@@ -451,7 +457,7 @@ ${a.system}`,
|
||||
// Agents
|
||||
const agents = options.agents || this.ai.options?.llm?.agents;
|
||||
const delegateState: {resp: string | null} = {resp: null};
|
||||
if(agents?.length) tools.push(...this.setupAgent(agents, agents, history, nestedAborts, options._agentDepth || 0, delegateState));
|
||||
if(agents?.length) tools.push(...this.setupAgent(agents, history, nestedAborts, options._agentDepth || 0, delegateState));
|
||||
|
||||
// Memory
|
||||
const mem = MemoryManager.normalize(options.memory);
|
||||
|
||||
Reference in New Issue
Block a user