@aigne/core 1.33.2 → 1.36.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 +29 -0
- package/lib/cjs/agents/agent.d.ts +71 -10
- package/lib/cjs/agents/agent.js +73 -28
- package/lib/cjs/agents/ai-agent.js +6 -3
- package/lib/cjs/agents/team-agent.js +3 -13
- package/lib/cjs/aigne/context.d.ts +1 -0
- package/lib/cjs/aigne/context.js +25 -10
- package/lib/cjs/loader/agent-js.d.ts +2 -11
- package/lib/cjs/loader/agent-js.js +4 -8
- package/lib/cjs/loader/agent-yaml.d.ts +18 -2
- package/lib/cjs/loader/agent-yaml.js +32 -13
- package/lib/cjs/loader/index.d.ts +2 -2
- package/lib/cjs/loader/index.js +48 -15
- package/lib/cjs/loader/schema.d.ts +10 -0
- package/lib/cjs/loader/schema.js +17 -1
- package/lib/cjs/package.json +3 -1
- package/lib/cjs/utils/type-utils.d.ts +1 -1
- package/lib/cjs/utils/type-utils.js +2 -4
- package/lib/dts/agents/agent.d.ts +71 -10
- package/lib/dts/aigne/context.d.ts +1 -0
- package/lib/dts/loader/agent-js.d.ts +2 -11
- package/lib/dts/loader/agent-yaml.d.ts +18 -2
- package/lib/dts/loader/index.d.ts +2 -2
- package/lib/dts/loader/schema.d.ts +10 -0
- package/lib/dts/utils/type-utils.d.ts +1 -1
- package/lib/esm/agents/agent.d.ts +71 -10
- package/lib/esm/agents/agent.js +73 -28
- package/lib/esm/agents/ai-agent.js +6 -3
- package/lib/esm/agents/team-agent.js +3 -13
- package/lib/esm/aigne/context.d.ts +1 -0
- package/lib/esm/aigne/context.js +25 -10
- package/lib/esm/loader/agent-js.d.ts +2 -11
- package/lib/esm/loader/agent-js.js +5 -6
- package/lib/esm/loader/agent-yaml.d.ts +18 -2
- package/lib/esm/loader/agent-yaml.js +33 -11
- package/lib/esm/loader/index.d.ts +2 -2
- package/lib/esm/loader/index.js +49 -16
- package/lib/esm/loader/schema.d.ts +10 -0
- package/lib/esm/loader/schema.js +12 -0
- package/lib/esm/package.json +3 -1
- package/lib/esm/utils/type-utils.d.ts +1 -1
- package/lib/esm/utils/type-utils.js +2 -4
- package/package.json +4 -4
|
@@ -1,29 +1,48 @@
|
|
|
1
1
|
import { jsonSchemaToZod } from "@aigne/json-schema-to-zod";
|
|
2
2
|
import { nodejs } from "@aigne/platform-helpers/nodejs/index.js";
|
|
3
|
-
import camelize from "camelize-ts";
|
|
4
3
|
import { parse } from "yaml";
|
|
5
4
|
import { z } from "zod";
|
|
6
5
|
import { AIAgentToolChoice } from "../agents/ai-agent.js";
|
|
7
6
|
import { ProcessMode } from "../agents/team-agent.js";
|
|
8
7
|
import { tryOrThrow } from "../utils/type-utils.js";
|
|
9
|
-
import { inputOutputSchema, optionalize } from "./schema.js";
|
|
8
|
+
import { camelizeSchema, defaultInputSchema, inputOutputSchema, optionalize } from "./schema.js";
|
|
10
9
|
export async function loadAgentFromYamlFile(path) {
|
|
11
10
|
const agentSchema = z.lazy(() => {
|
|
11
|
+
const nestAgentSchema = z.lazy(() => z.union([
|
|
12
|
+
agentSchema,
|
|
13
|
+
z.string(),
|
|
14
|
+
camelizeSchema(z.object({
|
|
15
|
+
url: z.string(),
|
|
16
|
+
defaultInput: optionalize(defaultInputSchema),
|
|
17
|
+
hooks: optionalize(z.union([hooksSchema, z.array(hooksSchema)])),
|
|
18
|
+
})),
|
|
19
|
+
]));
|
|
20
|
+
const hooksSchema = camelizeSchema(z.object({
|
|
21
|
+
onStart: optionalize(nestAgentSchema),
|
|
22
|
+
onSuccess: optionalize(nestAgentSchema),
|
|
23
|
+
onError: optionalize(nestAgentSchema),
|
|
24
|
+
onEnd: optionalize(nestAgentSchema),
|
|
25
|
+
onSkillStart: optionalize(nestAgentSchema),
|
|
26
|
+
onSkillEnd: optionalize(nestAgentSchema),
|
|
27
|
+
onHandoff: optionalize(nestAgentSchema),
|
|
28
|
+
}));
|
|
12
29
|
const baseAgentSchema = z.object({
|
|
13
30
|
name: optionalize(z.string()),
|
|
14
31
|
description: optionalize(z.string()),
|
|
15
32
|
inputSchema: optionalize(inputOutputSchema({ path })).transform((v) => v ? jsonSchemaToZod(v) : undefined),
|
|
33
|
+
defaultInput: optionalize(defaultInputSchema),
|
|
16
34
|
outputSchema: optionalize(inputOutputSchema({ path })).transform((v) => v ? jsonSchemaToZod(v) : undefined),
|
|
17
|
-
|
|
35
|
+
hooks: optionalize(z.union([hooksSchema, z.array(hooksSchema)])),
|
|
36
|
+
skills: optionalize(z.array(nestAgentSchema)),
|
|
18
37
|
memory: optionalize(z.union([
|
|
19
38
|
z.boolean(),
|
|
20
|
-
z.object({
|
|
39
|
+
camelizeSchema(z.object({
|
|
21
40
|
provider: z.string(),
|
|
22
41
|
subscribeTopic: optionalize(z.array(z.string())),
|
|
23
|
-
}),
|
|
42
|
+
})),
|
|
24
43
|
])),
|
|
25
44
|
});
|
|
26
|
-
return z.discriminatedUnion("type", [
|
|
45
|
+
return camelizeSchema(z.discriminatedUnion("type", [
|
|
27
46
|
z
|
|
28
47
|
.object({
|
|
29
48
|
type: z.literal("ai"),
|
|
@@ -34,18 +53,21 @@ export async function loadAgentFromYamlFile(path) {
|
|
|
34
53
|
}),
|
|
35
54
|
])).transform((v) => typeof v === "string"
|
|
36
55
|
? v
|
|
37
|
-
: v &&
|
|
56
|
+
: v &&
|
|
57
|
+
nodejs.fs.readFile(nodejs.path.join(nodejs.path.dirname(path), v.url), "utf8")),
|
|
38
58
|
inputKey: optionalize(z.string()),
|
|
39
59
|
outputKey: optionalize(z.string()),
|
|
40
60
|
toolChoice: optionalize(z.nativeEnum(AIAgentToolChoice)),
|
|
41
61
|
})
|
|
42
62
|
.extend(baseAgentSchema.shape),
|
|
43
|
-
z
|
|
63
|
+
z
|
|
64
|
+
.object({
|
|
44
65
|
type: z.literal("mcp"),
|
|
45
66
|
url: optionalize(z.string()),
|
|
46
67
|
command: optionalize(z.string()),
|
|
47
68
|
args: optionalize(z.array(z.string())),
|
|
48
|
-
})
|
|
69
|
+
})
|
|
70
|
+
.extend(baseAgentSchema.shape),
|
|
49
71
|
z
|
|
50
72
|
.object({
|
|
51
73
|
type: z.literal("team"),
|
|
@@ -59,10 +81,10 @@ export async function loadAgentFromYamlFile(path) {
|
|
|
59
81
|
jsonata: z.string(),
|
|
60
82
|
})
|
|
61
83
|
.extend(baseAgentSchema.shape),
|
|
62
|
-
]);
|
|
84
|
+
]));
|
|
63
85
|
});
|
|
64
86
|
const raw = await tryOrThrow(() => nodejs.fs.readFile(path, "utf8"), (error) => new Error(`Failed to load agent definition from ${path}: ${error.message}`));
|
|
65
|
-
const json = tryOrThrow(() =>
|
|
87
|
+
const json = tryOrThrow(() => parse(raw), (error) => new Error(`Failed to parse agent definition from ${path}: ${error.message}`));
|
|
66
88
|
const agent = await tryOrThrow(async () => await agentSchema.parseAsync({
|
|
67
89
|
...json,
|
|
68
90
|
type: json.type ?? "ai",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Camelize } from "camelize-ts";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { Agent } from "../agents/agent.js";
|
|
3
|
+
import { Agent, type AgentOptions } from "../agents/agent.js";
|
|
4
4
|
import type { ChatModel, ChatModelOptions } from "../agents/chat-model.js";
|
|
5
5
|
import type { AIGNEOptions } from "../aigne/aigne.js";
|
|
6
6
|
import type { MemoryAgent, MemoryAgentOptions } from "../memory/memory.js";
|
|
@@ -25,7 +25,7 @@ export interface LoadOptions {
|
|
|
25
25
|
path: string;
|
|
26
26
|
}
|
|
27
27
|
export declare function load(options: LoadOptions): Promise<AIGNEOptions>;
|
|
28
|
-
export declare function loadAgent(path: string, options?: LoadOptions): Promise<Agent>;
|
|
28
|
+
export declare function loadAgent(path: string, options?: LoadOptions, agentOptions?: AgentOptions): Promise<Agent>;
|
|
29
29
|
export declare function loadModel(models: LoadableModel[], model?: Camelize<z.infer<typeof aigneFileSchema>["model"]>, modelOptions?: ChatModelOptions): Promise<ChatModel | undefined>;
|
|
30
30
|
declare const aigneFileSchema: z.ZodObject<{
|
|
31
31
|
name: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
|
package/lib/esm/loader/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { MCPAgent } from "../agents/mcp-agent.js";
|
|
|
8
8
|
import { TeamAgent } from "../agents/team-agent.js";
|
|
9
9
|
import { TransformAgent } from "../agents/transform-agent.js";
|
|
10
10
|
import { PromptBuilder } from "../prompt/prompt-builder.js";
|
|
11
|
-
import { tryOrThrow } from "../utils/type-utils.js";
|
|
11
|
+
import { isNonNullable, tryOrThrow } from "../utils/type-utils.js";
|
|
12
12
|
import { loadAgentFromJsFile } from "./agent-js.js";
|
|
13
13
|
import { loadAgentFromYamlFile } from "./agent-yaml.js";
|
|
14
14
|
import { optionalize } from "./schema.js";
|
|
@@ -30,7 +30,7 @@ export async function load(options) {
|
|
|
30
30
|
skills,
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
|
-
export async function loadAgent(path, options) {
|
|
33
|
+
export async function loadAgent(path, options, agentOptions) {
|
|
34
34
|
if ([".js", ".mjs", ".ts", ".mts"].includes(nodejs.path.extname(path))) {
|
|
35
35
|
const agent = await loadAgentFromJsFile(path);
|
|
36
36
|
if (agent instanceof Agent)
|
|
@@ -39,38 +39,74 @@ export async function loadAgent(path, options) {
|
|
|
39
39
|
}
|
|
40
40
|
if ([".yml", ".yaml"].includes(nodejs.path.extname(path))) {
|
|
41
41
|
const agent = await loadAgentFromYamlFile(path);
|
|
42
|
-
return parseAgent(path, agent, options);
|
|
42
|
+
return parseAgent(path, agent, options, agentOptions);
|
|
43
43
|
}
|
|
44
44
|
throw new Error(`Unsupported agent file type: ${path}`);
|
|
45
45
|
}
|
|
46
|
-
async function
|
|
46
|
+
async function loadNestAgent(path, agent, options) {
|
|
47
|
+
return typeof agent === "object" && "type" in agent
|
|
48
|
+
? parseAgent(path, agent, options)
|
|
49
|
+
: typeof agent === "string"
|
|
50
|
+
? loadAgent(nodejs.path.join(nodejs.path.dirname(path), agent), options)
|
|
51
|
+
: loadAgent(nodejs.path.join(nodejs.path.dirname(path), agent.url), options, {
|
|
52
|
+
defaultInput: agent.defaultInput,
|
|
53
|
+
hooks: await parseHooks(path, agent.hooks, options),
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
async function parseHooks(path, hooks, options) {
|
|
57
|
+
hooks = [hooks].flat().filter(isNonNullable);
|
|
58
|
+
if (!hooks.length)
|
|
59
|
+
return undefined;
|
|
60
|
+
return await Promise.all(hooks.map(async (hook) => ({
|
|
61
|
+
onStart: hook.onStart ? await loadNestAgent(path, hook.onStart, options) : undefined,
|
|
62
|
+
onSuccess: hook.onSuccess ? await loadNestAgent(path, hook.onSuccess, options) : undefined,
|
|
63
|
+
onError: hook.onError ? await loadNestAgent(path, hook.onError, options) : undefined,
|
|
64
|
+
onEnd: hook.onEnd ? await loadNestAgent(path, hook.onEnd, options) : undefined,
|
|
65
|
+
onSkillStart: hook.onSkillStart
|
|
66
|
+
? await loadNestAgent(path, hook.onSkillStart, options)
|
|
67
|
+
: undefined,
|
|
68
|
+
onSkillEnd: hook.onSkillEnd
|
|
69
|
+
? await loadNestAgent(path, hook.onSkillEnd, options)
|
|
70
|
+
: undefined,
|
|
71
|
+
onHandoff: hook.onHandoff ? await loadNestAgent(path, hook.onHandoff, options) : undefined,
|
|
72
|
+
})));
|
|
73
|
+
}
|
|
74
|
+
async function parseAgent(path, agent, options, agentOptions) {
|
|
47
75
|
const skills = "skills" in agent
|
|
48
76
|
? agent.skills &&
|
|
49
|
-
(await Promise.all(agent.skills.map((skill) =>
|
|
50
|
-
? loadAgent(nodejs.path.join(nodejs.path.dirname(path), skill), options)
|
|
51
|
-
: parseAgent(path, skill, options))))
|
|
77
|
+
(await Promise.all(agent.skills.map((skill) => loadNestAgent(path, skill, options))))
|
|
52
78
|
: undefined;
|
|
53
79
|
const memory = "memory" in agent && options?.memories?.length
|
|
54
80
|
? await loadMemory(options.memories, typeof agent.memory === "object" ? agent.memory.provider : undefined, typeof agent.memory === "object" ? agent.memory : {})
|
|
55
81
|
: undefined;
|
|
82
|
+
const baseOptions = {
|
|
83
|
+
...agentOptions,
|
|
84
|
+
...agent,
|
|
85
|
+
skills,
|
|
86
|
+
memory,
|
|
87
|
+
hooks: [
|
|
88
|
+
...((await parseHooks(path, agent.hooks, options)) ?? []),
|
|
89
|
+
...[agentOptions?.hooks].flat().filter(isNonNullable),
|
|
90
|
+
],
|
|
91
|
+
};
|
|
56
92
|
switch (agent.type) {
|
|
57
93
|
case "ai": {
|
|
58
94
|
return AIAgent.from({
|
|
59
|
-
...
|
|
95
|
+
...baseOptions,
|
|
60
96
|
instructions: agent.instructions &&
|
|
61
97
|
PromptBuilder.from(agent.instructions, { workingDir: nodejs.path.dirname(path) }),
|
|
62
|
-
memory,
|
|
63
|
-
skills,
|
|
64
98
|
});
|
|
65
99
|
}
|
|
66
100
|
case "mcp": {
|
|
67
101
|
if (agent.url) {
|
|
68
102
|
return MCPAgent.from({
|
|
103
|
+
...baseOptions,
|
|
69
104
|
url: agent.url,
|
|
70
105
|
});
|
|
71
106
|
}
|
|
72
107
|
if (agent.command) {
|
|
73
108
|
return MCPAgent.from({
|
|
109
|
+
...baseOptions,
|
|
74
110
|
command: agent.command,
|
|
75
111
|
args: agent.args,
|
|
76
112
|
});
|
|
@@ -79,16 +115,13 @@ async function parseAgent(path, agent, options) {
|
|
|
79
115
|
}
|
|
80
116
|
case "team": {
|
|
81
117
|
return TeamAgent.from({
|
|
82
|
-
...
|
|
83
|
-
memory,
|
|
84
|
-
skills,
|
|
118
|
+
...baseOptions,
|
|
85
119
|
});
|
|
86
120
|
}
|
|
87
121
|
case "transform": {
|
|
88
122
|
return TransformAgent.from({
|
|
89
|
-
...
|
|
90
|
-
|
|
91
|
-
skills,
|
|
123
|
+
...baseOptions,
|
|
124
|
+
jsonata: agent.jsonata,
|
|
92
125
|
});
|
|
93
126
|
}
|
|
94
127
|
}
|
|
@@ -22,4 +22,14 @@ export declare const inputOutputSchema: ({ path }: {
|
|
|
22
22
|
required?: string[] | undefined;
|
|
23
23
|
additionalProperties?: boolean | undefined;
|
|
24
24
|
}>]>;
|
|
25
|
+
export declare const defaultInputSchema: z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodObject<{
|
|
26
|
+
$get: z.ZodString;
|
|
27
|
+
}, "strip", z.ZodTypeAny, {
|
|
28
|
+
$get: string;
|
|
29
|
+
}, {
|
|
30
|
+
$get: string;
|
|
31
|
+
}>, z.ZodUnknown]>>;
|
|
25
32
|
export declare function optionalize<T>(schema: ZodType<T>): ZodType<T | undefined>;
|
|
33
|
+
export declare function camelizeSchema<T>(schema: ZodType<T>, { shallow }?: {
|
|
34
|
+
shallow?: boolean;
|
|
35
|
+
}): ZodType<T>;
|
package/lib/esm/loader/schema.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { nodejs } from "@aigne/platform-helpers/nodejs/index.js";
|
|
2
|
+
import camelize from "camelize-ts";
|
|
2
3
|
import { parse } from "yaml";
|
|
3
4
|
import { z } from "zod";
|
|
5
|
+
import { DEFAULT_INPUT_ACTION_GET } from "../agents/agent.js";
|
|
6
|
+
import { isRecord } from "../utils/type-utils.js";
|
|
4
7
|
export const inputOutputSchema = ({ path }) => {
|
|
5
8
|
const includeExternalSchema = async (schema) => {
|
|
6
9
|
if (schema?.type === "object" && schema.properties) {
|
|
@@ -45,6 +48,15 @@ export const inputOutputSchema = ({ path }) => {
|
|
|
45
48
|
jsonSchemaSchema,
|
|
46
49
|
]);
|
|
47
50
|
};
|
|
51
|
+
export const defaultInputSchema = z.record(z.string(), z.union([
|
|
52
|
+
z.object({
|
|
53
|
+
[DEFAULT_INPUT_ACTION_GET]: z.string(),
|
|
54
|
+
}),
|
|
55
|
+
z.unknown(),
|
|
56
|
+
]));
|
|
48
57
|
export function optionalize(schema) {
|
|
49
58
|
return schema.nullish().transform((v) => v ?? undefined);
|
|
50
59
|
}
|
|
60
|
+
export function camelizeSchema(schema, { shallow = true } = {}) {
|
|
61
|
+
return z.preprocess((v) => (isRecord(v) ? camelize(v, shallow) : v), schema);
|
|
62
|
+
}
|
package/lib/esm/package.json
CHANGED
|
@@ -19,7 +19,7 @@ export declare function pick<T extends object, K extends keyof T>(obj: T, ...key
|
|
|
19
19
|
export declare function omit<T extends object, K extends keyof T>(obj: T, ...keys: (K | K[])[]): Omit<T, K>;
|
|
20
20
|
export declare function omitDeep<T, K>(obj: T, ...keys: (K | K[])[]): unknown;
|
|
21
21
|
export declare function omitBy<T extends Record<string, unknown>, K extends keyof T>(obj: T, predicate: (value: T[K], key: K) => boolean): Partial<T>;
|
|
22
|
-
export declare function flat<T>(value
|
|
22
|
+
export declare function flat<T>(...value: (T | T[])[]): NonNullable<T>[];
|
|
23
23
|
export declare function createAccessorArray<T>(array: T[], accessor: (array: T[], name: string) => T | undefined): T[] & {
|
|
24
24
|
[key: string]: T;
|
|
25
25
|
};
|
|
@@ -84,10 +84,8 @@ export function omitBy(obj, predicate) {
|
|
|
84
84
|
return !predicate(value, k);
|
|
85
85
|
}));
|
|
86
86
|
}
|
|
87
|
-
export function flat(value) {
|
|
88
|
-
|
|
89
|
-
return [];
|
|
90
|
-
return Array.isArray(value) ? value : [value];
|
|
87
|
+
export function flat(...value) {
|
|
88
|
+
return value.flat().filter(isNonNullable);
|
|
91
89
|
}
|
|
92
90
|
export function createAccessorArray(array, accessor) {
|
|
93
91
|
return new Proxy(array, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.36.0",
|
|
4
4
|
"description": "AIGNE core library for building AI-powered applications",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -83,8 +83,8 @@
|
|
|
83
83
|
"yaml": "^2.8.0",
|
|
84
84
|
"zod": "^3.25.67",
|
|
85
85
|
"zod-to-json-schema": "^3.24.6",
|
|
86
|
-
"@aigne/observability-api": "^0.
|
|
87
|
-
"@aigne/platform-helpers": "^0.
|
|
86
|
+
"@aigne/observability-api": "^0.8.0",
|
|
87
|
+
"@aigne/platform-helpers": "^0.4.0"
|
|
88
88
|
},
|
|
89
89
|
"devDependencies": {
|
|
90
90
|
"@types/bun": "^1.2.18",
|
|
@@ -107,6 +107,6 @@
|
|
|
107
107
|
"clean": "rimraf lib test/coverage",
|
|
108
108
|
"test": "bun --cwd test test",
|
|
109
109
|
"test:coverage": "bun --cwd test test --coverage --coverage-reporter=lcov --coverage-reporter=text",
|
|
110
|
-
"postbuild": "
|
|
110
|
+
"postbuild": "node ../../scripts/post-build-lib.mjs"
|
|
111
111
|
}
|
|
112
112
|
}
|