@aigne/core 1.9.0 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/LICENSE +93 -0
- package/README.md +89 -0
- package/README.zh.md +89 -0
- package/lib/cjs/agents/agent.d.ts +30 -3
- package/lib/cjs/agents/agent.js +51 -22
- package/lib/cjs/agents/ai-agent.d.ts +14 -11
- package/lib/cjs/agents/ai-agent.js +36 -17
- package/lib/cjs/agents/user-agent.d.ts +3 -3
- package/lib/cjs/agents/user-agent.js +14 -8
- package/lib/cjs/execution-engine/context.d.ts +18 -7
- package/lib/cjs/execution-engine/context.js +76 -28
- package/lib/cjs/loader/agent-js.d.ts +2 -2
- package/lib/cjs/loader/agent-js.js +4 -5
- package/lib/cjs/loader/agent-yaml.d.ts +8 -5
- package/lib/cjs/loader/agent-yaml.js +13 -1
- package/lib/cjs/loader/index.d.ts +4 -4
- package/lib/cjs/loader/index.js +4 -15
- package/lib/cjs/models/chat-model.d.ts +4 -0
- package/lib/cjs/models/chat-model.js +6 -0
- package/lib/cjs/models/claude-chat-model.d.ts +3 -1
- package/lib/cjs/models/claude-chat-model.js +75 -60
- package/lib/cjs/models/open-router-chat-model.d.ts +1 -0
- package/lib/cjs/models/open-router-chat-model.js +1 -0
- package/lib/cjs/models/openai-chat-model.d.ts +12 -3
- package/lib/cjs/models/openai-chat-model.js +110 -46
- package/lib/cjs/utils/camelize.d.ts +13 -0
- package/lib/cjs/utils/camelize.js +16 -0
- package/lib/cjs/utils/stream-utils.d.ts +17 -0
- package/lib/cjs/utils/stream-utils.js +165 -0
- package/lib/cjs/utils/type-utils.d.ts +1 -0
- package/lib/cjs/utils/type-utils.js +7 -0
- package/lib/dts/agents/agent.d.ts +30 -3
- package/lib/dts/agents/ai-agent.d.ts +14 -11
- package/lib/dts/agents/user-agent.d.ts +3 -3
- package/lib/dts/execution-engine/context.d.ts +18 -7
- package/lib/dts/loader/agent-js.d.ts +2 -2
- package/lib/dts/loader/agent-yaml.d.ts +8 -5
- package/lib/dts/loader/index.d.ts +4 -4
- package/lib/dts/models/chat-model.d.ts +4 -0
- package/lib/dts/models/claude-chat-model.d.ts +3 -1
- package/lib/dts/models/open-router-chat-model.d.ts +1 -0
- package/lib/dts/models/openai-chat-model.d.ts +12 -3
- package/lib/dts/utils/camelize.d.ts +13 -0
- package/lib/dts/utils/stream-utils.d.ts +17 -0
- package/lib/dts/utils/type-utils.d.ts +1 -0
- package/lib/esm/agents/agent.d.ts +30 -3
- package/lib/esm/agents/agent.js +51 -23
- package/lib/esm/agents/ai-agent.d.ts +14 -11
- package/lib/esm/agents/ai-agent.js +37 -18
- package/lib/esm/agents/user-agent.d.ts +3 -3
- package/lib/esm/agents/user-agent.js +15 -9
- package/lib/esm/execution-engine/context.d.ts +18 -7
- package/lib/esm/execution-engine/context.js +78 -30
- package/lib/esm/loader/agent-js.d.ts +2 -2
- package/lib/esm/loader/agent-js.js +4 -5
- package/lib/esm/loader/agent-yaml.d.ts +8 -5
- package/lib/esm/loader/agent-yaml.js +13 -1
- package/lib/esm/loader/index.d.ts +4 -4
- package/lib/esm/loader/index.js +4 -15
- package/lib/esm/models/chat-model.d.ts +4 -0
- package/lib/esm/models/chat-model.js +6 -0
- package/lib/esm/models/claude-chat-model.d.ts +3 -1
- package/lib/esm/models/claude-chat-model.js +75 -60
- package/lib/esm/models/open-router-chat-model.d.ts +1 -0
- package/lib/esm/models/open-router-chat-model.js +1 -0
- package/lib/esm/models/openai-chat-model.d.ts +12 -3
- package/lib/esm/models/openai-chat-model.js +110 -45
- package/lib/esm/utils/camelize.d.ts +13 -0
- package/lib/esm/utils/camelize.js +10 -0
- package/lib/esm/utils/stream-utils.d.ts +17 -0
- package/lib/esm/utils/stream-utils.js +149 -0
- package/lib/esm/utils/type-utils.d.ts +1 -0
- package/lib/esm/utils/type-utils.js +6 -0
- package/package.json +4 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import EventEmitter from "node:events";
|
|
2
|
-
import { Agent, type FunctionAgentFn, type Message } from "../agents/agent.js";
|
|
2
|
+
import { Agent, type AgentCallOptions, type AgentProcessAsyncGenerator, type AgentResponse, type AgentResponseStream, type FunctionAgentFn, type Message } from "../agents/agent.js";
|
|
3
3
|
import { UserAgent } from "../agents/user-agent.js";
|
|
4
4
|
import type { ChatModel } from "../models/chat-model.js";
|
|
5
5
|
import { type OmitPropertiesFromArrayFirstElement } from "../utils/type-utils.js";
|
|
@@ -27,7 +27,7 @@ export interface ContextEventMap {
|
|
|
27
27
|
export type ContextEmitEventMap = {
|
|
28
28
|
[K in keyof ContextEventMap]: OmitPropertiesFromArrayFirstElement<ContextEventMap[K], "contextId" | "parentContextId" | "timestamp">;
|
|
29
29
|
};
|
|
30
|
-
export interface CallOptions {
|
|
30
|
+
export interface CallOptions extends AgentCallOptions {
|
|
31
31
|
returnActiveAgent?: boolean;
|
|
32
32
|
disableTransfer?: boolean;
|
|
33
33
|
}
|
|
@@ -48,19 +48,30 @@ export interface Context extends TypedEventEmitter<ContextEventMap, ContextEmitE
|
|
|
48
48
|
* @param agent Agent to call
|
|
49
49
|
* @param message Message to pass to the agent
|
|
50
50
|
* @param options.returnActiveAgent return the active agent
|
|
51
|
+
* @param options.streaming return a stream of the output
|
|
51
52
|
* @returns the output of the agent and the final active agent
|
|
52
53
|
*/
|
|
53
54
|
call<I extends Message, O extends Message>(agent: Runnable<I, O>, message: I | string, options: CallOptions & {
|
|
54
55
|
returnActiveAgent: true;
|
|
56
|
+
streaming?: false;
|
|
55
57
|
}): Promise<[O, Runnable]>;
|
|
58
|
+
call<I extends Message, O extends Message>(agent: Runnable<I, O>, message: I | string, options: CallOptions & {
|
|
59
|
+
returnActiveAgent: true;
|
|
60
|
+
streaming: true;
|
|
61
|
+
}): Promise<[AgentResponseStream<O>, Promise<Runnable>]>;
|
|
56
62
|
/**
|
|
57
63
|
* Call an agent with a message
|
|
58
64
|
* @param agent Agent to call
|
|
59
65
|
* @param message Message to pass to the agent
|
|
60
66
|
* @returns the output of the agent
|
|
61
67
|
*/
|
|
62
|
-
call<I extends Message, O extends Message>(agent: Runnable<I, O>, message: I | string, options?: CallOptions
|
|
63
|
-
|
|
68
|
+
call<I extends Message, O extends Message>(agent: Runnable<I, O>, message: I | string, options?: CallOptions & {
|
|
69
|
+
streaming?: false;
|
|
70
|
+
}): Promise<O>;
|
|
71
|
+
call<I extends Message, O extends Message>(agent: Runnable<I, O>, message: I | string, options: CallOptions & {
|
|
72
|
+
streaming: true;
|
|
73
|
+
}): Promise<AgentResponseStream<O>>;
|
|
74
|
+
call<I extends Message, O extends Message>(agent: Runnable<I, O>, message?: I | string, options?: CallOptions): UserAgent<I, O> | Promise<AgentResponse<O> | [AgentResponse<O>, Runnable]>;
|
|
64
75
|
/**
|
|
65
76
|
* Publish a message to a topic, the engine will call the listeners of the topic
|
|
66
77
|
* @param topic topic name, or an array of topic names
|
|
@@ -99,6 +110,7 @@ export declare class ExecutionContext implements Context {
|
|
|
99
110
|
reset?: boolean;
|
|
100
111
|
}): ExecutionContext;
|
|
101
112
|
call: Context["call"];
|
|
113
|
+
private onCallSuccess;
|
|
102
114
|
publish: Context["publish"];
|
|
103
115
|
subscribe: Context["subscribe"];
|
|
104
116
|
unsubscribe: Context["unsubscribe"];
|
|
@@ -122,9 +134,8 @@ declare class ExecutionContextInternal {
|
|
|
122
134
|
private timer?;
|
|
123
135
|
private initTimeout;
|
|
124
136
|
get status(): "normal" | "timeout";
|
|
125
|
-
call<I extends Message, O extends Message>(agent: Runnable<I, O>, input: I, context: Context, options?: CallOptions):
|
|
126
|
-
|
|
127
|
-
output: O;
|
|
137
|
+
call<I extends Message, O extends Message>(agent: Runnable<I, O>, input: I, context: Context, options?: CallOptions): AgentProcessAsyncGenerator<O & {
|
|
138
|
+
__activeAgent__: Runnable;
|
|
128
139
|
}>;
|
|
129
140
|
private callAgent;
|
|
130
141
|
}
|
|
@@ -4,12 +4,12 @@ export declare function loadAgentFromJsFile(path: string): Promise<{
|
|
|
4
4
|
name: string;
|
|
5
5
|
fn: (args_0: Message) => Message;
|
|
6
6
|
description?: string | undefined;
|
|
7
|
-
|
|
7
|
+
inputSchema?: ZodObject<Record<string, ZodType<any, z.ZodTypeDef, any>>, z.UnknownKeysParam, z.ZodTypeAny, {
|
|
8
8
|
[x: string]: any;
|
|
9
9
|
}, {
|
|
10
10
|
[x: string]: any;
|
|
11
11
|
}> | undefined;
|
|
12
|
-
|
|
12
|
+
outputSchema?: ZodObject<Record<string, ZodType<any, z.ZodTypeDef, any>>, z.UnknownKeysParam, z.ZodTypeAny, {
|
|
13
13
|
[x: string]: any;
|
|
14
14
|
}, {
|
|
15
15
|
[x: string]: any;
|
|
@@ -2,21 +2,24 @@ import { type ZodObject, type ZodType, z } from "zod";
|
|
|
2
2
|
export declare function loadAgentFromYamlFile(path: string): Promise<{
|
|
3
3
|
type: "ai";
|
|
4
4
|
name: string;
|
|
5
|
-
description?: string | undefined;
|
|
6
5
|
tools?: string[] | undefined;
|
|
6
|
+
description?: string | undefined;
|
|
7
7
|
instructions?: string | undefined;
|
|
8
|
-
|
|
8
|
+
memory?: true | {
|
|
9
|
+
subscribeTopic: string[];
|
|
10
|
+
} | undefined;
|
|
11
|
+
inputSchema?: ZodObject<Record<string, ZodType<any, z.ZodTypeDef, any>>, z.UnknownKeysParam, z.ZodTypeAny, {
|
|
9
12
|
[x: string]: any;
|
|
10
13
|
}, {
|
|
11
14
|
[x: string]: any;
|
|
12
15
|
}> | undefined;
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
toolChoice?: "auto" | "none" | "required" | "router" | undefined;
|
|
17
|
+
outputSchema?: ZodObject<Record<string, ZodType<any, z.ZodTypeDef, any>>, z.UnknownKeysParam, z.ZodTypeAny, {
|
|
15
18
|
[x: string]: any;
|
|
16
19
|
}, {
|
|
17
20
|
[x: string]: any;
|
|
18
21
|
}> | undefined;
|
|
19
|
-
|
|
22
|
+
outputKey?: string | undefined;
|
|
20
23
|
} | {
|
|
21
24
|
type: "mcp";
|
|
22
25
|
url?: string | undefined;
|
|
@@ -8,8 +8,8 @@ export declare function load(options: LoadOptions): Promise<{
|
|
|
8
8
|
model: ChatModel | undefined;
|
|
9
9
|
agents: Agent<import("../agents/agent.js").Message, import("../agents/agent.js").Message>[];
|
|
10
10
|
tools: Agent<import("../agents/agent.js").Message, import("../agents/agent.js").Message>[];
|
|
11
|
-
description?: string | null | undefined;
|
|
12
11
|
name?: string | null | undefined;
|
|
12
|
+
description?: string | null | undefined;
|
|
13
13
|
chat_model?: {
|
|
14
14
|
name?: string | null | undefined;
|
|
15
15
|
temperature?: number | null | undefined;
|
|
@@ -63,9 +63,9 @@ declare const aigneFileSchema: z.ZodObject<{
|
|
|
63
63
|
agents: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
|
|
64
64
|
tools: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
|
|
65
65
|
}, "strip", z.ZodTypeAny, {
|
|
66
|
-
description?: string | null | undefined;
|
|
67
66
|
tools?: string[] | null | undefined;
|
|
68
67
|
name?: string | null | undefined;
|
|
68
|
+
description?: string | null | undefined;
|
|
69
69
|
chat_model?: {
|
|
70
70
|
name?: string | null | undefined;
|
|
71
71
|
temperature?: number | null | undefined;
|
|
@@ -76,9 +76,9 @@ declare const aigneFileSchema: z.ZodObject<{
|
|
|
76
76
|
} | null | undefined;
|
|
77
77
|
agents?: string[] | null | undefined;
|
|
78
78
|
}, {
|
|
79
|
-
description?: string | null | undefined;
|
|
80
79
|
tools?: string[] | null | undefined;
|
|
81
80
|
name?: string | null | undefined;
|
|
81
|
+
description?: string | null | undefined;
|
|
82
82
|
chat_model?: string | {
|
|
83
83
|
name?: string | null | undefined;
|
|
84
84
|
temperature?: number | null | undefined;
|
|
@@ -90,9 +90,9 @@ declare const aigneFileSchema: z.ZodObject<{
|
|
|
90
90
|
agents?: string[] | null | undefined;
|
|
91
91
|
}>;
|
|
92
92
|
export declare function loadAIGNEFile(path: string): Promise<{
|
|
93
|
-
description?: string | null | undefined;
|
|
94
93
|
tools?: string[] | null | undefined;
|
|
95
94
|
name?: string | null | undefined;
|
|
95
|
+
description?: string | null | undefined;
|
|
96
96
|
chat_model?: {
|
|
97
97
|
name?: string | null | undefined;
|
|
98
98
|
temperature?: number | null | undefined;
|
|
@@ -2,6 +2,10 @@ import { Agent, type Message } from "../agents/agent.js";
|
|
|
2
2
|
import type { Context } from "../execution-engine/context.js";
|
|
3
3
|
export declare abstract class ChatModel extends Agent<ChatModelInput, ChatModelOutput> {
|
|
4
4
|
constructor();
|
|
5
|
+
protected supportsParallelToolCalls: boolean;
|
|
6
|
+
getModelCapabilities(): {
|
|
7
|
+
supportsParallelToolCalls: boolean;
|
|
8
|
+
};
|
|
5
9
|
protected preprocess(input: ChatModelInput, context: Context): void;
|
|
6
10
|
protected postprocess(input: ChatModelInput, output: ChatModelOutput, context: Context): void;
|
|
7
11
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import Anthropic from "@anthropic-ai/sdk";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
import type { AgentCallOptions, AgentResponse } from "../agents/agent.js";
|
|
4
|
+
import type { Context } from "../execution-engine/context.js";
|
|
3
5
|
import { ChatModel, type ChatModelInput, type ChatModelOptions, type ChatModelOutput } from "./chat-model.js";
|
|
4
6
|
export interface ClaudeChatModelOptions {
|
|
5
7
|
apiKey?: string;
|
|
@@ -60,7 +62,7 @@ export declare class ClaudeChatModel extends ChatModel {
|
|
|
60
62
|
protected _client?: Anthropic;
|
|
61
63
|
get client(): Anthropic;
|
|
62
64
|
get modelOptions(): ChatModelOptions | undefined;
|
|
63
|
-
process(input: ChatModelInput): Promise<ChatModelOutput
|
|
65
|
+
process(input: ChatModelInput, _context: Context, options?: AgentCallOptions): Promise<AgentResponse<ChatModelOutput>>;
|
|
64
66
|
private extractResultFromClaudeStream;
|
|
65
67
|
private requestStructuredOutput;
|
|
66
68
|
}
|
|
@@ -2,4 +2,5 @@ import { OpenAIChatModel, type OpenAIChatModelOptions } from "./openai-chat-mode
|
|
|
2
2
|
export declare class OpenRouterChatModel extends OpenAIChatModel {
|
|
3
3
|
constructor(options?: OpenAIChatModelOptions);
|
|
4
4
|
protected apiKeyEnvName: string;
|
|
5
|
+
protected supportsParallelToolCalls: boolean;
|
|
5
6
|
}
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import OpenAI from "openai";
|
|
2
2
|
import type { ChatCompletionMessageParam, ChatCompletionTool } from "openai/resources";
|
|
3
|
-
import type { Stream } from "openai/streaming.js";
|
|
4
3
|
import { z } from "zod";
|
|
4
|
+
import type { AgentCallOptions, AgentResponse } from "../agents/agent.js";
|
|
5
|
+
import type { Context } from "../execution-engine/context.js";
|
|
5
6
|
import { ChatModel, type ChatModelInput, type ChatModelInputMessage, type ChatModelInputTool, type ChatModelOptions, type ChatModelOutput, type Role } from "./chat-model.js";
|
|
7
|
+
export interface OpenAIChatModelCapabilities {
|
|
8
|
+
supportsNativeStructuredOutputs: boolean;
|
|
9
|
+
supportsEndWithSystemMessage: boolean;
|
|
10
|
+
supportsToolsUseWithJsonSchema: boolean;
|
|
11
|
+
supportsParallelToolCalls: boolean;
|
|
12
|
+
supportsToolsEmptyParameters: boolean;
|
|
13
|
+
supportsTemperature: boolean;
|
|
14
|
+
}
|
|
6
15
|
export interface OpenAIChatModelOptions {
|
|
7
16
|
apiKey?: string;
|
|
8
17
|
baseURL?: string;
|
|
@@ -71,9 +80,10 @@ export declare class OpenAIChatModel extends ChatModel {
|
|
|
71
80
|
protected supportsToolsUseWithJsonSchema: boolean;
|
|
72
81
|
protected supportsParallelToolCalls: boolean;
|
|
73
82
|
protected supportsToolsEmptyParameters: boolean;
|
|
83
|
+
protected supportsTemperature: boolean;
|
|
74
84
|
get client(): OpenAI;
|
|
75
85
|
get modelOptions(): ChatModelOptions | undefined;
|
|
76
|
-
process(input: ChatModelInput): Promise<ChatModelOutput
|
|
86
|
+
process(input: ChatModelInput, _context: Context, options?: AgentCallOptions): Promise<AgentResponse<ChatModelOutput>>;
|
|
77
87
|
private getParallelToolCalls;
|
|
78
88
|
private getRunMessages;
|
|
79
89
|
private getRunResponseFormat;
|
|
@@ -87,4 +97,3 @@ export declare function toolsFromInputTools(tools?: ChatModelInputTool[], option
|
|
|
87
97
|
addTypeToEmptyParameters?: boolean;
|
|
88
98
|
}): ChatCompletionTool[] | undefined;
|
|
89
99
|
export declare function jsonSchemaToOpenAIJsonSchema(schema: Record<string, unknown>): Record<string, unknown>;
|
|
90
|
-
export declare function extractResultFromStream(stream: Stream<OpenAI.Chat.Completions.ChatCompletionChunk>, jsonMode?: boolean): Promise<ChatModelOutput>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare function customCamelize<T extends Record<string, unknown>, K extends KeyofUnion<T> = never>(obj: T, { shallowKeys }?: {
|
|
2
|
+
shallowKeys?: K[];
|
|
3
|
+
}): CustomCamelize<T, K>;
|
|
4
|
+
type KeyofUnion<U> = U extends Record<string, unknown> ? keyof U : never;
|
|
5
|
+
type CamelCase<S extends string> = S extends `${infer P1}_${infer P2}${infer P3}` ? `${P1}${Uppercase<P2>}${CamelCase<P3>}` : S;
|
|
6
|
+
declare const _unique: unique symbol;
|
|
7
|
+
type _never = typeof _unique;
|
|
8
|
+
type ExtractTypeFromUnion<T, U> = Extract<T, U> extends never ? _never : Extract<T, U> extends Array<infer E> ? Array<E> : U;
|
|
9
|
+
type ExtractTypeWithConstFromUnion<T, U> = Exclude<T, Exclude<T, U>>;
|
|
10
|
+
export type CustomCamelize<T, ShallowKeys extends KeyofUnion<T> | undefined = undefined> = ExtractTypeFromUnion<T, never> extends never ? never : ExtractTypeFromUnion<T, Date> extends Date ? ExtractTypeWithConstFromUnion<T, Date> | CustomCamelize<Exclude<T, Date>> : ExtractTypeFromUnion<T, RegExp> extends RegExp ? ExtractTypeWithConstFromUnion<T, RegExp> | CustomCamelize<Exclude<T, RegExp>> : ExtractTypeFromUnion<T, Array<unknown>> extends Array<infer U> ? Array<CustomCamelize<U>> | CustomCamelize<Exclude<T, Array<U>>> : ExtractTypeFromUnion<T, Function> extends Function ? ExtractTypeWithConstFromUnion<T, Function> | CustomCamelize<Exclude<T, Function>> : ExtractTypeFromUnion<T, object> extends object ? {
|
|
11
|
+
[K in keyof T as Uncapitalize<CamelCase<string & K>>]: K extends Exclude<ShallowKeys, undefined> ? T[K] : CustomCamelize<T[K]>;
|
|
12
|
+
} : T;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type AgentProcessAsyncGenerator, type AgentResponseChunk, type AgentResponseStream, type Message } from "../agents/agent.js";
|
|
2
|
+
import type { MESSAGE_KEY } from "../prompt/prompt-builder.js";
|
|
3
|
+
import { type PromiseOrValue } from "./type-utils.js";
|
|
4
|
+
export declare function objectToAgentResponseStream<T extends Message>(json: T): AgentResponseStream<T>;
|
|
5
|
+
export declare function mergeAgentResponseChunk<T extends Message>(output: T, chunk: AgentResponseChunk<T>): T;
|
|
6
|
+
export declare function agentResponseStreamToObject<T extends Message>(stream: AgentResponseStream<T> | AgentProcessAsyncGenerator<T>): Promise<T>;
|
|
7
|
+
export declare function asyncGeneratorToReadableStream<T extends Message>(generator: AgentProcessAsyncGenerator<T>): AgentResponseStream<T>;
|
|
8
|
+
export declare function onAgentResponseStreamEnd<T extends Message>(stream: AgentResponseStream<T>, callback: (result: T) => PromiseOrValue<Partial<T> | void>, options?: {
|
|
9
|
+
errorCallback?: (error: Error) => Error;
|
|
10
|
+
processChunk?: (chunk: AgentResponseChunk<T>) => AgentResponseChunk<T>;
|
|
11
|
+
}): ReadableStream<any>;
|
|
12
|
+
export declare function isAsyncGenerator<T extends AsyncGenerator>(value: AsyncGenerator | unknown): value is T;
|
|
13
|
+
export declare function arrayToAgentProcessAsyncGenerator<T extends Message>(chunks: (AgentResponseChunk<T> | Error)[], result?: Partial<T>): AgentProcessAsyncGenerator<T>;
|
|
14
|
+
export declare function arrayToAgentResponseStream<T>(chunks: (AgentResponseChunk<T> | Error)[]): AgentResponseStream<T>;
|
|
15
|
+
export declare function readableStreamToArray<T>(stream: ReadableStream<T>): Promise<T[]>;
|
|
16
|
+
export declare function readableStreamToAsyncIterator<T>(stream: ReadableStream<T>): AsyncIterable<T>;
|
|
17
|
+
export declare function stringToAgentResponseStream(str: string, key?: "text" | typeof MESSAGE_KEY | string): AgentResponseStream<Message>;
|
|
@@ -7,6 +7,7 @@ export declare function isEmpty(obj: unknown): boolean;
|
|
|
7
7
|
export declare function isNonNullable<T>(value: T): value is NonNullable<T>;
|
|
8
8
|
export declare function isNotEmpty<T>(arr: T[]): arr is [T, ...T[]];
|
|
9
9
|
export declare function duplicates<T>(arr: T[], key?: (item: T) => unknown): T[];
|
|
10
|
+
export declare function omitBy<T extends Record<string, unknown>, K extends keyof T>(obj: T, predicate: (value: T[K], key: K) => boolean): Partial<T>;
|
|
10
11
|
export declare function orArrayToArray<T>(value?: T | T[]): T[];
|
|
11
12
|
export declare function createAccessorArray<T>(array: T[], accessor: (array: T[], name: string) => T | undefined): T[] & {
|
|
12
13
|
[key: string]: T;
|
|
@@ -19,6 +19,9 @@ export interface AgentOptions<I extends Message = Message, O extends Message = M
|
|
|
19
19
|
disableEvents?: boolean;
|
|
20
20
|
memory?: AgentMemory | AgentMemoryOptions | true;
|
|
21
21
|
}
|
|
22
|
+
export interface AgentCallOptions {
|
|
23
|
+
streaming?: boolean;
|
|
24
|
+
}
|
|
22
25
|
export declare abstract class Agent<I extends Message = Message, O extends Message = Message> {
|
|
23
26
|
constructor({ inputSchema, outputSchema, ...options }: AgentOptions<I, O>);
|
|
24
27
|
readonly memory?: AgentMemory;
|
|
@@ -50,14 +53,38 @@ export declare abstract class Agent<I extends Message = Message, O extends Messa
|
|
|
50
53
|
get isCallable(): boolean;
|
|
51
54
|
private checkContextStatus;
|
|
52
55
|
private newDefaultContext;
|
|
53
|
-
call(input: I | string, context
|
|
56
|
+
call(input: I | string, context: Context | undefined, options: AgentCallOptions & {
|
|
57
|
+
streaming: true;
|
|
58
|
+
}): Promise<AgentResponseStream<O>>;
|
|
59
|
+
call(input: I | string, context?: Context, options?: AgentCallOptions & {
|
|
60
|
+
streaming?: false;
|
|
61
|
+
}): Promise<O>;
|
|
62
|
+
call(input: I | string, context?: Context, options?: AgentCallOptions): Promise<AgentResponse<O>>;
|
|
63
|
+
private processAgentOutput;
|
|
64
|
+
private processAgentError;
|
|
54
65
|
protected checkUsageAgentCalls(context: Context): void;
|
|
55
66
|
protected preprocess(_: I, context: Context): void;
|
|
56
67
|
protected postprocess(input: I, output: O, context: Context): void;
|
|
57
|
-
abstract process(input: I, context: Context):
|
|
68
|
+
abstract process(input: I, context: Context, options?: AgentCallOptions): AgentProcessResult<O | TransferAgentOutput>;
|
|
58
69
|
shutdown(): Promise<void>;
|
|
59
70
|
[inspect.custom](): string;
|
|
60
71
|
}
|
|
72
|
+
export type AgentResponse<T> = T | AgentResponseStream<T>;
|
|
73
|
+
export type AgentResponseStream<T> = ReadableStream<AgentResponseChunk<T>>;
|
|
74
|
+
export type AgentResponseChunk<T> = AgentResponseDelta<T>;
|
|
75
|
+
export declare function isEmptyChunk<T>(chunk: AgentResponseChunk<T>): boolean;
|
|
76
|
+
export interface AgentResponseDelta<T> {
|
|
77
|
+
delta: {
|
|
78
|
+
text?: Partial<{
|
|
79
|
+
[key in keyof T as Extract<T[key], string> extends string ? key : never]: string;
|
|
80
|
+
}> | {
|
|
81
|
+
[key: string]: string;
|
|
82
|
+
};
|
|
83
|
+
json?: Partial<T>;
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
export type AgentProcessAsyncGenerator<O extends Message> = AsyncGenerator<AgentResponseChunk<O>, Partial<O> | undefined | void>;
|
|
87
|
+
export type AgentProcessResult<O extends Message> = Promise<AgentResponse<O>> | AgentProcessAsyncGenerator<O>;
|
|
61
88
|
export type AgentInputOutputSchema<I extends Message = Message> = ZodType<I> | ((agent: Agent) => ZodType<I>);
|
|
62
89
|
export interface FunctionAgentOptions<I extends Message = Message, O extends Message = Message> extends AgentOptions<I, O> {
|
|
63
90
|
fn?: FunctionAgentFn<I, O>;
|
|
@@ -66,6 +93,6 @@ export declare class FunctionAgent<I extends Message = Message, O extends Messag
|
|
|
66
93
|
static from<I extends Message, O extends Message>(options: FunctionAgentOptions<I, O> | FunctionAgentFn<I, O>): FunctionAgent<I, O>;
|
|
67
94
|
constructor(options: FunctionAgentOptions<I, O>);
|
|
68
95
|
fn: FunctionAgentFn<I, O>;
|
|
69
|
-
process(input: I, context: Context): Promise<
|
|
96
|
+
process(input: I, context: Context, options?: AgentCallOptions): Promise<AgentResponse<O | TransferAgentOutput>>;
|
|
70
97
|
}
|
|
71
98
|
export type FunctionAgentFn<I extends Message = Message, O extends Message = Message> = (input: I, context: Context) => O | Promise<O> | Agent | Promise<Agent>;
|
package/lib/esm/agents/agent.js
CHANGED
|
@@ -2,7 +2,8 @@ import { inspect } from "node:util";
|
|
|
2
2
|
import { ZodObject, z } from "zod";
|
|
3
3
|
import { createMessage } from "../prompt/prompt-builder.js";
|
|
4
4
|
import { logger } from "../utils/logger.js";
|
|
5
|
-
import {
|
|
5
|
+
import { agentResponseStreamToObject, asyncGeneratorToReadableStream, isAsyncGenerator, objectToAgentResponseStream, onAgentResponseStreamEnd, } from "../utils/stream-utils.js";
|
|
6
|
+
import { checkArguments, createAccessorArray, isEmpty, orArrayToArray, } from "../utils/type-utils.js";
|
|
6
7
|
import { AgentMemory } from "./memory.js";
|
|
7
8
|
import { replaceTransferAgentToName, transferToAgentOutput, } from "./types.js";
|
|
8
9
|
export class Agent {
|
|
@@ -94,7 +95,7 @@ export class Agent {
|
|
|
94
95
|
async newDefaultContext() {
|
|
95
96
|
return import("../execution-engine/context.js").then((m) => new m.ExecutionContext());
|
|
96
97
|
}
|
|
97
|
-
async call(input, context) {
|
|
98
|
+
async call(input, context, options) {
|
|
98
99
|
const ctx = context ?? (await this.newDefaultContext());
|
|
99
100
|
const message = typeof input === "string" ? createMessage(input) : input;
|
|
100
101
|
logger.core("Call agent %s started with input: %O", this.name, input);
|
|
@@ -104,27 +105,51 @@ export class Agent {
|
|
|
104
105
|
const parsedInput = checkArguments(`Agent ${this.name} input`, this.inputSchema, message);
|
|
105
106
|
this.preprocess(parsedInput, ctx);
|
|
106
107
|
this.checkContextStatus(ctx);
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
return
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
108
|
+
const response = await this.process(parsedInput, ctx, options);
|
|
109
|
+
if (options?.streaming) {
|
|
110
|
+
const stream = response instanceof ReadableStream
|
|
111
|
+
? response
|
|
112
|
+
: isAsyncGenerator(response)
|
|
113
|
+
? asyncGeneratorToReadableStream(response)
|
|
114
|
+
: objectToAgentResponseStream(response);
|
|
115
|
+
return onAgentResponseStreamEnd(stream, async (result) => {
|
|
116
|
+
return await this.processAgentOutput(parsedInput, result, ctx);
|
|
117
|
+
}, {
|
|
118
|
+
errorCallback: (error) => {
|
|
119
|
+
try {
|
|
120
|
+
this.processAgentError(error, ctx);
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
return error;
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
return await this.processAgentOutput(parsedInput, response instanceof ReadableStream
|
|
129
|
+
? await agentResponseStreamToObject(response)
|
|
130
|
+
: isAsyncGenerator(response)
|
|
131
|
+
? await agentResponseStreamToObject(response)
|
|
132
|
+
: response, ctx);
|
|
120
133
|
}
|
|
121
134
|
catch (error) {
|
|
122
|
-
|
|
123
|
-
if (!this.disableEvents)
|
|
124
|
-
ctx.emit("agentFailed", { agent: this, error });
|
|
125
|
-
throw error;
|
|
135
|
+
this.processAgentError(error, ctx);
|
|
126
136
|
}
|
|
127
137
|
}
|
|
138
|
+
async processAgentOutput(input, output, context) {
|
|
139
|
+
const parsedOutput = checkArguments(`Agent ${this.name} output`, this.outputSchema, output);
|
|
140
|
+
const finalOutput = this.includeInputInOutput ? { ...input, ...parsedOutput } : parsedOutput;
|
|
141
|
+
this.postprocess(input, finalOutput, context);
|
|
142
|
+
logger.core("Call agent %s succeed with output: %O", this.name, finalOutput);
|
|
143
|
+
if (!this.disableEvents)
|
|
144
|
+
context.emit("agentSucceed", { agent: this, output: finalOutput });
|
|
145
|
+
return finalOutput;
|
|
146
|
+
}
|
|
147
|
+
processAgentError(error, context) {
|
|
148
|
+
logger.core("Call agent %s failed with error: %O", this.name, error);
|
|
149
|
+
if (!this.disableEvents)
|
|
150
|
+
context.emit("agentFailed", { agent: this, error });
|
|
151
|
+
throw error;
|
|
152
|
+
}
|
|
128
153
|
checkUsageAgentCalls(context) {
|
|
129
154
|
const { limits, usage } = context;
|
|
130
155
|
if (limits?.maxAgentCalls && usage.agentCalls >= limits.maxAgentCalls) {
|
|
@@ -152,6 +177,9 @@ export class Agent {
|
|
|
152
177
|
return this.name;
|
|
153
178
|
}
|
|
154
179
|
}
|
|
180
|
+
export function isEmptyChunk(chunk) {
|
|
181
|
+
return isEmpty(chunk.delta.json) && isEmpty(chunk.delta.text);
|
|
182
|
+
}
|
|
155
183
|
function checkAgentInputOutputSchema(schema) {
|
|
156
184
|
if (!(schema instanceof ZodObject) && typeof schema !== "function") {
|
|
157
185
|
throw new Error("schema must be a zod object or function return a zod object ");
|
|
@@ -166,12 +194,12 @@ export class FunctionAgent extends Agent {
|
|
|
166
194
|
this.fn = options.fn ?? (() => ({}));
|
|
167
195
|
}
|
|
168
196
|
fn;
|
|
169
|
-
async process(input, context) {
|
|
170
|
-
|
|
197
|
+
async process(input, context, options) {
|
|
198
|
+
let result = await this.fn(input, context);
|
|
171
199
|
if (result instanceof Agent) {
|
|
172
|
-
|
|
200
|
+
result = transferToAgentOutput(result);
|
|
173
201
|
}
|
|
174
|
-
return result;
|
|
202
|
+
return options?.streaming ? objectToAgentResponseStream(result) : result;
|
|
175
203
|
}
|
|
176
204
|
}
|
|
177
205
|
function functionToAgent(agent) {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import type { Context } from "../execution-engine/context.js";
|
|
3
3
|
import { ChatModel } from "../models/chat-model.js";
|
|
4
|
+
import type { ChatModelInput } from "../models/chat-model.js";
|
|
4
5
|
import { PromptBuilder } from "../prompt/prompt-builder.js";
|
|
5
|
-
import { Agent, type AgentOptions, type Message } from "./agent.js";
|
|
6
|
+
import { Agent, type AgentOptions, type AgentProcessAsyncGenerator, type Message } from "./agent.js";
|
|
7
|
+
import { type TransferAgentOutput } from "./types.js";
|
|
6
8
|
export interface AIAgentOptions<I extends Message = Message, O extends Message = Message> extends AgentOptions<I, O> {
|
|
7
9
|
model?: ChatModel;
|
|
8
10
|
instructions?: string | PromptBuilder;
|
|
@@ -27,35 +29,35 @@ export declare const aiAgentOptionsSchema: z.ZodObject<{
|
|
|
27
29
|
disableLogging: z.ZodOptional<z.ZodBoolean>;
|
|
28
30
|
memory: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodAny, z.ZodAny]>>;
|
|
29
31
|
}, "strip", z.ZodTypeAny, {
|
|
30
|
-
description?: string | undefined;
|
|
31
|
-
memory?: any;
|
|
32
|
-
includeInputInOutput?: boolean | undefined;
|
|
33
|
-
subscribeTopic?: string | string[] | undefined;
|
|
34
|
-
publishTopic?: string | string[] | ((...args: unknown[]) => unknown) | undefined;
|
|
35
32
|
tools?: (Agent<Message, Message> | ((...args: unknown[]) => unknown))[] | undefined;
|
|
36
33
|
toolChoice?: Agent<Message, Message> | "auto" | "none" | "required" | "router" | undefined;
|
|
37
34
|
name?: string | undefined;
|
|
35
|
+
description?: string | undefined;
|
|
38
36
|
model?: ChatModel | undefined;
|
|
39
37
|
instructions?: string | PromptBuilder | undefined;
|
|
40
38
|
outputKey?: string | undefined;
|
|
41
39
|
enableHistory?: boolean | undefined;
|
|
42
40
|
maxHistoryMessages?: number | undefined;
|
|
43
|
-
disableLogging?: boolean | undefined;
|
|
44
|
-
}, {
|
|
45
|
-
description?: string | undefined;
|
|
46
|
-
memory?: any;
|
|
47
41
|
includeInputInOutput?: boolean | undefined;
|
|
48
42
|
subscribeTopic?: string | string[] | undefined;
|
|
49
43
|
publishTopic?: string | string[] | ((...args: unknown[]) => unknown) | undefined;
|
|
44
|
+
disableLogging?: boolean | undefined;
|
|
45
|
+
memory?: any;
|
|
46
|
+
}, {
|
|
50
47
|
tools?: (Agent<Message, Message> | ((...args: unknown[]) => unknown))[] | undefined;
|
|
51
48
|
toolChoice?: Agent<Message, Message> | "auto" | "none" | "required" | "router" | undefined;
|
|
52
49
|
name?: string | undefined;
|
|
50
|
+
description?: string | undefined;
|
|
53
51
|
model?: ChatModel | undefined;
|
|
54
52
|
instructions?: string | PromptBuilder | undefined;
|
|
55
53
|
outputKey?: string | undefined;
|
|
56
54
|
enableHistory?: boolean | undefined;
|
|
57
55
|
maxHistoryMessages?: number | undefined;
|
|
56
|
+
includeInputInOutput?: boolean | undefined;
|
|
57
|
+
subscribeTopic?: string | string[] | undefined;
|
|
58
|
+
publishTopic?: string | string[] | ((...args: unknown[]) => unknown) | undefined;
|
|
58
59
|
disableLogging?: boolean | undefined;
|
|
60
|
+
memory?: any;
|
|
59
61
|
}>;
|
|
60
62
|
export declare class AIAgent<I extends Message = Message, O extends Message = Message> extends Agent<I, O> {
|
|
61
63
|
static from<I extends Message, O extends Message>(options: AIAgentOptions<I, O>): AIAgent<I, O>;
|
|
@@ -64,5 +66,6 @@ export declare class AIAgent<I extends Message = Message, O extends Message = Me
|
|
|
64
66
|
instructions: PromptBuilder;
|
|
65
67
|
outputKey?: string;
|
|
66
68
|
toolChoice?: AIAgentToolChoice;
|
|
67
|
-
process(input: I, context: Context):
|
|
69
|
+
process(input: I, context: Context): AgentProcessAsyncGenerator<O | TransferAgentOutput>;
|
|
70
|
+
processRouter(input: I, model: ChatModel, modelInput: ChatModelInput, context: Context, toolsMap: Map<string, Agent>): AgentProcessAsyncGenerator<O | TransferAgentOutput>;
|
|
68
71
|
}
|
|
@@ -2,7 +2,9 @@ import { z } from "zod";
|
|
|
2
2
|
import { ChatModel } from "../models/chat-model.js";
|
|
3
3
|
import { MESSAGE_KEY, PromptBuilder } from "../prompt/prompt-builder.js";
|
|
4
4
|
import { AgentMessageTemplate, ToolMessageTemplate } from "../prompt/template.js";
|
|
5
|
-
import {
|
|
5
|
+
import { readableStreamToAsyncIterator } from "../utils/stream-utils.js";
|
|
6
|
+
import { isEmpty } from "../utils/type-utils.js";
|
|
7
|
+
import { Agent, } from "./agent.js";
|
|
6
8
|
import { isTransferAgentOutput } from "./types.js";
|
|
7
9
|
export const aiAgentToolChoiceSchema = z.union([
|
|
8
10
|
z.literal("auto"),
|
|
@@ -46,23 +48,35 @@ export class AIAgent extends Agent {
|
|
|
46
48
|
instructions;
|
|
47
49
|
outputKey;
|
|
48
50
|
toolChoice;
|
|
49
|
-
async process(input, context) {
|
|
51
|
+
async *process(input, context) {
|
|
50
52
|
const model = context.model ?? this.model;
|
|
51
53
|
if (!model)
|
|
52
54
|
throw new Error("model is required to run AIAgent");
|
|
53
|
-
const { toolAgents,
|
|
55
|
+
const { toolAgents, ...modelInput } = await this.instructions.build({
|
|
54
56
|
agent: this,
|
|
55
57
|
input,
|
|
56
58
|
model,
|
|
57
59
|
context,
|
|
58
60
|
});
|
|
59
61
|
const toolsMap = new Map(toolAgents?.map((i) => [i.name, i]));
|
|
62
|
+
if (this.toolChoice === "router") {
|
|
63
|
+
yield* this.processRouter(input, model, modelInput, context, toolsMap);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
60
66
|
const toolCallMessages = [];
|
|
67
|
+
const outputKey = this.outputKey || MESSAGE_KEY;
|
|
61
68
|
for (;;) {
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
const modelOutput = {};
|
|
70
|
+
const stream = await context.call(model, { ...modelInput, messages: modelInput.messages.concat(toolCallMessages) }, { streaming: true });
|
|
71
|
+
for await (const value of readableStreamToAsyncIterator(stream)) {
|
|
72
|
+
if (value.delta.text?.text) {
|
|
73
|
+
yield { delta: { text: { [outputKey]: value.delta.text.text } } };
|
|
74
|
+
}
|
|
75
|
+
if (value.delta.json) {
|
|
76
|
+
Object.assign(modelOutput, value.delta.json);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const { toolCalls, json, text } = modelOutput;
|
|
66
80
|
if (toolCalls?.length) {
|
|
67
81
|
const executedToolCalls = [];
|
|
68
82
|
// Execute tools
|
|
@@ -81,14 +95,6 @@ export class AIAgent extends Agent {
|
|
|
81
95
|
// Continue LLM function calling loop if any tools were executed
|
|
82
96
|
if (executedToolCalls.length) {
|
|
83
97
|
toolCallMessages.push(AgentMessageTemplate.from(undefined, executedToolCalls.map(({ call }) => call)).format(), ...executedToolCalls.map(({ call, output }) => ToolMessageTemplate.from(output, call.id).format()));
|
|
84
|
-
// Return the output of the first tool if the toolChoice is "router"
|
|
85
|
-
if (this.toolChoice === "router") {
|
|
86
|
-
const output = executedToolCalls[0]?.output;
|
|
87
|
-
if (!output || executedToolCalls.length !== 1) {
|
|
88
|
-
throw new Error("Router toolChoice requires exactly one tool to be executed");
|
|
89
|
-
}
|
|
90
|
-
return output;
|
|
91
|
-
}
|
|
92
98
|
continue;
|
|
93
99
|
}
|
|
94
100
|
}
|
|
@@ -96,11 +102,24 @@ export class AIAgent extends Agent {
|
|
|
96
102
|
if (modelInput.responseFormat?.type === "json_schema") {
|
|
97
103
|
Object.assign(result, json);
|
|
98
104
|
}
|
|
99
|
-
else {
|
|
100
|
-
const outputKey = this.outputKey || MESSAGE_KEY;
|
|
105
|
+
else if (text) {
|
|
101
106
|
Object.assign(result, { [outputKey]: text });
|
|
102
107
|
}
|
|
103
|
-
|
|
108
|
+
if (!isEmpty(result)) {
|
|
109
|
+
yield { delta: { json: result } };
|
|
110
|
+
}
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async *processRouter(input, model, modelInput, context, toolsMap) {
|
|
115
|
+
const { toolCalls: [call] = [], } = await context.call(model, modelInput);
|
|
116
|
+
if (!call) {
|
|
117
|
+
throw new Error("Router toolChoice requires exactly one tool to be executed");
|
|
104
118
|
}
|
|
119
|
+
const tool = toolsMap.get(call.function.name);
|
|
120
|
+
if (!tool)
|
|
121
|
+
throw new Error(`Tool not found: ${call.function.name}`);
|
|
122
|
+
const stream = await context.call(tool, { ...call.function.arguments, ...input }, { streaming: true });
|
|
123
|
+
yield* readableStreamToAsyncIterator(stream);
|
|
105
124
|
}
|
|
106
125
|
}
|
|
@@ -2,7 +2,7 @@ import { ReadableStream } from "node:stream/web";
|
|
|
2
2
|
import { type Context, type Runnable } from "../execution-engine/context.js";
|
|
3
3
|
import type { MessagePayload } from "../execution-engine/message-queue.js";
|
|
4
4
|
import { type PromiseOrValue } from "../utils/type-utils.js";
|
|
5
|
-
import { Agent, type AgentOptions, type Message } from "./agent.js";
|
|
5
|
+
import { Agent, type AgentOptions, type AgentProcessAsyncGenerator, type Message } from "./agent.js";
|
|
6
6
|
export interface UserAgentOptions<I extends Message = Message, O extends Message = Message> extends AgentOptions<I, O> {
|
|
7
7
|
context: Context;
|
|
8
8
|
process?: (input: I, context: Context) => PromiseOrValue<O>;
|
|
@@ -14,8 +14,8 @@ export declare class UserAgent<I extends Message = Message, O extends Message =
|
|
|
14
14
|
context: Context;
|
|
15
15
|
private _process?;
|
|
16
16
|
private activeAgent?;
|
|
17
|
-
call
|
|
18
|
-
process(input: I, context: Context):
|
|
17
|
+
call: Agent<I, O>["call"];
|
|
18
|
+
process(input: I, context: Context): AgentProcessAsyncGenerator<O>;
|
|
19
19
|
publish: Context["publish"];
|
|
20
20
|
subscribe: Context["subscribe"];
|
|
21
21
|
unsubscribe: Context["unsubscribe"];
|