@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,5 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { nodejs } from "@aigne/platform-helpers/nodejs/index.js";
|
|
2
|
+
import nunjucks from "nunjucks";
|
|
2
3
|
import { z } from "zod";
|
|
4
|
+
import { isNil } from "../utils/type-utils.js";
|
|
5
|
+
nunjucks.runtime.suppressValue = (v) => {
|
|
6
|
+
if (isNil(v))
|
|
7
|
+
return "";
|
|
8
|
+
return typeof v === "object" ? JSON.stringify(v) : v;
|
|
9
|
+
};
|
|
3
10
|
export class PromptTemplate {
|
|
4
11
|
template;
|
|
5
12
|
static from(template) {
|
|
@@ -8,12 +15,42 @@ export class PromptTemplate {
|
|
|
8
15
|
constructor(template) {
|
|
9
16
|
this.template = template;
|
|
10
17
|
}
|
|
11
|
-
format(variables) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
async format(variables = {}, options) {
|
|
19
|
+
let env = new nunjucks.Environment();
|
|
20
|
+
if (options?.workingDir) {
|
|
21
|
+
env = new nunjucks.Environment(new CustomLoader({ workingDir: options.workingDir }));
|
|
22
|
+
}
|
|
23
|
+
return new Promise((resolve, reject) => env.renderString(this.template, variables, (err, res) => {
|
|
24
|
+
if (err || !res) {
|
|
25
|
+
reject(err || new Error(`Failed to render template: ${this.template}`));
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
resolve(res);
|
|
29
|
+
}
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export class CustomLoader extends nunjucks.Loader {
|
|
34
|
+
options;
|
|
35
|
+
constructor(options) {
|
|
36
|
+
super();
|
|
37
|
+
this.options = options;
|
|
38
|
+
}
|
|
39
|
+
async = true;
|
|
40
|
+
getSource(name, callback) {
|
|
41
|
+
let result = null;
|
|
42
|
+
nodejs.fs.readFile(nodejs.path.join(this.options.workingDir, name), "utf-8").then((content) => {
|
|
43
|
+
result = {
|
|
44
|
+
src: content,
|
|
45
|
+
path: name,
|
|
46
|
+
noCache: true,
|
|
47
|
+
};
|
|
48
|
+
callback(null, result);
|
|
49
|
+
}, (error) => {
|
|
50
|
+
callback(error, null);
|
|
16
51
|
});
|
|
52
|
+
// nunjucks expects return LoaderSource synchronously, but we handle it asynchronously.
|
|
53
|
+
return result;
|
|
17
54
|
}
|
|
18
55
|
}
|
|
19
56
|
export class ChatMessageTemplate {
|
|
@@ -25,17 +62,17 @@ export class ChatMessageTemplate {
|
|
|
25
62
|
this.content = content;
|
|
26
63
|
this.name = name;
|
|
27
64
|
}
|
|
28
|
-
format(variables) {
|
|
65
|
+
async format(variables, options) {
|
|
29
66
|
let { content } = this;
|
|
30
67
|
if (Array.isArray(content)) {
|
|
31
|
-
content = content.map((i) => {
|
|
68
|
+
content = await Promise.all(content.map(async (i) => {
|
|
32
69
|
if (i.type === "text")
|
|
33
|
-
return { ...i, text: PromptTemplate.from(i.text).format(variables) };
|
|
70
|
+
return { ...i, text: await PromptTemplate.from(i.text).format(variables, options) };
|
|
34
71
|
return i;
|
|
35
|
-
});
|
|
72
|
+
}));
|
|
36
73
|
}
|
|
37
74
|
else if (typeof content === "string") {
|
|
38
|
-
content = PromptTemplate.from(content).format(variables);
|
|
75
|
+
content = await PromptTemplate.from(content).format(variables, options);
|
|
39
76
|
}
|
|
40
77
|
return {
|
|
41
78
|
role: this.role,
|
|
@@ -63,9 +100,9 @@ export class AgentMessageTemplate extends ChatMessageTemplate {
|
|
|
63
100
|
super("agent", content, name);
|
|
64
101
|
this.toolCalls = toolCalls;
|
|
65
102
|
}
|
|
66
|
-
format(variables) {
|
|
103
|
+
async format(variables, options) {
|
|
67
104
|
return {
|
|
68
|
-
...super.format(variables),
|
|
105
|
+
...(await super.format(variables, options)),
|
|
69
106
|
toolCalls: this.toolCalls,
|
|
70
107
|
};
|
|
71
108
|
}
|
|
@@ -81,9 +118,9 @@ export class ToolMessageTemplate extends ChatMessageTemplate {
|
|
|
81
118
|
: JSON.stringify(content, (_, value) => typeof value === "bigint" ? value.toString() : value), name);
|
|
82
119
|
this.toolCallId = toolCallId;
|
|
83
120
|
}
|
|
84
|
-
format(variables) {
|
|
121
|
+
async format(variables, options) {
|
|
85
122
|
return {
|
|
86
|
-
...super.format(variables),
|
|
123
|
+
...(await super.format(variables, options)),
|
|
87
124
|
toolCallId: this.toolCallId,
|
|
88
125
|
};
|
|
89
126
|
}
|
|
@@ -96,8 +133,8 @@ export class ChatMessagesTemplate {
|
|
|
96
133
|
constructor(messages) {
|
|
97
134
|
this.messages = messages;
|
|
98
135
|
}
|
|
99
|
-
format(variables) {
|
|
100
|
-
return this.messages.map((message) => message.format(variables));
|
|
136
|
+
async format(variables, options) {
|
|
137
|
+
return Promise.all(this.messages.map((message) => message.format(variables, options)));
|
|
101
138
|
}
|
|
102
139
|
}
|
|
103
140
|
const systemChatMessageSchema = z.object({
|
|
@@ -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;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import equal from "fast-deep-equal";
|
|
2
2
|
import { isAgentResponseDelta, isEmptyChunk, } from "../agents/agent.js";
|
|
3
|
-
import { omitBy } from "./type-utils.js";
|
|
3
|
+
import { isRecord, omitBy } from "./type-utils.js";
|
|
4
4
|
import "./stream-polyfill.js";
|
|
5
5
|
export function objectToAgentResponseStream(json) {
|
|
6
|
+
if (!isRecord(json)) {
|
|
7
|
+
throw new Error(`expect to return a record type such as {result: ...}, but got (${typeof json}): ${json}`);
|
|
8
|
+
}
|
|
6
9
|
return new ReadableStream({
|
|
7
10
|
pull(controller) {
|
|
8
11
|
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,56 @@
|
|
|
1
|
+
import { isAgentResponseDelta } from "../agents/agent.js";
|
|
2
|
+
export class ExtractMetadataTransform extends TransformStream {
|
|
3
|
+
buffer = "";
|
|
4
|
+
cursor = 0;
|
|
5
|
+
state = "none";
|
|
6
|
+
constructor({ start, end, parse, }) {
|
|
7
|
+
super({
|
|
8
|
+
transform: async (chunk, controller) => {
|
|
9
|
+
if (isAgentResponseDelta(chunk) && chunk.delta.text?.text) {
|
|
10
|
+
const text = chunk.delta.text.text;
|
|
11
|
+
this.buffer += text;
|
|
12
|
+
for (;;) {
|
|
13
|
+
if (this.state === "none") {
|
|
14
|
+
const found = findMatchIndex(this.buffer, this.cursor, start);
|
|
15
|
+
if (found.start > this.cursor) {
|
|
16
|
+
const text = this.buffer.slice(this.cursor, found.start);
|
|
17
|
+
this.cursor = found.start;
|
|
18
|
+
controller.enqueue({ delta: { text: { text } } });
|
|
19
|
+
}
|
|
20
|
+
if (found.end) {
|
|
21
|
+
this.state = "start";
|
|
22
|
+
this.cursor = found.end;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (this.state === "start") {
|
|
26
|
+
const found = findMatchIndex(this.buffer, this.cursor, end);
|
|
27
|
+
if (found.end) {
|
|
28
|
+
const metadata = this.buffer.slice(this.cursor, found.start);
|
|
29
|
+
const json = parse(metadata);
|
|
30
|
+
controller.enqueue({ delta: { json: { json } } });
|
|
31
|
+
this.state = "none";
|
|
32
|
+
this.cursor = found.end;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
controller.enqueue(chunk);
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function findMatchIndex(str, position, match) {
|
|
46
|
+
const i = str.indexOf(match, position);
|
|
47
|
+
if (i >= 0)
|
|
48
|
+
return { start: i, end: i + match.length };
|
|
49
|
+
for (let i = match.length - 1; i > 0; i--) {
|
|
50
|
+
const m = match.slice(0, i);
|
|
51
|
+
if (str.endsWith(m)) {
|
|
52
|
+
return { start: str.length - m.length };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return { start: str.length };
|
|
56
|
+
}
|
|
@@ -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
|
};
|
|
@@ -37,7 +37,7 @@ export function duplicates(arr, key = (item) => item) {
|
|
|
37
37
|
export function remove(arr, remove) {
|
|
38
38
|
const removed = [];
|
|
39
39
|
for (let i = 0; i < arr.length; i++) {
|
|
40
|
-
// biome-ignore lint/style/noNonNullAssertion:
|
|
40
|
+
// biome-ignore lint/style/noNonNullAssertion: false positive
|
|
41
41
|
const item = arr[i];
|
|
42
42
|
if ((Array.isArray(remove) && remove.includes(item)) ||
|
|
43
43
|
(typeof remove === "function" && remove(item))) {
|
|
@@ -84,7 +84,7 @@ export function omitBy(obj, predicate) {
|
|
|
84
84
|
return !predicate(value, k);
|
|
85
85
|
}));
|
|
86
86
|
}
|
|
87
|
-
export function
|
|
87
|
+
export function flat(value) {
|
|
88
88
|
if (isNil(value))
|
|
89
89
|
return [];
|
|
90
90
|
return Array.isArray(value) ? value : [value];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.32.0",
|
|
4
4
|
"description": "AIGNE core library for building AI-powered applications",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -63,35 +63,37 @@
|
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
65
|
"@aigne/json-schema-to-zod": "^1.3.3",
|
|
66
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
66
|
+
"@modelcontextprotocol/sdk": "^1.13.3",
|
|
67
67
|
"@types/debug": "^4.1.12",
|
|
68
68
|
"camelize-ts": "^3.0.0",
|
|
69
69
|
"content-type": "^1.0.5",
|
|
70
|
-
"debug": "^4.4.
|
|
71
|
-
"eventsource-parser": "^3.0.
|
|
70
|
+
"debug": "^4.4.1",
|
|
71
|
+
"eventsource-parser": "^3.0.3",
|
|
72
72
|
"fast-deep-equal": "^3.1.3",
|
|
73
73
|
"immer": "^10.1.1",
|
|
74
74
|
"jsonata": "^2.0.6",
|
|
75
75
|
"mustache": "^4.2.0",
|
|
76
76
|
"nanoid": "^5.1.5",
|
|
77
|
+
"nunjucks": "^3.2.4",
|
|
77
78
|
"p-retry": "^6.2.1",
|
|
78
79
|
"raw-body": "^3.0.0",
|
|
79
80
|
"strict-event-emitter": "^0.5.1",
|
|
80
81
|
"ufo": "^1.6.1",
|
|
81
82
|
"uuid": "^11.1.0",
|
|
82
|
-
"yaml": "^2.
|
|
83
|
-
"zod": "^3.
|
|
84
|
-
"zod-to-json-schema": "^3.24.
|
|
85
|
-
"@aigne/
|
|
86
|
-
"@aigne/
|
|
83
|
+
"yaml": "^2.8.0",
|
|
84
|
+
"zod": "^3.25.67",
|
|
85
|
+
"zod-to-json-schema": "^3.24.6",
|
|
86
|
+
"@aigne/observability-api": "^0.6.0",
|
|
87
|
+
"@aigne/platform-helpers": "^0.3.0"
|
|
87
88
|
},
|
|
88
89
|
"devDependencies": {
|
|
89
|
-
"@types/bun": "^1.2.
|
|
90
|
-
"@types/compression": "^1.
|
|
91
|
-
"@types/content-type": "^1.1.
|
|
92
|
-
"@types/express": "^5.0.
|
|
90
|
+
"@types/bun": "^1.2.17",
|
|
91
|
+
"@types/compression": "^1.8.1",
|
|
92
|
+
"@types/content-type": "^1.1.9",
|
|
93
|
+
"@types/express": "^5.0.3",
|
|
93
94
|
"@types/mustache": "^4.2.6",
|
|
94
|
-
"@types/node": "^
|
|
95
|
+
"@types/node": "^24.0.10",
|
|
96
|
+
"@types/nunjucks": "^3.2.6",
|
|
95
97
|
"compression": "^1.8.0",
|
|
96
98
|
"detect-port": "^2.1.0",
|
|
97
99
|
"express": "^5.1.0",
|