@aigne/core 1.18.6 → 1.20.1
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 +28 -0
- package/lib/cjs/agents/agent.d.ts +31 -8
- package/lib/cjs/agents/agent.js +31 -22
- package/lib/cjs/agents/ai-agent.d.ts +18 -6
- package/lib/cjs/agents/ai-agent.js +23 -12
- package/lib/cjs/agents/guide-rail-agent.d.ts +1 -1
- package/lib/cjs/agents/mcp-agent.d.ts +1 -1
- package/lib/cjs/agents/team-agent.js +1 -1
- package/lib/cjs/aigne/aigne.d.ts +10 -10
- package/lib/cjs/aigne/context.d.ts +11 -6
- package/lib/cjs/aigne/context.js +73 -48
- package/lib/cjs/aigne/message-queue.d.ts +1 -1
- package/lib/cjs/aigne/message-queue.js +2 -3
- package/lib/cjs/aigne/usage.d.ts +1 -0
- package/lib/cjs/aigne/usage.js +1 -0
- package/lib/cjs/loader/agent-yaml.d.ts +2 -1
- package/lib/cjs/loader/agent-yaml.js +4 -0
- package/lib/cjs/prompt/prompt-builder.d.ts +2 -16
- package/lib/cjs/prompt/prompt-builder.js +12 -25
- package/lib/cjs/utils/event-stream.d.ts +5 -1
- package/lib/cjs/utils/event-stream.js +88 -23
- package/lib/cjs/utils/stream-utils.d.ts +9 -7
- package/lib/cjs/utils/stream-utils.js +48 -15
- package/lib/cjs/utils/type-utils.d.ts +2 -0
- package/lib/cjs/utils/type-utils.js +18 -0
- package/lib/dts/agents/agent.d.ts +31 -8
- package/lib/dts/agents/ai-agent.d.ts +18 -6
- package/lib/dts/agents/guide-rail-agent.d.ts +1 -1
- package/lib/dts/agents/mcp-agent.d.ts +1 -1
- package/lib/dts/aigne/aigne.d.ts +10 -10
- package/lib/dts/aigne/context.d.ts +11 -6
- package/lib/dts/aigne/message-queue.d.ts +1 -1
- package/lib/dts/aigne/usage.d.ts +1 -0
- package/lib/dts/loader/agent-yaml.d.ts +2 -1
- package/lib/dts/prompt/prompt-builder.d.ts +2 -16
- package/lib/dts/utils/event-stream.d.ts +5 -1
- package/lib/dts/utils/stream-utils.d.ts +9 -7
- package/lib/dts/utils/type-utils.d.ts +2 -0
- package/lib/esm/agents/agent.d.ts +31 -8
- package/lib/esm/agents/agent.js +29 -22
- package/lib/esm/agents/ai-agent.d.ts +18 -6
- package/lib/esm/agents/ai-agent.js +25 -14
- package/lib/esm/agents/guide-rail-agent.d.ts +1 -1
- package/lib/esm/agents/mcp-agent.d.ts +1 -1
- package/lib/esm/agents/team-agent.js +2 -2
- package/lib/esm/aigne/aigne.d.ts +10 -10
- package/lib/esm/aigne/context.d.ts +11 -6
- package/lib/esm/aigne/context.js +76 -51
- package/lib/esm/aigne/message-queue.d.ts +1 -1
- package/lib/esm/aigne/message-queue.js +2 -3
- package/lib/esm/aigne/usage.d.ts +1 -0
- package/lib/esm/aigne/usage.js +1 -0
- package/lib/esm/loader/agent-yaml.d.ts +2 -1
- package/lib/esm/loader/agent-yaml.js +4 -0
- package/lib/esm/prompt/prompt-builder.d.ts +2 -16
- package/lib/esm/prompt/prompt-builder.js +12 -23
- package/lib/esm/utils/event-stream.d.ts +5 -1
- package/lib/esm/utils/event-stream.js +86 -22
- package/lib/esm/utils/stream-utils.d.ts +9 -7
- package/lib/esm/utils/stream-utils.js +48 -16
- package/lib/esm/utils/type-utils.d.ts +2 -0
- package/lib/esm/utils/type-utils.js +16 -0
- package/package.json +2 -2
package/lib/esm/aigne/context.js
CHANGED
|
@@ -2,13 +2,13 @@ import equal from "fast-deep-equal";
|
|
|
2
2
|
import { Emitter } from "strict-event-emitter";
|
|
3
3
|
import { v7 } from "uuid";
|
|
4
4
|
import { z } from "zod";
|
|
5
|
-
import { Agent, isEmptyChunk, } from "../agents/agent.js";
|
|
5
|
+
import { Agent, isAgentResponseDelta, isEmptyChunk, } from "../agents/agent.js";
|
|
6
6
|
import { isTransferAgentOutput, transferAgentOutputKey, } from "../agents/types.js";
|
|
7
7
|
import { UserAgent } from "../agents/user-agent.js";
|
|
8
|
-
import {
|
|
8
|
+
import { AgentResponseProgressStream } from "../utils/event-stream.js";
|
|
9
9
|
import { promiseWithResolvers } from "../utils/promise.js";
|
|
10
|
-
import { agentResponseStreamToObject, asyncGeneratorToReadableStream, onAgentResponseStreamEnd, } from "../utils/stream-utils.js";
|
|
11
|
-
import { checkArguments, isEmpty, isNil,
|
|
10
|
+
import { agentResponseStreamToObject, asyncGeneratorToReadableStream, mergeReadableStreams, onAgentResponseStreamEnd, } from "../utils/stream-utils.js";
|
|
11
|
+
import { checkArguments, isEmpty, isNil, omit, } from "../utils/type-utils.js";
|
|
12
12
|
import { MessageQueue, toMessagePayload, } from "./message-queue.js";
|
|
13
13
|
import { newEmptyContextUsage } from "./usage.js";
|
|
14
14
|
/**
|
|
@@ -80,38 +80,54 @@ export class AIGNEContext {
|
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
const newContext = this.newContext();
|
|
83
|
-
|
|
84
|
-
return Promise.resolve(newContext.internal.invoke(agent, msg, newContext, options)).then(async (response) => {
|
|
83
|
+
return Promise.resolve(newContext.internal.invoke(agent, message, newContext, options)).then(async (response) => {
|
|
85
84
|
if (!options?.streaming) {
|
|
86
|
-
|
|
85
|
+
let { __activeAgent__: activeAgent, ...output } = await agentResponseStreamToObject(response);
|
|
86
|
+
output = await this.onInvocationResult(output, options);
|
|
87
87
|
if (options?.returnActiveAgent) {
|
|
88
88
|
return [output, activeAgent];
|
|
89
89
|
}
|
|
90
90
|
return output;
|
|
91
91
|
}
|
|
92
92
|
const activeAgentPromise = promiseWithResolvers();
|
|
93
|
-
const stream = onAgentResponseStreamEnd(asyncGeneratorToReadableStream(response),
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
processChunk(chunk) {
|
|
97
|
-
if (chunk.delta.json) {
|
|
93
|
+
const stream = onAgentResponseStreamEnd(asyncGeneratorToReadableStream(response), {
|
|
94
|
+
onChunk(chunk) {
|
|
95
|
+
if (isAgentResponseDelta(chunk) && chunk.delta.json) {
|
|
98
96
|
return {
|
|
99
97
|
...chunk,
|
|
100
98
|
delta: {
|
|
101
99
|
...chunk.delta,
|
|
102
|
-
json:
|
|
100
|
+
json: omit(chunk.delta.json, "__activeAgent__"),
|
|
103
101
|
},
|
|
104
102
|
};
|
|
105
103
|
}
|
|
106
|
-
|
|
104
|
+
},
|
|
105
|
+
onResult: async (output) => {
|
|
106
|
+
activeAgentPromise.resolve(output.__activeAgent__);
|
|
107
|
+
return await this.onInvocationResult(output, options);
|
|
107
108
|
},
|
|
108
109
|
});
|
|
110
|
+
const finalStream = !options.returnProgressChunks
|
|
111
|
+
? stream
|
|
112
|
+
: mergeReadableStreams(stream, new AgentResponseProgressStream(newContext));
|
|
109
113
|
if (options.returnActiveAgent) {
|
|
110
|
-
return [
|
|
114
|
+
return [finalStream, activeAgentPromise.promise];
|
|
111
115
|
}
|
|
112
|
-
return
|
|
116
|
+
return finalStream;
|
|
113
117
|
});
|
|
114
118
|
});
|
|
119
|
+
async onInvocationResult(output, options) {
|
|
120
|
+
if (!options?.returnMetadata) {
|
|
121
|
+
return output;
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
...output,
|
|
125
|
+
$meta: {
|
|
126
|
+
...output.$meta,
|
|
127
|
+
usage: this.usage,
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
}
|
|
115
131
|
publish = ((topic, payload, options) => {
|
|
116
132
|
if (options?.userContext) {
|
|
117
133
|
Object.assign(this.userContext, options.userContext);
|
|
@@ -164,7 +180,6 @@ class AIGNEContextShared {
|
|
|
164
180
|
this.memories = overrides?.memories ?? [];
|
|
165
181
|
}
|
|
166
182
|
messageQueue;
|
|
167
|
-
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
168
183
|
events = new Emitter();
|
|
169
184
|
get model() {
|
|
170
185
|
return this.parent?.model;
|
|
@@ -198,44 +213,54 @@ class AIGNEContextShared {
|
|
|
198
213
|
return withAbortSignal(this.abortController.signal, new Error("AIGNEContext is timeout"), () => this.invokeAgent(agent, input, context, options));
|
|
199
214
|
}
|
|
200
215
|
async *invokeAgent(agent, input, context, options) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
for await (const value of stream) {
|
|
214
|
-
if (value.delta.json) {
|
|
215
|
-
value.delta.json = omitExistsProperties(result, value.delta.json);
|
|
216
|
-
Object.assign(result, value.delta.json);
|
|
216
|
+
const startedAt = Date.now();
|
|
217
|
+
try {
|
|
218
|
+
let activeAgent = agent;
|
|
219
|
+
for (;;) {
|
|
220
|
+
const result = {};
|
|
221
|
+
if (options?.sourceAgent && activeAgent !== options.sourceAgent) {
|
|
222
|
+
options.sourceAgent.hooks.onHandoff?.({
|
|
223
|
+
context,
|
|
224
|
+
source: options.sourceAgent,
|
|
225
|
+
target: activeAgent,
|
|
226
|
+
input,
|
|
227
|
+
});
|
|
217
228
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
229
|
+
const stream = await activeAgent.invoke(input, { ...options, context, streaming: true });
|
|
230
|
+
for await (const value of stream) {
|
|
231
|
+
if (isAgentResponseDelta(value)) {
|
|
232
|
+
if (value.delta.json) {
|
|
233
|
+
value.delta.json = omitExistsProperties(result, value.delta.json);
|
|
234
|
+
Object.assign(result, value.delta.json);
|
|
235
|
+
}
|
|
236
|
+
delete value.delta.json?.[transferAgentOutputKey];
|
|
237
|
+
}
|
|
238
|
+
if (isEmptyChunk(value))
|
|
239
|
+
continue;
|
|
240
|
+
yield value;
|
|
241
|
+
}
|
|
242
|
+
if (!options?.disableTransfer) {
|
|
243
|
+
const transferToAgent = isTransferAgentOutput(result)
|
|
244
|
+
? result[transferAgentOutputKey].agent
|
|
245
|
+
: undefined;
|
|
246
|
+
if (transferToAgent) {
|
|
247
|
+
activeAgent = transferToAgent;
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
230
250
|
}
|
|
251
|
+
break;
|
|
231
252
|
}
|
|
232
|
-
|
|
253
|
+
yield {
|
|
254
|
+
delta: {
|
|
255
|
+
json: { __activeAgent__: activeAgent },
|
|
256
|
+
},
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
finally {
|
|
260
|
+
const endedAt = Date.now();
|
|
261
|
+
const duration = endedAt - startedAt;
|
|
262
|
+
this.usage.duration += duration;
|
|
233
263
|
}
|
|
234
|
-
yield {
|
|
235
|
-
delta: {
|
|
236
|
-
json: { __activeAgent__: activeAgent },
|
|
237
|
-
},
|
|
238
|
-
};
|
|
239
264
|
}
|
|
240
265
|
}
|
|
241
266
|
function omitExistsProperties(result, { ...delta }) {
|
|
@@ -21,7 +21,7 @@ export interface MessagePayload {
|
|
|
21
21
|
/**
|
|
22
22
|
* @hidden
|
|
23
23
|
*/
|
|
24
|
-
export declare function toMessagePayload(payload: Omit<MessagePayload, "context"> |
|
|
24
|
+
export declare function toMessagePayload(payload: Omit<MessagePayload, "context"> | Message, options?: Partial<Pick<MessagePayload, "role" | "source">>): Omit<MessagePayload, "context">;
|
|
25
25
|
/**
|
|
26
26
|
* @hidden
|
|
27
27
|
*/
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Emitter } from "strict-event-emitter";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { createMessage } from "../prompt/prompt-builder.js";
|
|
4
3
|
import { checkArguments, isNil, orArrayToArray } from "../utils/type-utils.js";
|
|
5
4
|
/**
|
|
6
5
|
* @hidden
|
|
@@ -24,12 +23,12 @@ function isMessagePayload(payload) {
|
|
|
24
23
|
*/
|
|
25
24
|
export function toMessagePayload(payload, options) {
|
|
26
25
|
if (isMessagePayload(payload)) {
|
|
27
|
-
return { ...payload,
|
|
26
|
+
return { ...payload, ...options };
|
|
28
27
|
}
|
|
29
28
|
return {
|
|
30
29
|
role: options?.role || "user",
|
|
31
30
|
source: options?.source,
|
|
32
|
-
message:
|
|
31
|
+
message: payload,
|
|
33
32
|
};
|
|
34
33
|
}
|
|
35
34
|
/**
|
package/lib/esm/aigne/usage.d.ts
CHANGED
package/lib/esm/aigne/usage.js
CHANGED
|
@@ -5,11 +5,11 @@ export declare function loadAgentFromYamlFile(path: string): Promise<{
|
|
|
5
5
|
name: string;
|
|
6
6
|
description?: string | undefined;
|
|
7
7
|
skills?: string[] | undefined;
|
|
8
|
-
instructions?: string | undefined;
|
|
9
8
|
memory?: true | {
|
|
10
9
|
provider: string;
|
|
11
10
|
subscribeTopic?: string[] | undefined;
|
|
12
11
|
} | undefined;
|
|
12
|
+
instructions?: string | undefined;
|
|
13
13
|
inputSchema?: ZodObject<Record<string, ZodType<any, z.ZodTypeDef, any>>, z.UnknownKeysParam, z.ZodTypeAny, {
|
|
14
14
|
[x: string]: any;
|
|
15
15
|
}, {
|
|
@@ -20,6 +20,7 @@ export declare function loadAgentFromYamlFile(path: string): Promise<{
|
|
|
20
20
|
}, {
|
|
21
21
|
[x: string]: any;
|
|
22
22
|
}> | undefined;
|
|
23
|
+
inputKey?: string | undefined;
|
|
23
24
|
outputKey?: string | undefined;
|
|
24
25
|
toolChoice?: AIAgentToolChoice | undefined;
|
|
25
26
|
} | {
|
|
@@ -18,6 +18,10 @@ const agentFileSchema = z.discriminatedUnion("type", [
|
|
|
18
18
|
.string()
|
|
19
19
|
.nullish()
|
|
20
20
|
.transform((v) => v ?? undefined),
|
|
21
|
+
input_key: z
|
|
22
|
+
.string()
|
|
23
|
+
.nullish()
|
|
24
|
+
.transform((v) => v ?? undefined),
|
|
21
25
|
input_schema: inputOutputSchema
|
|
22
26
|
.nullish()
|
|
23
27
|
.transform((v) => (v ? jsonSchemaToZod(v) : undefined)),
|
|
@@ -3,33 +3,19 @@ import { Agent, type AgentInvokeOptions, type Message } from "../agents/agent.js
|
|
|
3
3
|
import type { AIAgent } from "../agents/ai-agent.js";
|
|
4
4
|
import type { ChatModel, ChatModelInput } from "../agents/chat-model.js";
|
|
5
5
|
import { ChatMessagesTemplate } from "./template.js";
|
|
6
|
-
export declare const MESSAGE_KEY = "$message";
|
|
7
|
-
export declare function createMessage<V extends Message>(message: string, variables?: V): {
|
|
8
|
-
[MESSAGE_KEY]: string;
|
|
9
|
-
} & typeof variables;
|
|
10
|
-
export declare function createMessage<I extends Message, V extends Message>(message: I, variables?: V): I & typeof variables;
|
|
11
|
-
export declare function createMessage<I extends Message, V extends Message>(message: string | I, variables?: V): ({
|
|
12
|
-
[MESSAGE_KEY]: string;
|
|
13
|
-
} | I) & typeof variables;
|
|
14
|
-
export declare function getMessage(input: Message): string | undefined;
|
|
15
6
|
export interface PromptBuilderOptions {
|
|
16
7
|
instructions?: string | ChatMessagesTemplate;
|
|
17
8
|
}
|
|
18
9
|
export interface PromptBuildOptions extends Pick<AgentInvokeOptions, "context"> {
|
|
19
|
-
agent?: AIAgent
|
|
10
|
+
agent?: AIAgent<any, any, any>;
|
|
20
11
|
input?: Message;
|
|
21
12
|
model?: ChatModel;
|
|
22
13
|
outputSchema?: Agent["outputSchema"];
|
|
23
14
|
}
|
|
24
15
|
export declare class PromptBuilder {
|
|
25
|
-
static from(instructions: string): PromptBuilder;
|
|
26
|
-
static from(instructions: GetPromptResult): PromptBuilder;
|
|
27
|
-
static from(instructions: {
|
|
28
|
-
path: string;
|
|
29
|
-
}): Promise<PromptBuilder>;
|
|
30
16
|
static from(instructions: string | {
|
|
31
17
|
path: string;
|
|
32
|
-
} | GetPromptResult): PromptBuilder
|
|
18
|
+
} | GetPromptResult): PromptBuilder;
|
|
33
19
|
private static fromFile;
|
|
34
20
|
private static fromMCPPromptResult;
|
|
35
21
|
constructor(options?: PromptBuilderOptions);
|
|
@@ -3,23 +3,9 @@ import { stringify } from "yaml";
|
|
|
3
3
|
import { ZodObject } from "zod";
|
|
4
4
|
import { Agent } from "../agents/agent.js";
|
|
5
5
|
import { outputSchemaToResponseFormatSchema } from "../utils/json-schema.js";
|
|
6
|
-
import {
|
|
6
|
+
import { unique } from "../utils/type-utils.js";
|
|
7
7
|
import { MEMORY_MESSAGE_TEMPLATE } from "./prompts/memory-message-template.js";
|
|
8
8
|
import { AgentMessageTemplate, ChatMessagesTemplate, PromptTemplate, SystemMessageTemplate, UserMessageTemplate, } from "./template.js";
|
|
9
|
-
export const MESSAGE_KEY = "$message";
|
|
10
|
-
export function createMessage(message, variables) {
|
|
11
|
-
return (typeof message === "string"
|
|
12
|
-
? { [MESSAGE_KEY]: message, ...variables }
|
|
13
|
-
: { ...message, ...variables });
|
|
14
|
-
}
|
|
15
|
-
export function getMessage(input) {
|
|
16
|
-
const userInputMessage = input[MESSAGE_KEY];
|
|
17
|
-
if (typeof userInputMessage === "string")
|
|
18
|
-
return userInputMessage;
|
|
19
|
-
if (!isNil(userInputMessage))
|
|
20
|
-
return JSON.stringify(userInputMessage);
|
|
21
|
-
return undefined;
|
|
22
|
-
}
|
|
23
9
|
export class PromptBuilder {
|
|
24
10
|
static from(instructions) {
|
|
25
11
|
if (typeof instructions === "string")
|
|
@@ -30,8 +16,8 @@ export class PromptBuilder {
|
|
|
30
16
|
return PromptBuilder.fromFile(instructions.path);
|
|
31
17
|
throw new Error(`Invalid instructions ${instructions}`);
|
|
32
18
|
}
|
|
33
|
-
static
|
|
34
|
-
const text =
|
|
19
|
+
static fromFile(path) {
|
|
20
|
+
const text = nodejs.fsSync.readFileSync(path, "utf-8");
|
|
35
21
|
return PromptBuilder.from(text);
|
|
36
22
|
}
|
|
37
23
|
static fromMCPPromptResult(result) {
|
|
@@ -75,22 +61,25 @@ export class PromptBuilder {
|
|
|
75
61
|
}
|
|
76
62
|
async buildMessages(options) {
|
|
77
63
|
const { input } = options;
|
|
64
|
+
const inputKey = options.agent?.inputKey;
|
|
65
|
+
const message = inputKey && typeof input?.[inputKey] === "string" ? input[inputKey] : undefined;
|
|
78
66
|
const messages = (typeof this.instructions === "string"
|
|
79
67
|
? ChatMessagesTemplate.from([SystemMessageTemplate.from(this.instructions)])
|
|
80
68
|
: this.instructions)?.format(options.input) ?? [];
|
|
81
69
|
const memories = [];
|
|
82
|
-
if (options.agent) {
|
|
83
|
-
memories.push(...(await options.agent.retrieveMemories({ search:
|
|
70
|
+
if (options.agent?.inputKey) {
|
|
71
|
+
memories.push(...(await options.agent.retrieveMemories({ search: message }, options)));
|
|
84
72
|
}
|
|
85
73
|
if (options.context.memories?.length) {
|
|
86
74
|
memories.push(...options.context.memories);
|
|
87
75
|
}
|
|
88
76
|
if (memories.length)
|
|
89
77
|
messages.push(...this.convertMemoriesToMessages(memories, options));
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
78
|
+
if (message) {
|
|
79
|
+
messages.push({
|
|
80
|
+
role: "user",
|
|
81
|
+
content: message,
|
|
82
|
+
});
|
|
94
83
|
}
|
|
95
84
|
return messages;
|
|
96
85
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type AgentResponseChunk, type AgentResponseProgress, type AgentResponseStream, type Message } from "../agents/agent.js";
|
|
2
|
+
import type { Context } from "../aigne/context.js";
|
|
2
3
|
export declare class EventStreamParser<T> extends TransformStream<string, T | Error> {
|
|
3
4
|
constructor();
|
|
4
5
|
}
|
|
@@ -9,3 +10,6 @@ export declare class AgentResponseStreamParser<O extends Message> extends Transf
|
|
|
9
10
|
export declare class AgentResponseStreamSSE<O extends Message> extends ReadableStream<string> {
|
|
10
11
|
constructor(stream: AgentResponseStream<O>);
|
|
11
12
|
}
|
|
13
|
+
export declare class AgentResponseProgressStream extends ReadableStream<AgentResponseProgress> {
|
|
14
|
+
constructor(context: Context);
|
|
15
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createParser } from "eventsource-parser";
|
|
2
2
|
import { produce } from "immer";
|
|
3
|
+
import { isAgentResponseDelta, isAgentResponseProgress, } from "../agents/agent.js";
|
|
3
4
|
import { tryOrThrow } from "./type-utils.js";
|
|
4
5
|
export class EventStreamParser extends TransformStream {
|
|
5
6
|
constructor() {
|
|
@@ -12,11 +13,16 @@ export class EventStreamParser extends TransformStream {
|
|
|
12
13
|
controller.enqueue(new Error(`Parse response chunk json error: ${e.message} ${event.data}`));
|
|
13
14
|
});
|
|
14
15
|
if (json) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
switch (event.event) {
|
|
17
|
+
case "error":
|
|
18
|
+
controller.enqueue(new Error(json.message));
|
|
19
|
+
break;
|
|
20
|
+
default: {
|
|
21
|
+
if (!event.event)
|
|
22
|
+
controller.enqueue(json);
|
|
23
|
+
else
|
|
24
|
+
console.warn(`Unknown event type: ${event.event}`, event.data);
|
|
25
|
+
}
|
|
20
26
|
}
|
|
21
27
|
}
|
|
22
28
|
},
|
|
@@ -38,25 +44,35 @@ export class AgentResponseStreamParser extends TransformStream {
|
|
|
38
44
|
controller.terminate();
|
|
39
45
|
return;
|
|
40
46
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
if (isAgentResponseDelta(chunk)) {
|
|
48
|
+
this.json = produce(this.json, (draft) => {
|
|
49
|
+
if (chunk.delta.json)
|
|
50
|
+
Object.assign(draft, chunk.delta.json);
|
|
51
|
+
if (chunk.delta.text) {
|
|
52
|
+
for (const [key, text] of Object.entries(chunk.delta.text)) {
|
|
53
|
+
const original = draft[key];
|
|
54
|
+
const t = (original || "") + (text || "");
|
|
55
|
+
if (t)
|
|
56
|
+
Object.assign(draft, { [key]: t });
|
|
57
|
+
}
|
|
50
58
|
}
|
|
59
|
+
});
|
|
60
|
+
controller.enqueue({
|
|
61
|
+
...chunk,
|
|
62
|
+
delta: {
|
|
63
|
+
...chunk.delta,
|
|
64
|
+
json: this.json,
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
else if (isAgentResponseProgress(chunk)) {
|
|
69
|
+
if (chunk.progress.event === "agentFailed") {
|
|
70
|
+
const { name, message } = chunk.progress.error;
|
|
71
|
+
chunk.progress.error = new Error(message);
|
|
72
|
+
chunk.progress.error.name = name;
|
|
51
73
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
...chunk,
|
|
55
|
-
delta: {
|
|
56
|
-
...chunk.delta,
|
|
57
|
-
json: this.json,
|
|
58
|
-
},
|
|
59
|
-
});
|
|
74
|
+
controller.enqueue(chunk);
|
|
75
|
+
}
|
|
60
76
|
},
|
|
61
77
|
});
|
|
62
78
|
}
|
|
@@ -73,6 +89,14 @@ export class AgentResponseStreamSSE extends ReadableStream {
|
|
|
73
89
|
controller.close();
|
|
74
90
|
return;
|
|
75
91
|
}
|
|
92
|
+
if (isAgentResponseProgress(value)) {
|
|
93
|
+
if (value.progress.event === "agentFailed") {
|
|
94
|
+
value.progress.error = {
|
|
95
|
+
name: value.progress.error.name,
|
|
96
|
+
message: value.progress.error.message,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
76
100
|
controller.enqueue(`data: ${JSON.stringify(value)}\n\n`);
|
|
77
101
|
}
|
|
78
102
|
catch (error) {
|
|
@@ -83,3 +107,43 @@ export class AgentResponseStreamSSE extends ReadableStream {
|
|
|
83
107
|
});
|
|
84
108
|
}
|
|
85
109
|
}
|
|
110
|
+
export class AgentResponseProgressStream extends ReadableStream {
|
|
111
|
+
constructor(context) {
|
|
112
|
+
super({
|
|
113
|
+
async start(controller) {
|
|
114
|
+
const writeEvent = (eventName, event) => {
|
|
115
|
+
const progress = {
|
|
116
|
+
...event,
|
|
117
|
+
event: eventName,
|
|
118
|
+
agent: { name: event.agent.name },
|
|
119
|
+
};
|
|
120
|
+
controller.enqueue({ progress });
|
|
121
|
+
};
|
|
122
|
+
const close = () => {
|
|
123
|
+
context.off("agentStarted", onAgentStarted);
|
|
124
|
+
context.off("agentSucceed", onAgentSucceed);
|
|
125
|
+
context.off("agentFailed", onAgentFailed);
|
|
126
|
+
controller.close();
|
|
127
|
+
};
|
|
128
|
+
const onAgentStarted = (event) => {
|
|
129
|
+
writeEvent("agentStarted", event);
|
|
130
|
+
};
|
|
131
|
+
const onAgentSucceed = (event) => {
|
|
132
|
+
writeEvent("agentSucceed", event);
|
|
133
|
+
if (event.contextId === context.id) {
|
|
134
|
+
close();
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
const onAgentFailed = (event) => {
|
|
138
|
+
writeEvent("agentFailed", event);
|
|
139
|
+
if (event.contextId === context.id) {
|
|
140
|
+
close();
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
context.on("agentStarted", onAgentStarted);
|
|
144
|
+
context.on("agentSucceed", onAgentSucceed);
|
|
145
|
+
context.on("agentFailed", onAgentFailed);
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
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
2
|
import { type PromiseOrValue } from "./type-utils.js";
|
|
4
3
|
import "./stream-polyfill.js";
|
|
5
4
|
export declare function objectToAgentResponseStream<T extends Message>(json: T): AgentResponseStream<T>;
|
|
6
5
|
export declare function mergeAgentResponseChunk<T extends Message>(output: T, chunk: AgentResponseChunk<T>): T;
|
|
7
6
|
export declare function agentResponseStreamToObject<T extends Message>(stream: AgentResponseStream<T> | AgentProcessAsyncGenerator<T>): Promise<T>;
|
|
8
7
|
export declare function asyncGeneratorToReadableStream<T extends Message>(generator: AgentProcessAsyncGenerator<T>): AgentResponseStream<T>;
|
|
9
|
-
export declare function onAgentResponseStreamEnd<T extends Message>(stream: AgentResponseStream<T>,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
export declare function onAgentResponseStreamEnd<T extends Message>(stream: AgentResponseStream<T>, options?: {
|
|
9
|
+
onChunk?: (chunk: AgentResponseChunk<T>) => PromiseOrValue<AgentResponseChunk<T> | undefined | void>;
|
|
10
|
+
onResult?: (result: T) => PromiseOrValue<Partial<T> | undefined | void>;
|
|
11
|
+
onError?: (error: Error) => PromiseOrValue<Error>;
|
|
12
|
+
}): AgentResponseStream<T>;
|
|
13
13
|
export declare function isAsyncGenerator<T extends AsyncGenerator>(value: AsyncGenerator | unknown): value is T;
|
|
14
14
|
export declare function arrayToAgentProcessAsyncGenerator<T extends Message>(chunks: (AgentResponseChunk<T> | Error)[], result?: Partial<T>): AgentProcessAsyncGenerator<T>;
|
|
15
15
|
export declare function arrayToReadableStream<T>(chunks: (T | Error)[]): ReadableStream<T>;
|
|
@@ -17,8 +17,10 @@ export declare function readableStreamToArray<T>(stream: ReadableStream<T>, opti
|
|
|
17
17
|
catchError: true;
|
|
18
18
|
}): Promise<(T | Error)[]>;
|
|
19
19
|
export declare function readableStreamToArray<T>(stream: ReadableStream<T>, options?: {
|
|
20
|
-
catchError?:
|
|
20
|
+
catchError?: boolean;
|
|
21
21
|
}): Promise<T[]>;
|
|
22
|
-
export declare function stringToAgentResponseStream(str: string, key?: "text" |
|
|
22
|
+
export declare function stringToAgentResponseStream(str: string, key?: "text" | string): AgentResponseStream<Message>;
|
|
23
23
|
export declare function toReadableStream(stream: NodeJS.ReadStream): ReadableStream<Uint8Array<ArrayBufferLike>>;
|
|
24
24
|
export declare function readAllString(stream: NodeJS.ReadStream | ReadableStream): Promise<string>;
|
|
25
|
+
export declare function mergeReadableStreams<T1, T2>(s1: ReadableStream<T1>, s2: ReadableStream<T2>): ReadableStream<T1 | T2>;
|
|
26
|
+
export declare function mergeReadableStreams(...streams: ReadableStream<any>[]): ReadableStream<any>;
|