@aigne/core 1.29.1 → 1.32.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 +52 -0
- package/lib/cjs/agents/agent.d.ts +0 -2
- package/lib/cjs/agents/agent.js +4 -9
- package/lib/cjs/agents/ai-agent.d.ts +74 -0
- package/lib/cjs/agents/ai-agent.js +44 -4
- package/lib/cjs/agents/user-agent.js +1 -1
- package/lib/cjs/aigne/context.d.ts +4 -0
- package/lib/cjs/aigne/context.js +0 -10
- package/lib/cjs/aigne/index.d.ts +1 -1
- package/lib/cjs/aigne/index.js +1 -1
- package/lib/cjs/aigne/message-queue.js +6 -6
- package/lib/cjs/loader/index.js +3 -0
- package/lib/cjs/prompt/prompt-builder.d.ts +6 -2
- package/lib/cjs/prompt/prompt-builder.js +48 -19
- package/lib/cjs/prompt/prompts/memory-message-template.d.ts +1 -1
- package/lib/cjs/prompt/prompts/memory-message-template.js +2 -4
- package/lib/cjs/prompt/prompts/structured-stream-instructions.d.ts +7 -0
- package/lib/cjs/prompt/prompts/structured-stream-instructions.js +27 -0
- package/lib/cjs/prompt/template.d.ts +21 -7
- package/lib/cjs/prompt/template.js +57 -19
- package/lib/cjs/utils/mcp-utils.d.ts +1 -1
- package/lib/cjs/utils/stream-utils.js +3 -0
- package/lib/cjs/utils/structured-stream-extractor.d.ts +14 -0
- package/lib/cjs/utils/structured-stream-extractor.js +60 -0
- package/lib/cjs/utils/type-utils.d.ts +1 -1
- package/lib/cjs/utils/type-utils.js +3 -3
- package/lib/dts/agents/agent.d.ts +0 -2
- package/lib/dts/agents/ai-agent.d.ts +74 -0
- package/lib/dts/aigne/context.d.ts +4 -0
- package/lib/dts/aigne/index.d.ts +1 -1
- package/lib/dts/prompt/prompt-builder.d.ts +6 -2
- package/lib/dts/prompt/prompts/memory-message-template.d.ts +1 -1
- package/lib/dts/prompt/prompts/structured-stream-instructions.d.ts +7 -0
- package/lib/dts/prompt/template.d.ts +21 -7
- package/lib/dts/utils/mcp-utils.d.ts +1 -1
- package/lib/dts/utils/structured-stream-extractor.d.ts +14 -0
- package/lib/dts/utils/type-utils.d.ts +1 -1
- package/lib/esm/agents/agent.d.ts +0 -2
- package/lib/esm/agents/agent.js +5 -10
- package/lib/esm/agents/ai-agent.d.ts +74 -0
- package/lib/esm/agents/ai-agent.js +44 -4
- package/lib/esm/agents/user-agent.js +2 -2
- package/lib/esm/aigne/context.d.ts +4 -0
- package/lib/esm/aigne/context.js +1 -11
- package/lib/esm/aigne/index.d.ts +1 -1
- package/lib/esm/aigne/index.js +1 -1
- package/lib/esm/aigne/message-queue.js +7 -7
- package/lib/esm/loader/agent-js.js +1 -1
- package/lib/esm/loader/index.js +3 -0
- package/lib/esm/prompt/prompt-builder.d.ts +6 -2
- package/lib/esm/prompt/prompt-builder.js +49 -20
- package/lib/esm/prompt/prompts/memory-message-template.d.ts +1 -1
- package/lib/esm/prompt/prompts/memory-message-template.js +2 -4
- package/lib/esm/prompt/prompts/structured-stream-instructions.d.ts +7 -0
- package/lib/esm/prompt/prompts/structured-stream-instructions.js +24 -0
- package/lib/esm/prompt/template.d.ts +21 -7
- package/lib/esm/prompt/template.js +54 -17
- package/lib/esm/utils/mcp-utils.d.ts +1 -1
- package/lib/esm/utils/stream-utils.js +4 -1
- package/lib/esm/utils/structured-stream-extractor.d.ts +14 -0
- package/lib/esm/utils/structured-stream-extractor.js +56 -0
- package/lib/esm/utils/type-utils.d.ts +1 -1
- package/lib/esm/utils/type-utils.js +2 -2
- package/package.json +16 -14
|
@@ -1,16 +1,30 @@
|
|
|
1
|
+
import nunjucks, { type Callback, type LoaderSource } from "nunjucks";
|
|
1
2
|
import type { ChatModelInputMessage, ChatModelInputMessageContent, ChatModelOutputToolCall } from "../agents/chat-model.js";
|
|
3
|
+
export interface FormatOptions {
|
|
4
|
+
workingDir?: string;
|
|
5
|
+
}
|
|
2
6
|
export declare class PromptTemplate {
|
|
3
7
|
template: string;
|
|
4
8
|
static from(template: string): PromptTemplate;
|
|
5
9
|
constructor(template: string);
|
|
6
|
-
format(variables?: Record<string, unknown
|
|
10
|
+
format(variables?: Record<string, unknown>, options?: FormatOptions): Promise<string>;
|
|
11
|
+
}
|
|
12
|
+
export declare class CustomLoader extends nunjucks.Loader {
|
|
13
|
+
options: {
|
|
14
|
+
workingDir: string;
|
|
15
|
+
};
|
|
16
|
+
constructor(options: {
|
|
17
|
+
workingDir: string;
|
|
18
|
+
});
|
|
19
|
+
async: boolean;
|
|
20
|
+
getSource(name: string, callback: Callback<Error, LoaderSource>): LoaderSource;
|
|
7
21
|
}
|
|
8
22
|
export declare class ChatMessageTemplate {
|
|
9
23
|
role: "system" | "user" | "agent" | "tool";
|
|
10
24
|
content?: ChatModelInputMessage["content"];
|
|
11
25
|
name?: string | undefined;
|
|
12
26
|
constructor(role: "system" | "user" | "agent" | "tool", content?: ChatModelInputMessage["content"], name?: string | undefined);
|
|
13
|
-
format(variables?: Record<string, unknown
|
|
27
|
+
format(variables?: Record<string, unknown>, options?: FormatOptions): Promise<ChatModelInputMessage>;
|
|
14
28
|
}
|
|
15
29
|
export declare class SystemMessageTemplate extends ChatMessageTemplate {
|
|
16
30
|
static from(content: string, name?: string): SystemMessageTemplate;
|
|
@@ -22,19 +36,19 @@ export declare class AgentMessageTemplate extends ChatMessageTemplate {
|
|
|
22
36
|
toolCalls?: ChatModelOutputToolCall[] | undefined;
|
|
23
37
|
static from(template?: ChatModelInputMessage["content"], toolCalls?: ChatModelOutputToolCall[], name?: string): AgentMessageTemplate;
|
|
24
38
|
constructor(content?: ChatModelInputMessage["content"], toolCalls?: ChatModelOutputToolCall[] | undefined, name?: string);
|
|
25
|
-
format(variables?: Record<string, unknown
|
|
39
|
+
format(variables?: Record<string, unknown>, options?: FormatOptions): Promise<{
|
|
26
40
|
toolCalls: ChatModelOutputToolCall[] | undefined;
|
|
27
41
|
role: import("../agents/chat-model.js").Role;
|
|
28
42
|
content?: ChatModelInputMessageContent;
|
|
29
43
|
toolCallId?: string;
|
|
30
44
|
name?: string;
|
|
31
|
-
}
|
|
45
|
+
}>;
|
|
32
46
|
}
|
|
33
47
|
export declare class ToolMessageTemplate extends ChatMessageTemplate {
|
|
34
48
|
toolCallId: string;
|
|
35
49
|
static from(content: object | string, toolCallId: string, name?: string): ToolMessageTemplate;
|
|
36
50
|
constructor(content: object | string, toolCallId: string, name?: string);
|
|
37
|
-
format(variables?: Record<string, unknown
|
|
51
|
+
format(variables?: Record<string, unknown>, options?: FormatOptions): Promise<{
|
|
38
52
|
toolCallId: string;
|
|
39
53
|
role: import("../agents/chat-model.js").Role;
|
|
40
54
|
content?: ChatModelInputMessageContent;
|
|
@@ -47,12 +61,12 @@ export declare class ToolMessageTemplate extends ChatMessageTemplate {
|
|
|
47
61
|
};
|
|
48
62
|
}[];
|
|
49
63
|
name?: string;
|
|
50
|
-
}
|
|
64
|
+
}>;
|
|
51
65
|
}
|
|
52
66
|
export declare class ChatMessagesTemplate {
|
|
53
67
|
messages: ChatMessageTemplate[];
|
|
54
68
|
static from(messages: ChatMessageTemplate[] | string): ChatMessagesTemplate;
|
|
55
69
|
constructor(messages: ChatMessageTemplate[]);
|
|
56
|
-
format(variables?: Record<string, unknown
|
|
70
|
+
format(variables?: Record<string, unknown>, options?: FormatOptions): Promise<ChatModelInputMessage[]>;
|
|
57
71
|
}
|
|
58
72
|
export declare function parseChatMessages(messages: unknown): ChatMessageTemplate[] | undefined;
|
|
@@ -3,10 +3,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.ChatMessagesTemplate = exports.ToolMessageTemplate = exports.AgentMessageTemplate = exports.UserMessageTemplate = exports.SystemMessageTemplate = exports.ChatMessageTemplate = exports.PromptTemplate = void 0;
|
|
6
|
+
exports.ChatMessagesTemplate = exports.ToolMessageTemplate = exports.AgentMessageTemplate = exports.UserMessageTemplate = exports.SystemMessageTemplate = exports.ChatMessageTemplate = exports.CustomLoader = exports.PromptTemplate = void 0;
|
|
7
7
|
exports.parseChatMessages = parseChatMessages;
|
|
8
|
-
const
|
|
8
|
+
const index_js_1 = require("@aigne/platform-helpers/nodejs/index.js");
|
|
9
|
+
const nunjucks_1 = __importDefault(require("nunjucks"));
|
|
9
10
|
const zod_1 = require("zod");
|
|
11
|
+
const type_utils_js_1 = require("../utils/type-utils.js");
|
|
12
|
+
nunjucks_1.default.runtime.suppressValue = (v) => {
|
|
13
|
+
if ((0, type_utils_js_1.isNil)(v))
|
|
14
|
+
return "";
|
|
15
|
+
return typeof v === "object" ? JSON.stringify(v) : v;
|
|
16
|
+
};
|
|
10
17
|
class PromptTemplate {
|
|
11
18
|
template;
|
|
12
19
|
static from(template) {
|
|
@@ -15,15 +22,46 @@ class PromptTemplate {
|
|
|
15
22
|
constructor(template) {
|
|
16
23
|
this.template = template;
|
|
17
24
|
}
|
|
18
|
-
format(variables) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
async format(variables = {}, options) {
|
|
26
|
+
let env = new nunjucks_1.default.Environment();
|
|
27
|
+
if (options?.workingDir) {
|
|
28
|
+
env = new nunjucks_1.default.Environment(new CustomLoader({ workingDir: options.workingDir }));
|
|
29
|
+
}
|
|
30
|
+
return new Promise((resolve, reject) => env.renderString(this.template, variables, (err, res) => {
|
|
31
|
+
if (err || !res) {
|
|
32
|
+
reject(err || new Error(`Failed to render template: ${this.template}`));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
resolve(res);
|
|
36
|
+
}
|
|
37
|
+
}));
|
|
24
38
|
}
|
|
25
39
|
}
|
|
26
40
|
exports.PromptTemplate = PromptTemplate;
|
|
41
|
+
class CustomLoader extends nunjucks_1.default.Loader {
|
|
42
|
+
options;
|
|
43
|
+
constructor(options) {
|
|
44
|
+
super();
|
|
45
|
+
this.options = options;
|
|
46
|
+
}
|
|
47
|
+
async = true;
|
|
48
|
+
getSource(name, callback) {
|
|
49
|
+
let result = null;
|
|
50
|
+
index_js_1.nodejs.fs.readFile(index_js_1.nodejs.path.join(this.options.workingDir, name), "utf-8").then((content) => {
|
|
51
|
+
result = {
|
|
52
|
+
src: content,
|
|
53
|
+
path: name,
|
|
54
|
+
noCache: true,
|
|
55
|
+
};
|
|
56
|
+
callback(null, result);
|
|
57
|
+
}, (error) => {
|
|
58
|
+
callback(error, null);
|
|
59
|
+
});
|
|
60
|
+
// nunjucks expects return LoaderSource synchronously, but we handle it asynchronously.
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.CustomLoader = CustomLoader;
|
|
27
65
|
class ChatMessageTemplate {
|
|
28
66
|
role;
|
|
29
67
|
content;
|
|
@@ -33,17 +71,17 @@ class ChatMessageTemplate {
|
|
|
33
71
|
this.content = content;
|
|
34
72
|
this.name = name;
|
|
35
73
|
}
|
|
36
|
-
format(variables) {
|
|
74
|
+
async format(variables, options) {
|
|
37
75
|
let { content } = this;
|
|
38
76
|
if (Array.isArray(content)) {
|
|
39
|
-
content = content.map((i) => {
|
|
77
|
+
content = await Promise.all(content.map(async (i) => {
|
|
40
78
|
if (i.type === "text")
|
|
41
|
-
return { ...i, text: PromptTemplate.from(i.text).format(variables) };
|
|
79
|
+
return { ...i, text: await PromptTemplate.from(i.text).format(variables, options) };
|
|
42
80
|
return i;
|
|
43
|
-
});
|
|
81
|
+
}));
|
|
44
82
|
}
|
|
45
83
|
else if (typeof content === "string") {
|
|
46
|
-
content = PromptTemplate.from(content).format(variables);
|
|
84
|
+
content = await PromptTemplate.from(content).format(variables, options);
|
|
47
85
|
}
|
|
48
86
|
return {
|
|
49
87
|
role: this.role,
|
|
@@ -74,9 +112,9 @@ class AgentMessageTemplate extends ChatMessageTemplate {
|
|
|
74
112
|
super("agent", content, name);
|
|
75
113
|
this.toolCalls = toolCalls;
|
|
76
114
|
}
|
|
77
|
-
format(variables) {
|
|
115
|
+
async format(variables, options) {
|
|
78
116
|
return {
|
|
79
|
-
...super.format(variables),
|
|
117
|
+
...(await super.format(variables, options)),
|
|
80
118
|
toolCalls: this.toolCalls,
|
|
81
119
|
};
|
|
82
120
|
}
|
|
@@ -93,9 +131,9 @@ class ToolMessageTemplate extends ChatMessageTemplate {
|
|
|
93
131
|
: JSON.stringify(content, (_, value) => typeof value === "bigint" ? value.toString() : value), name);
|
|
94
132
|
this.toolCallId = toolCallId;
|
|
95
133
|
}
|
|
96
|
-
format(variables) {
|
|
134
|
+
async format(variables, options) {
|
|
97
135
|
return {
|
|
98
|
-
...super.format(variables),
|
|
136
|
+
...(await super.format(variables, options)),
|
|
99
137
|
toolCallId: this.toolCallId,
|
|
100
138
|
};
|
|
101
139
|
}
|
|
@@ -109,8 +147,8 @@ class ChatMessagesTemplate {
|
|
|
109
147
|
constructor(messages) {
|
|
110
148
|
this.messages = messages;
|
|
111
149
|
}
|
|
112
|
-
format(variables) {
|
|
113
|
-
return this.messages.map((message) => message.format(variables));
|
|
150
|
+
async format(variables, options) {
|
|
151
|
+
return Promise.all(this.messages.map((message) => message.format(variables, options)));
|
|
114
152
|
}
|
|
115
153
|
}
|
|
116
154
|
exports.ChatMessagesTemplate = ChatMessagesTemplate;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ListPromptsResult, type
|
|
1
|
+
import { type ListPromptsResult, type ListResourcesResult, type ListResourceTemplatesResult, type ListToolsResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
2
|
import { type MCPBaseOptions, MCPPrompt, MCPResource, MCPTool } from "../agents/mcp-agent.js";
|
|
3
3
|
export declare function toolFromMCPTool(tool: ListToolsResult["tools"][number], options: MCPBaseOptions): MCPTool;
|
|
4
4
|
export declare function promptFromMCPPrompt(prompt: ListPromptsResult["prompts"][number], options: MCPBaseOptions): MCPPrompt;
|
|
@@ -21,6 +21,9 @@ const agent_js_1 = require("../agents/agent.js");
|
|
|
21
21
|
const type_utils_js_1 = require("./type-utils.js");
|
|
22
22
|
require("./stream-polyfill.js");
|
|
23
23
|
function objectToAgentResponseStream(json) {
|
|
24
|
+
if (!(0, type_utils_js_1.isRecord)(json)) {
|
|
25
|
+
throw new Error(`expect to return a record type such as {result: ...}, but got (${typeof json}): ${json}`);
|
|
26
|
+
}
|
|
24
27
|
return new ReadableStream({
|
|
25
28
|
pull(controller) {
|
|
26
29
|
controller.enqueue({ delta: { json } });
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type AgentResponseChunk } from "../agents/agent.js";
|
|
2
|
+
import type { ChatModelOutput } from "../agents/chat-model.js";
|
|
3
|
+
export declare class ExtractMetadataTransform extends TransformStream<AgentResponseChunk<ChatModelOutput>, AgentResponseChunk<ChatModelOutput & {
|
|
4
|
+
metadata?: string;
|
|
5
|
+
}>> {
|
|
6
|
+
private buffer;
|
|
7
|
+
private cursor;
|
|
8
|
+
private state;
|
|
9
|
+
constructor({ start, end, parse, }: {
|
|
10
|
+
start: string;
|
|
11
|
+
end: string;
|
|
12
|
+
parse: (raw: string) => object;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ExtractMetadataTransform = void 0;
|
|
4
|
+
const agent_js_1 = require("../agents/agent.js");
|
|
5
|
+
class ExtractMetadataTransform extends TransformStream {
|
|
6
|
+
buffer = "";
|
|
7
|
+
cursor = 0;
|
|
8
|
+
state = "none";
|
|
9
|
+
constructor({ start, end, parse, }) {
|
|
10
|
+
super({
|
|
11
|
+
transform: async (chunk, controller) => {
|
|
12
|
+
if ((0, agent_js_1.isAgentResponseDelta)(chunk) && chunk.delta.text?.text) {
|
|
13
|
+
const text = chunk.delta.text.text;
|
|
14
|
+
this.buffer += text;
|
|
15
|
+
for (;;) {
|
|
16
|
+
if (this.state === "none") {
|
|
17
|
+
const found = findMatchIndex(this.buffer, this.cursor, start);
|
|
18
|
+
if (found.start > this.cursor) {
|
|
19
|
+
const text = this.buffer.slice(this.cursor, found.start);
|
|
20
|
+
this.cursor = found.start;
|
|
21
|
+
controller.enqueue({ delta: { text: { text } } });
|
|
22
|
+
}
|
|
23
|
+
if (found.end) {
|
|
24
|
+
this.state = "start";
|
|
25
|
+
this.cursor = found.end;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (this.state === "start") {
|
|
29
|
+
const found = findMatchIndex(this.buffer, this.cursor, end);
|
|
30
|
+
if (found.end) {
|
|
31
|
+
const metadata = this.buffer.slice(this.cursor, found.start);
|
|
32
|
+
const json = parse(metadata);
|
|
33
|
+
controller.enqueue({ delta: { json: { json } } });
|
|
34
|
+
this.state = "none";
|
|
35
|
+
this.cursor = found.end;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
controller.enqueue(chunk);
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.ExtractMetadataTransform = ExtractMetadataTransform;
|
|
49
|
+
function findMatchIndex(str, position, match) {
|
|
50
|
+
const i = str.indexOf(match, position);
|
|
51
|
+
if (i >= 0)
|
|
52
|
+
return { start: i, end: i + match.length };
|
|
53
|
+
for (let i = match.length - 1; i > 0; i--) {
|
|
54
|
+
const m = match.slice(0, i);
|
|
55
|
+
if (str.endsWith(m)) {
|
|
56
|
+
return { start: str.length - m.length };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return { start: str.length };
|
|
60
|
+
}
|
|
@@ -19,7 +19,7 @@ export declare function pick<T extends object, K extends keyof T>(obj: T, ...key
|
|
|
19
19
|
export declare function omit<T extends object, K extends keyof T>(obj: T, ...keys: (K | K[])[]): Omit<T, K>;
|
|
20
20
|
export declare function omitDeep<T, K>(obj: T, ...keys: (K | K[])[]): unknown;
|
|
21
21
|
export declare function omitBy<T extends Record<string, unknown>, K extends keyof T>(obj: T, predicate: (value: T[K], key: K) => boolean): Partial<T>;
|
|
22
|
-
export declare function
|
|
22
|
+
export declare function flat<T>(value?: T | T[]): T[];
|
|
23
23
|
export declare function createAccessorArray<T>(array: T[], accessor: (array: T[], name: string) => T | undefined): T[] & {
|
|
24
24
|
[key: string]: T;
|
|
25
25
|
};
|
|
@@ -12,7 +12,7 @@ exports.pick = pick;
|
|
|
12
12
|
exports.omit = omit;
|
|
13
13
|
exports.omitDeep = omitDeep;
|
|
14
14
|
exports.omitBy = omitBy;
|
|
15
|
-
exports.
|
|
15
|
+
exports.flat = flat;
|
|
16
16
|
exports.createAccessorArray = createAccessorArray;
|
|
17
17
|
exports.checkArguments = checkArguments;
|
|
18
18
|
exports.tryOrThrow = tryOrThrow;
|
|
@@ -55,7 +55,7 @@ function duplicates(arr, key = (item) => item) {
|
|
|
55
55
|
function remove(arr, remove) {
|
|
56
56
|
const removed = [];
|
|
57
57
|
for (let i = 0; i < arr.length; i++) {
|
|
58
|
-
// biome-ignore lint/style/noNonNullAssertion:
|
|
58
|
+
// biome-ignore lint/style/noNonNullAssertion: false positive
|
|
59
59
|
const item = arr[i];
|
|
60
60
|
if ((Array.isArray(remove) && remove.includes(item)) ||
|
|
61
61
|
(typeof remove === "function" && remove(item))) {
|
|
@@ -102,7 +102,7 @@ function omitBy(obj, predicate) {
|
|
|
102
102
|
return !predicate(value, k);
|
|
103
103
|
}));
|
|
104
104
|
}
|
|
105
|
-
function
|
|
105
|
+
function flat(value) {
|
|
106
106
|
if (isNil(value))
|
|
107
107
|
return [];
|
|
108
108
|
return Array.isArray(value) ? value : [value];
|
|
@@ -137,8 +137,6 @@ export interface AgentInvokeOptions<U extends UserContext = UserContext> {
|
|
|
137
137
|
* and returns the final JSON result
|
|
138
138
|
*/
|
|
139
139
|
streaming?: boolean;
|
|
140
|
-
userContext?: U;
|
|
141
|
-
memories?: Pick<Memory, "content">[];
|
|
142
140
|
}
|
|
143
141
|
/**
|
|
144
142
|
* Agent is the base class for all agents.
|
|
@@ -50,6 +50,48 @@ export interface AIAgentOptions<I extends Message = Message, O extends Message =
|
|
|
50
50
|
* @default true
|
|
51
51
|
*/
|
|
52
52
|
catchToolsError?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Whether to enable structured stream mode
|
|
55
|
+
*
|
|
56
|
+
* When enabled, the AI model's streaming response will be processed to extract
|
|
57
|
+
* structured metadata. The model needs to include specific format metadata tags
|
|
58
|
+
* (like <metadata></metadata>) in its response, which will be parsed as JSON
|
|
59
|
+
* objects and passed through the stream.
|
|
60
|
+
*
|
|
61
|
+
* This is useful for scenarios that need to extract structured information
|
|
62
|
+
* (like classifications, scores, tags, etc.) from AI responses.
|
|
63
|
+
*
|
|
64
|
+
* @default false
|
|
65
|
+
*/
|
|
66
|
+
structuredStreamMode?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Custom structured stream instructions configuration
|
|
69
|
+
*
|
|
70
|
+
* Allows customization of structured stream mode behavior, including:
|
|
71
|
+
* - instructions: Prompt instructions to guide the AI model on how to output structured data
|
|
72
|
+
* - metadataStart: Metadata start marker (e.g., "<metadata>")
|
|
73
|
+
* - metadataEnd: Metadata end marker (e.g., "</metadata>")
|
|
74
|
+
* - parse: Function to parse metadata content, converting raw string to object
|
|
75
|
+
*
|
|
76
|
+
* If not provided, the default STRUCTURED_STREAM_INSTRUCTIONS configuration will be used,
|
|
77
|
+
* which outputs structured data in YAML format within <metadata> tags.
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* {
|
|
82
|
+
* instructions: "Output metadata in JSON format at the end of response in markdown code block with json language",
|
|
83
|
+
* metadataStart: "```json",
|
|
84
|
+
* metadataEnd: "```",
|
|
85
|
+
* parse: JSON.parse
|
|
86
|
+
* }
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
customStructuredStreamInstructions?: {
|
|
90
|
+
instructions: string | PromptBuilder;
|
|
91
|
+
metadataStart: string;
|
|
92
|
+
metadataEnd: string;
|
|
93
|
+
parse: (raw: string) => object;
|
|
94
|
+
};
|
|
53
95
|
/**
|
|
54
96
|
* Whether to include memory agents as tools for the AI model
|
|
55
97
|
*
|
|
@@ -217,6 +259,38 @@ export declare class AIAgent<I extends Message = any, O extends Message = any> e
|
|
|
217
259
|
* @default true
|
|
218
260
|
*/
|
|
219
261
|
catchToolsError: boolean;
|
|
262
|
+
/**
|
|
263
|
+
* Whether to enable structured stream mode
|
|
264
|
+
*
|
|
265
|
+
* When enabled, the AI model's streaming response will be processed to extract
|
|
266
|
+
* structured metadata. The model needs to include specific format metadata tags
|
|
267
|
+
* (like <metadata></metadata>) in its response, which will be parsed as JSON
|
|
268
|
+
* objects and passed through the stream.
|
|
269
|
+
*
|
|
270
|
+
* This is useful for scenarios that need to extract structured information
|
|
271
|
+
* (like classifications, scores, tags, etc.) from AI responses.
|
|
272
|
+
*
|
|
273
|
+
* @default false
|
|
274
|
+
*/
|
|
275
|
+
structuredStreamMode?: boolean;
|
|
276
|
+
/**
|
|
277
|
+
* Custom structured stream instructions configuration
|
|
278
|
+
*
|
|
279
|
+
* Allows customization of structured stream mode behavior, including:
|
|
280
|
+
* - instructions: Prompt instructions to guide the AI model on how to output structured data
|
|
281
|
+
* - metadataStart: Metadata start marker (e.g., "<metadata>")
|
|
282
|
+
* - metadataEnd: Metadata end marker (e.g., "</metadata>")
|
|
283
|
+
* - parse: Function to parse metadata content, converting raw string to object
|
|
284
|
+
*
|
|
285
|
+
* If not provided, the default STRUCTURED_STREAM_INSTRUCTIONS configuration will be used,
|
|
286
|
+
* which outputs structured data in YAML format within <metadata> tags.
|
|
287
|
+
*/
|
|
288
|
+
customStructuredStreamInstructions?: {
|
|
289
|
+
instructions: PromptBuilder;
|
|
290
|
+
metadataStart: string;
|
|
291
|
+
metadataEnd: string;
|
|
292
|
+
parse: (raw: string) => object;
|
|
293
|
+
};
|
|
220
294
|
/**
|
|
221
295
|
* Process an input message and generate a response
|
|
222
296
|
*
|
|
@@ -54,11 +54,15 @@ export interface InvokeOptions<U extends UserContext = UserContext> extends Part
|
|
|
54
54
|
* @default true
|
|
55
55
|
*/
|
|
56
56
|
newContext?: boolean;
|
|
57
|
+
userContext?: U;
|
|
58
|
+
memories?: Pick<Memory, "content">[];
|
|
57
59
|
}
|
|
58
60
|
/**
|
|
59
61
|
* @hidden
|
|
60
62
|
*/
|
|
61
63
|
export interface UserContext extends Record<string, unknown> {
|
|
64
|
+
userId?: string;
|
|
65
|
+
sessionId?: string;
|
|
62
66
|
}
|
|
63
67
|
/**
|
|
64
68
|
* @hidden
|
package/lib/dts/aigne/index.d.ts
CHANGED
|
@@ -5,8 +5,9 @@ import type { ChatModel, ChatModelInput } from "../agents/chat-model.js";
|
|
|
5
5
|
import { ChatMessagesTemplate } from "./template.js";
|
|
6
6
|
export interface PromptBuilderOptions {
|
|
7
7
|
instructions?: string | ChatMessagesTemplate;
|
|
8
|
+
workingDir?: string;
|
|
8
9
|
}
|
|
9
|
-
export interface PromptBuildOptions extends Pick<AgentInvokeOptions, "context"
|
|
10
|
+
export interface PromptBuildOptions extends Partial<Pick<AgentInvokeOptions, "context">> {
|
|
10
11
|
agent?: AIAgent;
|
|
11
12
|
input?: Message;
|
|
12
13
|
model?: ChatModel;
|
|
@@ -15,11 +16,14 @@ export interface PromptBuildOptions extends Pick<AgentInvokeOptions, "context">
|
|
|
15
16
|
export declare class PromptBuilder {
|
|
16
17
|
static from(instructions: string | {
|
|
17
18
|
path: string;
|
|
18
|
-
} | GetPromptResult
|
|
19
|
+
} | GetPromptResult, { workingDir }?: {
|
|
20
|
+
workingDir?: string;
|
|
21
|
+
}): PromptBuilder;
|
|
19
22
|
private static fromFile;
|
|
20
23
|
private static fromMCPPromptResult;
|
|
21
24
|
constructor(options?: PromptBuilderOptions);
|
|
22
25
|
instructions?: string | ChatMessagesTemplate;
|
|
26
|
+
workingDir?: string;
|
|
23
27
|
build(options: PromptBuildOptions): Promise<ChatModelInput & {
|
|
24
28
|
toolAgents?: Agent[];
|
|
25
29
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const MEMORY_MESSAGE_TEMPLATE = "
|
|
1
|
+
export declare const MEMORY_MESSAGE_TEMPLATE = "<related-memories>\n{{memories}}\n</related-memories>\n";
|
|
@@ -1,16 +1,30 @@
|
|
|
1
|
+
import nunjucks, { type Callback, type LoaderSource } from "nunjucks";
|
|
1
2
|
import type { ChatModelInputMessage, ChatModelInputMessageContent, ChatModelOutputToolCall } from "../agents/chat-model.js";
|
|
3
|
+
export interface FormatOptions {
|
|
4
|
+
workingDir?: string;
|
|
5
|
+
}
|
|
2
6
|
export declare class PromptTemplate {
|
|
3
7
|
template: string;
|
|
4
8
|
static from(template: string): PromptTemplate;
|
|
5
9
|
constructor(template: string);
|
|
6
|
-
format(variables?: Record<string, unknown
|
|
10
|
+
format(variables?: Record<string, unknown>, options?: FormatOptions): Promise<string>;
|
|
11
|
+
}
|
|
12
|
+
export declare class CustomLoader extends nunjucks.Loader {
|
|
13
|
+
options: {
|
|
14
|
+
workingDir: string;
|
|
15
|
+
};
|
|
16
|
+
constructor(options: {
|
|
17
|
+
workingDir: string;
|
|
18
|
+
});
|
|
19
|
+
async: boolean;
|
|
20
|
+
getSource(name: string, callback: Callback<Error, LoaderSource>): LoaderSource;
|
|
7
21
|
}
|
|
8
22
|
export declare class ChatMessageTemplate {
|
|
9
23
|
role: "system" | "user" | "agent" | "tool";
|
|
10
24
|
content?: ChatModelInputMessage["content"];
|
|
11
25
|
name?: string | undefined;
|
|
12
26
|
constructor(role: "system" | "user" | "agent" | "tool", content?: ChatModelInputMessage["content"], name?: string | undefined);
|
|
13
|
-
format(variables?: Record<string, unknown
|
|
27
|
+
format(variables?: Record<string, unknown>, options?: FormatOptions): Promise<ChatModelInputMessage>;
|
|
14
28
|
}
|
|
15
29
|
export declare class SystemMessageTemplate extends ChatMessageTemplate {
|
|
16
30
|
static from(content: string, name?: string): SystemMessageTemplate;
|
|
@@ -22,19 +36,19 @@ export declare class AgentMessageTemplate extends ChatMessageTemplate {
|
|
|
22
36
|
toolCalls?: ChatModelOutputToolCall[] | undefined;
|
|
23
37
|
static from(template?: ChatModelInputMessage["content"], toolCalls?: ChatModelOutputToolCall[], name?: string): AgentMessageTemplate;
|
|
24
38
|
constructor(content?: ChatModelInputMessage["content"], toolCalls?: ChatModelOutputToolCall[] | undefined, name?: string);
|
|
25
|
-
format(variables?: Record<string, unknown
|
|
39
|
+
format(variables?: Record<string, unknown>, options?: FormatOptions): Promise<{
|
|
26
40
|
toolCalls: ChatModelOutputToolCall[] | undefined;
|
|
27
41
|
role: import("../agents/chat-model.js").Role;
|
|
28
42
|
content?: ChatModelInputMessageContent;
|
|
29
43
|
toolCallId?: string;
|
|
30
44
|
name?: string;
|
|
31
|
-
}
|
|
45
|
+
}>;
|
|
32
46
|
}
|
|
33
47
|
export declare class ToolMessageTemplate extends ChatMessageTemplate {
|
|
34
48
|
toolCallId: string;
|
|
35
49
|
static from(content: object | string, toolCallId: string, name?: string): ToolMessageTemplate;
|
|
36
50
|
constructor(content: object | string, toolCallId: string, name?: string);
|
|
37
|
-
format(variables?: Record<string, unknown
|
|
51
|
+
format(variables?: Record<string, unknown>, options?: FormatOptions): Promise<{
|
|
38
52
|
toolCallId: string;
|
|
39
53
|
role: import("../agents/chat-model.js").Role;
|
|
40
54
|
content?: ChatModelInputMessageContent;
|
|
@@ -47,12 +61,12 @@ export declare class ToolMessageTemplate extends ChatMessageTemplate {
|
|
|
47
61
|
};
|
|
48
62
|
}[];
|
|
49
63
|
name?: string;
|
|
50
|
-
}
|
|
64
|
+
}>;
|
|
51
65
|
}
|
|
52
66
|
export declare class ChatMessagesTemplate {
|
|
53
67
|
messages: ChatMessageTemplate[];
|
|
54
68
|
static from(messages: ChatMessageTemplate[] | string): ChatMessagesTemplate;
|
|
55
69
|
constructor(messages: ChatMessageTemplate[]);
|
|
56
|
-
format(variables?: Record<string, unknown
|
|
70
|
+
format(variables?: Record<string, unknown>, options?: FormatOptions): Promise<ChatModelInputMessage[]>;
|
|
57
71
|
}
|
|
58
72
|
export declare function parseChatMessages(messages: unknown): ChatMessageTemplate[] | undefined;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ListPromptsResult, type
|
|
1
|
+
import { type ListPromptsResult, type ListResourcesResult, type ListResourceTemplatesResult, type ListToolsResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
2
|
import { type MCPBaseOptions, MCPPrompt, MCPResource, MCPTool } from "../agents/mcp-agent.js";
|
|
3
3
|
export declare function toolFromMCPTool(tool: ListToolsResult["tools"][number], options: MCPBaseOptions): MCPTool;
|
|
4
4
|
export declare function promptFromMCPPrompt(prompt: ListPromptsResult["prompts"][number], options: MCPBaseOptions): MCPPrompt;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type AgentResponseChunk } from "../agents/agent.js";
|
|
2
|
+
import type { ChatModelOutput } from "../agents/chat-model.js";
|
|
3
|
+
export declare class ExtractMetadataTransform extends TransformStream<AgentResponseChunk<ChatModelOutput>, AgentResponseChunk<ChatModelOutput & {
|
|
4
|
+
metadata?: string;
|
|
5
|
+
}>> {
|
|
6
|
+
private buffer;
|
|
7
|
+
private cursor;
|
|
8
|
+
private state;
|
|
9
|
+
constructor({ start, end, parse, }: {
|
|
10
|
+
start: string;
|
|
11
|
+
end: string;
|
|
12
|
+
parse: (raw: string) => object;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
@@ -19,7 +19,7 @@ export declare function pick<T extends object, K extends keyof T>(obj: T, ...key
|
|
|
19
19
|
export declare function omit<T extends object, K extends keyof T>(obj: T, ...keys: (K | K[])[]): Omit<T, K>;
|
|
20
20
|
export declare function omitDeep<T, K>(obj: T, ...keys: (K | K[])[]): unknown;
|
|
21
21
|
export declare function omitBy<T extends Record<string, unknown>, K extends keyof T>(obj: T, predicate: (value: T[K], key: K) => boolean): Partial<T>;
|
|
22
|
-
export declare function
|
|
22
|
+
export declare function flat<T>(value?: T | T[]): T[];
|
|
23
23
|
export declare function createAccessorArray<T>(array: T[], accessor: (array: T[], name: string) => T | undefined): T[] & {
|
|
24
24
|
[key: string]: T;
|
|
25
25
|
};
|
|
@@ -137,8 +137,6 @@ export interface AgentInvokeOptions<U extends UserContext = UserContext> {
|
|
|
137
137
|
* and returns the final JSON result
|
|
138
138
|
*/
|
|
139
139
|
streaming?: boolean;
|
|
140
|
-
userContext?: U;
|
|
141
|
-
memories?: Pick<Memory, "content">[];
|
|
142
140
|
}
|
|
143
141
|
/**
|
|
144
142
|
* Agent is the base class for all agents.
|
package/lib/esm/agents/agent.js
CHANGED
|
@@ -2,7 +2,7 @@ import { nodejs } from "@aigne/platform-helpers/nodejs/index.js";
|
|
|
2
2
|
import { ZodObject, z } from "zod";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
4
|
import { agentResponseStreamToObject, asyncGeneratorToReadableStream, isAsyncGenerator, objectToAgentResponseStream, onAgentResponseStreamEnd, } from "../utils/stream-utils.js";
|
|
5
|
-
import { checkArguments, createAccessorArray, isEmpty,
|
|
5
|
+
import { checkArguments, createAccessorArray, flat, isEmpty, isRecord, } from "../utils/type-utils.js";
|
|
6
6
|
import { replaceTransferAgentToName, transferToAgentOutput, } from "./types.js";
|
|
7
7
|
export * from "./types.js";
|
|
8
8
|
export const agentOptionsSchema = z.object({
|
|
@@ -222,7 +222,7 @@ export class Agent {
|
|
|
222
222
|
this.subscribeToTopics(context);
|
|
223
223
|
}
|
|
224
224
|
subscribeToTopics(context) {
|
|
225
|
-
for (const topic of
|
|
225
|
+
for (const topic of flat(this.subscribeTopic).concat(this.topic)) {
|
|
226
226
|
this.subscriptions.push(context.subscribe(topic, (payload) => this.onMessage(payload)));
|
|
227
227
|
}
|
|
228
228
|
}
|
|
@@ -291,14 +291,6 @@ export class Agent {
|
|
|
291
291
|
...options,
|
|
292
292
|
context: options.context ?? (await this.newDefaultContext()),
|
|
293
293
|
};
|
|
294
|
-
if (options.userContext) {
|
|
295
|
-
Object.assign(opts.context.userContext, options.userContext);
|
|
296
|
-
options.userContext = undefined;
|
|
297
|
-
}
|
|
298
|
-
if (options.memories?.length) {
|
|
299
|
-
opts.context.memories.push(...options.memories);
|
|
300
|
-
options.memories = undefined;
|
|
301
|
-
}
|
|
302
294
|
logger.debug("Invoke agent %s started with input: %O", this.name, input);
|
|
303
295
|
if (!this.disableEvents)
|
|
304
296
|
opts.context.emit("agentStarted", { agent: this, input });
|
|
@@ -357,6 +349,9 @@ export class Agent {
|
|
|
357
349
|
*/
|
|
358
350
|
async processAgentOutput(input, output, options) {
|
|
359
351
|
const { context } = options;
|
|
352
|
+
if (!isRecord(output)) {
|
|
353
|
+
throw new Error(`expect to return a record type such as {result: ...}, but got (${typeof output}): ${output}`);
|
|
354
|
+
}
|
|
360
355
|
const parsedOutput = checkArguments(`Agent ${this.name} output`, this.outputSchema, output);
|
|
361
356
|
const finalOutput = this.includeInputInOutput ? { ...input, ...parsedOutput } : parsedOutput;
|
|
362
357
|
await this.postprocess(input, finalOutput, options);
|