@aigne/core 1.70.1 → 1.71.0-beta.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/lib/cjs/agents/agent.d.ts +4 -0
  3. package/lib/cjs/agents/agent.js +3 -0
  4. package/lib/cjs/agents/image-agent.js +2 -2
  5. package/lib/cjs/agents/types.d.ts +9 -1
  6. package/lib/cjs/loader/agent-js.d.ts +1 -2
  7. package/lib/cjs/loader/agent-js.js +2 -2
  8. package/lib/cjs/loader/agent-yaml.d.ts +19 -3
  9. package/lib/cjs/loader/agent-yaml.js +151 -110
  10. package/lib/cjs/loader/index.d.ts +11 -1
  11. package/lib/cjs/loader/index.js +43 -17
  12. package/lib/cjs/prompt/prompt-builder.d.ts +3 -3
  13. package/lib/cjs/prompt/prompt-builder.js +8 -2
  14. package/lib/cjs/prompt/skills/afs.js +41 -4
  15. package/lib/cjs/prompt/template.d.ts +1 -0
  16. package/lib/cjs/prompt/template.js +5 -3
  17. package/lib/cjs/utils/agent-utils.d.ts +3 -2
  18. package/lib/cjs/utils/agent-utils.js +7 -0
  19. package/lib/cjs/utils/token-estimator.d.ts +9 -0
  20. package/lib/cjs/utils/token-estimator.js +66 -0
  21. package/lib/dts/agents/agent.d.ts +4 -0
  22. package/lib/dts/agents/types.d.ts +9 -1
  23. package/lib/dts/loader/agent-js.d.ts +1 -2
  24. package/lib/dts/loader/agent-yaml.d.ts +19 -3
  25. package/lib/dts/loader/index.d.ts +11 -1
  26. package/lib/dts/prompt/prompt-builder.d.ts +3 -3
  27. package/lib/dts/prompt/template.d.ts +1 -0
  28. package/lib/dts/utils/agent-utils.d.ts +3 -2
  29. package/lib/dts/utils/token-estimator.d.ts +9 -0
  30. package/lib/esm/agents/agent.d.ts +4 -0
  31. package/lib/esm/agents/agent.js +3 -0
  32. package/lib/esm/agents/image-agent.js +2 -2
  33. package/lib/esm/agents/types.d.ts +9 -1
  34. package/lib/esm/loader/agent-js.d.ts +1 -2
  35. package/lib/esm/loader/agent-js.js +2 -2
  36. package/lib/esm/loader/agent-yaml.d.ts +19 -3
  37. package/lib/esm/loader/agent-yaml.js +147 -110
  38. package/lib/esm/loader/index.d.ts +11 -1
  39. package/lib/esm/loader/index.js +42 -20
  40. package/lib/esm/prompt/prompt-builder.d.ts +3 -3
  41. package/lib/esm/prompt/prompt-builder.js +8 -2
  42. package/lib/esm/prompt/skills/afs.js +41 -4
  43. package/lib/esm/prompt/template.d.ts +1 -0
  44. package/lib/esm/prompt/template.js +5 -3
  45. package/lib/esm/utils/agent-utils.d.ts +3 -2
  46. package/lib/esm/utils/agent-utils.js +6 -0
  47. package/lib/esm/utils/token-estimator.d.ts +9 -0
  48. package/lib/esm/utils/token-estimator.js +63 -0
  49. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.71.0-beta.1](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.71.0-beta...core-v1.71.0-beta.1) (2025-12-08)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * correct run example & doc improvements ([#707](https://github.com/AIGNE-io/aigne-framework/issues/707)) ([f98fc5d](https://github.com/AIGNE-io/aigne-framework/commit/f98fc5df28fd6ce6134128c2f0e5395c1554b740))
9
+
10
+ ## [1.71.0-beta](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.70.1...core-v1.71.0-beta) (2025-12-07)
11
+
12
+
13
+ ### Features
14
+
15
+ * support define agent by third library & orchestrator agent refactor ([#799](https://github.com/AIGNE-io/aigne-framework/issues/799)) ([7264b11](https://github.com/AIGNE-io/aigne-framework/commit/7264b11ab6eed787e928367f09aa08d254968d40))
16
+
17
+
18
+ ### Dependencies
19
+
20
+ * The following workspace dependencies were updated
21
+ * dependencies
22
+ * @aigne/afs bumped to 1.3.0-beta
23
+ * @aigne/afs-history bumped to 1.1.3-beta
24
+
3
25
  ## [1.70.1](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.70.1-beta...core-v1.70.1) (2025-12-06)
4
26
 
5
27
 
@@ -205,6 +205,10 @@ export declare abstract class Agent<I extends Message = any, O extends Message =
205
205
  * @returns Agent name
206
206
  */
207
207
  [nodejs.customInspect]: () => string;
208
+ static load<I extends Message = any, O extends Message = any>(_options: {
209
+ filepath: string;
210
+ parsed: object;
211
+ }): Promise<Agent<I, O>>;
208
212
  constructor(options?: AgentOptions<I, O>);
209
213
  /**
210
214
  * List of memories this agent can use
@@ -125,6 +125,9 @@ exports.agentOptionsSchema = zod_1.z.object({
125
125
  * {@includeCode ../../test/agents/agent.test.ts#example-custom-agent}
126
126
  */
127
127
  class Agent {
128
+ static async load(_options) {
129
+ throw new Error("Not implemented");
130
+ }
128
131
  constructor(options = {}) {
129
132
  (0, type_utils_js_1.checkArguments)("Agent options", exports.agentOptionsSchema, options);
130
133
  const { inputSchema, outputSchema } = options;
@@ -37,10 +37,10 @@ class ImageAgent extends agent_js_1.Agent {
37
37
  if (!imageModel)
38
38
  throw new Error("image model is required to run ImageAgent");
39
39
  const modelOptions = await imageModel.getModelOptions(input, options);
40
- const { prompt, image } = await this.instructions.buildImagePrompt({
40
+ const { prompt, image } = await this.instructions.buildPrompt({
41
41
  ...options,
42
42
  input,
43
- agent: this,
43
+ inputFileKey: this.inputFileKey,
44
44
  });
45
45
  const n = input.n || modelOptions?.n;
46
46
  return (await this.invokeChildAgent(imageModel, {
@@ -1,5 +1,5 @@
1
1
  import z, { type ZodType } from "zod";
2
- import { type Agent, DEFAULT_INPUT_ACTION_GET, type Message } from "./agent.js";
2
+ import { type Agent, type AgentOptions, DEFAULT_INPUT_ACTION_GET, type Message } from "./agent.js";
3
3
  export declare const transferAgentOutputKey = "$transferAgentTo";
4
4
  export interface TransferAgentOutput extends Message {
5
5
  [transferAgentOutputKey]: {
@@ -21,3 +21,11 @@ export declare function getterSchema<T extends ZodType>(schema: T): z.ZodUnion<[
21
21
  }, {
22
22
  $get: string;
23
23
  }>]>;
24
+ export interface AgentClass {
25
+ new (...args: any[]): Agent<any, any>;
26
+ load<I extends Message = any, O extends Message = any>(options: {
27
+ filepath: string;
28
+ parsed: AgentOptions;
29
+ [key: string]: any;
30
+ }): Promise<Agent<I, O>>;
31
+ }
@@ -1,2 +1 @@
1
- import { Agent } from "../agents/agent.js";
2
- export declare function loadAgentFromJsFile(path: string): Promise<Agent<any, any> | import("./agent-yaml.js").AgentSchema>;
1
+ export declare function loadAgentFromJsFile(path: string): Promise<import("../index.js").Agent<any, any> | import("./agent-yaml.js").AgentSchema>;
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.loadAgentFromJsFile = loadAgentFromJsFile;
4
4
  const index_js_1 = require("@aigne/platform-helpers/nodejs/index.js");
5
- const agent_js_1 = require("../agents/agent.js");
5
+ const agent_utils_js_1 = require("../utils/agent-utils.js");
6
6
  const type_utils_js_1 = require("../utils/type-utils.js");
7
7
  const agent_yaml_js_1 = require("./agent-yaml.js");
8
8
  const error_js_1 = require("./error.js");
@@ -10,7 +10,7 @@ const importFn = new Function("path", "return import(path)");
10
10
  async function loadAgentFromJsFile(path) {
11
11
  const url = index_js_1.nodejs.path.isAbsolute(path) ? index_js_1.nodejs.url.pathToFileURL(path).toString() : path;
12
12
  const { default: agent } = await (0, type_utils_js_1.tryOrThrow)(() => importFn(url), (error) => new error_js_1.LoadJsAgentError(`Failed to load agent definition from ${url}: ${error.message}`));
13
- if (agent instanceof agent_js_1.Agent)
13
+ if ((0, agent_utils_js_1.isAgent)(agent))
14
14
  return agent;
15
15
  return (0, type_utils_js_1.tryOrThrow)(() => (0, agent_yaml_js_1.parseAgentFile)(path, {
16
16
  type: "function",
@@ -1,9 +1,10 @@
1
1
  import type { AFSOptions } from "@aigne/afs";
2
2
  import { type ZodType, z } from "zod";
3
- import type { AgentHooks, FunctionAgentFn, TaskRenderMode } from "../agents/agent.js";
3
+ import type { AgentClass, AgentHooks, FunctionAgentFn, TaskRenderMode } from "../agents/agent.js";
4
4
  import { AIAgentToolChoice } from "../agents/ai-agent.js";
5
5
  import { type Role } from "../agents/chat-model.js";
6
6
  import { ProcessMode, type ReflectionMode } from "../agents/team-agent.js";
7
+ import type { LoadOptions } from "./index.js";
7
8
  import { chatModelSchema, imageModelSchema } from "./schema.js";
8
9
  export interface HooksSchema {
9
10
  priority?: AgentHooks["priority"];
@@ -44,6 +45,7 @@ export interface BaseAgentSchema {
44
45
  afs?: boolean | (Omit<AFSOptions, "modules"> & {
45
46
  modules?: AFSModuleSchema[];
46
47
  });
48
+ shareAFS?: boolean;
47
49
  }
48
50
  export type Instructions = {
49
51
  role: Exclude<Role, "tool">;
@@ -93,6 +95,20 @@ export interface FunctionAgentSchema extends BaseAgentSchema {
93
95
  type: "function";
94
96
  process: FunctionAgentFn;
95
97
  }
96
- export type AgentSchema = AIAgentSchema | ImageAgentSchema | MCPAgentSchema | TeamAgentSchema | TransformAgentSchema | FunctionAgentSchema;
98
+ export interface ThirdAgentSchema extends BaseAgentSchema {
99
+ agentClass?: AgentClass;
100
+ type: "";
101
+ [key: string]: any;
102
+ }
103
+ export type AgentSchema = AIAgentSchema | ImageAgentSchema | MCPAgentSchema | TeamAgentSchema | TransformAgentSchema | FunctionAgentSchema | ThirdAgentSchema;
97
104
  export declare function parseAgentFile(path: string, data: any): Promise<AgentSchema>;
98
- export declare function loadAgentFromYamlFile(path: string): Promise<AgentSchema>;
105
+ export declare function loadAgentFromYamlFile(path: string, options?: LoadOptions): Promise<AgentSchema>;
106
+ export declare const getInstructionsSchema: ({ filepath }: {
107
+ filepath: string;
108
+ }) => ZodType<Instructions>;
109
+ export declare const getAgentSchema: ({ filepath }: {
110
+ filepath: string;
111
+ }) => ZodType<AgentSchema, z.ZodTypeDef, AgentSchema>;
112
+ export declare const getNestAgentSchema: ({ filepath, }: {
113
+ filepath: string;
114
+ }) => ZodType<NestAgentSchema>;
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getNestAgentSchema = exports.getAgentSchema = exports.getInstructionsSchema = void 0;
3
4
  exports.parseAgentFile = parseAgentFile;
4
5
  exports.loadAgentFromYamlFile = loadAgentFromYamlFile;
5
6
  const json_schema_to_zod_1 = require("@aigne/json-schema-to-zod");
@@ -13,6 +14,69 @@ const type_utils_js_1 = require("../utils/type-utils.js");
13
14
  const function_agent_js_1 = require("./function-agent.js");
14
15
  const schema_js_1 = require("./schema.js");
15
16
  async function parseAgentFile(path, data) {
17
+ const agentSchema = (0, exports.getAgentSchema)({ filepath: path });
18
+ return agentSchema.parseAsync({
19
+ ...data,
20
+ model: data.model || data.chatModel || data.chat_model,
21
+ });
22
+ }
23
+ async function loadAgentFromYamlFile(path, options) {
24
+ const raw = await (0, type_utils_js_1.tryOrThrow)(() => index_js_1.nodejs.fs.readFile(path, "utf8"), (error) => new Error(`Failed to load agent definition from ${path}: ${error.message}`));
25
+ const json = (0, type_utils_js_1.tryOrThrow)(() => (0, yaml_1.parse)(raw), (error) => new Error(`Failed to parse agent definition from ${path}: ${error.message}`));
26
+ if (!["ai", "image", "mcp", "team", "transform", "function"].includes(json?.type)) {
27
+ if (typeof json?.type === "string") {
28
+ if (!options?.require)
29
+ throw new Error(`Module loader is not provided to load agent type module ${json.type} from ${path}`);
30
+ const Mod = await options.require(json.type, { parent: path });
31
+ if (typeof Mod?.default?.prototype?.constructor !== "function") {
32
+ throw new Error(`The agent type module ${json.type} does not export a default Agent class`);
33
+ }
34
+ json.agentClass = Mod.default;
35
+ }
36
+ }
37
+ const agent = await (0, type_utils_js_1.tryOrThrow)(async () => await parseAgentFile(path, {
38
+ ...json,
39
+ type: json.type ?? "ai",
40
+ skills: json.skills ?? json.tools,
41
+ }), (error) => new Error(`Failed to validate agent definition from ${path}: ${error.message}`));
42
+ return agent;
43
+ }
44
+ const instructionItemSchema = zod_1.z.union([
45
+ zod_1.z.object({
46
+ role: chat_model_js_1.roleSchema.default("system"),
47
+ url: zod_1.z.string(),
48
+ }),
49
+ zod_1.z.object({
50
+ role: chat_model_js_1.roleSchema.default("system"),
51
+ content: zod_1.z.string(),
52
+ }),
53
+ ]);
54
+ const parseInstructionItem = ({ filepath }) => async ({ role, ...v }) => {
55
+ if (role === "tool")
56
+ throw new Error(`'tool' role is not allowed in instruction item in agent file ${filepath}`);
57
+ if ("content" in v && typeof v.content === "string") {
58
+ return { role, content: v.content, path: filepath };
59
+ }
60
+ if ("url" in v && typeof v.url === "string") {
61
+ const url = index_js_1.nodejs.path.isAbsolute(v.url)
62
+ ? v.url
63
+ : index_js_1.nodejs.path.join(index_js_1.nodejs.path.dirname(filepath), v.url);
64
+ return index_js_1.nodejs.fs.readFile(url, "utf8").then((content) => ({ role, content, path: url }));
65
+ }
66
+ throw new Error(`Invalid instruction item in agent file ${filepath}. Expected 'content' or 'url' property`);
67
+ };
68
+ const getInstructionsSchema = ({ filepath }) => zod_1.z
69
+ .union([zod_1.z.string(), instructionItemSchema, zod_1.z.array(instructionItemSchema)])
70
+ .transform(async (v) => {
71
+ if (typeof v === "string")
72
+ return [{ role: "system", content: v, path: filepath }];
73
+ if (Array.isArray(v)) {
74
+ return Promise.all(v.map((item) => parseInstructionItem({ filepath })(item)));
75
+ }
76
+ return [await parseInstructionItem({ filepath })(v)];
77
+ });
78
+ exports.getInstructionsSchema = getInstructionsSchema;
79
+ const getAgentSchema = ({ filepath }) => {
16
80
  const agentSchema = zod_1.z.lazy(() => {
17
81
  const nestAgentSchema = zod_1.z.lazy(() => zod_1.z.union([
18
82
  agentSchema,
@@ -41,9 +105,9 @@ async function parseAgentFile(path, data) {
41
105
  imageModel: (0, schema_js_1.optionalize)(schema_js_1.imageModelSchema),
42
106
  taskTitle: (0, schema_js_1.optionalize)(zod_1.z.string()),
43
107
  taskRenderMode: (0, schema_js_1.optionalize)(zod_1.z.union([zod_1.z.literal("hide"), zod_1.z.literal("collapse")])),
44
- inputSchema: (0, schema_js_1.optionalize)((0, schema_js_1.inputOutputSchema)({ path })).transform((v) => v ? (0, json_schema_to_zod_1.jsonSchemaToZod)(v) : undefined),
108
+ inputSchema: (0, schema_js_1.optionalize)((0, schema_js_1.inputOutputSchema)({ path: filepath })).transform((v) => v ? (0, json_schema_to_zod_1.jsonSchemaToZod)(v) : undefined),
45
109
  defaultInput: (0, schema_js_1.optionalize)(schema_js_1.defaultInputSchema),
46
- outputSchema: (0, schema_js_1.optionalize)((0, schema_js_1.inputOutputSchema)({ path })).transform((v) => v ? (0, json_schema_to_zod_1.jsonSchemaToZod)(v) : undefined),
110
+ outputSchema: (0, schema_js_1.optionalize)((0, schema_js_1.inputOutputSchema)({ path: filepath })).transform((v) => v ? (0, json_schema_to_zod_1.jsonSchemaToZod)(v) : undefined),
47
111
  includeInputInOutput: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
48
112
  hooks: (0, schema_js_1.optionalize)(zod_1.z.union([hooksSchema, zod_1.z.array(hooksSchema)])),
49
113
  skills: (0, schema_js_1.optionalize)(zod_1.z.array(nestAgentSchema)),
@@ -66,117 +130,94 @@ async function parseAgentFile(path, data) {
66
130
  ]))),
67
131
  })),
68
132
  ])),
133
+ shareAFS: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
69
134
  });
70
- const instructionItemSchema = zod_1.z.union([
71
- zod_1.z.object({
72
- role: chat_model_js_1.roleSchema.default("system"),
73
- url: zod_1.z.string(),
74
- }),
75
- zod_1.z.object({
76
- role: chat_model_js_1.roleSchema.default("system"),
77
- content: zod_1.z.string(),
78
- }),
79
- ]);
80
- const parseInstructionItem = async ({ role, ...v }) => {
81
- if (role === "tool")
82
- throw new Error(`'tool' role is not allowed in instruction item in agent file ${path}`);
83
- if ("content" in v && typeof v.content === "string") {
84
- return { role, content: v.content, path };
85
- }
86
- if ("url" in v && typeof v.url === "string") {
87
- const url = index_js_1.nodejs.path.isAbsolute(v.url)
88
- ? v.url
89
- : index_js_1.nodejs.path.join(index_js_1.nodejs.path.dirname(path), v.url);
90
- return index_js_1.nodejs.fs.readFile(url, "utf8").then((content) => ({ role, content, path: url }));
91
- }
92
- throw new Error(`Invalid instruction item in agent file ${path}. Expected 'content' or 'url' property`);
93
- };
94
- const instructionsSchema = zod_1.z
95
- .union([zod_1.z.string(), instructionItemSchema, zod_1.z.array(instructionItemSchema)])
96
- .transform(async (v) => {
97
- if (typeof v === "string")
98
- return [{ role: "system", content: v, path }];
99
- if (Array.isArray(v)) {
100
- return Promise.all(v.map((item) => parseInstructionItem(item)));
101
- }
102
- return [await parseInstructionItem(v)];
103
- });
104
- return (0, schema_js_1.camelizeSchema)(zod_1.z.discriminatedUnion("type", [
105
- zod_1.z
106
- .object({
107
- type: zod_1.z.literal("ai"),
108
- instructions: (0, schema_js_1.optionalize)(instructionsSchema),
109
- autoReorderSystemMessages: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
110
- autoMergeSystemMessages: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
111
- inputKey: (0, schema_js_1.optionalize)(zod_1.z.string()),
112
- outputKey: (0, schema_js_1.optionalize)(zod_1.z.string()),
113
- inputFileKey: (0, schema_js_1.optionalize)(zod_1.z.string()),
114
- outputFileKey: (0, schema_js_1.optionalize)(zod_1.z.string()),
115
- toolChoice: (0, schema_js_1.optionalize)(zod_1.z.nativeEnum(ai_agent_js_1.AIAgentToolChoice)),
116
- toolCallsConcurrency: (0, schema_js_1.optionalize)(zod_1.z.number().int().min(0)),
117
- keepTextInToolUses: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
118
- catchToolsError: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
119
- structuredStreamMode: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
120
- })
121
- .extend(baseAgentSchema.shape),
122
- zod_1.z
123
- .object({
124
- type: zod_1.z.literal("image"),
125
- instructions: instructionsSchema,
126
- inputFileKey: (0, schema_js_1.optionalize)(zod_1.z.string()),
127
- })
128
- .extend(baseAgentSchema.shape),
129
- zod_1.z
130
- .object({
131
- type: zod_1.z.literal("mcp"),
132
- url: (0, schema_js_1.optionalize)(zod_1.z.string()),
133
- command: (0, schema_js_1.optionalize)(zod_1.z.string()),
134
- args: (0, schema_js_1.optionalize)(zod_1.z.array(zod_1.z.string())),
135
- })
136
- .extend(baseAgentSchema.shape),
137
- zod_1.z
138
- .object({
139
- type: zod_1.z.literal("team"),
140
- mode: (0, schema_js_1.optionalize)(zod_1.z.nativeEnum(team_agent_js_1.ProcessMode)),
141
- iterateOn: (0, schema_js_1.optionalize)(zod_1.z.string()),
142
- concurrency: (0, schema_js_1.optionalize)(zod_1.z.number().int().min(1)),
143
- iterateWithPreviousOutput: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
144
- includeAllStepsOutput: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
145
- reflection: (0, schema_js_1.camelizeSchema)((0, schema_js_1.optionalize)(zod_1.z.object({
146
- reviewer: nestAgentSchema,
147
- isApproved: zod_1.z.string(),
148
- maxIterations: (0, schema_js_1.optionalize)(zod_1.z.number().int().min(1)),
149
- returnLastOnMaxIterations: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
150
- customErrorMessage: (0, schema_js_1.optionalize)(zod_1.z.string()),
151
- }))),
152
- })
153
- .extend(baseAgentSchema.shape),
135
+ const instructionsSchema = (0, exports.getInstructionsSchema)({ filepath: filepath });
136
+ return (0, schema_js_1.camelizeSchema)(zod_1.z.union([
154
137
  zod_1.z
155
138
  .object({
156
- type: zod_1.z.literal("transform"),
157
- jsonata: zod_1.z.string(),
139
+ type: zod_1.z.string(),
140
+ agentClass: zod_1.z.custom((v) => typeof v?.prototype?.constructor === "function"),
158
141
  })
159
- .extend(baseAgentSchema.shape),
160
- zod_1.z
161
- .object({
162
- type: zod_1.z.literal("function"),
163
- process: zod_1.z.preprocess((v) => (typeof v === "string" ? (0, function_agent_js_1.codeToFunctionAgentFn)(v) : v), zod_1.z.custom()),
164
- })
165
- .extend(baseAgentSchema.shape),
142
+ .extend(baseAgentSchema.shape)
143
+ .passthrough(),
144
+ zod_1.z.discriminatedUnion("type", [
145
+ zod_1.z
146
+ .object({
147
+ type: zod_1.z.literal("ai"),
148
+ instructions: (0, schema_js_1.optionalize)(instructionsSchema),
149
+ autoReorderSystemMessages: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
150
+ autoMergeSystemMessages: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
151
+ inputKey: (0, schema_js_1.optionalize)(zod_1.z.string()),
152
+ outputKey: (0, schema_js_1.optionalize)(zod_1.z.string()),
153
+ inputFileKey: (0, schema_js_1.optionalize)(zod_1.z.string()),
154
+ outputFileKey: (0, schema_js_1.optionalize)(zod_1.z.string()),
155
+ toolChoice: (0, schema_js_1.optionalize)(zod_1.z.nativeEnum(ai_agent_js_1.AIAgentToolChoice)),
156
+ toolCallsConcurrency: (0, schema_js_1.optionalize)(zod_1.z.number().int().min(0)),
157
+ keepTextInToolUses: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
158
+ catchToolsError: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
159
+ structuredStreamMode: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
160
+ })
161
+ .extend(baseAgentSchema.shape),
162
+ zod_1.z
163
+ .object({
164
+ type: zod_1.z.literal("image"),
165
+ instructions: instructionsSchema,
166
+ inputFileKey: (0, schema_js_1.optionalize)(zod_1.z.string()),
167
+ })
168
+ .extend(baseAgentSchema.shape),
169
+ zod_1.z
170
+ .object({
171
+ type: zod_1.z.literal("mcp"),
172
+ url: (0, schema_js_1.optionalize)(zod_1.z.string()),
173
+ command: (0, schema_js_1.optionalize)(zod_1.z.string()),
174
+ args: (0, schema_js_1.optionalize)(zod_1.z.array(zod_1.z.string())),
175
+ })
176
+ .extend(baseAgentSchema.shape),
177
+ zod_1.z
178
+ .object({
179
+ type: zod_1.z.literal("team"),
180
+ mode: (0, schema_js_1.optionalize)(zod_1.z.nativeEnum(team_agent_js_1.ProcessMode)),
181
+ iterateOn: (0, schema_js_1.optionalize)(zod_1.z.string()),
182
+ concurrency: (0, schema_js_1.optionalize)(zod_1.z.number().int().min(1)),
183
+ iterateWithPreviousOutput: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
184
+ includeAllStepsOutput: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
185
+ reflection: (0, schema_js_1.camelizeSchema)((0, schema_js_1.optionalize)(zod_1.z.object({
186
+ reviewer: nestAgentSchema,
187
+ isApproved: zod_1.z.string(),
188
+ maxIterations: (0, schema_js_1.optionalize)(zod_1.z.number().int().min(1)),
189
+ returnLastOnMaxIterations: (0, schema_js_1.optionalize)(zod_1.z.boolean()),
190
+ customErrorMessage: (0, schema_js_1.optionalize)(zod_1.z.string()),
191
+ }))),
192
+ })
193
+ .extend(baseAgentSchema.shape),
194
+ zod_1.z
195
+ .object({
196
+ type: zod_1.z.literal("transform"),
197
+ jsonata: zod_1.z.string(),
198
+ })
199
+ .extend(baseAgentSchema.shape),
200
+ zod_1.z
201
+ .object({
202
+ type: zod_1.z.literal("function"),
203
+ process: zod_1.z.preprocess((v) => (typeof v === "string" ? (0, function_agent_js_1.codeToFunctionAgentFn)(v) : v), zod_1.z.custom()),
204
+ })
205
+ .extend(baseAgentSchema.shape),
206
+ ]),
166
207
  ]));
167
208
  });
168
- return agentSchema.parseAsync({
169
- ...data,
170
- model: data.model || data.chatModel || data.chat_model,
171
- });
172
- }
173
- async function loadAgentFromYamlFile(path) {
174
- const raw = await (0, type_utils_js_1.tryOrThrow)(() => index_js_1.nodejs.fs.readFile(path, "utf8"), (error) => new Error(`Failed to load agent definition from ${path}: ${error.message}`));
175
- const json = (0, type_utils_js_1.tryOrThrow)(() => (0, yaml_1.parse)(raw), (error) => new Error(`Failed to parse agent definition from ${path}: ${error.message}`));
176
- const agent = await (0, type_utils_js_1.tryOrThrow)(async () => await parseAgentFile(path, {
177
- ...json,
178
- type: json.type ?? "ai",
179
- skills: json.skills ?? json.tools,
180
- }), (error) => new Error(`Failed to validate agent definition from ${path}: ${error.message}`));
181
- return agent;
182
- }
209
+ return agentSchema;
210
+ };
211
+ exports.getAgentSchema = getAgentSchema;
212
+ const getNestAgentSchema = ({ filepath, }) => {
213
+ const agentSchema = (0, exports.getAgentSchema)({ filepath });
214
+ return zod_1.z.lazy(() => zod_1.z.union([
215
+ agentSchema,
216
+ zod_1.z.string(),
217
+ (0, schema_js_1.camelizeSchema)(zod_1.z.object({
218
+ url: zod_1.z.string(),
219
+ defaultInput: (0, schema_js_1.optionalize)(schema_js_1.defaultInputSchema),
220
+ })),
221
+ ]));
222
+ };
223
+ exports.getNestAgentSchema = getNestAgentSchema;
@@ -1,11 +1,13 @@
1
- import { type AFSModule } from "@aigne/afs";
1
+ import { AFS, type AFSModule } from "@aigne/afs";
2
2
  import { type ZodType, z } from "zod";
3
3
  import { Agent, type AgentOptions } from "../agents/agent.js";
4
4
  import type { ChatModel } from "../agents/chat-model.js";
5
5
  import type { ImageModel } from "../agents/image-model.js";
6
6
  import type { AIGNEOptions } from "../aigne/aigne.js";
7
7
  import type { MemoryAgent, MemoryAgentOptions } from "../memory/memory.js";
8
+ import { PromptBuilder } from "../prompt/prompt-builder.js";
8
9
  import { type PromiseOrValue } from "../utils/type-utils.js";
10
+ import { type Instructions, loadAgentFromYamlFile, type NestAgentSchema } from "./agent-yaml.js";
9
11
  export interface LoadOptions {
10
12
  memories?: {
11
13
  new (parameters?: MemoryAgentOptions): MemoryAgent;
@@ -13,6 +15,7 @@ export interface LoadOptions {
13
15
  model?: ChatModel | ((model?: z.infer<typeof aigneFileSchema>["model"]) => PromiseOrValue<ChatModel | undefined>);
14
16
  imageModel?: ImageModel | ((model?: z.infer<typeof aigneFileSchema>["imageModel"]) => PromiseOrValue<ImageModel | undefined>);
15
17
  afs?: {
18
+ sharedAFS?: AFS;
16
19
  availableModules?: {
17
20
  module: string;
18
21
  alias?: string[];
@@ -20,9 +23,14 @@ export interface LoadOptions {
20
23
  }[];
21
24
  };
22
25
  aigne?: z.infer<typeof aigneFileSchema>;
26
+ require?: (modulePath: string, options: {
27
+ parent?: string;
28
+ }) => Promise<any>;
23
29
  }
24
30
  export declare function load(path: string, options?: LoadOptions): Promise<AIGNEOptions>;
25
31
  export declare function loadAgent(path: string, options?: LoadOptions, agentOptions?: AgentOptions): Promise<Agent>;
32
+ export declare function loadNestAgent(path: string, agent: NestAgentSchema, options?: LoadOptions, agentOptions?: AgentOptions & Record<string, unknown>): Promise<Agent>;
33
+ export declare function parseAgent(path: string, agent: Awaited<ReturnType<typeof loadAgentFromYamlFile>>, options?: LoadOptions, agentOptions?: AgentOptions): Promise<Agent>;
26
34
  type CliAgent = string | {
27
35
  url?: string;
28
36
  name?: string;
@@ -230,4 +238,6 @@ export declare function loadAIGNEFile(path: string): Promise<{
230
238
  aigne: z.infer<typeof aigneFileSchema>;
231
239
  rootDir: string;
232
240
  }>;
241
+ export declare function findAIGNEFile(path: string): Promise<string>;
242
+ export declare function instructionsToPromptBuilder(instructions: Instructions): PromptBuilder;
233
243
  export {};
@@ -2,7 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.load = load;
4
4
  exports.loadAgent = loadAgent;
5
+ exports.loadNestAgent = loadNestAgent;
6
+ exports.parseAgent = parseAgent;
5
7
  exports.loadAIGNEFile = loadAIGNEFile;
8
+ exports.findAIGNEFile = findAIGNEFile;
9
+ exports.instructionsToPromptBuilder = instructionsToPromptBuilder;
6
10
  const afs_1 = require("@aigne/afs");
7
11
  const index_js_1 = require("@aigne/platform-helpers/nodejs/index.js");
8
12
  const yaml_1 = require("yaml");
@@ -15,6 +19,7 @@ const team_agent_js_1 = require("../agents/team-agent.js");
15
19
  const transform_agent_js_1 = require("../agents/transform-agent.js");
16
20
  const prompt_builder_js_1 = require("../prompt/prompt-builder.js");
17
21
  const template_js_1 = require("../prompt/template.js");
22
+ const agent_utils_js_1 = require("../utils/agent-utils.js");
18
23
  const type_utils_js_1 = require("../utils/type-utils.js");
19
24
  const agent_js_js_1 = require("./agent-js.js");
20
25
  const agent_yaml_js_1 = require("./agent-yaml.js");
@@ -71,17 +76,18 @@ async function loadAgent(path, options, agentOptions) {
71
76
  return parseAgent(path, agent, options, agentOptions);
72
77
  }
73
78
  if ([".yml", ".yaml"].includes(index_js_1.nodejs.path.extname(path))) {
74
- const agent = await (0, agent_yaml_js_1.loadAgentFromYamlFile)(path);
79
+ const agent = await (0, agent_yaml_js_1.loadAgentFromYamlFile)(path, options);
75
80
  return parseAgent(path, agent, options, agentOptions);
76
81
  }
77
82
  throw new Error(`Unsupported agent file type: ${path}`);
78
83
  }
79
- async function loadNestAgent(path, agent, options) {
84
+ async function loadNestAgent(path, agent, options, agentOptions) {
80
85
  return typeof agent === "object" && "type" in agent
81
- ? parseAgent(path, agent, options)
86
+ ? parseAgent(path, agent, options, agentOptions)
82
87
  : typeof agent === "string"
83
- ? loadAgent(index_js_1.nodejs.path.join(index_js_1.nodejs.path.dirname(path), agent), options)
88
+ ? loadAgent(index_js_1.nodejs.path.join(index_js_1.nodejs.path.dirname(path), agent), options, agentOptions)
84
89
  : loadAgent(index_js_1.nodejs.path.join(index_js_1.nodejs.path.dirname(path), agent.url), options, {
90
+ ...agentOptions,
85
91
  defaultInput: agent.defaultInput,
86
92
  hooks: await parseHooks(path, agent.hooks, options),
87
93
  });
@@ -113,14 +119,17 @@ async function loadSkills(path, skills, options) {
113
119
  return loadedSkills;
114
120
  }
115
121
  async function parseAgent(path, agent, options, agentOptions) {
116
- const skills = "skills" in agent && agent.skills ? await loadSkills(path, agent.skills, options) : undefined;
122
+ if ((0, agent_utils_js_1.isAgent)(agent))
123
+ return agent;
117
124
  const memory = "memory" in agent && options?.memories?.length
118
125
  ? await loadMemory(options.memories, typeof agent.memory === "object" ? agent.memory.provider : undefined, typeof agent.memory === "object" ? agent.memory : {})
119
126
  : undefined;
120
127
  let afs;
121
- if (typeof agent.afs === "boolean") {
122
- if (agent.afs)
123
- afs = new afs_1.AFS();
128
+ if (agent.afs !== false && (!agent.afs || agent.afs === true) && options?.afs?.sharedAFS) {
129
+ afs = options.afs.sharedAFS;
130
+ }
131
+ else if (agent.afs === true) {
132
+ afs = new afs_1.AFS();
124
133
  }
125
134
  else if (agent.afs) {
126
135
  afs = new afs_1.AFS();
@@ -133,6 +142,12 @@ async function parseAgent(path, agent, options, agentOptions) {
133
142
  afs.mount(module);
134
143
  }
135
144
  }
145
+ const skills = "skills" in agent && agent.skills
146
+ ? await loadSkills(path, agent.skills, {
147
+ ...options,
148
+ afs: { ...options?.afs, sharedAFS: (agent.shareAFS && afs) || options?.afs?.sharedAFS },
149
+ })
150
+ : [];
136
151
  const model = agent.model && typeof options?.model === "function"
137
152
  ? await options.model({ ...options.aigne?.model, ...(0, type_utils_js_1.omitBy)(agent.model, (v) => (0, type_utils_js_1.isNil)(v)) })
138
153
  : undefined;
@@ -147,22 +162,17 @@ async function parseAgent(path, agent, options, agentOptions) {
147
162
  ...agent,
148
163
  model,
149
164
  imageModel,
150
- skills,
151
165
  memory,
152
166
  hooks: [
153
167
  ...((await parseHooks(path, agent.hooks, options)) ?? []),
154
168
  ...[agentOptions?.hooks].flat().filter(type_utils_js_1.isNonNullable),
155
169
  ],
156
- afs,
170
+ skills: [...(agentOptions?.skills || []), ...skills],
171
+ afs: afs || agentOptions?.afs,
157
172
  };
158
173
  let instructions;
159
- if ("instructions" in agent && agent.instructions) {
160
- instructions = new prompt_builder_js_1.PromptBuilder({
161
- instructions: template_js_1.ChatMessagesTemplate.from((0, template_js_1.parseChatMessages)(agent.instructions.map((i) => ({
162
- ...i,
163
- options: { workingDir: index_js_1.nodejs.path.dirname(i.path) },
164
- })))),
165
- });
174
+ if ("instructions" in agent && agent.instructions && ["ai", "image"].includes(agent.type)) {
175
+ instructions = instructionsToPromptBuilder(agent.instructions);
166
176
  }
167
177
  switch (agent.type) {
168
178
  case "ai": {
@@ -219,6 +229,14 @@ async function parseAgent(path, agent, options, agentOptions) {
219
229
  });
220
230
  }
221
231
  }
232
+ if ("agentClass" in agent && agent.agentClass) {
233
+ return await agent.agentClass.load({
234
+ filepath: path,
235
+ parsed: baseOptions,
236
+ options,
237
+ });
238
+ }
239
+ throw new Error(`Unsupported agent type: ${"type" in agent ? agent.type : "unknown"} at path: ${path}`);
222
240
  }
223
241
  async function loadMemory(memories, provider, options) {
224
242
  const M = !provider
@@ -274,3 +292,11 @@ async function findAIGNEFile(path) {
274
292
  }
275
293
  throw new Error(`aigne.yaml not found in ${path}. Please ensure you are in the correct directory or provide a valid path.`);
276
294
  }
295
+ function instructionsToPromptBuilder(instructions) {
296
+ return new prompt_builder_js_1.PromptBuilder({
297
+ instructions: template_js_1.ChatMessagesTemplate.from((0, template_js_1.parseChatMessages)(instructions.map((i) => ({
298
+ ...i,
299
+ options: { workingDir: index_js_1.nodejs.path.dirname(i.path) },
300
+ })))),
301
+ });
302
+ }
@@ -2,7 +2,6 @@ import type { GetPromptResult } from "@modelcontextprotocol/sdk/types.js";
2
2
  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
- import type { ImageAgent } from "../agents/image-agent.js";
6
5
  import { type FileUnionContent } from "../agents/model.js";
7
6
  import { ChatMessagesTemplate } from "./template.js";
8
7
  export interface PromptBuilderOptions {
@@ -26,11 +25,12 @@ export declare class PromptBuilder {
26
25
  constructor(options?: PromptBuilderOptions);
27
26
  instructions?: string | ChatMessagesTemplate;
28
27
  workingDir?: string;
28
+ copy(): PromptBuilder;
29
29
  build(options: PromptBuildOptions): Promise<ChatModelInput & {
30
30
  toolAgents?: Agent[];
31
31
  }>;
32
- buildImagePrompt(options: Pick<PromptBuildOptions, "input" | "context"> & {
33
- agent: ImageAgent;
32
+ buildPrompt(options: Pick<PromptBuildOptions, "input" | "context"> & {
33
+ inputFileKey?: string;
34
34
  }): Promise<{
35
35
  prompt: string;
36
36
  image?: FileUnionContent[];