@aigne/core 1.56.0 → 1.57.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 CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.57.1](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.57.0...core-v1.57.1) (2025-08-29)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **core:** load nested prompt files with relative paths correctly ([#432](https://github.com/AIGNE-io/aigne-framework/issues/432)) ([036ffa7](https://github.com/AIGNE-io/aigne-framework/commit/036ffa72391d3f27870a5022b7964739805a6161))
9
+
10
+ ## [1.57.0](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.56.0...core-v1.57.0) (2025-08-28)
11
+
12
+
13
+ ### Features
14
+
15
+ * **cli:** add searchable checkbox component with dynamic filtering ([#426](https://github.com/AIGNE-io/aigne-framework/issues/426)) ([1a76fe7](https://github.com/AIGNE-io/aigne-framework/commit/1a76fe7c2f7d91bc4041dfcd73850b39a18a036b))
16
+
3
17
  ## [1.56.0](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.55.1...core-v1.56.0) (2025-08-27)
4
18
 
5
19
 
@@ -14,7 +14,9 @@ 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, agentOptions?: AgentOptions): Promise<Agent>;
17
+ export declare function loadAgent(path: string, options?: LoadOptions & {
18
+ rootDir?: string;
19
+ }, agentOptions?: AgentOptions): Promise<Agent>;
18
20
  declare const aigneFileSchema: z.ZodObject<{
19
21
  name: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
20
22
  description: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
@@ -22,7 +22,10 @@ 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) => [path, await loadAgent(path, options)])));
25
+ const allAgents = Object.fromEntries(await Promise.all(Array.from(allAgentPaths).map(async (path) => [
26
+ path,
27
+ await loadAgent(path, { ...options, rootDir }),
28
+ ])));
26
29
  const pickAgents = (paths) => paths.map((filename) => allAgents[index_js_1.nodejs.path.join(rootDir, filename)]).filter(type_utils_js_1.isNonNullable);
27
30
  return {
28
31
  ...aigne,
@@ -85,6 +88,7 @@ async function parseHooks(path, hooks, options) {
85
88
  })));
86
89
  }
87
90
  async function parseAgent(path, agent, options, agentOptions) {
91
+ const workingDir = options?.rootDir ?? index_js_1.nodejs.path.dirname(path);
88
92
  const skills = "skills" in agent
89
93
  ? agent.skills &&
90
94
  (await Promise.all(agent.skills.map((skill) => loadNestAgent(path, skill, options))))
@@ -106,16 +110,13 @@ async function parseAgent(path, agent, options, agentOptions) {
106
110
  case "ai": {
107
111
  return ai_agent_js_1.AIAgent.from({
108
112
  ...baseOptions,
109
- instructions: agent.instructions &&
110
- prompt_builder_js_1.PromptBuilder.from(agent.instructions, { workingDir: index_js_1.nodejs.path.dirname(path) }),
113
+ instructions: agent.instructions && prompt_builder_js_1.PromptBuilder.from(agent.instructions, { workingDir }),
111
114
  });
112
115
  }
113
116
  case "image": {
114
117
  return image_agent_js_1.ImageAgent.from({
115
118
  ...baseOptions,
116
- instructions: prompt_builder_js_1.PromptBuilder.from(agent.instructions, {
117
- workingDir: index_js_1.nodejs.path.dirname(path),
118
- }),
119
+ instructions: prompt_builder_js_1.PromptBuilder.from(agent.instructions, { workingDir }),
119
120
  });
120
121
  }
121
122
  case "mcp": {
@@ -17,6 +17,7 @@ export declare class CustomLoader extends nunjucks.Loader {
17
17
  workingDir: string;
18
18
  });
19
19
  async: boolean;
20
+ private findFile;
20
21
  getSource(name: string, callback: Callback<Error, LoaderSource>): LoaderSource;
21
22
  }
22
23
  export declare class ChatMessageTemplate {
@@ -45,17 +45,38 @@ class CustomLoader extends nunjucks_1.default.Loader {
45
45
  this.options = options;
46
46
  }
47
47
  async = true;
48
+ async findFile(dir, name) {
49
+ name = index_js_1.nodejs.path.basename(name);
50
+ const files = await index_js_1.nodejs.fs.readdir(dir, { withFileTypes: true });
51
+ const file = files.find((f) => f.name === name);
52
+ if (file)
53
+ return index_js_1.nodejs.path.join(file.parentPath, file.name);
54
+ for (const dir of files) {
55
+ if (dir.isDirectory()) {
56
+ const result = await this.findFile(index_js_1.nodejs.path.join(dir.parentPath, dir.name), name);
57
+ if (result)
58
+ return result;
59
+ }
60
+ }
61
+ return null;
62
+ }
48
63
  getSource(name, callback) {
49
64
  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);
65
+ this.findFile(this.options.workingDir, name).then((path) => {
66
+ if (!path) {
67
+ callback(new Error(`Template not found: ${name}`), null);
68
+ return;
69
+ }
70
+ return index_js_1.nodejs.fs.readFile(path, "utf-8").then((content) => {
71
+ result = {
72
+ src: content,
73
+ path: name,
74
+ noCache: true,
75
+ };
76
+ callback(null, result);
77
+ }, (error) => {
78
+ callback(error, null);
79
+ });
59
80
  });
60
81
  // nunjucks expects return LoaderSource synchronously, but we handle it asynchronously.
61
82
  return result;
@@ -14,7 +14,9 @@ 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, agentOptions?: AgentOptions): Promise<Agent>;
17
+ export declare function loadAgent(path: string, options?: LoadOptions & {
18
+ rootDir?: string;
19
+ }, agentOptions?: AgentOptions): Promise<Agent>;
18
20
  declare const aigneFileSchema: z.ZodObject<{
19
21
  name: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
20
22
  description: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
@@ -17,6 +17,7 @@ export declare class CustomLoader extends nunjucks.Loader {
17
17
  workingDir: string;
18
18
  });
19
19
  async: boolean;
20
+ private findFile;
20
21
  getSource(name: string, callback: Callback<Error, LoaderSource>): LoaderSource;
21
22
  }
22
23
  export declare class ChatMessageTemplate {
@@ -14,7 +14,9 @@ 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, agentOptions?: AgentOptions): Promise<Agent>;
17
+ export declare function loadAgent(path: string, options?: LoadOptions & {
18
+ rootDir?: string;
19
+ }, agentOptions?: AgentOptions): Promise<Agent>;
18
20
  declare const aigneFileSchema: z.ZodObject<{
19
21
  name: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
20
22
  description: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
@@ -17,7 +17,10 @@ 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) => [path, await loadAgent(path, options)])));
20
+ const allAgents = Object.fromEntries(await Promise.all(Array.from(allAgentPaths).map(async (path) => [
21
+ path,
22
+ await loadAgent(path, { ...options, rootDir }),
23
+ ])));
21
24
  const pickAgents = (paths) => paths.map((filename) => allAgents[nodejs.path.join(rootDir, filename)]).filter(isNonNullable);
22
25
  return {
23
26
  ...aigne,
@@ -80,6 +83,7 @@ async function parseHooks(path, hooks, options) {
80
83
  })));
81
84
  }
82
85
  async function parseAgent(path, agent, options, agentOptions) {
86
+ const workingDir = options?.rootDir ?? nodejs.path.dirname(path);
83
87
  const skills = "skills" in agent
84
88
  ? agent.skills &&
85
89
  (await Promise.all(agent.skills.map((skill) => loadNestAgent(path, skill, options))))
@@ -101,16 +105,13 @@ async function parseAgent(path, agent, options, agentOptions) {
101
105
  case "ai": {
102
106
  return AIAgent.from({
103
107
  ...baseOptions,
104
- instructions: agent.instructions &&
105
- PromptBuilder.from(agent.instructions, { workingDir: nodejs.path.dirname(path) }),
108
+ instructions: agent.instructions && PromptBuilder.from(agent.instructions, { workingDir }),
106
109
  });
107
110
  }
108
111
  case "image": {
109
112
  return ImageAgent.from({
110
113
  ...baseOptions,
111
- instructions: PromptBuilder.from(agent.instructions, {
112
- workingDir: nodejs.path.dirname(path),
113
- }),
114
+ instructions: PromptBuilder.from(agent.instructions, { workingDir }),
114
115
  });
115
116
  }
116
117
  case "mcp": {
@@ -17,6 +17,7 @@ export declare class CustomLoader extends nunjucks.Loader {
17
17
  workingDir: string;
18
18
  });
19
19
  async: boolean;
20
+ private findFile;
20
21
  getSource(name: string, callback: Callback<Error, LoaderSource>): LoaderSource;
21
22
  }
22
23
  export declare class ChatMessageTemplate {
@@ -37,17 +37,38 @@ export class CustomLoader extends nunjucks.Loader {
37
37
  this.options = options;
38
38
  }
39
39
  async = true;
40
+ async findFile(dir, name) {
41
+ name = nodejs.path.basename(name);
42
+ const files = await nodejs.fs.readdir(dir, { withFileTypes: true });
43
+ const file = files.find((f) => f.name === name);
44
+ if (file)
45
+ return nodejs.path.join(file.parentPath, file.name);
46
+ for (const dir of files) {
47
+ if (dir.isDirectory()) {
48
+ const result = await this.findFile(nodejs.path.join(dir.parentPath, dir.name), name);
49
+ if (result)
50
+ return result;
51
+ }
52
+ }
53
+ return null;
54
+ }
40
55
  getSource(name, callback) {
41
56
  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);
57
+ this.findFile(this.options.workingDir, name).then((path) => {
58
+ if (!path) {
59
+ callback(new Error(`Template not found: ${name}`), null);
60
+ return;
61
+ }
62
+ return nodejs.fs.readFile(path, "utf-8").then((content) => {
63
+ result = {
64
+ src: content,
65
+ path: name,
66
+ noCache: true,
67
+ };
68
+ callback(null, result);
69
+ }, (error) => {
70
+ callback(error, null);
71
+ });
51
72
  });
52
73
  // nunjucks expects return LoaderSource synchronously, but we handle it asynchronously.
53
74
  return result;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/core",
3
- "version": "1.56.0",
3
+ "version": "1.57.1",
4
4
  "description": "The functional core of agentic AI",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -66,7 +66,7 @@
66
66
  },
67
67
  "dependencies": {
68
68
  "@aigne/json-schema-to-zod": "^1.3.3",
69
- "@inquirer/prompts": "^7.6.0",
69
+ "@inquirer/prompts": "^7.8.4",
70
70
  "@modelcontextprotocol/sdk": "^1.15.0",
71
71
  "@opentelemetry/api": "^1.9.0",
72
72
  "@opentelemetry/sdk-trace-base": "^2.0.1",
@@ -91,8 +91,8 @@
91
91
  "yaml": "^2.8.0",
92
92
  "zod": "^3.25.67",
93
93
  "zod-to-json-schema": "^3.24.6",
94
- "@aigne/observability-api": "^0.10.1",
95
- "@aigne/platform-helpers": "^0.6.2"
94
+ "@aigne/platform-helpers": "^0.6.2",
95
+ "@aigne/observability-api": "^0.10.1"
96
96
  },
97
97
  "devDependencies": {
98
98
  "@types/bun": "^1.2.18",