@aigne/core 1.69.2 → 1.70.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 (34) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/lib/cjs/agents/chat-model.d.ts +9 -10
  3. package/lib/cjs/agents/chat-model.js +20 -34
  4. package/lib/cjs/agents/image-agent.d.ts +0 -2
  5. package/lib/cjs/agents/image-agent.js +3 -5
  6. package/lib/cjs/agents/image-model.d.ts +1 -1
  7. package/lib/cjs/agents/image-model.js +0 -1
  8. package/lib/cjs/agents/model.d.ts +17 -1
  9. package/lib/cjs/agents/model.js +46 -0
  10. package/lib/cjs/agents/video-model.d.ts +1 -1
  11. package/lib/cjs/agents/video-model.js +0 -1
  12. package/lib/cjs/loader/agent-yaml.d.ts +0 -1
  13. package/lib/cjs/loader/agent-yaml.js +0 -1
  14. package/lib/cjs/prompt/skills/afs.js +30 -6
  15. package/lib/dts/agents/chat-model.d.ts +9 -10
  16. package/lib/dts/agents/image-agent.d.ts +0 -2
  17. package/lib/dts/agents/image-model.d.ts +1 -1
  18. package/lib/dts/agents/model.d.ts +17 -1
  19. package/lib/dts/agents/video-model.d.ts +1 -1
  20. package/lib/dts/loader/agent-yaml.d.ts +0 -1
  21. package/lib/esm/agents/chat-model.d.ts +9 -10
  22. package/lib/esm/agents/chat-model.js +21 -35
  23. package/lib/esm/agents/image-agent.d.ts +0 -2
  24. package/lib/esm/agents/image-agent.js +3 -5
  25. package/lib/esm/agents/image-model.d.ts +1 -1
  26. package/lib/esm/agents/image-model.js +0 -1
  27. package/lib/esm/agents/model.d.ts +17 -1
  28. package/lib/esm/agents/model.js +48 -2
  29. package/lib/esm/agents/video-model.d.ts +1 -1
  30. package/lib/esm/agents/video-model.js +0 -1
  31. package/lib/esm/loader/agent-yaml.d.ts +0 -1
  32. package/lib/esm/loader/agent-yaml.js +0 -1
  33. package/lib/esm/prompt/skills/afs.js +30 -6
  34. package/package.json +5 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.70.0-beta.1](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.70.0-beta...core-v1.70.0-beta.1) (2025-12-05)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * return tree view instead of list for afs_list ([#774](https://github.com/AIGNE-io/aigne-framework/issues/774)) ([8ec2f93](https://github.com/AIGNE-io/aigne-framework/commit/8ec2f93fb5870f6404d886ad0197cc21c61dfd74))
9
+
10
+ ## [1.70.0-beta](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.69.2...core-v1.70.0-beta) (2025-12-02)
11
+
12
+
13
+ ### Features
14
+
15
+ * **core:** add nested getter pattern support for model options ([#796](https://github.com/AIGNE-io/aigne-framework/issues/796)) ([824b2fe](https://github.com/AIGNE-io/aigne-framework/commit/824b2fe55cb2a24620e2bb73b470532918fa2996))
16
+
17
+
18
+ ### Dependencies
19
+
20
+ * The following workspace dependencies were updated
21
+ * dependencies
22
+ * @aigne/afs bumped to 1.2.3-beta
23
+ * @aigne/afs-history bumped to 1.1.2-beta
24
+
3
25
  ## [1.69.2](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.69.2-beta.1...core-v1.69.2) (2025-11-28)
4
26
 
5
27
 
@@ -1,4 +1,4 @@
1
- import { z } from "zod";
1
+ import { type ZodType, z } from "zod";
2
2
  import { type PromiseOrValue } from "../utils/type-utils.js";
3
3
  import { type AgentInvokeOptions, type AgentOptions, type AgentProcessResult, type AgentResponse, type AgentResponseStream, type GetterSchema, type Message } from "./agent.js";
4
4
  import { type FileType, type FileUnionContent, Model } from "./model.js";
@@ -40,7 +40,6 @@ export declare abstract class ChatModel extends Model<ChatModelInput, ChatModelO
40
40
  apiKey?: string;
41
41
  model?: string;
42
42
  }>;
43
- getModelOptions(input: Message, options: AgentInvokeOptions): Promise<ChatModelInputOptions>;
44
43
  /**
45
44
  * Indicates whether the model supports parallel tool calls
46
45
  *
@@ -157,7 +156,7 @@ export interface ChatModelInput extends Message {
157
156
  /**
158
157
  * Model-specific configuration options
159
158
  */
160
- modelOptions?: ChatModelInputOptionsWithGetter;
159
+ modelOptions?: ChatModelInputOptions;
161
160
  }
162
161
  /**
163
162
  * Message role types
@@ -241,8 +240,8 @@ export declare const unionContentSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
241
240
  type: "text";
242
241
  text: string;
243
242
  }>, z.ZodObject<{
244
- filename: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
245
- mimeType: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
243
+ filename: ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
244
+ mimeType: ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
246
245
  } & {
247
246
  type: z.ZodLiteral<"local">;
248
247
  path: z.ZodString;
@@ -257,8 +256,8 @@ export declare const unionContentSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
257
256
  filename?: string | undefined;
258
257
  mimeType?: string | undefined;
259
258
  }>, z.ZodObject<{
260
- filename: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
261
- mimeType: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
259
+ filename: ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
260
+ mimeType: ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
262
261
  } & {
263
262
  type: z.ZodLiteral<"url">;
264
263
  url: z.ZodString;
@@ -273,8 +272,8 @@ export declare const unionContentSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
273
272
  filename?: string | undefined;
274
273
  mimeType?: string | undefined;
275
274
  }>, z.ZodObject<{
276
- filename: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
277
- mimeType: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
275
+ filename: ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
276
+ mimeType: ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
278
277
  } & {
279
278
  type: z.ZodLiteral<"file">;
280
279
  data: z.ZodString;
@@ -497,7 +496,7 @@ export interface ChatModelOutputUsage {
497
496
  export declare const chatModelOutputUsageSchema: z.ZodObject<{
498
497
  inputTokens: z.ZodNumber;
499
498
  outputTokens: z.ZodNumber;
500
- aigneHubCredits: z.ZodType<number | undefined, z.ZodTypeDef, number | undefined>;
499
+ aigneHubCredits: ZodType<number | undefined, z.ZodTypeDef, number | undefined>;
501
500
  }, "strip", z.ZodTypeAny, {
502
501
  inputTokens: number;
503
502
  outputTokens: number;
@@ -92,34 +92,12 @@ class ChatModel extends model_js_1.Model {
92
92
  inputSchema: chatModelInputSchema,
93
93
  outputSchema: chatModelOutputSchema,
94
94
  retryOnError,
95
- model: undefined,
96
95
  });
97
96
  this.options = options;
98
97
  }
99
98
  get credential() {
100
99
  return {};
101
100
  }
102
- async getModelOptions(input, options) {
103
- const result = {};
104
- for (const [key, val] of Object.entries({
105
- ...this.options?.modelOptions,
106
- ...("modelOptions" in input ? input.modelOptions : {}),
107
- })) {
108
- if (val &&
109
- typeof val === "object" &&
110
- agent_js_1.DEFAULT_INPUT_ACTION_GET in val &&
111
- typeof val[agent_js_1.DEFAULT_INPUT_ACTION_GET] === "string") {
112
- const getterPath = val[agent_js_1.DEFAULT_INPUT_ACTION_GET];
113
- const value = input[getterPath] ?? options.context.userContext[getterPath];
114
- if (!(0, type_utils_js_1.isNil)(value))
115
- Object.assign(result, { [key]: value });
116
- }
117
- else {
118
- Object.assign(result, { [key]: val });
119
- }
120
- }
121
- return result;
122
- }
123
101
  /**
124
102
  * Indicates whether the model supports parallel tool calls
125
103
  *
@@ -351,25 +329,33 @@ const chatModelInputToolChoiceSchema = zod_1.z.union([
351
329
  zod_1.z.literal("required"),
352
330
  chatModelInputToolSchema,
353
331
  ]);
354
- const modelOptionsSchema = zod_1.z.object({
355
- model: (0, schema_js_1.optionalize)((0, agent_js_1.getterSchema)(zod_1.z.string())),
356
- temperature: (0, schema_js_1.optionalize)((0, agent_js_1.getterSchema)(zod_1.z.number())),
357
- topP: (0, schema_js_1.optionalize)((0, agent_js_1.getterSchema)(zod_1.z.number())),
358
- frequencyPenalty: (0, schema_js_1.optionalize)((0, agent_js_1.getterSchema)(zod_1.z.number())),
359
- presencePenalty: (0, schema_js_1.optionalize)((0, agent_js_1.getterSchema)(zod_1.z.number())),
360
- parallelToolCalls: (0, schema_js_1.optionalize)((0, agent_js_1.getterSchema)(zod_1.z.boolean())).default(true),
361
- modalities: (0, schema_js_1.optionalize)((0, agent_js_1.getterSchema)(zod_1.z.array(zod_1.z.enum(["text", "image", "audio"])))),
362
- reasoningEffort: (0, schema_js_1.optionalize)((0, agent_js_1.getterSchema)(zod_1.z.union([
332
+ const modelOptionsSchemaProperties = {
333
+ model: zod_1.z.string(),
334
+ temperature: zod_1.z.number(),
335
+ topP: zod_1.z.number(),
336
+ frequencyPenalty: zod_1.z.number(),
337
+ presencePenalty: zod_1.z.number(),
338
+ parallelToolCalls: zod_1.z.boolean().default(true),
339
+ modalities: zod_1.z.array(zod_1.z.enum(["text", "image", "audio"])),
340
+ reasoningEffort: zod_1.z.union([
363
341
  zod_1.z.number(),
364
342
  zod_1.z.literal("minimal"),
365
343
  zod_1.z.literal("low"),
366
344
  zod_1.z.literal("medium"),
367
345
  zod_1.z.literal("high"),
368
- ]))),
369
- });
346
+ ]),
347
+ };
348
+ const modelOptionsSchema = zod_1.z.object(Object.fromEntries(Object.entries(modelOptionsSchemaProperties).map(([key, schema]) => [
349
+ key,
350
+ (0, schema_js_1.optionalize)(schema),
351
+ ])));
352
+ const modelOptionsWithGetterSchema = zod_1.z.object(Object.fromEntries(Object.entries(modelOptionsSchemaProperties).map(([key, schema]) => [
353
+ key,
354
+ (0, schema_js_1.optionalize)((0, agent_js_1.getterSchema)(schema)),
355
+ ])));
370
356
  const chatModelOptionsSchema = agent_js_1.agentOptionsSchema.extend({
371
357
  model: (0, schema_js_1.optionalize)(zod_1.z.string()),
372
- modelOptions: (0, schema_js_1.optionalize)(modelOptionsSchema),
358
+ modelOptions: (0, schema_js_1.optionalize)(modelOptionsWithGetterSchema),
373
359
  });
374
360
  const chatModelInputSchema = zod_1.z.object({
375
361
  messages: zod_1.z.array(chatModelInputMessageSchema),
@@ -6,7 +6,6 @@ import { type FileType } from "./model.js";
6
6
  export interface ImageAgentOptions<I extends Message = any, O extends ImageModelOutput = any> extends Omit<AgentOptions<I, O>, "outputSchema"> {
7
7
  instructions: string | PromptBuilder;
8
8
  inputFileKey?: string;
9
- modelOptions?: Record<string, any>;
10
9
  outputFileType?: FileType;
11
10
  }
12
11
  export declare const imageAgentOptionsSchema: ZodObject<{
@@ -18,7 +17,6 @@ export declare class ImageAgent<I extends Message = any, O extends ImageModelOut
18
17
  constructor(options: ImageAgentOptions<I, O>);
19
18
  instructions: PromptBuilder;
20
19
  inputFileKey?: string;
21
- modelOptions?: Record<string, any>;
22
20
  outputFileType?: FileType;
23
21
  process(input: I, options: AgentInvokeOptions): Promise<O>;
24
22
  }
@@ -12,7 +12,6 @@ const image_model_js_1 = require("./image-model.js");
12
12
  const model_js_1 = require("./model.js");
13
13
  exports.imageAgentOptionsSchema = agent_js_1.agentOptionsSchema.extend({
14
14
  instructions: zod_1.default.union([zod_1.default.string(), zod_1.default.custom()]),
15
- modelOptions: zod_1.default.record(zod_1.default.any()).optional(),
16
15
  outputFileType: model_js_1.fileTypeSchema.optional(),
17
16
  });
18
17
  class ImageAgent extends agent_js_1.Agent {
@@ -28,26 +27,25 @@ class ImageAgent extends agent_js_1.Agent {
28
27
  ? prompt_builder_js_1.PromptBuilder.from(options.instructions)
29
28
  : options.instructions;
30
29
  this.inputFileKey = options.inputFileKey;
31
- this.modelOptions = options.modelOptions;
32
30
  this.outputFileType = options.outputFileType;
33
31
  }
34
32
  instructions;
35
33
  inputFileKey;
36
- modelOptions;
37
34
  outputFileType;
38
35
  async process(input, options) {
39
36
  const imageModel = this.imageModel || options.imageModel || options.context.imageModel;
40
37
  if (!imageModel)
41
38
  throw new Error("image model is required to run ImageAgent");
39
+ const modelOptions = await imageModel.getModelOptions(input, options);
42
40
  const { prompt, image } = await this.instructions.buildImagePrompt({
43
41
  ...options,
44
42
  input,
45
43
  agent: this,
46
44
  });
47
- const n = input.n || this.modelOptions?.n;
45
+ const n = input.n || modelOptions?.n;
48
46
  return (await this.invokeChildAgent(imageModel, {
49
47
  n: n && typeof n === "number" ? n : undefined,
50
- modelOptions: this.modelOptions,
48
+ modelOptions,
51
49
  prompt,
52
50
  image,
53
51
  outputFileType: this.outputFileType,
@@ -5,7 +5,7 @@ import { type ChatModelOutputUsage } from "./chat-model.js";
5
5
  import { type FileType, type FileUnionContent, Model } from "./model.js";
6
6
  export interface ImageModelOptions<I extends ImageModelInput = ImageModelInput, O extends ImageModelOutput = ImageModelOutput> extends Omit<AgentOptions<I, O>, "model"> {
7
7
  model?: string;
8
- modelOptions?: Omit<ImageModelInputOptions, "model">;
8
+ modelOptions?: ImageModelInputOptionsWithGetter;
9
9
  }
10
10
  export declare abstract class ImageModel<I extends ImageModelInput = ImageModelInput, O extends ImageModelOutput = ImageModelOutput> extends Model<I, O> {
11
11
  options?: ImageModelOptions<I, O> | undefined;
@@ -13,7 +13,6 @@ class ImageModel extends model_js_1.Model {
13
13
  inputSchema: exports.imageModelInputSchema,
14
14
  outputSchema: exports.imageModelOutputSchema,
15
15
  ...options,
16
- model: undefined,
17
16
  });
18
17
  this.options = options;
19
18
  }
@@ -1,6 +1,22 @@
1
1
  import { z } from "zod";
2
- import { Agent, type AgentInvokeOptions, type Message } from "./agent.js";
2
+ import { Agent, type AgentInvokeOptions, type AgentOptions, type Message } from "./agent.js";
3
3
  export declare abstract class Model<I extends Message = any, O extends Message = any> extends Agent<I, O> {
4
+ options?: (Omit<AgentOptions<I, O>, "model"> & {
5
+ modelOptions?: Record<string, unknown>;
6
+ }) | undefined;
7
+ constructor(options?: (Omit<AgentOptions<I, O>, "model"> & {
8
+ modelOptions?: Record<string, unknown>;
9
+ }) | undefined);
10
+ /**
11
+ * Resolves model options by merging instance-level and input-level options,
12
+ * and recursively resolving getter patterns
13
+ *
14
+ * @param input - The input message containing potential modelOptions
15
+ * @param options - The agent invocation options containing context
16
+ * @returns Resolved model options with all getters replaced by actual values
17
+ */
18
+ getModelOptions(input: Message, options: AgentInvokeOptions): Promise<Record<string, unknown>>;
19
+ protected preprocess(input: I, options: AgentInvokeOptions): Promise<void>;
4
20
  transformFileType(fileType: "file", data: FileUnionContent, options: AgentInvokeOptions): Promise<FileContent>;
5
21
  transformFileType(fileType: "local" | undefined, data: FileUnionContent, options: AgentInvokeOptions): Promise<LocalContent>;
6
22
  transformFileType(fileType: FileType | undefined, data: FileUnionContent, options: AgentInvokeOptions): Promise<FileUnionContent>;
@@ -43,6 +43,52 @@ const fetch_js_1 = require("../utils/fetch.js");
43
43
  const type_utils_js_1 = require("../utils/type-utils.js");
44
44
  const agent_js_1 = require("./agent.js");
45
45
  class Model extends agent_js_1.Agent {
46
+ options;
47
+ constructor(options) {
48
+ super(options);
49
+ this.options = options;
50
+ }
51
+ /**
52
+ * Resolves model options by merging instance-level and input-level options,
53
+ * and recursively resolving getter patterns
54
+ *
55
+ * @param input - The input message containing potential modelOptions
56
+ * @param options - The agent invocation options containing context
57
+ * @returns Resolved model options with all getters replaced by actual values
58
+ */
59
+ async getModelOptions(input, options) {
60
+ const resolveGetters = (obj) => {
61
+ if (!obj || typeof obj !== "object")
62
+ return obj;
63
+ // Check if this object itself is a getter pattern
64
+ if (agent_js_1.DEFAULT_INPUT_ACTION_GET in obj && typeof obj[agent_js_1.DEFAULT_INPUT_ACTION_GET] === "string") {
65
+ const getterPath = obj[agent_js_1.DEFAULT_INPUT_ACTION_GET];
66
+ const value = input[getterPath] ?? options.context.userContext[getterPath];
67
+ return (0, type_utils_js_1.isNil)(value) ? undefined : value;
68
+ }
69
+ // If it's an array, recursively resolve each element
70
+ if (Array.isArray(obj)) {
71
+ return obj.map((item) => resolveGetters(item));
72
+ }
73
+ // If it's a plain object, recursively resolve each property
74
+ return Object.entries(obj).reduce((resolved, [key, val]) => {
75
+ const resolvedValue = resolveGetters(val);
76
+ if (!(0, type_utils_js_1.isNil)(resolvedValue)) {
77
+ resolved[key] = resolvedValue;
78
+ }
79
+ return resolved;
80
+ }, {});
81
+ };
82
+ const mergedOptions = {
83
+ ...this.options?.modelOptions,
84
+ ...("modelOptions" in input ? input.modelOptions : {}),
85
+ };
86
+ return resolveGetters(mergedOptions);
87
+ }
88
+ async preprocess(input, options) {
89
+ Object.assign(input, { modelOptions: await this.getModelOptions(input, options) });
90
+ return super.preprocess(input, options);
91
+ }
46
92
  async transformFileType(fileType = "local", data, options) {
47
93
  if (fileType === data.type)
48
94
  return data;
@@ -5,7 +5,7 @@ import { type ChatModelOutputUsage } from "./chat-model.js";
5
5
  import { type FileType, type FileUnionContent, Model } from "./model.js";
6
6
  export interface VideoModelOptions<I extends VideoModelInput = VideoModelInput, O extends VideoModelOutput = VideoModelOutput> extends Omit<AgentOptions<I, O>, "model"> {
7
7
  model?: string;
8
- modelOptions?: Omit<VideoModelInputOptions, "model">;
8
+ modelOptions?: VideoModelInputOptionsWithGetter;
9
9
  }
10
10
  export declare abstract class VideoModel<I extends VideoModelInput = VideoModelInput, O extends VideoModelOutput = VideoModelOutput> extends Model<I, O> {
11
11
  options?: VideoModelOptions<I, O> | undefined;
@@ -12,7 +12,6 @@ class VideoModel extends model_js_1.Model {
12
12
  inputSchema: exports.videoModelInputSchema,
13
13
  outputSchema: exports.videoModelOutputSchema,
14
14
  ...options,
15
- model: undefined,
16
15
  });
17
16
  this.options = options;
18
17
  }
@@ -67,7 +67,6 @@ export interface ImageAgentSchema extends BaseAgentSchema {
67
67
  type: "image";
68
68
  instructions: Instructions;
69
69
  inputFileKey?: string;
70
- modelOptions?: Record<string, any>;
71
70
  }
72
71
  export interface MCPAgentSchema extends BaseAgentSchema {
73
72
  type: "mcp";
@@ -124,7 +124,6 @@ async function parseAgentFile(path, data) {
124
124
  type: zod_1.z.literal("image"),
125
125
  instructions: instructionsSchema,
126
126
  inputFileKey: (0, schema_js_1.optionalize)(zod_1.z.string()),
127
- modelOptions: (0, schema_js_1.optionalize)((0, schema_js_1.camelizeSchema)(zod_1.z.record(zod_1.z.any()))),
128
127
  })
129
128
  .extend(baseAgentSchema.shape),
130
129
  zod_1.z
@@ -7,24 +7,24 @@ async function getAFSSkills(afs) {
7
7
  return [
8
8
  agent_js_1.FunctionAgent.from({
9
9
  name: "afs_list",
10
- description: "Browse directory contents in the AFS like filesystem ls/tree command - shows files and folders in the specified path",
10
+ description: "Get a tree view of directory contents in the AFS - shows hierarchical structure of files and folders",
11
11
  inputSchema: zod_1.z.object({
12
12
  path: zod_1.z.string().describe("The directory path to browse (e.g., '/', '/docs', '/src')"),
13
13
  options: zod_1.z
14
14
  .object({
15
- recursive: zod_1.z.boolean().optional().describe("Whether to list files recursively"),
16
- maxDepth: zod_1.z.number().optional().describe("Maximum depth to list files"),
17
- limit: zod_1.z.number().optional().describe("Maximum number of entries to return"),
15
+ maxDepth: zod_1.z.number().optional().describe("Maximum depth to display in the tree view"),
18
16
  })
19
17
  .optional(),
20
18
  }),
21
19
  process: async (input) => {
22
- const result = await afs.list(input.path, input.options);
20
+ const { list, message } = await afs.list(input.path, input.options);
21
+ const result = buildTreeView(list);
23
22
  return {
24
23
  status: "success",
25
24
  tool: "afs_list",
26
25
  options: input.options,
27
- ...result,
26
+ message,
27
+ result,
28
28
  };
29
29
  },
30
30
  }),
@@ -107,3 +107,27 @@ async function getAFSSkills(afs) {
107
107
  }),
108
108
  ];
109
109
  }
110
+ function buildTreeView(entries) {
111
+ const tree = {};
112
+ for (const entry of entries) {
113
+ const parts = entry.path.split("/").filter(Boolean);
114
+ let current = tree;
115
+ for (const part of parts) {
116
+ if (!current[part]) {
117
+ current[part] = {};
118
+ }
119
+ current = current[part];
120
+ }
121
+ }
122
+ function renderTree(node, prefix = "") {
123
+ let result = "";
124
+ const keys = Object.keys(node);
125
+ keys.forEach((key, index) => {
126
+ const isLast = index === keys.length - 1;
127
+ result += `${prefix}${isLast ? "└── " : "├── "}${key}\n`;
128
+ result += renderTree(node[key], `${prefix}${isLast ? " " : "│ "}`);
129
+ });
130
+ return result;
131
+ }
132
+ return renderTree(tree);
133
+ }
@@ -1,4 +1,4 @@
1
- import { z } from "zod";
1
+ import { type ZodType, z } from "zod";
2
2
  import { type PromiseOrValue } from "../utils/type-utils.js";
3
3
  import { type AgentInvokeOptions, type AgentOptions, type AgentProcessResult, type AgentResponse, type AgentResponseStream, type GetterSchema, type Message } from "./agent.js";
4
4
  import { type FileType, type FileUnionContent, Model } from "./model.js";
@@ -40,7 +40,6 @@ export declare abstract class ChatModel extends Model<ChatModelInput, ChatModelO
40
40
  apiKey?: string;
41
41
  model?: string;
42
42
  }>;
43
- getModelOptions(input: Message, options: AgentInvokeOptions): Promise<ChatModelInputOptions>;
44
43
  /**
45
44
  * Indicates whether the model supports parallel tool calls
46
45
  *
@@ -157,7 +156,7 @@ export interface ChatModelInput extends Message {
157
156
  /**
158
157
  * Model-specific configuration options
159
158
  */
160
- modelOptions?: ChatModelInputOptionsWithGetter;
159
+ modelOptions?: ChatModelInputOptions;
161
160
  }
162
161
  /**
163
162
  * Message role types
@@ -241,8 +240,8 @@ export declare const unionContentSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
241
240
  type: "text";
242
241
  text: string;
243
242
  }>, z.ZodObject<{
244
- filename: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
245
- mimeType: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
243
+ filename: ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
244
+ mimeType: ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
246
245
  } & {
247
246
  type: z.ZodLiteral<"local">;
248
247
  path: z.ZodString;
@@ -257,8 +256,8 @@ export declare const unionContentSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
257
256
  filename?: string | undefined;
258
257
  mimeType?: string | undefined;
259
258
  }>, z.ZodObject<{
260
- filename: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
261
- mimeType: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
259
+ filename: ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
260
+ mimeType: ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
262
261
  } & {
263
262
  type: z.ZodLiteral<"url">;
264
263
  url: z.ZodString;
@@ -273,8 +272,8 @@ export declare const unionContentSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
273
272
  filename?: string | undefined;
274
273
  mimeType?: string | undefined;
275
274
  }>, z.ZodObject<{
276
- filename: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
277
- mimeType: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
275
+ filename: ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
276
+ mimeType: ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
278
277
  } & {
279
278
  type: z.ZodLiteral<"file">;
280
279
  data: z.ZodString;
@@ -497,7 +496,7 @@ export interface ChatModelOutputUsage {
497
496
  export declare const chatModelOutputUsageSchema: z.ZodObject<{
498
497
  inputTokens: z.ZodNumber;
499
498
  outputTokens: z.ZodNumber;
500
- aigneHubCredits: z.ZodType<number | undefined, z.ZodTypeDef, number | undefined>;
499
+ aigneHubCredits: ZodType<number | undefined, z.ZodTypeDef, number | undefined>;
501
500
  }, "strip", z.ZodTypeAny, {
502
501
  inputTokens: number;
503
502
  outputTokens: number;
@@ -6,7 +6,6 @@ import { type FileType } from "./model.js";
6
6
  export interface ImageAgentOptions<I extends Message = any, O extends ImageModelOutput = any> extends Omit<AgentOptions<I, O>, "outputSchema"> {
7
7
  instructions: string | PromptBuilder;
8
8
  inputFileKey?: string;
9
- modelOptions?: Record<string, any>;
10
9
  outputFileType?: FileType;
11
10
  }
12
11
  export declare const imageAgentOptionsSchema: ZodObject<{
@@ -18,7 +17,6 @@ export declare class ImageAgent<I extends Message = any, O extends ImageModelOut
18
17
  constructor(options: ImageAgentOptions<I, O>);
19
18
  instructions: PromptBuilder;
20
19
  inputFileKey?: string;
21
- modelOptions?: Record<string, any>;
22
20
  outputFileType?: FileType;
23
21
  process(input: I, options: AgentInvokeOptions): Promise<O>;
24
22
  }
@@ -5,7 +5,7 @@ import { type ChatModelOutputUsage } from "./chat-model.js";
5
5
  import { type FileType, type FileUnionContent, Model } from "./model.js";
6
6
  export interface ImageModelOptions<I extends ImageModelInput = ImageModelInput, O extends ImageModelOutput = ImageModelOutput> extends Omit<AgentOptions<I, O>, "model"> {
7
7
  model?: string;
8
- modelOptions?: Omit<ImageModelInputOptions, "model">;
8
+ modelOptions?: ImageModelInputOptionsWithGetter;
9
9
  }
10
10
  export declare abstract class ImageModel<I extends ImageModelInput = ImageModelInput, O extends ImageModelOutput = ImageModelOutput> extends Model<I, O> {
11
11
  options?: ImageModelOptions<I, O> | undefined;
@@ -1,6 +1,22 @@
1
1
  import { z } from "zod";
2
- import { Agent, type AgentInvokeOptions, type Message } from "./agent.js";
2
+ import { Agent, type AgentInvokeOptions, type AgentOptions, type Message } from "./agent.js";
3
3
  export declare abstract class Model<I extends Message = any, O extends Message = any> extends Agent<I, O> {
4
+ options?: (Omit<AgentOptions<I, O>, "model"> & {
5
+ modelOptions?: Record<string, unknown>;
6
+ }) | undefined;
7
+ constructor(options?: (Omit<AgentOptions<I, O>, "model"> & {
8
+ modelOptions?: Record<string, unknown>;
9
+ }) | undefined);
10
+ /**
11
+ * Resolves model options by merging instance-level and input-level options,
12
+ * and recursively resolving getter patterns
13
+ *
14
+ * @param input - The input message containing potential modelOptions
15
+ * @param options - The agent invocation options containing context
16
+ * @returns Resolved model options with all getters replaced by actual values
17
+ */
18
+ getModelOptions(input: Message, options: AgentInvokeOptions): Promise<Record<string, unknown>>;
19
+ protected preprocess(input: I, options: AgentInvokeOptions): Promise<void>;
4
20
  transformFileType(fileType: "file", data: FileUnionContent, options: AgentInvokeOptions): Promise<FileContent>;
5
21
  transformFileType(fileType: "local" | undefined, data: FileUnionContent, options: AgentInvokeOptions): Promise<LocalContent>;
6
22
  transformFileType(fileType: FileType | undefined, data: FileUnionContent, options: AgentInvokeOptions): Promise<FileUnionContent>;
@@ -5,7 +5,7 @@ import { type ChatModelOutputUsage } from "./chat-model.js";
5
5
  import { type FileType, type FileUnionContent, Model } from "./model.js";
6
6
  export interface VideoModelOptions<I extends VideoModelInput = VideoModelInput, O extends VideoModelOutput = VideoModelOutput> extends Omit<AgentOptions<I, O>, "model"> {
7
7
  model?: string;
8
- modelOptions?: Omit<VideoModelInputOptions, "model">;
8
+ modelOptions?: VideoModelInputOptionsWithGetter;
9
9
  }
10
10
  export declare abstract class VideoModel<I extends VideoModelInput = VideoModelInput, O extends VideoModelOutput = VideoModelOutput> extends Model<I, O> {
11
11
  options?: VideoModelOptions<I, O> | undefined;
@@ -67,7 +67,6 @@ export interface ImageAgentSchema extends BaseAgentSchema {
67
67
  type: "image";
68
68
  instructions: Instructions;
69
69
  inputFileKey?: string;
70
- modelOptions?: Record<string, any>;
71
70
  }
72
71
  export interface MCPAgentSchema extends BaseAgentSchema {
73
72
  type: "mcp";
@@ -1,4 +1,4 @@
1
- import { z } from "zod";
1
+ import { type ZodType, z } from "zod";
2
2
  import { type PromiseOrValue } from "../utils/type-utils.js";
3
3
  import { type AgentInvokeOptions, type AgentOptions, type AgentProcessResult, type AgentResponse, type AgentResponseStream, type GetterSchema, type Message } from "./agent.js";
4
4
  import { type FileType, type FileUnionContent, Model } from "./model.js";
@@ -40,7 +40,6 @@ export declare abstract class ChatModel extends Model<ChatModelInput, ChatModelO
40
40
  apiKey?: string;
41
41
  model?: string;
42
42
  }>;
43
- getModelOptions(input: Message, options: AgentInvokeOptions): Promise<ChatModelInputOptions>;
44
43
  /**
45
44
  * Indicates whether the model supports parallel tool calls
46
45
  *
@@ -157,7 +156,7 @@ export interface ChatModelInput extends Message {
157
156
  /**
158
157
  * Model-specific configuration options
159
158
  */
160
- modelOptions?: ChatModelInputOptionsWithGetter;
159
+ modelOptions?: ChatModelInputOptions;
161
160
  }
162
161
  /**
163
162
  * Message role types
@@ -241,8 +240,8 @@ export declare const unionContentSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
241
240
  type: "text";
242
241
  text: string;
243
242
  }>, z.ZodObject<{
244
- filename: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
245
- mimeType: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
243
+ filename: ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
244
+ mimeType: ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
246
245
  } & {
247
246
  type: z.ZodLiteral<"local">;
248
247
  path: z.ZodString;
@@ -257,8 +256,8 @@ export declare const unionContentSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
257
256
  filename?: string | undefined;
258
257
  mimeType?: string | undefined;
259
258
  }>, z.ZodObject<{
260
- filename: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
261
- mimeType: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
259
+ filename: ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
260
+ mimeType: ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
262
261
  } & {
263
262
  type: z.ZodLiteral<"url">;
264
263
  url: z.ZodString;
@@ -273,8 +272,8 @@ export declare const unionContentSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
273
272
  filename?: string | undefined;
274
273
  mimeType?: string | undefined;
275
274
  }>, z.ZodObject<{
276
- filename: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
277
- mimeType: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
275
+ filename: ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
276
+ mimeType: ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
278
277
  } & {
279
278
  type: z.ZodLiteral<"file">;
280
279
  data: z.ZodString;
@@ -497,7 +496,7 @@ export interface ChatModelOutputUsage {
497
496
  export declare const chatModelOutputUsageSchema: z.ZodObject<{
498
497
  inputTokens: z.ZodNumber;
499
498
  outputTokens: z.ZodNumber;
500
- aigneHubCredits: z.ZodType<number | undefined, z.ZodTypeDef, number | undefined>;
499
+ aigneHubCredits: ZodType<number | undefined, z.ZodTypeDef, number | undefined>;
501
500
  }, "strip", z.ZodTypeAny, {
502
501
  inputTokens: number;
503
502
  outputTokens: number;
@@ -5,7 +5,7 @@ import { optionalize } from "../loader/schema.js";
5
5
  import { wrapAutoParseJsonSchema } from "../utils/json-schema.js";
6
6
  import { logger } from "../utils/logger.js";
7
7
  import { checkArguments, isNil, omitByDeep } from "../utils/type-utils.js";
8
- import { agentOptionsSchema, DEFAULT_INPUT_ACTION_GET, getterSchema, } from "./agent.js";
8
+ import { agentOptionsSchema, getterSchema, } from "./agent.js";
9
9
  import { fileContentSchema, fileUnionContentSchema, localContentSchema, Model, urlContentSchema, } from "./model.js";
10
10
  const CHAT_MODEL_DEFAULT_RETRY_OPTIONS = {
11
11
  retries: 3,
@@ -55,34 +55,12 @@ export class ChatModel extends Model {
55
55
  inputSchema: chatModelInputSchema,
56
56
  outputSchema: chatModelOutputSchema,
57
57
  retryOnError,
58
- model: undefined,
59
58
  });
60
59
  this.options = options;
61
60
  }
62
61
  get credential() {
63
62
  return {};
64
63
  }
65
- async getModelOptions(input, options) {
66
- const result = {};
67
- for (const [key, val] of Object.entries({
68
- ...this.options?.modelOptions,
69
- ...("modelOptions" in input ? input.modelOptions : {}),
70
- })) {
71
- if (val &&
72
- typeof val === "object" &&
73
- DEFAULT_INPUT_ACTION_GET in val &&
74
- typeof val[DEFAULT_INPUT_ACTION_GET] === "string") {
75
- const getterPath = val[DEFAULT_INPUT_ACTION_GET];
76
- const value = input[getterPath] ?? options.context.userContext[getterPath];
77
- if (!isNil(value))
78
- Object.assign(result, { [key]: value });
79
- }
80
- else {
81
- Object.assign(result, { [key]: val });
82
- }
83
- }
84
- return result;
85
- }
86
64
  /**
87
65
  * Indicates whether the model supports parallel tool calls
88
66
  *
@@ -313,25 +291,33 @@ const chatModelInputToolChoiceSchema = z.union([
313
291
  z.literal("required"),
314
292
  chatModelInputToolSchema,
315
293
  ]);
316
- const modelOptionsSchema = z.object({
317
- model: optionalize(getterSchema(z.string())),
318
- temperature: optionalize(getterSchema(z.number())),
319
- topP: optionalize(getterSchema(z.number())),
320
- frequencyPenalty: optionalize(getterSchema(z.number())),
321
- presencePenalty: optionalize(getterSchema(z.number())),
322
- parallelToolCalls: optionalize(getterSchema(z.boolean())).default(true),
323
- modalities: optionalize(getterSchema(z.array(z.enum(["text", "image", "audio"])))),
324
- reasoningEffort: optionalize(getterSchema(z.union([
294
+ const modelOptionsSchemaProperties = {
295
+ model: z.string(),
296
+ temperature: z.number(),
297
+ topP: z.number(),
298
+ frequencyPenalty: z.number(),
299
+ presencePenalty: z.number(),
300
+ parallelToolCalls: z.boolean().default(true),
301
+ modalities: z.array(z.enum(["text", "image", "audio"])),
302
+ reasoningEffort: z.union([
325
303
  z.number(),
326
304
  z.literal("minimal"),
327
305
  z.literal("low"),
328
306
  z.literal("medium"),
329
307
  z.literal("high"),
330
- ]))),
331
- });
308
+ ]),
309
+ };
310
+ const modelOptionsSchema = z.object(Object.fromEntries(Object.entries(modelOptionsSchemaProperties).map(([key, schema]) => [
311
+ key,
312
+ optionalize(schema),
313
+ ])));
314
+ const modelOptionsWithGetterSchema = z.object(Object.fromEntries(Object.entries(modelOptionsSchemaProperties).map(([key, schema]) => [
315
+ key,
316
+ optionalize(getterSchema(schema)),
317
+ ])));
332
318
  const chatModelOptionsSchema = agentOptionsSchema.extend({
333
319
  model: optionalize(z.string()),
334
- modelOptions: optionalize(modelOptionsSchema),
320
+ modelOptions: optionalize(modelOptionsWithGetterSchema),
335
321
  });
336
322
  const chatModelInputSchema = z.object({
337
323
  messages: z.array(chatModelInputMessageSchema),
@@ -6,7 +6,6 @@ import { type FileType } from "./model.js";
6
6
  export interface ImageAgentOptions<I extends Message = any, O extends ImageModelOutput = any> extends Omit<AgentOptions<I, O>, "outputSchema"> {
7
7
  instructions: string | PromptBuilder;
8
8
  inputFileKey?: string;
9
- modelOptions?: Record<string, any>;
10
9
  outputFileType?: FileType;
11
10
  }
12
11
  export declare const imageAgentOptionsSchema: ZodObject<{
@@ -18,7 +17,6 @@ export declare class ImageAgent<I extends Message = any, O extends ImageModelOut
18
17
  constructor(options: ImageAgentOptions<I, O>);
19
18
  instructions: PromptBuilder;
20
19
  inputFileKey?: string;
21
- modelOptions?: Record<string, any>;
22
20
  outputFileType?: FileType;
23
21
  process(input: I, options: AgentInvokeOptions): Promise<O>;
24
22
  }
@@ -6,7 +6,6 @@ import { imageModelOutputSchema } from "./image-model.js";
6
6
  import { fileTypeSchema } from "./model.js";
7
7
  export const imageAgentOptionsSchema = agentOptionsSchema.extend({
8
8
  instructions: z.union([z.string(), z.custom()]),
9
- modelOptions: z.record(z.any()).optional(),
10
9
  outputFileType: fileTypeSchema.optional(),
11
10
  });
12
11
  export class ImageAgent extends Agent {
@@ -22,26 +21,25 @@ export class ImageAgent extends Agent {
22
21
  ? PromptBuilder.from(options.instructions)
23
22
  : options.instructions;
24
23
  this.inputFileKey = options.inputFileKey;
25
- this.modelOptions = options.modelOptions;
26
24
  this.outputFileType = options.outputFileType;
27
25
  }
28
26
  instructions;
29
27
  inputFileKey;
30
- modelOptions;
31
28
  outputFileType;
32
29
  async process(input, options) {
33
30
  const imageModel = this.imageModel || options.imageModel || options.context.imageModel;
34
31
  if (!imageModel)
35
32
  throw new Error("image model is required to run ImageAgent");
33
+ const modelOptions = await imageModel.getModelOptions(input, options);
36
34
  const { prompt, image } = await this.instructions.buildImagePrompt({
37
35
  ...options,
38
36
  input,
39
37
  agent: this,
40
38
  });
41
- const n = input.n || this.modelOptions?.n;
39
+ const n = input.n || modelOptions?.n;
42
40
  return (await this.invokeChildAgent(imageModel, {
43
41
  n: n && typeof n === "number" ? n : undefined,
44
- modelOptions: this.modelOptions,
42
+ modelOptions,
45
43
  prompt,
46
44
  image,
47
45
  outputFileType: this.outputFileType,
@@ -5,7 +5,7 @@ import { type ChatModelOutputUsage } from "./chat-model.js";
5
5
  import { type FileType, type FileUnionContent, Model } from "./model.js";
6
6
  export interface ImageModelOptions<I extends ImageModelInput = ImageModelInput, O extends ImageModelOutput = ImageModelOutput> extends Omit<AgentOptions<I, O>, "model"> {
7
7
  model?: string;
8
- modelOptions?: Omit<ImageModelInputOptions, "model">;
8
+ modelOptions?: ImageModelInputOptionsWithGetter;
9
9
  }
10
10
  export declare abstract class ImageModel<I extends ImageModelInput = ImageModelInput, O extends ImageModelOutput = ImageModelOutput> extends Model<I, O> {
11
11
  options?: ImageModelOptions<I, O> | undefined;
@@ -10,7 +10,6 @@ export class ImageModel extends Model {
10
10
  inputSchema: imageModelInputSchema,
11
11
  outputSchema: imageModelOutputSchema,
12
12
  ...options,
13
- model: undefined,
14
13
  });
15
14
  this.options = options;
16
15
  }
@@ -1,6 +1,22 @@
1
1
  import { z } from "zod";
2
- import { Agent, type AgentInvokeOptions, type Message } from "./agent.js";
2
+ import { Agent, type AgentInvokeOptions, type AgentOptions, type Message } from "./agent.js";
3
3
  export declare abstract class Model<I extends Message = any, O extends Message = any> extends Agent<I, O> {
4
+ options?: (Omit<AgentOptions<I, O>, "model"> & {
5
+ modelOptions?: Record<string, unknown>;
6
+ }) | undefined;
7
+ constructor(options?: (Omit<AgentOptions<I, O>, "model"> & {
8
+ modelOptions?: Record<string, unknown>;
9
+ }) | undefined);
10
+ /**
11
+ * Resolves model options by merging instance-level and input-level options,
12
+ * and recursively resolving getter patterns
13
+ *
14
+ * @param input - The input message containing potential modelOptions
15
+ * @param options - The agent invocation options containing context
16
+ * @returns Resolved model options with all getters replaced by actual values
17
+ */
18
+ getModelOptions(input: Message, options: AgentInvokeOptions): Promise<Record<string, unknown>>;
19
+ protected preprocess(input: I, options: AgentInvokeOptions): Promise<void>;
4
20
  transformFileType(fileType: "file", data: FileUnionContent, options: AgentInvokeOptions): Promise<FileContent>;
5
21
  transformFileType(fileType: "local" | undefined, data: FileUnionContent, options: AgentInvokeOptions): Promise<LocalContent>;
6
22
  transformFileType(fileType: FileType | undefined, data: FileUnionContent, options: AgentInvokeOptions): Promise<FileUnionContent>;
@@ -4,9 +4,55 @@ import { parseURL } from "ufo";
4
4
  import { z } from "zod";
5
5
  import { optionalize } from "../loader/schema.js";
6
6
  import { fetch } from "../utils/fetch.js";
7
- import { pick } from "../utils/type-utils.js";
8
- import { Agent } from "./agent.js";
7
+ import { isNil, pick } from "../utils/type-utils.js";
8
+ import { Agent, DEFAULT_INPUT_ACTION_GET, } from "./agent.js";
9
9
  export class Model extends Agent {
10
+ options;
11
+ constructor(options) {
12
+ super(options);
13
+ this.options = options;
14
+ }
15
+ /**
16
+ * Resolves model options by merging instance-level and input-level options,
17
+ * and recursively resolving getter patterns
18
+ *
19
+ * @param input - The input message containing potential modelOptions
20
+ * @param options - The agent invocation options containing context
21
+ * @returns Resolved model options with all getters replaced by actual values
22
+ */
23
+ async getModelOptions(input, options) {
24
+ const resolveGetters = (obj) => {
25
+ if (!obj || typeof obj !== "object")
26
+ return obj;
27
+ // Check if this object itself is a getter pattern
28
+ if (DEFAULT_INPUT_ACTION_GET in obj && typeof obj[DEFAULT_INPUT_ACTION_GET] === "string") {
29
+ const getterPath = obj[DEFAULT_INPUT_ACTION_GET];
30
+ const value = input[getterPath] ?? options.context.userContext[getterPath];
31
+ return isNil(value) ? undefined : value;
32
+ }
33
+ // If it's an array, recursively resolve each element
34
+ if (Array.isArray(obj)) {
35
+ return obj.map((item) => resolveGetters(item));
36
+ }
37
+ // If it's a plain object, recursively resolve each property
38
+ return Object.entries(obj).reduce((resolved, [key, val]) => {
39
+ const resolvedValue = resolveGetters(val);
40
+ if (!isNil(resolvedValue)) {
41
+ resolved[key] = resolvedValue;
42
+ }
43
+ return resolved;
44
+ }, {});
45
+ };
46
+ const mergedOptions = {
47
+ ...this.options?.modelOptions,
48
+ ...("modelOptions" in input ? input.modelOptions : {}),
49
+ };
50
+ return resolveGetters(mergedOptions);
51
+ }
52
+ async preprocess(input, options) {
53
+ Object.assign(input, { modelOptions: await this.getModelOptions(input, options) });
54
+ return super.preprocess(input, options);
55
+ }
10
56
  async transformFileType(fileType = "local", data, options) {
11
57
  if (fileType === data.type)
12
58
  return data;
@@ -5,7 +5,7 @@ import { type ChatModelOutputUsage } from "./chat-model.js";
5
5
  import { type FileType, type FileUnionContent, Model } from "./model.js";
6
6
  export interface VideoModelOptions<I extends VideoModelInput = VideoModelInput, O extends VideoModelOutput = VideoModelOutput> extends Omit<AgentOptions<I, O>, "model"> {
7
7
  model?: string;
8
- modelOptions?: Omit<VideoModelInputOptions, "model">;
8
+ modelOptions?: VideoModelInputOptionsWithGetter;
9
9
  }
10
10
  export declare abstract class VideoModel<I extends VideoModelInput = VideoModelInput, O extends VideoModelOutput = VideoModelOutput> extends Model<I, O> {
11
11
  options?: VideoModelOptions<I, O> | undefined;
@@ -9,7 +9,6 @@ export class VideoModel extends Model {
9
9
  inputSchema: videoModelInputSchema,
10
10
  outputSchema: videoModelOutputSchema,
11
11
  ...options,
12
- model: undefined,
13
12
  });
14
13
  this.options = options;
15
14
  }
@@ -67,7 +67,6 @@ export interface ImageAgentSchema extends BaseAgentSchema {
67
67
  type: "image";
68
68
  instructions: Instructions;
69
69
  inputFileKey?: string;
70
- modelOptions?: Record<string, any>;
71
70
  }
72
71
  export interface MCPAgentSchema extends BaseAgentSchema {
73
72
  type: "mcp";
@@ -120,7 +120,6 @@ export async function parseAgentFile(path, data) {
120
120
  type: z.literal("image"),
121
121
  instructions: instructionsSchema,
122
122
  inputFileKey: optionalize(z.string()),
123
- modelOptions: optionalize(camelizeSchema(z.record(z.any()))),
124
123
  })
125
124
  .extend(baseAgentSchema.shape),
126
125
  z
@@ -4,24 +4,24 @@ export async function getAFSSkills(afs) {
4
4
  return [
5
5
  FunctionAgent.from({
6
6
  name: "afs_list",
7
- description: "Browse directory contents in the AFS like filesystem ls/tree command - shows files and folders in the specified path",
7
+ description: "Get a tree view of directory contents in the AFS - shows hierarchical structure of files and folders",
8
8
  inputSchema: z.object({
9
9
  path: z.string().describe("The directory path to browse (e.g., '/', '/docs', '/src')"),
10
10
  options: z
11
11
  .object({
12
- recursive: z.boolean().optional().describe("Whether to list files recursively"),
13
- maxDepth: z.number().optional().describe("Maximum depth to list files"),
14
- limit: z.number().optional().describe("Maximum number of entries to return"),
12
+ maxDepth: z.number().optional().describe("Maximum depth to display in the tree view"),
15
13
  })
16
14
  .optional(),
17
15
  }),
18
16
  process: async (input) => {
19
- const result = await afs.list(input.path, input.options);
17
+ const { list, message } = await afs.list(input.path, input.options);
18
+ const result = buildTreeView(list);
20
19
  return {
21
20
  status: "success",
22
21
  tool: "afs_list",
23
22
  options: input.options,
24
- ...result,
23
+ message,
24
+ result,
25
25
  };
26
26
  },
27
27
  }),
@@ -104,3 +104,27 @@ export async function getAFSSkills(afs) {
104
104
  }),
105
105
  ];
106
106
  }
107
+ function buildTreeView(entries) {
108
+ const tree = {};
109
+ for (const entry of entries) {
110
+ const parts = entry.path.split("/").filter(Boolean);
111
+ let current = tree;
112
+ for (const part of parts) {
113
+ if (!current[part]) {
114
+ current[part] = {};
115
+ }
116
+ current = current[part];
117
+ }
118
+ }
119
+ function renderTree(node, prefix = "") {
120
+ let result = "";
121
+ const keys = Object.keys(node);
122
+ keys.forEach((key, index) => {
123
+ const isLast = index === keys.length - 1;
124
+ result += `${prefix}${isLast ? "└── " : "├── "}${key}\n`;
125
+ result += renderTree(node[key], `${prefix}${isLast ? " " : "│ "}`);
126
+ });
127
+ return result;
128
+ }
129
+ return renderTree(tree);
130
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/core",
3
- "version": "1.69.2",
3
+ "version": "1.70.0-beta.1",
4
4
  "description": "The functional core of agentic AI",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -92,10 +92,10 @@
92
92
  "zod": "^3.25.67",
93
93
  "zod-from-json-schema": "^0.0.5",
94
94
  "zod-to-json-schema": "^3.24.6",
95
- "@aigne/afs": "^1.2.2",
96
- "@aigne/afs-history": "^1.1.1",
97
- "@aigne/observability-api": "^0.11.11",
98
- "@aigne/platform-helpers": "^0.6.5"
95
+ "@aigne/afs": "^1.2.3-beta",
96
+ "@aigne/afs-history": "^1.1.2-beta",
97
+ "@aigne/platform-helpers": "^0.6.5",
98
+ "@aigne/observability-api": "^0.11.11"
99
99
  },
100
100
  "devDependencies": {
101
101
  "@types/bun": "^1.2.22",