@aigne/core 1.57.2 → 1.57.4
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 +14 -0
- package/lib/cjs/loader/agent-yaml.d.ts +6 -2
- package/lib/cjs/loader/agent-yaml.js +2 -2
- package/lib/cjs/loader/index.d.ts +1 -3
- package/lib/cjs/loader/index.js +11 -7
- package/lib/cjs/prompt/template.d.ts +2 -1
- package/lib/cjs/prompt/template.js +17 -31
- package/lib/dts/loader/agent-yaml.d.ts +6 -2
- package/lib/dts/loader/index.d.ts +1 -3
- package/lib/dts/prompt/template.d.ts +2 -1
- package/lib/esm/loader/agent-yaml.d.ts +6 -2
- package/lib/esm/loader/agent-yaml.js +2 -2
- package/lib/esm/loader/index.d.ts +1 -3
- package/lib/esm/loader/index.js +11 -7
- package/lib/esm/prompt/template.d.ts +2 -1
- package/lib/esm/prompt/template.js +17 -31
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.57.4](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.57.3...core-v1.57.4) (2025-08-30)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **core:** handle relative path correctly ([#440](https://github.com/AIGNE-io/aigne-framework/issues/440)) ([45a65fe](https://github.com/AIGNE-io/aigne-framework/commit/45a65fea432da44218007e566fe952fa973d8ae2))
|
|
9
|
+
|
|
10
|
+
## [1.57.3](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.57.2...core-v1.57.3) (2025-08-30)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **core:** improve nested prompt file resolution ([#437](https://github.com/AIGNE-io/aigne-framework/issues/437)) ([38b5b13](https://github.com/AIGNE-io/aigne-framework/commit/38b5b1397b7897cddef39d60c8cae2152e37dc5b))
|
|
16
|
+
|
|
3
17
|
## [1.57.2](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.57.1...core-v1.57.2) (2025-08-29)
|
|
4
18
|
|
|
5
19
|
|
|
@@ -32,16 +32,20 @@ export interface BaseAgentSchema {
|
|
|
32
32
|
subscribeTopic?: string[];
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
+
export type Instructions = {
|
|
36
|
+
content: string;
|
|
37
|
+
path: string;
|
|
38
|
+
};
|
|
35
39
|
export interface AIAgentSchema extends BaseAgentSchema {
|
|
36
40
|
type: "ai";
|
|
37
|
-
instructions?:
|
|
41
|
+
instructions?: Instructions;
|
|
38
42
|
inputKey?: string;
|
|
39
43
|
outputKey?: string;
|
|
40
44
|
toolChoice?: AIAgentToolChoice;
|
|
41
45
|
}
|
|
42
46
|
export interface ImageAgentSchema extends BaseAgentSchema {
|
|
43
47
|
type: "image";
|
|
44
|
-
instructions:
|
|
48
|
+
instructions: Instructions;
|
|
45
49
|
modelOptions?: Record<string, any>;
|
|
46
50
|
}
|
|
47
51
|
export interface MCPAgentSchema extends BaseAgentSchema {
|
|
@@ -58,8 +58,8 @@ async function parseAgentFile(path, data) {
|
|
|
58
58
|
}),
|
|
59
59
|
])
|
|
60
60
|
.transform((v) => typeof v === "string"
|
|
61
|
-
? v
|
|
62
|
-
:
|
|
61
|
+
? { content: v, path }
|
|
62
|
+
: Promise.resolve(index_js_1.nodejs.path.join(index_js_1.nodejs.path.dirname(path), v.url)).then((path) => index_js_1.nodejs.fs.readFile(path, "utf8").then((content) => ({ content, path }))));
|
|
63
63
|
return (0, schema_js_1.camelizeSchema)(zod_1.z.discriminatedUnion("type", [
|
|
64
64
|
zod_1.z
|
|
65
65
|
.object({
|
|
@@ -14,9 +14,7 @@ export interface LoadOptions {
|
|
|
14
14
|
key?: string | number;
|
|
15
15
|
}
|
|
16
16
|
export declare function load(path: string, options?: LoadOptions): Promise<AIGNEOptions>;
|
|
17
|
-
export declare function loadAgent(path: string, options?: LoadOptions
|
|
18
|
-
rootDir?: string;
|
|
19
|
-
}, agentOptions?: AgentOptions): Promise<Agent>;
|
|
17
|
+
export declare function loadAgent(path: string, options?: LoadOptions, agentOptions?: AgentOptions): Promise<Agent>;
|
|
20
18
|
declare const aigneFileSchema: z.ZodObject<{
|
|
21
19
|
name: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
|
|
22
20
|
description: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
|
package/lib/cjs/loader/index.js
CHANGED
|
@@ -22,10 +22,7 @@ async function load(path, options = {}) {
|
|
|
22
22
|
options.key ??= Date.now();
|
|
23
23
|
const { aigne, rootDir } = await loadAIGNEFile(path);
|
|
24
24
|
const allAgentPaths = new Set((0, type_utils_js_1.flat)(aigne.agents, aigne.skills, aigne.mcpServer?.agents, aigne.cli?.agents, aigne.cli?.chat).map((i) => index_js_1.nodejs.path.join(rootDir, i)));
|
|
25
|
-
const allAgents = Object.fromEntries(await Promise.all(Array.from(allAgentPaths).map(async (path) => [
|
|
26
|
-
path,
|
|
27
|
-
await loadAgent(path, { ...options, rootDir }),
|
|
28
|
-
])));
|
|
25
|
+
const allAgents = Object.fromEntries(await Promise.all(Array.from(allAgentPaths).map(async (path) => [path, await loadAgent(path, options)])));
|
|
29
26
|
const pickAgents = (paths) => paths.map((filename) => allAgents[index_js_1.nodejs.path.join(rootDir, filename)]).filter(type_utils_js_1.isNonNullable);
|
|
30
27
|
return {
|
|
31
28
|
...aigne,
|
|
@@ -88,7 +85,6 @@ async function parseHooks(path, hooks, options) {
|
|
|
88
85
|
})));
|
|
89
86
|
}
|
|
90
87
|
async function parseAgent(path, agent, options, agentOptions) {
|
|
91
|
-
const workingDir = options?.rootDir ?? index_js_1.nodejs.path.dirname(path);
|
|
92
88
|
const skills = "skills" in agent
|
|
93
89
|
? agent.skills &&
|
|
94
90
|
(await Promise.all(agent.skills.map((skill) => loadNestAgent(path, skill, options))))
|
|
@@ -106,17 +102,25 @@ async function parseAgent(path, agent, options, agentOptions) {
|
|
|
106
102
|
...[agentOptions?.hooks].flat().filter(type_utils_js_1.isNonNullable),
|
|
107
103
|
],
|
|
108
104
|
};
|
|
105
|
+
let instructions;
|
|
106
|
+
if ("instructions" in agent && agent.instructions) {
|
|
107
|
+
instructions = prompt_builder_js_1.PromptBuilder.from(agent.instructions.content, {
|
|
108
|
+
workingDir: index_js_1.nodejs.path.dirname(agent.instructions.path),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
109
111
|
switch (agent.type) {
|
|
110
112
|
case "ai": {
|
|
111
113
|
return ai_agent_js_1.AIAgent.from({
|
|
112
114
|
...baseOptions,
|
|
113
|
-
instructions
|
|
115
|
+
instructions,
|
|
114
116
|
});
|
|
115
117
|
}
|
|
116
118
|
case "image": {
|
|
119
|
+
if (!instructions)
|
|
120
|
+
throw new Error(`Missing required instructions for image agent at path: ${path}`);
|
|
117
121
|
return image_agent_js_1.ImageAgent.from({
|
|
118
122
|
...baseOptions,
|
|
119
|
-
instructions
|
|
123
|
+
instructions,
|
|
120
124
|
});
|
|
121
125
|
}
|
|
122
126
|
case "mcp": {
|
|
@@ -17,7 +17,8 @@ export declare class CustomLoader extends nunjucks.Loader {
|
|
|
17
17
|
workingDir: string;
|
|
18
18
|
});
|
|
19
19
|
async: boolean;
|
|
20
|
-
|
|
20
|
+
isRelative(filename: string): boolean;
|
|
21
|
+
resolve(from: string, to: string): string;
|
|
21
22
|
getSource(name: string, callback: Callback<Error, LoaderSource>): LoaderSource;
|
|
22
23
|
}
|
|
23
24
|
export declare class ChatMessageTemplate {
|
|
@@ -38,7 +38,6 @@ class PromptTemplate {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
exports.PromptTemplate = PromptTemplate;
|
|
41
|
-
const IGNORED_PROMPT_DIRS = ["node_modules", ".git"];
|
|
42
41
|
class CustomLoader extends nunjucks_1.default.Loader {
|
|
43
42
|
options;
|
|
44
43
|
constructor(options) {
|
|
@@ -46,39 +45,26 @@ class CustomLoader extends nunjucks_1.default.Loader {
|
|
|
46
45
|
this.options = options;
|
|
47
46
|
}
|
|
48
47
|
async = true;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
return index_js_1.nodejs.path.join(file.parentPath, file.name);
|
|
55
|
-
for (const entry of files) {
|
|
56
|
-
if (entry.isDirectory()) {
|
|
57
|
-
if (IGNORED_PROMPT_DIRS.includes(entry.name))
|
|
58
|
-
continue;
|
|
59
|
-
const result = await this.findFile(index_js_1.nodejs.path.join(entry.parentPath, entry.name), name);
|
|
60
|
-
if (result)
|
|
61
|
-
return result;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
48
|
+
isRelative(filename) {
|
|
49
|
+
return !index_js_1.nodejs.path.isAbsolute(filename);
|
|
50
|
+
}
|
|
51
|
+
resolve(from, to) {
|
|
52
|
+
return index_js_1.nodejs.path.resolve(index_js_1.nodejs.path.dirname(from), to);
|
|
64
53
|
}
|
|
65
54
|
getSource(name, callback) {
|
|
66
55
|
let result = null;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}, (error) => {
|
|
80
|
-
callback(error, null);
|
|
81
|
-
});
|
|
56
|
+
const path = index_js_1.nodejs.path.isAbsolute(name)
|
|
57
|
+
? name
|
|
58
|
+
: index_js_1.nodejs.path.join(this.options.workingDir, name);
|
|
59
|
+
index_js_1.nodejs.fs.readFile(path, "utf-8").then((content) => {
|
|
60
|
+
result = {
|
|
61
|
+
src: content,
|
|
62
|
+
path,
|
|
63
|
+
noCache: true,
|
|
64
|
+
};
|
|
65
|
+
callback(null, result);
|
|
66
|
+
}, (error) => {
|
|
67
|
+
callback(error, null);
|
|
82
68
|
});
|
|
83
69
|
// nunjucks expects return LoaderSource synchronously, but we handle it asynchronously.
|
|
84
70
|
return result;
|
|
@@ -32,16 +32,20 @@ export interface BaseAgentSchema {
|
|
|
32
32
|
subscribeTopic?: string[];
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
+
export type Instructions = {
|
|
36
|
+
content: string;
|
|
37
|
+
path: string;
|
|
38
|
+
};
|
|
35
39
|
export interface AIAgentSchema extends BaseAgentSchema {
|
|
36
40
|
type: "ai";
|
|
37
|
-
instructions?:
|
|
41
|
+
instructions?: Instructions;
|
|
38
42
|
inputKey?: string;
|
|
39
43
|
outputKey?: string;
|
|
40
44
|
toolChoice?: AIAgentToolChoice;
|
|
41
45
|
}
|
|
42
46
|
export interface ImageAgentSchema extends BaseAgentSchema {
|
|
43
47
|
type: "image";
|
|
44
|
-
instructions:
|
|
48
|
+
instructions: Instructions;
|
|
45
49
|
modelOptions?: Record<string, any>;
|
|
46
50
|
}
|
|
47
51
|
export interface MCPAgentSchema extends BaseAgentSchema {
|
|
@@ -14,9 +14,7 @@ export interface LoadOptions {
|
|
|
14
14
|
key?: string | number;
|
|
15
15
|
}
|
|
16
16
|
export declare function load(path: string, options?: LoadOptions): Promise<AIGNEOptions>;
|
|
17
|
-
export declare function loadAgent(path: string, options?: LoadOptions
|
|
18
|
-
rootDir?: string;
|
|
19
|
-
}, agentOptions?: AgentOptions): Promise<Agent>;
|
|
17
|
+
export declare function loadAgent(path: string, options?: LoadOptions, agentOptions?: AgentOptions): Promise<Agent>;
|
|
20
18
|
declare const aigneFileSchema: z.ZodObject<{
|
|
21
19
|
name: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
|
|
22
20
|
description: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
|
|
@@ -17,7 +17,8 @@ export declare class CustomLoader extends nunjucks.Loader {
|
|
|
17
17
|
workingDir: string;
|
|
18
18
|
});
|
|
19
19
|
async: boolean;
|
|
20
|
-
|
|
20
|
+
isRelative(filename: string): boolean;
|
|
21
|
+
resolve(from: string, to: string): string;
|
|
21
22
|
getSource(name: string, callback: Callback<Error, LoaderSource>): LoaderSource;
|
|
22
23
|
}
|
|
23
24
|
export declare class ChatMessageTemplate {
|
|
@@ -32,16 +32,20 @@ export interface BaseAgentSchema {
|
|
|
32
32
|
subscribeTopic?: string[];
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
+
export type Instructions = {
|
|
36
|
+
content: string;
|
|
37
|
+
path: string;
|
|
38
|
+
};
|
|
35
39
|
export interface AIAgentSchema extends BaseAgentSchema {
|
|
36
40
|
type: "ai";
|
|
37
|
-
instructions?:
|
|
41
|
+
instructions?: Instructions;
|
|
38
42
|
inputKey?: string;
|
|
39
43
|
outputKey?: string;
|
|
40
44
|
toolChoice?: AIAgentToolChoice;
|
|
41
45
|
}
|
|
42
46
|
export interface ImageAgentSchema extends BaseAgentSchema {
|
|
43
47
|
type: "image";
|
|
44
|
-
instructions:
|
|
48
|
+
instructions: Instructions;
|
|
45
49
|
modelOptions?: Record<string, any>;
|
|
46
50
|
}
|
|
47
51
|
export interface MCPAgentSchema extends BaseAgentSchema {
|
|
@@ -54,8 +54,8 @@ export async function parseAgentFile(path, data) {
|
|
|
54
54
|
}),
|
|
55
55
|
])
|
|
56
56
|
.transform((v) => typeof v === "string"
|
|
57
|
-
? v
|
|
58
|
-
:
|
|
57
|
+
? { content: v, path }
|
|
58
|
+
: Promise.resolve(nodejs.path.join(nodejs.path.dirname(path), v.url)).then((path) => nodejs.fs.readFile(path, "utf8").then((content) => ({ content, path }))));
|
|
59
59
|
return camelizeSchema(z.discriminatedUnion("type", [
|
|
60
60
|
z
|
|
61
61
|
.object({
|
|
@@ -14,9 +14,7 @@ export interface LoadOptions {
|
|
|
14
14
|
key?: string | number;
|
|
15
15
|
}
|
|
16
16
|
export declare function load(path: string, options?: LoadOptions): Promise<AIGNEOptions>;
|
|
17
|
-
export declare function loadAgent(path: string, options?: LoadOptions
|
|
18
|
-
rootDir?: string;
|
|
19
|
-
}, agentOptions?: AgentOptions): Promise<Agent>;
|
|
17
|
+
export declare function loadAgent(path: string, options?: LoadOptions, agentOptions?: AgentOptions): Promise<Agent>;
|
|
20
18
|
declare const aigneFileSchema: z.ZodObject<{
|
|
21
19
|
name: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
|
|
22
20
|
description: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
|
package/lib/esm/loader/index.js
CHANGED
|
@@ -17,10 +17,7 @@ export async function load(path, options = {}) {
|
|
|
17
17
|
options.key ??= Date.now();
|
|
18
18
|
const { aigne, rootDir } = await loadAIGNEFile(path);
|
|
19
19
|
const allAgentPaths = new Set(flat(aigne.agents, aigne.skills, aigne.mcpServer?.agents, aigne.cli?.agents, aigne.cli?.chat).map((i) => nodejs.path.join(rootDir, i)));
|
|
20
|
-
const allAgents = Object.fromEntries(await Promise.all(Array.from(allAgentPaths).map(async (path) => [
|
|
21
|
-
path,
|
|
22
|
-
await loadAgent(path, { ...options, rootDir }),
|
|
23
|
-
])));
|
|
20
|
+
const allAgents = Object.fromEntries(await Promise.all(Array.from(allAgentPaths).map(async (path) => [path, await loadAgent(path, options)])));
|
|
24
21
|
const pickAgents = (paths) => paths.map((filename) => allAgents[nodejs.path.join(rootDir, filename)]).filter(isNonNullable);
|
|
25
22
|
return {
|
|
26
23
|
...aigne,
|
|
@@ -83,7 +80,6 @@ async function parseHooks(path, hooks, options) {
|
|
|
83
80
|
})));
|
|
84
81
|
}
|
|
85
82
|
async function parseAgent(path, agent, options, agentOptions) {
|
|
86
|
-
const workingDir = options?.rootDir ?? nodejs.path.dirname(path);
|
|
87
83
|
const skills = "skills" in agent
|
|
88
84
|
? agent.skills &&
|
|
89
85
|
(await Promise.all(agent.skills.map((skill) => loadNestAgent(path, skill, options))))
|
|
@@ -101,17 +97,25 @@ async function parseAgent(path, agent, options, agentOptions) {
|
|
|
101
97
|
...[agentOptions?.hooks].flat().filter(isNonNullable),
|
|
102
98
|
],
|
|
103
99
|
};
|
|
100
|
+
let instructions;
|
|
101
|
+
if ("instructions" in agent && agent.instructions) {
|
|
102
|
+
instructions = PromptBuilder.from(agent.instructions.content, {
|
|
103
|
+
workingDir: nodejs.path.dirname(agent.instructions.path),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
104
106
|
switch (agent.type) {
|
|
105
107
|
case "ai": {
|
|
106
108
|
return AIAgent.from({
|
|
107
109
|
...baseOptions,
|
|
108
|
-
instructions
|
|
110
|
+
instructions,
|
|
109
111
|
});
|
|
110
112
|
}
|
|
111
113
|
case "image": {
|
|
114
|
+
if (!instructions)
|
|
115
|
+
throw new Error(`Missing required instructions for image agent at path: ${path}`);
|
|
112
116
|
return ImageAgent.from({
|
|
113
117
|
...baseOptions,
|
|
114
|
-
instructions
|
|
118
|
+
instructions,
|
|
115
119
|
});
|
|
116
120
|
}
|
|
117
121
|
case "mcp": {
|
|
@@ -17,7 +17,8 @@ export declare class CustomLoader extends nunjucks.Loader {
|
|
|
17
17
|
workingDir: string;
|
|
18
18
|
});
|
|
19
19
|
async: boolean;
|
|
20
|
-
|
|
20
|
+
isRelative(filename: string): boolean;
|
|
21
|
+
resolve(from: string, to: string): string;
|
|
21
22
|
getSource(name: string, callback: Callback<Error, LoaderSource>): LoaderSource;
|
|
22
23
|
}
|
|
23
24
|
export declare class ChatMessageTemplate {
|
|
@@ -30,7 +30,6 @@ export class PromptTemplate {
|
|
|
30
30
|
}));
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
-
const IGNORED_PROMPT_DIRS = ["node_modules", ".git"];
|
|
34
33
|
export class CustomLoader extends nunjucks.Loader {
|
|
35
34
|
options;
|
|
36
35
|
constructor(options) {
|
|
@@ -38,39 +37,26 @@ export class CustomLoader extends nunjucks.Loader {
|
|
|
38
37
|
this.options = options;
|
|
39
38
|
}
|
|
40
39
|
async = true;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return nodejs.path.join(file.parentPath, file.name);
|
|
47
|
-
for (const entry of files) {
|
|
48
|
-
if (entry.isDirectory()) {
|
|
49
|
-
if (IGNORED_PROMPT_DIRS.includes(entry.name))
|
|
50
|
-
continue;
|
|
51
|
-
const result = await this.findFile(nodejs.path.join(entry.parentPath, entry.name), name);
|
|
52
|
-
if (result)
|
|
53
|
-
return result;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
40
|
+
isRelative(filename) {
|
|
41
|
+
return !nodejs.path.isAbsolute(filename);
|
|
42
|
+
}
|
|
43
|
+
resolve(from, to) {
|
|
44
|
+
return nodejs.path.resolve(nodejs.path.dirname(from), to);
|
|
56
45
|
}
|
|
57
46
|
getSource(name, callback) {
|
|
58
47
|
let result = null;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}, (error) => {
|
|
72
|
-
callback(error, null);
|
|
73
|
-
});
|
|
48
|
+
const path = nodejs.path.isAbsolute(name)
|
|
49
|
+
? name
|
|
50
|
+
: nodejs.path.join(this.options.workingDir, name);
|
|
51
|
+
nodejs.fs.readFile(path, "utf-8").then((content) => {
|
|
52
|
+
result = {
|
|
53
|
+
src: content,
|
|
54
|
+
path,
|
|
55
|
+
noCache: true,
|
|
56
|
+
};
|
|
57
|
+
callback(null, result);
|
|
58
|
+
}, (error) => {
|
|
59
|
+
callback(error, null);
|
|
74
60
|
});
|
|
75
61
|
// nunjucks expects return LoaderSource synchronously, but we handle it asynchronously.
|
|
76
62
|
return result;
|