@aigne/core 1.70.1 → 1.71.0-beta

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 +15 -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 +10 -1
  11. package/lib/cjs/loader/index.js +42 -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 +10 -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 +10 -1
  39. package/lib/esm/loader/index.js +41 -19
  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 +3 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.71.0-beta](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.70.1...core-v1.71.0-beta) (2025-12-07)
4
+
5
+
6
+ ### Features
7
+
8
+ * 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))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * The following workspace dependencies were updated
14
+ * dependencies
15
+ * @aigne/afs bumped to 1.3.0-beta
16
+ * @aigne/afs-history bumped to 1.1.3-beta
17
+
3
18
  ## [1.70.1](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.70.1-beta...core-v1.70.1) (2025-12-06)
4
19
 
5
20
 
@@ -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,5 @@ export declare function loadAIGNEFile(path: string): Promise<{
230
238
  aigne: z.infer<typeof aigneFileSchema>;
231
239
  rootDir: string;
232
240
  }>;
241
+ export declare function instructionsToPromptBuilder(instructions: Instructions): PromptBuilder;
233
242
  export {};
@@ -2,7 +2,10 @@
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.instructionsToPromptBuilder = instructionsToPromptBuilder;
6
9
  const afs_1 = require("@aigne/afs");
7
10
  const index_js_1 = require("@aigne/platform-helpers/nodejs/index.js");
8
11
  const yaml_1 = require("yaml");
@@ -15,6 +18,7 @@ const team_agent_js_1 = require("../agents/team-agent.js");
15
18
  const transform_agent_js_1 = require("../agents/transform-agent.js");
16
19
  const prompt_builder_js_1 = require("../prompt/prompt-builder.js");
17
20
  const template_js_1 = require("../prompt/template.js");
21
+ const agent_utils_js_1 = require("../utils/agent-utils.js");
18
22
  const type_utils_js_1 = require("../utils/type-utils.js");
19
23
  const agent_js_js_1 = require("./agent-js.js");
20
24
  const agent_yaml_js_1 = require("./agent-yaml.js");
@@ -71,17 +75,18 @@ async function loadAgent(path, options, agentOptions) {
71
75
  return parseAgent(path, agent, options, agentOptions);
72
76
  }
73
77
  if ([".yml", ".yaml"].includes(index_js_1.nodejs.path.extname(path))) {
74
- const agent = await (0, agent_yaml_js_1.loadAgentFromYamlFile)(path);
78
+ const agent = await (0, agent_yaml_js_1.loadAgentFromYamlFile)(path, options);
75
79
  return parseAgent(path, agent, options, agentOptions);
76
80
  }
77
81
  throw new Error(`Unsupported agent file type: ${path}`);
78
82
  }
79
- async function loadNestAgent(path, agent, options) {
83
+ async function loadNestAgent(path, agent, options, agentOptions) {
80
84
  return typeof agent === "object" && "type" in agent
81
- ? parseAgent(path, agent, options)
85
+ ? parseAgent(path, agent, options, agentOptions)
82
86
  : typeof agent === "string"
83
- ? loadAgent(index_js_1.nodejs.path.join(index_js_1.nodejs.path.dirname(path), agent), options)
87
+ ? loadAgent(index_js_1.nodejs.path.join(index_js_1.nodejs.path.dirname(path), agent), options, agentOptions)
84
88
  : loadAgent(index_js_1.nodejs.path.join(index_js_1.nodejs.path.dirname(path), agent.url), options, {
89
+ ...agentOptions,
85
90
  defaultInput: agent.defaultInput,
86
91
  hooks: await parseHooks(path, agent.hooks, options),
87
92
  });
@@ -113,14 +118,17 @@ async function loadSkills(path, skills, options) {
113
118
  return loadedSkills;
114
119
  }
115
120
  async function parseAgent(path, agent, options, agentOptions) {
116
- const skills = "skills" in agent && agent.skills ? await loadSkills(path, agent.skills, options) : undefined;
121
+ if ((0, agent_utils_js_1.isAgent)(agent))
122
+ return agent;
117
123
  const memory = "memory" in agent && options?.memories?.length
118
124
  ? await loadMemory(options.memories, typeof agent.memory === "object" ? agent.memory.provider : undefined, typeof agent.memory === "object" ? agent.memory : {})
119
125
  : undefined;
120
126
  let afs;
121
- if (typeof agent.afs === "boolean") {
122
- if (agent.afs)
123
- afs = new afs_1.AFS();
127
+ if (agent.afs !== false && (!agent.afs || agent.afs === true) && options?.afs?.sharedAFS) {
128
+ afs = options.afs.sharedAFS;
129
+ }
130
+ else if (agent.afs === true) {
131
+ afs = new afs_1.AFS();
124
132
  }
125
133
  else if (agent.afs) {
126
134
  afs = new afs_1.AFS();
@@ -133,6 +141,12 @@ async function parseAgent(path, agent, options, agentOptions) {
133
141
  afs.mount(module);
134
142
  }
135
143
  }
144
+ const skills = "skills" in agent && agent.skills
145
+ ? await loadSkills(path, agent.skills, {
146
+ ...options,
147
+ afs: { ...options?.afs, sharedAFS: (agent.shareAFS && afs) || options?.afs?.sharedAFS },
148
+ })
149
+ : [];
136
150
  const model = agent.model && typeof options?.model === "function"
137
151
  ? await options.model({ ...options.aigne?.model, ...(0, type_utils_js_1.omitBy)(agent.model, (v) => (0, type_utils_js_1.isNil)(v)) })
138
152
  : undefined;
@@ -147,22 +161,17 @@ async function parseAgent(path, agent, options, agentOptions) {
147
161
  ...agent,
148
162
  model,
149
163
  imageModel,
150
- skills,
151
164
  memory,
152
165
  hooks: [
153
166
  ...((await parseHooks(path, agent.hooks, options)) ?? []),
154
167
  ...[agentOptions?.hooks].flat().filter(type_utils_js_1.isNonNullable),
155
168
  ],
156
- afs,
169
+ skills: [...(agentOptions?.skills || []), ...skills],
170
+ afs: afs || agentOptions?.afs,
157
171
  };
158
172
  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
- });
173
+ if ("instructions" in agent && agent.instructions && ["ai", "image"].includes(agent.type)) {
174
+ instructions = instructionsToPromptBuilder(agent.instructions);
166
175
  }
167
176
  switch (agent.type) {
168
177
  case "ai": {
@@ -219,6 +228,14 @@ async function parseAgent(path, agent, options, agentOptions) {
219
228
  });
220
229
  }
221
230
  }
231
+ if ("agentClass" in agent && agent.agentClass) {
232
+ return await agent.agentClass.load({
233
+ filepath: path,
234
+ parsed: baseOptions,
235
+ options,
236
+ });
237
+ }
238
+ throw new Error(`Unsupported agent type: ${"type" in agent ? agent.type : "unknown"} at path: ${path}`);
222
239
  }
223
240
  async function loadMemory(memories, provider, options) {
224
241
  const M = !provider
@@ -274,3 +291,11 @@ async function findAIGNEFile(path) {
274
291
  }
275
292
  throw new Error(`aigne.yaml not found in ${path}. Please ensure you are in the correct directory or provide a valid path.`);
276
293
  }
294
+ function instructionsToPromptBuilder(instructions) {
295
+ return new prompt_builder_js_1.PromptBuilder({
296
+ instructions: template_js_1.ChatMessagesTemplate.from((0, template_js_1.parseChatMessages)(instructions.map((i) => ({
297
+ ...i,
298
+ options: { workingDir: index_js_1.nodejs.path.dirname(i.path) },
299
+ })))),
300
+ });
301
+ }
@@ -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[];