@aigne/core 1.5.1-2 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/lib/cjs/execution-engine/execution-engine.d.ts +4 -0
- package/lib/cjs/execution-engine/execution-engine.js +7 -1
- package/lib/{esm/loader/function-agent.d.ts → cjs/loader/agent-js.d.ts} +1 -5
- package/lib/cjs/loader/{function-agent.js → agent-js.js} +2 -2
- package/lib/cjs/loader/{ai-agent.d.ts → agent-yaml.d.ts} +7 -4
- package/lib/cjs/loader/agent-yaml.js +58 -0
- package/lib/cjs/loader/index.d.ts +14 -4
- package/lib/cjs/loader/index.js +57 -22
- package/lib/dts/execution-engine/execution-engine.d.ts +4 -0
- package/lib/{cjs/loader/function-agent.d.ts → dts/loader/agent-js.d.ts} +1 -5
- package/lib/dts/loader/{ai-agent.d.ts → agent-yaml.d.ts} +7 -4
- package/lib/dts/loader/index.d.ts +14 -4
- package/lib/esm/execution-engine/execution-engine.d.ts +4 -0
- package/lib/esm/execution-engine/execution-engine.js +7 -1
- package/lib/{dts/loader/function-agent.d.ts → esm/loader/agent-js.d.ts} +1 -5
- package/lib/esm/loader/{function-agent.js → agent-js.js} +2 -2
- package/lib/esm/loader/{ai-agent.d.ts → agent-yaml.d.ts} +7 -4
- package/lib/esm/loader/agent-yaml.js +55 -0
- package/lib/esm/loader/index.d.ts +14 -4
- package/lib/esm/loader/index.js +56 -21
- package/package.json +6 -5
- package/lib/cjs/loader/ai-agent.js +0 -40
- package/lib/esm/loader/ai-agent.js +0 -37
package/CHANGELOG.md
CHANGED
|
@@ -22,6 +22,20 @@
|
|
|
22
22
|
* rename @aigne/core-next to @aigne/core ([3a81009](https://github.com/AIGNE-io/aigne-framework/commit/3a8100962c81813217b687ae28e8de604419c622))
|
|
23
23
|
* use text resource from MCP correctly ([8b9eba8](https://github.com/AIGNE-io/aigne-framework/commit/8b9eba83352ec096a2a5d4f410d4c4bde7420bce))
|
|
24
24
|
|
|
25
|
+
## [1.6.0](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.5.0...core-v1.6.0) (2025-04-08)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Features
|
|
29
|
+
|
|
30
|
+
* add `serve` command for @aigne/cli ([#54](https://github.com/AIGNE-io/aigne-framework/issues/54)) ([1cca843](https://github.com/AIGNE-io/aigne-framework/commit/1cca843f1760abe832b6651108fa858130f47355))
|
|
31
|
+
* add agent library support ([#51](https://github.com/AIGNE-io/aigne-framework/issues/51)) ([1f0d34d](https://github.com/AIGNE-io/aigne-framework/commit/1f0d34ddda3154283a4bc958ddb9b68b4ac106b0))
|
|
32
|
+
* support token/call/time limits for ExecutionEngine ([#44](https://github.com/AIGNE-io/aigne-framework/issues/44)) ([5a2ca0a](https://github.com/AIGNE-io/aigne-framework/commit/5a2ca0a033267dd4765f574b53dca71e932e53d4))
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
### Bug Fixes
|
|
36
|
+
|
|
37
|
+
* support reconnect to the MCP server automatically ([#50](https://github.com/AIGNE-io/aigne-framework/issues/50)) ([898d83f](https://github.com/AIGNE-io/aigne-framework/commit/898d83f75fc655142b93c70a1afeda376a2e92b4))
|
|
38
|
+
|
|
25
39
|
## [1.5.0](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.4.0...core-v1.5.0) (2025-03-27)
|
|
26
40
|
|
|
27
41
|
|
|
@@ -5,6 +5,8 @@ import { ChatModel } from "../models/chat-model.js";
|
|
|
5
5
|
import { type ContextLimits, ExecutionContext, type Runnable } from "./context.js";
|
|
6
6
|
import { type MessagePayload, MessageQueue, type MessageQueueListener, type Unsubscribe } from "./message-queue.js";
|
|
7
7
|
export interface ExecutionEngineOptions {
|
|
8
|
+
name?: string;
|
|
9
|
+
description?: string;
|
|
8
10
|
model?: ChatModel;
|
|
9
11
|
tools?: Agent[];
|
|
10
12
|
agents?: Agent[];
|
|
@@ -15,6 +17,8 @@ export declare class ExecutionEngine extends EventEmitter {
|
|
|
15
17
|
path: string;
|
|
16
18
|
} & ExecutionEngineOptions): Promise<ExecutionEngine>;
|
|
17
19
|
constructor(options?: ExecutionEngineOptions);
|
|
20
|
+
name?: string;
|
|
21
|
+
description?: string;
|
|
18
22
|
readonly messageQueue: MessageQueue;
|
|
19
23
|
model?: ChatModel;
|
|
20
24
|
readonly tools: Agent<Message, Message>[] & {
|
|
@@ -14,10 +14,12 @@ const context_js_1 = require("./context.js");
|
|
|
14
14
|
const message_queue_js_1 = require("./message-queue.js");
|
|
15
15
|
class ExecutionEngine extends node_events_1.default {
|
|
16
16
|
static async load({ path, ...options }) {
|
|
17
|
-
const { model, agents, tools } = await (0, index_js_1.load)({ path });
|
|
17
|
+
const { model, agents, tools, ...aigne } = await (0, index_js_1.load)({ path });
|
|
18
18
|
return new ExecutionEngine({
|
|
19
19
|
model,
|
|
20
20
|
...options,
|
|
21
|
+
name: options.name || aigne.name || undefined,
|
|
22
|
+
description: options.description || aigne.description || undefined,
|
|
21
23
|
agents: agents.concat(options.agents ?? []),
|
|
22
24
|
tools: tools.concat(options.tools ?? []),
|
|
23
25
|
});
|
|
@@ -26,6 +28,8 @@ class ExecutionEngine extends node_events_1.default {
|
|
|
26
28
|
if (options)
|
|
27
29
|
(0, type_utils_js_1.checkArguments)("ExecutionEngine", executionEngineOptionsSchema, options);
|
|
28
30
|
super();
|
|
31
|
+
this.name = options?.name;
|
|
32
|
+
this.description = options?.description;
|
|
29
33
|
this.model = options?.model;
|
|
30
34
|
this.limits = options?.limits;
|
|
31
35
|
if (options?.tools?.length)
|
|
@@ -34,6 +38,8 @@ class ExecutionEngine extends node_events_1.default {
|
|
|
34
38
|
this.addAgent(...options.agents);
|
|
35
39
|
this.initProcessExitHandler();
|
|
36
40
|
}
|
|
41
|
+
name;
|
|
42
|
+
description;
|
|
37
43
|
messageQueue = new message_queue_js_1.MessageQueue();
|
|
38
44
|
model;
|
|
39
45
|
tools = (0, type_utils_js_1.createAccessorArray)([], (arr, name) => arr.find((i) => i.name === name));
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { type ZodObject, type ZodType, z } from "zod";
|
|
2
2
|
import type { Message } from "../agents/agent.js";
|
|
3
|
-
export declare function loadAgentFromJsFile(path: string
|
|
4
|
-
import?: (path: string) => Promise<{
|
|
5
|
-
default: unknown;
|
|
6
|
-
}>;
|
|
7
|
-
}): Promise<{
|
|
3
|
+
export declare function loadAgentFromJsFile(path: string): Promise<{
|
|
8
4
|
name: string;
|
|
9
5
|
fn: (args_0: Message) => Message;
|
|
10
6
|
description?: string | undefined;
|
|
@@ -52,8 +52,8 @@ const agentJsFileSchema = zod_1.z.object({
|
|
|
52
52
|
.transform((v) => (v ? (0, json_schema_to_zod_1.jsonSchemaToZod)(v) : undefined)),
|
|
53
53
|
fn: zod_1.z.function(),
|
|
54
54
|
});
|
|
55
|
-
async function loadAgentFromJsFile(path
|
|
56
|
-
const { default: agent } = await (0, type_utils_js_1.tryOrThrow)(() =>
|
|
55
|
+
async function loadAgentFromJsFile(path) {
|
|
56
|
+
const { default: agent } = await (0, type_utils_js_1.tryOrThrow)(() => Promise.resolve(`${path}`).then(s => __importStar(require(s))), (error) => new Error(`Failed to load agent definition from ${path}: ${error.message}`));
|
|
57
57
|
if (typeof agent !== "function") {
|
|
58
58
|
throw new Error(`Agent file ${path} must export a default function, but got ${typeof agent}`);
|
|
59
59
|
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
1
|
import { type ZodObject, type ZodType, z } from "zod";
|
|
3
|
-
export declare function loadAgentFromYamlFile(path: string
|
|
4
|
-
|
|
5
|
-
}): Promise<{
|
|
2
|
+
export declare function loadAgentFromYamlFile(path: string): Promise<{
|
|
3
|
+
type: "ai";
|
|
6
4
|
name: string;
|
|
7
5
|
description?: string | undefined;
|
|
8
6
|
tools?: string[] | undefined;
|
|
@@ -18,4 +16,9 @@ export declare function loadAgentFromYamlFile(path: string, { readFile: _readFil
|
|
|
18
16
|
[x: string]: any;
|
|
19
17
|
}> | undefined;
|
|
20
18
|
output_key?: string | undefined;
|
|
19
|
+
} | {
|
|
20
|
+
type: "mcp";
|
|
21
|
+
url?: string | undefined;
|
|
22
|
+
command?: string | undefined;
|
|
23
|
+
args?: string[] | undefined;
|
|
21
24
|
}>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadAgentFromYamlFile = loadAgentFromYamlFile;
|
|
4
|
+
const promises_1 = require("node:fs/promises");
|
|
5
|
+
const json_schema_to_zod_1 = require("@aigne/json-schema-to-zod");
|
|
6
|
+
const yaml_1 = require("yaml");
|
|
7
|
+
const zod_1 = require("zod");
|
|
8
|
+
const type_utils_js_1 = require("../utils/type-utils.js");
|
|
9
|
+
const schema_js_1 = require("./schema.js");
|
|
10
|
+
const agentFileSchema = zod_1.z.discriminatedUnion("type", [
|
|
11
|
+
zod_1.z.object({
|
|
12
|
+
type: zod_1.z.literal("ai"),
|
|
13
|
+
name: zod_1.z.string(),
|
|
14
|
+
description: zod_1.z
|
|
15
|
+
.string()
|
|
16
|
+
.nullish()
|
|
17
|
+
.transform((v) => v ?? undefined),
|
|
18
|
+
instructions: zod_1.z
|
|
19
|
+
.string()
|
|
20
|
+
.nullish()
|
|
21
|
+
.transform((v) => v ?? undefined),
|
|
22
|
+
input_schema: schema_js_1.inputOutputSchema
|
|
23
|
+
.nullish()
|
|
24
|
+
.transform((v) => (v ? (0, json_schema_to_zod_1.jsonSchemaToZod)(v) : undefined)),
|
|
25
|
+
output_schema: schema_js_1.inputOutputSchema
|
|
26
|
+
.nullish()
|
|
27
|
+
.transform((v) => (v ? (0, json_schema_to_zod_1.jsonSchemaToZod)(v) : undefined)),
|
|
28
|
+
output_key: zod_1.z
|
|
29
|
+
.string()
|
|
30
|
+
.nullish()
|
|
31
|
+
.transform((v) => v ?? undefined),
|
|
32
|
+
tools: zod_1.z
|
|
33
|
+
.array(zod_1.z.string())
|
|
34
|
+
.nullish()
|
|
35
|
+
.transform((v) => v ?? undefined),
|
|
36
|
+
}),
|
|
37
|
+
zod_1.z.object({
|
|
38
|
+
type: zod_1.z.literal("mcp"),
|
|
39
|
+
url: zod_1.z
|
|
40
|
+
.string()
|
|
41
|
+
.nullish()
|
|
42
|
+
.transform((v) => v ?? undefined),
|
|
43
|
+
command: zod_1.z
|
|
44
|
+
.string()
|
|
45
|
+
.nullish()
|
|
46
|
+
.transform((v) => v ?? undefined),
|
|
47
|
+
args: zod_1.z
|
|
48
|
+
.array(zod_1.z.string())
|
|
49
|
+
.nullish()
|
|
50
|
+
.transform((v) => v ?? undefined),
|
|
51
|
+
}),
|
|
52
|
+
]);
|
|
53
|
+
async function loadAgentFromYamlFile(path) {
|
|
54
|
+
const raw = await (0, type_utils_js_1.tryOrThrow)(() => (0, promises_1.readFile)(path, "utf8"), (error) => new Error(`Failed to load agent definition from ${path}: ${error.message}`));
|
|
55
|
+
const json = await (0, type_utils_js_1.tryOrThrow)(() => (0, yaml_1.parse)(raw), (error) => new Error(`Failed to parse agent definition from ${path}: ${error.message}`));
|
|
56
|
+
const agent = (0, type_utils_js_1.tryOrThrow)(() => agentFileSchema.parse({ ...json, type: json.type ?? "ai" }), (error) => new Error(`Failed to validate agent definition from ${path}: ${error.message}`));
|
|
57
|
+
return agent;
|
|
58
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
1
|
import { type Agent } from "../agents/agent.js";
|
|
3
2
|
import type { ChatModel } from "../models/chat-model.js";
|
|
4
3
|
export interface LoadOptions {
|
|
@@ -8,15 +7,26 @@ export declare function load(options: LoadOptions): Promise<{
|
|
|
8
7
|
model: ChatModel | undefined;
|
|
9
8
|
agents: Agent<import("../agents/agent.js").Message, import("../agents/agent.js").Message>[];
|
|
10
9
|
tools: Agent<import("../agents/agent.js").Message, import("../agents/agent.js").Message>[];
|
|
10
|
+
description?: string | null | undefined;
|
|
11
|
+
name?: string | null | undefined;
|
|
12
|
+
chat_model?: {
|
|
13
|
+
name?: string | null | undefined;
|
|
14
|
+
temperature?: number | null | undefined;
|
|
15
|
+
provider?: string | null | undefined;
|
|
16
|
+
top_p?: number | null | undefined;
|
|
17
|
+
frequent_penalty?: number | null | undefined;
|
|
18
|
+
presence_penalty?: number | null | undefined;
|
|
19
|
+
} | null | undefined;
|
|
11
20
|
}>;
|
|
12
21
|
export declare function loadAgent(path: string): Promise<Agent>;
|
|
13
|
-
export declare function loadAIGNEFile(path: string
|
|
14
|
-
|
|
15
|
-
}): Promise<{
|
|
22
|
+
export declare function loadAIGNEFile(path: string): Promise<{
|
|
23
|
+
description?: string | null | undefined;
|
|
16
24
|
tools?: string[] | null | undefined;
|
|
25
|
+
name?: string | null | undefined;
|
|
17
26
|
chat_model?: {
|
|
18
27
|
name?: string | null | undefined;
|
|
19
28
|
temperature?: number | null | undefined;
|
|
29
|
+
provider?: string | null | undefined;
|
|
20
30
|
top_p?: number | null | undefined;
|
|
21
31
|
frequent_penalty?: number | null | undefined;
|
|
22
32
|
presence_penalty?: number | null | undefined;
|
package/lib/cjs/loader/index.js
CHANGED
|
@@ -9,19 +9,24 @@ const yaml_1 = require("yaml");
|
|
|
9
9
|
const zod_1 = require("zod");
|
|
10
10
|
const agent_js_1 = require("../agents/agent.js");
|
|
11
11
|
const ai_agent_js_1 = require("../agents/ai-agent.js");
|
|
12
|
+
const mcp_agent_js_1 = require("../agents/mcp-agent.js");
|
|
13
|
+
const claude_chat_model_js_1 = require("../models/claude-chat-model.js");
|
|
12
14
|
const openai_chat_model_js_1 = require("../models/openai-chat-model.js");
|
|
15
|
+
const xai_chat_model_js_1 = require("../models/xai-chat-model.js");
|
|
13
16
|
const type_utils_js_1 = require("../utils/type-utils.js");
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
+
const agent_js_js_1 = require("./agent-js.js");
|
|
18
|
+
const agent_yaml_js_1 = require("./agent-yaml.js");
|
|
19
|
+
const DEFAULT_MODEL_PROVIDER = "openai";
|
|
20
|
+
const AIGNE_FILE_NAME = ["aigne.yaml", "aigne.yml"];
|
|
17
21
|
async function load(options) {
|
|
18
22
|
const { path } = options;
|
|
19
|
-
const aigneFilePath =
|
|
23
|
+
const aigneFilePath = await getAIGNEFilePath(path);
|
|
20
24
|
const rootDir = (0, node_path_1.dirname)(aigneFilePath);
|
|
21
25
|
const aigne = await loadAIGNEFile(aigneFilePath);
|
|
22
26
|
const agents = await Promise.all((aigne.agents ?? []).map((filename) => loadAgent((0, node_path_1.join)(rootDir, filename))));
|
|
23
27
|
const tools = await Promise.all((aigne.tools ?? []).map((filename) => loadAgent((0, node_path_1.join)(rootDir, filename))));
|
|
24
28
|
return {
|
|
29
|
+
...aigne,
|
|
25
30
|
model: await loadModel(aigne.chat_model),
|
|
26
31
|
agents,
|
|
27
32
|
tools,
|
|
@@ -29,7 +34,7 @@ async function load(options) {
|
|
|
29
34
|
}
|
|
30
35
|
async function loadAgent(path) {
|
|
31
36
|
if ((0, node_path_1.extname)(path) === ".js") {
|
|
32
|
-
const agent = await (0,
|
|
37
|
+
const agent = await (0, agent_js_js_1.loadAgentFromJsFile)(path);
|
|
33
38
|
return agent_js_1.FunctionAgent.from({
|
|
34
39
|
name: agent.name,
|
|
35
40
|
description: agent.description,
|
|
@@ -39,16 +44,32 @@ async function loadAgent(path) {
|
|
|
39
44
|
});
|
|
40
45
|
}
|
|
41
46
|
if ((0, node_path_1.extname)(path) === ".yaml" || (0, node_path_1.extname)(path) === ".yml") {
|
|
42
|
-
const agent = await (0,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
const agent = await (0, agent_yaml_js_1.loadAgentFromYamlFile)(path);
|
|
48
|
+
if (agent.type === "ai") {
|
|
49
|
+
return ai_agent_js_1.AIAgent.from({
|
|
50
|
+
name: agent.name,
|
|
51
|
+
description: agent.description,
|
|
52
|
+
instructions: agent.instructions,
|
|
53
|
+
inputSchema: agent.input_schema,
|
|
54
|
+
outputSchema: agent.output_schema,
|
|
55
|
+
outputKey: agent.output_key,
|
|
56
|
+
tools: await Promise.all((agent.tools ?? []).map((filename) => loadAgent((0, node_path_1.join)((0, node_path_1.dirname)(path), filename)))),
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
if (agent.type === "mcp") {
|
|
60
|
+
if (agent.url) {
|
|
61
|
+
return mcp_agent_js_1.MCPAgent.from({
|
|
62
|
+
url: agent.url,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (agent.command) {
|
|
66
|
+
return mcp_agent_js_1.MCPAgent.from({
|
|
67
|
+
command: agent.command,
|
|
68
|
+
args: agent.args,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
throw new Error(`Missing url or command in mcp agent: ${path}`);
|
|
72
|
+
}
|
|
52
73
|
}
|
|
53
74
|
throw new Error(`Unsupported agent file type: ${path}`);
|
|
54
75
|
}
|
|
@@ -62,17 +83,20 @@ async function loadModel(model) {
|
|
|
62
83
|
frequencyPenalty: model.frequent_penalty ?? undefined,
|
|
63
84
|
presencePenalty: model.presence_penalty ?? undefined,
|
|
64
85
|
};
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
86
|
+
const availableModels = [openai_chat_model_js_1.OpenAIChatModel, claude_chat_model_js_1.ClaudeChatModel, xai_chat_model_js_1.XAIChatModel];
|
|
87
|
+
const M = availableModels.find((m) => m.name.toLowerCase().includes(model.provider || DEFAULT_MODEL_PROVIDER));
|
|
88
|
+
if (!M)
|
|
89
|
+
throw new Error(`Unsupported model: ${model.provider} ${model.name}`);
|
|
90
|
+
return new M(params);
|
|
70
91
|
}
|
|
71
92
|
const aigneFileSchema = zod_1.z.object({
|
|
93
|
+
name: zod_1.z.string().nullish(),
|
|
94
|
+
description: zod_1.z.string().nullish(),
|
|
72
95
|
chat_model: zod_1.z
|
|
73
96
|
.union([
|
|
74
97
|
zod_1.z.string(),
|
|
75
98
|
zod_1.z.object({
|
|
99
|
+
provider: zod_1.z.string().nullish(),
|
|
76
100
|
name: zod_1.z.string().nullish(),
|
|
77
101
|
temperature: zod_1.z.number().min(0).max(2).nullish(),
|
|
78
102
|
top_p: zod_1.z.number().min(0).nullish(),
|
|
@@ -85,9 +109,20 @@ const aigneFileSchema = zod_1.z.object({
|
|
|
85
109
|
agents: zod_1.z.array(zod_1.z.string()).nullish(),
|
|
86
110
|
tools: zod_1.z.array(zod_1.z.string()).nullish(),
|
|
87
111
|
});
|
|
88
|
-
async function loadAIGNEFile(path
|
|
89
|
-
const raw = await (0, type_utils_js_1.tryOrThrow)(() =>
|
|
112
|
+
async function loadAIGNEFile(path) {
|
|
113
|
+
const raw = await (0, type_utils_js_1.tryOrThrow)(() => (0, promises_1.readFile)(path, "utf8"), (error) => new Error(`Failed to load aigne.yaml from ${path}: ${error.message}`));
|
|
90
114
|
const json = await (0, type_utils_js_1.tryOrThrow)(() => (0, yaml_1.parse)(raw), (error) => new Error(`Failed to parse aigne.yaml from ${path}: ${error.message}`));
|
|
91
115
|
const agent = (0, type_utils_js_1.tryOrThrow)(() => aigneFileSchema.parse(json), (error) => new Error(`Failed to validate aigne.yaml from ${path}: ${error.message}`));
|
|
92
116
|
return agent;
|
|
93
117
|
}
|
|
118
|
+
async function getAIGNEFilePath(path) {
|
|
119
|
+
const s = await (0, promises_1.stat)(path);
|
|
120
|
+
if (s.isDirectory()) {
|
|
121
|
+
for (const file of AIGNE_FILE_NAME) {
|
|
122
|
+
const filePath = (0, node_path_1.join)(path, file);
|
|
123
|
+
if (await (0, promises_1.exists)(filePath))
|
|
124
|
+
return filePath;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return path;
|
|
128
|
+
}
|
|
@@ -5,6 +5,8 @@ import { ChatModel } from "../models/chat-model.js";
|
|
|
5
5
|
import { type ContextLimits, ExecutionContext, type Runnable } from "./context.js";
|
|
6
6
|
import { type MessagePayload, MessageQueue, type MessageQueueListener, type Unsubscribe } from "./message-queue.js";
|
|
7
7
|
export interface ExecutionEngineOptions {
|
|
8
|
+
name?: string;
|
|
9
|
+
description?: string;
|
|
8
10
|
model?: ChatModel;
|
|
9
11
|
tools?: Agent[];
|
|
10
12
|
agents?: Agent[];
|
|
@@ -15,6 +17,8 @@ export declare class ExecutionEngine extends EventEmitter {
|
|
|
15
17
|
path: string;
|
|
16
18
|
} & ExecutionEngineOptions): Promise<ExecutionEngine>;
|
|
17
19
|
constructor(options?: ExecutionEngineOptions);
|
|
20
|
+
name?: string;
|
|
21
|
+
description?: string;
|
|
18
22
|
readonly messageQueue: MessageQueue;
|
|
19
23
|
model?: ChatModel;
|
|
20
24
|
readonly tools: Agent<Message, Message>[] & {
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { type ZodObject, type ZodType, z } from "zod";
|
|
2
2
|
import type { Message } from "../agents/agent.js";
|
|
3
|
-
export declare function loadAgentFromJsFile(path: string
|
|
4
|
-
import?: (path: string) => Promise<{
|
|
5
|
-
default: unknown;
|
|
6
|
-
}>;
|
|
7
|
-
}): Promise<{
|
|
3
|
+
export declare function loadAgentFromJsFile(path: string): Promise<{
|
|
8
4
|
name: string;
|
|
9
5
|
fn: (args_0: Message) => Message;
|
|
10
6
|
description?: string | undefined;
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
1
|
import { type ZodObject, type ZodType, z } from "zod";
|
|
3
|
-
export declare function loadAgentFromYamlFile(path: string
|
|
4
|
-
|
|
5
|
-
}): Promise<{
|
|
2
|
+
export declare function loadAgentFromYamlFile(path: string): Promise<{
|
|
3
|
+
type: "ai";
|
|
6
4
|
name: string;
|
|
7
5
|
description?: string | undefined;
|
|
8
6
|
tools?: string[] | undefined;
|
|
@@ -18,4 +16,9 @@ export declare function loadAgentFromYamlFile(path: string, { readFile: _readFil
|
|
|
18
16
|
[x: string]: any;
|
|
19
17
|
}> | undefined;
|
|
20
18
|
output_key?: string | undefined;
|
|
19
|
+
} | {
|
|
20
|
+
type: "mcp";
|
|
21
|
+
url?: string | undefined;
|
|
22
|
+
command?: string | undefined;
|
|
23
|
+
args?: string[] | undefined;
|
|
21
24
|
}>;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
1
|
import { type Agent } from "../agents/agent.js";
|
|
3
2
|
import type { ChatModel } from "../models/chat-model.js";
|
|
4
3
|
export interface LoadOptions {
|
|
@@ -8,15 +7,26 @@ export declare function load(options: LoadOptions): Promise<{
|
|
|
8
7
|
model: ChatModel | undefined;
|
|
9
8
|
agents: Agent<import("../agents/agent.js").Message, import("../agents/agent.js").Message>[];
|
|
10
9
|
tools: Agent<import("../agents/agent.js").Message, import("../agents/agent.js").Message>[];
|
|
10
|
+
description?: string | null | undefined;
|
|
11
|
+
name?: string | null | undefined;
|
|
12
|
+
chat_model?: {
|
|
13
|
+
name?: string | null | undefined;
|
|
14
|
+
temperature?: number | null | undefined;
|
|
15
|
+
provider?: string | null | undefined;
|
|
16
|
+
top_p?: number | null | undefined;
|
|
17
|
+
frequent_penalty?: number | null | undefined;
|
|
18
|
+
presence_penalty?: number | null | undefined;
|
|
19
|
+
} | null | undefined;
|
|
11
20
|
}>;
|
|
12
21
|
export declare function loadAgent(path: string): Promise<Agent>;
|
|
13
|
-
export declare function loadAIGNEFile(path: string
|
|
14
|
-
|
|
15
|
-
}): Promise<{
|
|
22
|
+
export declare function loadAIGNEFile(path: string): Promise<{
|
|
23
|
+
description?: string | null | undefined;
|
|
16
24
|
tools?: string[] | null | undefined;
|
|
25
|
+
name?: string | null | undefined;
|
|
17
26
|
chat_model?: {
|
|
18
27
|
name?: string | null | undefined;
|
|
19
28
|
temperature?: number | null | undefined;
|
|
29
|
+
provider?: string | null | undefined;
|
|
20
30
|
top_p?: number | null | undefined;
|
|
21
31
|
frequent_penalty?: number | null | undefined;
|
|
22
32
|
presence_penalty?: number | null | undefined;
|
|
@@ -5,6 +5,8 @@ import { ChatModel } from "../models/chat-model.js";
|
|
|
5
5
|
import { type ContextLimits, ExecutionContext, type Runnable } from "./context.js";
|
|
6
6
|
import { type MessagePayload, MessageQueue, type MessageQueueListener, type Unsubscribe } from "./message-queue.js";
|
|
7
7
|
export interface ExecutionEngineOptions {
|
|
8
|
+
name?: string;
|
|
9
|
+
description?: string;
|
|
8
10
|
model?: ChatModel;
|
|
9
11
|
tools?: Agent[];
|
|
10
12
|
agents?: Agent[];
|
|
@@ -15,6 +17,8 @@ export declare class ExecutionEngine extends EventEmitter {
|
|
|
15
17
|
path: string;
|
|
16
18
|
} & ExecutionEngineOptions): Promise<ExecutionEngine>;
|
|
17
19
|
constructor(options?: ExecutionEngineOptions);
|
|
20
|
+
name?: string;
|
|
21
|
+
description?: string;
|
|
18
22
|
readonly messageQueue: MessageQueue;
|
|
19
23
|
model?: ChatModel;
|
|
20
24
|
readonly tools: Agent<Message, Message>[] & {
|
|
@@ -8,10 +8,12 @@ import { ExecutionContext } from "./context.js";
|
|
|
8
8
|
import { MessageQueue, } from "./message-queue.js";
|
|
9
9
|
export class ExecutionEngine extends EventEmitter {
|
|
10
10
|
static async load({ path, ...options }) {
|
|
11
|
-
const { model, agents, tools } = await load({ path });
|
|
11
|
+
const { model, agents, tools, ...aigne } = await load({ path });
|
|
12
12
|
return new ExecutionEngine({
|
|
13
13
|
model,
|
|
14
14
|
...options,
|
|
15
|
+
name: options.name || aigne.name || undefined,
|
|
16
|
+
description: options.description || aigne.description || undefined,
|
|
15
17
|
agents: agents.concat(options.agents ?? []),
|
|
16
18
|
tools: tools.concat(options.tools ?? []),
|
|
17
19
|
});
|
|
@@ -20,6 +22,8 @@ export class ExecutionEngine extends EventEmitter {
|
|
|
20
22
|
if (options)
|
|
21
23
|
checkArguments("ExecutionEngine", executionEngineOptionsSchema, options);
|
|
22
24
|
super();
|
|
25
|
+
this.name = options?.name;
|
|
26
|
+
this.description = options?.description;
|
|
23
27
|
this.model = options?.model;
|
|
24
28
|
this.limits = options?.limits;
|
|
25
29
|
if (options?.tools?.length)
|
|
@@ -28,6 +32,8 @@ export class ExecutionEngine extends EventEmitter {
|
|
|
28
32
|
this.addAgent(...options.agents);
|
|
29
33
|
this.initProcessExitHandler();
|
|
30
34
|
}
|
|
35
|
+
name;
|
|
36
|
+
description;
|
|
31
37
|
messageQueue = new MessageQueue();
|
|
32
38
|
model;
|
|
33
39
|
tools = createAccessorArray([], (arr, name) => arr.find((i) => i.name === name));
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { type ZodObject, type ZodType, z } from "zod";
|
|
2
2
|
import type { Message } from "../agents/agent.js";
|
|
3
|
-
export declare function loadAgentFromJsFile(path: string
|
|
4
|
-
import?: (path: string) => Promise<{
|
|
5
|
-
default: unknown;
|
|
6
|
-
}>;
|
|
7
|
-
}): Promise<{
|
|
3
|
+
export declare function loadAgentFromJsFile(path: string): Promise<{
|
|
8
4
|
name: string;
|
|
9
5
|
fn: (args_0: Message) => Message;
|
|
10
6
|
description?: string | undefined;
|
|
@@ -16,8 +16,8 @@ const agentJsFileSchema = z.object({
|
|
|
16
16
|
.transform((v) => (v ? jsonSchemaToZod(v) : undefined)),
|
|
17
17
|
fn: z.function(),
|
|
18
18
|
});
|
|
19
|
-
export async function loadAgentFromJsFile(path
|
|
20
|
-
const { default: agent } = await tryOrThrow(() =>
|
|
19
|
+
export async function loadAgentFromJsFile(path) {
|
|
20
|
+
const { default: agent } = await tryOrThrow(() => import(path), (error) => new Error(`Failed to load agent definition from ${path}: ${error.message}`));
|
|
21
21
|
if (typeof agent !== "function") {
|
|
22
22
|
throw new Error(`Agent file ${path} must export a default function, but got ${typeof agent}`);
|
|
23
23
|
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
1
|
import { type ZodObject, type ZodType, z } from "zod";
|
|
3
|
-
export declare function loadAgentFromYamlFile(path: string
|
|
4
|
-
|
|
5
|
-
}): Promise<{
|
|
2
|
+
export declare function loadAgentFromYamlFile(path: string): Promise<{
|
|
3
|
+
type: "ai";
|
|
6
4
|
name: string;
|
|
7
5
|
description?: string | undefined;
|
|
8
6
|
tools?: string[] | undefined;
|
|
@@ -18,4 +16,9 @@ export declare function loadAgentFromYamlFile(path: string, { readFile: _readFil
|
|
|
18
16
|
[x: string]: any;
|
|
19
17
|
}> | undefined;
|
|
20
18
|
output_key?: string | undefined;
|
|
19
|
+
} | {
|
|
20
|
+
type: "mcp";
|
|
21
|
+
url?: string | undefined;
|
|
22
|
+
command?: string | undefined;
|
|
23
|
+
args?: string[] | undefined;
|
|
21
24
|
}>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { jsonSchemaToZod } from "@aigne/json-schema-to-zod";
|
|
3
|
+
import { parse } from "yaml";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { tryOrThrow } from "../utils/type-utils.js";
|
|
6
|
+
import { inputOutputSchema } from "./schema.js";
|
|
7
|
+
const agentFileSchema = z.discriminatedUnion("type", [
|
|
8
|
+
z.object({
|
|
9
|
+
type: z.literal("ai"),
|
|
10
|
+
name: z.string(),
|
|
11
|
+
description: z
|
|
12
|
+
.string()
|
|
13
|
+
.nullish()
|
|
14
|
+
.transform((v) => v ?? undefined),
|
|
15
|
+
instructions: z
|
|
16
|
+
.string()
|
|
17
|
+
.nullish()
|
|
18
|
+
.transform((v) => v ?? undefined),
|
|
19
|
+
input_schema: inputOutputSchema
|
|
20
|
+
.nullish()
|
|
21
|
+
.transform((v) => (v ? jsonSchemaToZod(v) : undefined)),
|
|
22
|
+
output_schema: inputOutputSchema
|
|
23
|
+
.nullish()
|
|
24
|
+
.transform((v) => (v ? jsonSchemaToZod(v) : undefined)),
|
|
25
|
+
output_key: z
|
|
26
|
+
.string()
|
|
27
|
+
.nullish()
|
|
28
|
+
.transform((v) => v ?? undefined),
|
|
29
|
+
tools: z
|
|
30
|
+
.array(z.string())
|
|
31
|
+
.nullish()
|
|
32
|
+
.transform((v) => v ?? undefined),
|
|
33
|
+
}),
|
|
34
|
+
z.object({
|
|
35
|
+
type: z.literal("mcp"),
|
|
36
|
+
url: z
|
|
37
|
+
.string()
|
|
38
|
+
.nullish()
|
|
39
|
+
.transform((v) => v ?? undefined),
|
|
40
|
+
command: z
|
|
41
|
+
.string()
|
|
42
|
+
.nullish()
|
|
43
|
+
.transform((v) => v ?? undefined),
|
|
44
|
+
args: z
|
|
45
|
+
.array(z.string())
|
|
46
|
+
.nullish()
|
|
47
|
+
.transform((v) => v ?? undefined),
|
|
48
|
+
}),
|
|
49
|
+
]);
|
|
50
|
+
export async function loadAgentFromYamlFile(path) {
|
|
51
|
+
const raw = await tryOrThrow(() => readFile(path, "utf8"), (error) => new Error(`Failed to load agent definition from ${path}: ${error.message}`));
|
|
52
|
+
const json = await tryOrThrow(() => parse(raw), (error) => new Error(`Failed to parse agent definition from ${path}: ${error.message}`));
|
|
53
|
+
const agent = tryOrThrow(() => agentFileSchema.parse({ ...json, type: json.type ?? "ai" }), (error) => new Error(`Failed to validate agent definition from ${path}: ${error.message}`));
|
|
54
|
+
return agent;
|
|
55
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
1
|
import { type Agent } from "../agents/agent.js";
|
|
3
2
|
import type { ChatModel } from "../models/chat-model.js";
|
|
4
3
|
export interface LoadOptions {
|
|
@@ -8,15 +7,26 @@ export declare function load(options: LoadOptions): Promise<{
|
|
|
8
7
|
model: ChatModel | undefined;
|
|
9
8
|
agents: Agent<import("../agents/agent.js").Message, import("../agents/agent.js").Message>[];
|
|
10
9
|
tools: Agent<import("../agents/agent.js").Message, import("../agents/agent.js").Message>[];
|
|
10
|
+
description?: string | null | undefined;
|
|
11
|
+
name?: string | null | undefined;
|
|
12
|
+
chat_model?: {
|
|
13
|
+
name?: string | null | undefined;
|
|
14
|
+
temperature?: number | null | undefined;
|
|
15
|
+
provider?: string | null | undefined;
|
|
16
|
+
top_p?: number | null | undefined;
|
|
17
|
+
frequent_penalty?: number | null | undefined;
|
|
18
|
+
presence_penalty?: number | null | undefined;
|
|
19
|
+
} | null | undefined;
|
|
11
20
|
}>;
|
|
12
21
|
export declare function loadAgent(path: string): Promise<Agent>;
|
|
13
|
-
export declare function loadAIGNEFile(path: string
|
|
14
|
-
|
|
15
|
-
}): Promise<{
|
|
22
|
+
export declare function loadAIGNEFile(path: string): Promise<{
|
|
23
|
+
description?: string | null | undefined;
|
|
16
24
|
tools?: string[] | null | undefined;
|
|
25
|
+
name?: string | null | undefined;
|
|
17
26
|
chat_model?: {
|
|
18
27
|
name?: string | null | undefined;
|
|
19
28
|
temperature?: number | null | undefined;
|
|
29
|
+
provider?: string | null | undefined;
|
|
20
30
|
top_p?: number | null | undefined;
|
|
21
31
|
frequent_penalty?: number | null | undefined;
|
|
22
32
|
presence_penalty?: number | null | undefined;
|
package/lib/esm/loader/index.js
CHANGED
|
@@ -1,22 +1,27 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
1
|
+
import { exists, readFile, stat } from "node:fs/promises";
|
|
2
2
|
import { dirname, extname, join } from "node:path";
|
|
3
3
|
import { parse } from "yaml";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import { FunctionAgent } from "../agents/agent.js";
|
|
6
6
|
import { AIAgent } from "../agents/ai-agent.js";
|
|
7
|
+
import { MCPAgent } from "../agents/mcp-agent.js";
|
|
8
|
+
import { ClaudeChatModel } from "../models/claude-chat-model.js";
|
|
7
9
|
import { OpenAIChatModel } from "../models/openai-chat-model.js";
|
|
10
|
+
import { XAIChatModel } from "../models/xai-chat-model.js";
|
|
8
11
|
import { tryOrThrow } from "../utils/type-utils.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
const
|
|
12
|
+
import { loadAgentFromJsFile } from "./agent-js.js";
|
|
13
|
+
import { loadAgentFromYamlFile } from "./agent-yaml.js";
|
|
14
|
+
const DEFAULT_MODEL_PROVIDER = "openai";
|
|
15
|
+
const AIGNE_FILE_NAME = ["aigne.yaml", "aigne.yml"];
|
|
12
16
|
export async function load(options) {
|
|
13
17
|
const { path } = options;
|
|
14
|
-
const aigneFilePath =
|
|
18
|
+
const aigneFilePath = await getAIGNEFilePath(path);
|
|
15
19
|
const rootDir = dirname(aigneFilePath);
|
|
16
20
|
const aigne = await loadAIGNEFile(aigneFilePath);
|
|
17
21
|
const agents = await Promise.all((aigne.agents ?? []).map((filename) => loadAgent(join(rootDir, filename))));
|
|
18
22
|
const tools = await Promise.all((aigne.tools ?? []).map((filename) => loadAgent(join(rootDir, filename))));
|
|
19
23
|
return {
|
|
24
|
+
...aigne,
|
|
20
25
|
model: await loadModel(aigne.chat_model),
|
|
21
26
|
agents,
|
|
22
27
|
tools,
|
|
@@ -35,15 +40,31 @@ export async function loadAgent(path) {
|
|
|
35
40
|
}
|
|
36
41
|
if (extname(path) === ".yaml" || extname(path) === ".yml") {
|
|
37
42
|
const agent = await loadAgentFromYamlFile(path);
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
if (agent.type === "ai") {
|
|
44
|
+
return AIAgent.from({
|
|
45
|
+
name: agent.name,
|
|
46
|
+
description: agent.description,
|
|
47
|
+
instructions: agent.instructions,
|
|
48
|
+
inputSchema: agent.input_schema,
|
|
49
|
+
outputSchema: agent.output_schema,
|
|
50
|
+
outputKey: agent.output_key,
|
|
51
|
+
tools: await Promise.all((agent.tools ?? []).map((filename) => loadAgent(join(dirname(path), filename)))),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
if (agent.type === "mcp") {
|
|
55
|
+
if (agent.url) {
|
|
56
|
+
return MCPAgent.from({
|
|
57
|
+
url: agent.url,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
if (agent.command) {
|
|
61
|
+
return MCPAgent.from({
|
|
62
|
+
command: agent.command,
|
|
63
|
+
args: agent.args,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
throw new Error(`Missing url or command in mcp agent: ${path}`);
|
|
67
|
+
}
|
|
47
68
|
}
|
|
48
69
|
throw new Error(`Unsupported agent file type: ${path}`);
|
|
49
70
|
}
|
|
@@ -57,17 +78,20 @@ async function loadModel(model) {
|
|
|
57
78
|
frequencyPenalty: model.frequent_penalty ?? undefined,
|
|
58
79
|
presencePenalty: model.presence_penalty ?? undefined,
|
|
59
80
|
};
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
81
|
+
const availableModels = [OpenAIChatModel, ClaudeChatModel, XAIChatModel];
|
|
82
|
+
const M = availableModels.find((m) => m.name.toLowerCase().includes(model.provider || DEFAULT_MODEL_PROVIDER));
|
|
83
|
+
if (!M)
|
|
84
|
+
throw new Error(`Unsupported model: ${model.provider} ${model.name}`);
|
|
85
|
+
return new M(params);
|
|
65
86
|
}
|
|
66
87
|
const aigneFileSchema = z.object({
|
|
88
|
+
name: z.string().nullish(),
|
|
89
|
+
description: z.string().nullish(),
|
|
67
90
|
chat_model: z
|
|
68
91
|
.union([
|
|
69
92
|
z.string(),
|
|
70
93
|
z.object({
|
|
94
|
+
provider: z.string().nullish(),
|
|
71
95
|
name: z.string().nullish(),
|
|
72
96
|
temperature: z.number().min(0).max(2).nullish(),
|
|
73
97
|
top_p: z.number().min(0).nullish(),
|
|
@@ -80,9 +104,20 @@ const aigneFileSchema = z.object({
|
|
|
80
104
|
agents: z.array(z.string()).nullish(),
|
|
81
105
|
tools: z.array(z.string()).nullish(),
|
|
82
106
|
});
|
|
83
|
-
export async function loadAIGNEFile(path
|
|
84
|
-
const raw = await tryOrThrow(() =>
|
|
107
|
+
export async function loadAIGNEFile(path) {
|
|
108
|
+
const raw = await tryOrThrow(() => readFile(path, "utf8"), (error) => new Error(`Failed to load aigne.yaml from ${path}: ${error.message}`));
|
|
85
109
|
const json = await tryOrThrow(() => parse(raw), (error) => new Error(`Failed to parse aigne.yaml from ${path}: ${error.message}`));
|
|
86
110
|
const agent = tryOrThrow(() => aigneFileSchema.parse(json), (error) => new Error(`Failed to validate aigne.yaml from ${path}: ${error.message}`));
|
|
87
111
|
return agent;
|
|
88
112
|
}
|
|
113
|
+
async function getAIGNEFilePath(path) {
|
|
114
|
+
const s = await stat(path);
|
|
115
|
+
if (s.isDirectory()) {
|
|
116
|
+
for (const file of AIGNE_FILE_NAME) {
|
|
117
|
+
const filePath = join(path, file);
|
|
118
|
+
if (await exists(filePath))
|
|
119
|
+
return filePath;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return path;
|
|
123
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "AIGNE core library for building AI-powered applications",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -83,20 +83,21 @@
|
|
|
83
83
|
"@types/bun": "^1.2.8",
|
|
84
84
|
"@types/express": "^5.0.1",
|
|
85
85
|
"@types/mustache": "^4.2.5",
|
|
86
|
-
"@types/node": "^22.
|
|
86
|
+
"@types/node": "^22.14.0",
|
|
87
87
|
"detect-port": "^2.1.0",
|
|
88
88
|
"express": "^5.1.0",
|
|
89
89
|
"npm-run-all": "^4.1.5",
|
|
90
90
|
"openai": "^4.91.1",
|
|
91
91
|
"rimraf": "^6.0.1",
|
|
92
|
-
"typescript": "^5.8.2"
|
|
92
|
+
"typescript": "^5.8.2",
|
|
93
|
+
"@aigne/test-utils": "^1.0.0"
|
|
93
94
|
},
|
|
94
95
|
"scripts": {
|
|
95
96
|
"lint": "tsc --noEmit",
|
|
96
97
|
"build": "tsc --build scripts/tsconfig.build.json",
|
|
97
98
|
"clean": "rimraf lib test/coverage",
|
|
98
|
-
"test": "
|
|
99
|
-
"test:coverage": "
|
|
99
|
+
"test": "bun --cwd test test",
|
|
100
|
+
"test:coverage": "bun --cwd test test --coverage --coverage-reporter=lcov --coverage-reporter=text",
|
|
100
101
|
"postbuild": "echo '{\"type\": \"module\"}' > lib/esm/package.json && echo '{\"type\": \"commonjs\"}' > lib/cjs/package.json"
|
|
101
102
|
}
|
|
102
103
|
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.loadAgentFromYamlFile = loadAgentFromYamlFile;
|
|
4
|
-
const promises_1 = require("node:fs/promises");
|
|
5
|
-
const json_schema_to_zod_1 = require("@aigne/json-schema-to-zod");
|
|
6
|
-
const yaml_1 = require("yaml");
|
|
7
|
-
const zod_1 = require("zod");
|
|
8
|
-
const type_utils_js_1 = require("../utils/type-utils.js");
|
|
9
|
-
const schema_js_1 = require("./schema.js");
|
|
10
|
-
const agentFileSchema = zod_1.z.object({
|
|
11
|
-
name: zod_1.z.string(),
|
|
12
|
-
description: zod_1.z
|
|
13
|
-
.string()
|
|
14
|
-
.nullish()
|
|
15
|
-
.transform((v) => v ?? undefined),
|
|
16
|
-
instructions: zod_1.z
|
|
17
|
-
.string()
|
|
18
|
-
.nullish()
|
|
19
|
-
.transform((v) => v ?? undefined),
|
|
20
|
-
input_schema: schema_js_1.inputOutputSchema
|
|
21
|
-
.nullish()
|
|
22
|
-
.transform((v) => (v ? (0, json_schema_to_zod_1.jsonSchemaToZod)(v) : undefined)),
|
|
23
|
-
output_schema: schema_js_1.inputOutputSchema
|
|
24
|
-
.nullish()
|
|
25
|
-
.transform((v) => (v ? (0, json_schema_to_zod_1.jsonSchemaToZod)(v) : undefined)),
|
|
26
|
-
output_key: zod_1.z
|
|
27
|
-
.string()
|
|
28
|
-
.nullish()
|
|
29
|
-
.transform((v) => v ?? undefined),
|
|
30
|
-
tools: zod_1.z
|
|
31
|
-
.array(zod_1.z.string())
|
|
32
|
-
.nullish()
|
|
33
|
-
.transform((v) => v ?? undefined),
|
|
34
|
-
});
|
|
35
|
-
async function loadAgentFromYamlFile(path, { readFile: _readFile = promises_1.readFile } = {}) {
|
|
36
|
-
const raw = await (0, type_utils_js_1.tryOrThrow)(() => _readFile(path, "utf8"), (error) => new Error(`Failed to load agent definition from ${path}: ${error.message}`));
|
|
37
|
-
const json = await (0, type_utils_js_1.tryOrThrow)(() => (0, yaml_1.parse)(raw), (error) => new Error(`Failed to parse agent definition from ${path}: ${error.message}`));
|
|
38
|
-
const agent = (0, type_utils_js_1.tryOrThrow)(() => agentFileSchema.parse(json), (error) => new Error(`Failed to validate agent definition from ${path}: ${error.message}`));
|
|
39
|
-
return agent;
|
|
40
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
|
-
import { jsonSchemaToZod } from "@aigne/json-schema-to-zod";
|
|
3
|
-
import { parse } from "yaml";
|
|
4
|
-
import { z } from "zod";
|
|
5
|
-
import { tryOrThrow } from "../utils/type-utils.js";
|
|
6
|
-
import { inputOutputSchema } from "./schema.js";
|
|
7
|
-
const agentFileSchema = z.object({
|
|
8
|
-
name: z.string(),
|
|
9
|
-
description: z
|
|
10
|
-
.string()
|
|
11
|
-
.nullish()
|
|
12
|
-
.transform((v) => v ?? undefined),
|
|
13
|
-
instructions: z
|
|
14
|
-
.string()
|
|
15
|
-
.nullish()
|
|
16
|
-
.transform((v) => v ?? undefined),
|
|
17
|
-
input_schema: inputOutputSchema
|
|
18
|
-
.nullish()
|
|
19
|
-
.transform((v) => (v ? jsonSchemaToZod(v) : undefined)),
|
|
20
|
-
output_schema: inputOutputSchema
|
|
21
|
-
.nullish()
|
|
22
|
-
.transform((v) => (v ? jsonSchemaToZod(v) : undefined)),
|
|
23
|
-
output_key: z
|
|
24
|
-
.string()
|
|
25
|
-
.nullish()
|
|
26
|
-
.transform((v) => v ?? undefined),
|
|
27
|
-
tools: z
|
|
28
|
-
.array(z.string())
|
|
29
|
-
.nullish()
|
|
30
|
-
.transform((v) => v ?? undefined),
|
|
31
|
-
});
|
|
32
|
-
export async function loadAgentFromYamlFile(path, { readFile: _readFile = readFile } = {}) {
|
|
33
|
-
const raw = await tryOrThrow(() => _readFile(path, "utf8"), (error) => new Error(`Failed to load agent definition from ${path}: ${error.message}`));
|
|
34
|
-
const json = await tryOrThrow(() => parse(raw), (error) => new Error(`Failed to parse agent definition from ${path}: ${error.message}`));
|
|
35
|
-
const agent = tryOrThrow(() => agentFileSchema.parse(json), (error) => new Error(`Failed to validate agent definition from ${path}: ${error.message}`));
|
|
36
|
-
return agent;
|
|
37
|
-
}
|