@aigne/cli 1.49.0-beta.8 → 1.49.0-beta.9
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 +28 -0
- package/dist/commands/app.d.ts +30 -15
- package/dist/commands/app.js +111 -106
- package/dist/utils/evaluation/reporter.js +31 -12
- package/dist/utils/workers/run-aigne-in-child-process-worker.d.ts +21 -0
- package/dist/utils/workers/run-aigne-in-child-process-worker.js +81 -0
- package/dist/utils/workers/run-aigne-in-child-process.d.ts +7 -0
- package/dist/utils/workers/run-aigne-in-child-process.js +20 -0
- package/dist/utils/yargs.d.ts +1 -1
- package/package.json +11 -9
- package/dist/utils/workers/load-aigne-worker.d.ts +0 -1
- package/dist/utils/workers/load-aigne-worker.js +0 -13
- package/dist/utils/workers/load-aigne.d.ts +0 -2
- package/dist/utils/workers/load-aigne.js +0 -27
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.49.0-beta.9](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.49.0-beta.8...cli-v1.49.0-beta.9) (2025-09-26)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **cli:** add `--beta` `--target-version` `--force` options for `upgrade` command ([#555](https://github.com/AIGNE-io/aigne-framework/issues/555)) ([f9f0471](https://github.com/AIGNE-io/aigne-framework/commit/f9f04719020cca00bc3adbe8169c42422201df49))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **blocklet:** observability blocklet start failure ([#554](https://github.com/AIGNE-io/aigne-framework/issues/554)) ([8431d4d](https://github.com/AIGNE-io/aigne-framework/commit/8431d4d89a4b96f735f23e774e9545bbe1fd811c))
|
|
14
|
+
* **blocklet:** observability blocklet start failure ([#554](https://github.com/AIGNE-io/aigne-framework/issues/554)) ([8431d4d](https://github.com/AIGNE-io/aigne-framework/commit/8431d4d89a4b96f735f23e774e9545bbe1fd811c))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Dependencies
|
|
18
|
+
|
|
19
|
+
* The following workspace dependencies were updated
|
|
20
|
+
* dependencies
|
|
21
|
+
* @aigne/agent-library bumped to 1.21.46-beta.9
|
|
22
|
+
* @aigne/agentic-memory bumped to 1.0.46-beta.9
|
|
23
|
+
* @aigne/aigne-hub bumped to 0.10.0-beta.9
|
|
24
|
+
* @aigne/core bumped to 1.61.0-beta.8
|
|
25
|
+
* @aigne/default-memory bumped to 1.2.9-beta.9
|
|
26
|
+
* @aigne/observability-api bumped to 0.11.0-beta.1
|
|
27
|
+
* @aigne/openai bumped to 0.16.0-beta.9
|
|
28
|
+
* devDependencies
|
|
29
|
+
* @aigne/test-utils bumped to 0.5.53-beta.8
|
|
30
|
+
|
|
3
31
|
## [1.49.0-beta.8](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.49.0-beta.7...cli-v1.49.0-beta.8) (2025-09-26)
|
|
4
32
|
|
|
5
33
|
|
package/dist/commands/app.d.ts
CHANGED
|
@@ -1,27 +1,42 @@
|
|
|
1
|
-
import type { Agent, AIGNE, Message } from "@aigne/core";
|
|
2
1
|
import type { CommandModule } from "yargs";
|
|
2
|
+
import { type LoadAIGNEInChildProcessResult } from "../utils/workers/run-aigne-in-child-process.js";
|
|
3
|
+
import type { AgentInChildProcess } from "../utils/workers/run-aigne-in-child-process-worker.js";
|
|
3
4
|
import { type AgentRunCommonOptions } from "../utils/yargs.js";
|
|
4
5
|
export declare function createAppCommands(): CommandModule[];
|
|
5
6
|
export declare const agentCommandModule: ({ dir, agent, }: {
|
|
6
7
|
dir: string;
|
|
7
|
-
agent:
|
|
8
|
+
agent: AgentInChildProcess;
|
|
8
9
|
}) => CommandModule<unknown, AgentRunCommonOptions>;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
agent: string;
|
|
12
|
-
input: Message & AgentRunCommonOptions;
|
|
13
|
-
}): Promise<void>;
|
|
14
|
-
export declare function loadApplication({ name, dir, forceUpgrade, }: {
|
|
15
|
-
name: string;
|
|
16
|
-
dir?: string;
|
|
17
|
-
forceUpgrade?: boolean;
|
|
18
|
-
}): Promise<{
|
|
19
|
-
aigne: AIGNE;
|
|
10
|
+
interface LoadApplicationOptions {
|
|
11
|
+
packageName: string;
|
|
20
12
|
dir: string;
|
|
13
|
+
install?: boolean;
|
|
14
|
+
}
|
|
15
|
+
interface LoadApplicationResult {
|
|
16
|
+
aigne: LoadAIGNEInChildProcessResult;
|
|
21
17
|
version: string;
|
|
22
18
|
isCache?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare function loadApplication(options: LoadApplicationOptions & {
|
|
21
|
+
install: true;
|
|
22
|
+
}): Promise<LoadApplicationResult>;
|
|
23
|
+
export declare function loadApplication(options: LoadApplicationOptions & {
|
|
24
|
+
install?: false;
|
|
25
|
+
}): Promise<LoadApplicationResult | null>;
|
|
26
|
+
export declare function installApp({ dir, packageName, beta, version, }: {
|
|
27
|
+
dir: string;
|
|
28
|
+
packageName: string;
|
|
29
|
+
beta?: boolean;
|
|
30
|
+
version?: string;
|
|
31
|
+
}): Promise<{
|
|
32
|
+
url: string;
|
|
33
|
+
version: string;
|
|
23
34
|
}>;
|
|
24
|
-
export declare function getNpmTgzInfo(name: string
|
|
35
|
+
export declare function getNpmTgzInfo(name: string, { version, beta }?: {
|
|
36
|
+
version?: string;
|
|
37
|
+
beta?: boolean;
|
|
38
|
+
}): Promise<{
|
|
25
39
|
version: string;
|
|
26
|
-
url:
|
|
40
|
+
url: string;
|
|
27
41
|
}>;
|
|
42
|
+
export {};
|
package/dist/commands/app.js
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import assert from "node:assert";
|
|
2
1
|
import { spawn } from "node:child_process";
|
|
3
2
|
import { mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
|
|
4
3
|
import { homedir } from "node:os";
|
|
5
4
|
import { join } from "node:path";
|
|
6
5
|
import { logger } from "@aigne/core/utils/logger.js";
|
|
6
|
+
import { jsonSchemaToZod } from "@aigne/json-schema-to-zod";
|
|
7
7
|
import { Listr, PRESET_TIMER } from "@aigne/listr2";
|
|
8
8
|
import { joinURL } from "ufo";
|
|
9
9
|
import { downloadAndExtract } from "../utils/download.js";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { safeLoadAIGNE } from "../utils/workers/load-aigne.js";
|
|
13
|
-
import { parseAgentInput, withAgentInputSchema, } from "../utils/yargs.js";
|
|
10
|
+
import { runAIGNEInChildProcess, } from "../utils/workers/run-aigne-in-child-process.js";
|
|
11
|
+
import { withAgentInputSchema } from "../utils/yargs.js";
|
|
14
12
|
import { serveMCPServerFromDir } from "./serve-mcp.js";
|
|
15
13
|
const NPM_PACKAGE_CACHE_TIME_MS = 1000 * 60 * 60 * 24; // 1 day
|
|
16
14
|
/**
|
|
@@ -23,11 +21,13 @@ function shouldUseBetaApps() {
|
|
|
23
21
|
const builtinApps = [
|
|
24
22
|
{
|
|
25
23
|
name: "doc-smith",
|
|
24
|
+
packageName: "@aigne/doc-smith",
|
|
26
25
|
describe: "Generate and maintain project docs — powered by agents.",
|
|
27
26
|
aliases: ["docsmith", "doc"],
|
|
28
27
|
},
|
|
29
28
|
{
|
|
30
29
|
name: "web-smith",
|
|
30
|
+
packageName: "@aigne/web-smith",
|
|
31
31
|
describe: "Generate and maintain project website pages — powered by agents.",
|
|
32
32
|
aliases: ["websmith", "web"],
|
|
33
33
|
},
|
|
@@ -38,30 +38,28 @@ export function createAppCommands() {
|
|
|
38
38
|
describe: app.describe,
|
|
39
39
|
aliases: app.aliases,
|
|
40
40
|
builder: async (yargs) => {
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
});
|
|
44
|
-
yargs
|
|
45
|
-
.option("model", {
|
|
46
|
-
type: "string",
|
|
47
|
-
description: "Model to use for the application, example: openai:gpt-4.1 or google:gemini-2.5-flash",
|
|
48
|
-
})
|
|
49
|
-
.command(serveMcpCommandModule({ name: app.name, dir }))
|
|
50
|
-
.command(upgradeCommandModule({
|
|
51
|
-
name: app.name,
|
|
41
|
+
const dir = join(homedir(), ".aigne", "registry.npmjs.org", app.packageName);
|
|
42
|
+
const { aigne, version } = await loadApplication({
|
|
52
43
|
dir,
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
})
|
|
56
|
-
if (aigne.cli
|
|
44
|
+
packageName: app.packageName,
|
|
45
|
+
install: true,
|
|
46
|
+
});
|
|
47
|
+
if (aigne.cli?.chat) {
|
|
57
48
|
yargs.command({
|
|
58
49
|
...agentCommandModule({ dir, agent: aigne.cli.chat }),
|
|
59
50
|
command: "$0",
|
|
60
51
|
});
|
|
61
52
|
}
|
|
62
|
-
for (const agent of aigne.cli
|
|
53
|
+
for (const agent of aigne.cli?.agents ?? []) {
|
|
63
54
|
yargs.command(agentCommandModule({ dir, agent }));
|
|
64
55
|
}
|
|
56
|
+
yargs
|
|
57
|
+
.option("model", {
|
|
58
|
+
type: "string",
|
|
59
|
+
description: "Model to use for the application, example: openai:gpt-4.1 or google:gemini-2.5-flash",
|
|
60
|
+
})
|
|
61
|
+
.command(serveMcpCommandModule({ name: app.name, dir }))
|
|
62
|
+
.command(upgradeCommandModule({ packageName: app.packageName, dir }));
|
|
65
63
|
yargs.version(`${app.name} v${version}`).alias("version", "v");
|
|
66
64
|
return yargs.demandCommand();
|
|
67
65
|
},
|
|
@@ -92,18 +90,39 @@ const serveMcpCommandModule = ({ name, dir, }) => ({
|
|
|
92
90
|
await serveMCPServerFromDir({ ...options, dir });
|
|
93
91
|
},
|
|
94
92
|
});
|
|
95
|
-
const upgradeCommandModule = ({
|
|
93
|
+
const upgradeCommandModule = ({ packageName, dir, }) => ({
|
|
96
94
|
command: "upgrade",
|
|
97
|
-
describe: `Upgrade ${
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
95
|
+
describe: `Upgrade ${packageName} to the latest version`,
|
|
96
|
+
builder: (argv) => {
|
|
97
|
+
return argv
|
|
98
|
+
.option("beta", {
|
|
99
|
+
type: "boolean",
|
|
100
|
+
describe: "Use beta versions if available",
|
|
101
|
+
})
|
|
102
|
+
.option("target-version", {
|
|
103
|
+
type: "string",
|
|
104
|
+
describe: "Specify a version to upgrade to (default is latest)",
|
|
105
|
+
alias: ["to", "target"],
|
|
106
|
+
})
|
|
107
|
+
.option("force", {
|
|
108
|
+
type: "boolean",
|
|
109
|
+
describe: "Force upgrade even if already at latest version",
|
|
110
|
+
default: false,
|
|
111
|
+
});
|
|
112
|
+
},
|
|
113
|
+
handler: async ({ beta, targetVersion, force }) => {
|
|
114
|
+
beta ??= shouldUseBetaApps();
|
|
115
|
+
let app = await loadApplication({ packageName, dir });
|
|
116
|
+
const npm = await getNpmTgzInfo(packageName, { beta, version: targetVersion });
|
|
117
|
+
if (!app || force || npm.version !== app.version) {
|
|
118
|
+
if (force)
|
|
119
|
+
await rm(dir, { force: true, recursive: true });
|
|
120
|
+
await installApp({ packageName, dir, beta, version: targetVersion });
|
|
121
|
+
app = await loadApplication({ dir, packageName, install: true });
|
|
122
|
+
console.log(`\n✅ Upgraded ${packageName} to version ${app.version}`);
|
|
123
|
+
return;
|
|
105
124
|
}
|
|
106
|
-
console.log(`\n✅ ${
|
|
125
|
+
console.log(`\n✅ ${packageName} is already at the latest version (${app.version})`);
|
|
107
126
|
},
|
|
108
127
|
});
|
|
109
128
|
export const agentCommandModule = ({ dir, agent, }) => {
|
|
@@ -111,76 +130,76 @@ export const agentCommandModule = ({ dir, agent, }) => {
|
|
|
111
130
|
command: agent.name,
|
|
112
131
|
aliases: agent.alias || [],
|
|
113
132
|
describe: agent.description || "",
|
|
114
|
-
builder: async (yargs) =>
|
|
133
|
+
builder: async (yargs) => {
|
|
134
|
+
return withAgentInputSchema(yargs, { inputSchema: jsonSchemaToZod(agent.inputSchema) });
|
|
135
|
+
},
|
|
115
136
|
handler: async (options) => {
|
|
116
137
|
if (options.logLevel)
|
|
117
138
|
logger.level = options.logLevel;
|
|
118
|
-
await invokeCLIAgentFromDir
|
|
139
|
+
await runAIGNEInChildProcess("invokeCLIAgentFromDir", {
|
|
140
|
+
dir,
|
|
141
|
+
agent: agent.name,
|
|
142
|
+
input: options,
|
|
143
|
+
});
|
|
119
144
|
process.exit(0);
|
|
120
145
|
},
|
|
121
146
|
};
|
|
122
147
|
};
|
|
123
|
-
export async function
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const { chat } = aigne.cli;
|
|
130
|
-
const agent = chat && chat.name === options.agent
|
|
131
|
-
? chat
|
|
132
|
-
: aigne.cli.agents[options.agent] ||
|
|
133
|
-
aigne.agents[options.agent] ||
|
|
134
|
-
aigne.skills[options.agent] ||
|
|
135
|
-
aigne.mcpServer.agents[options.agent];
|
|
136
|
-
assert(agent, `Agent ${options.agent} not found in ${options.dir}`);
|
|
137
|
-
const input = await parseAgentInput(options.input, agent);
|
|
138
|
-
await runAgentWithAIGNE(aigne, agent, {
|
|
139
|
-
...options.input,
|
|
140
|
-
input,
|
|
141
|
-
chat: agent === chat || options.input.chat,
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
finally {
|
|
145
|
-
await aigne.shutdown();
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
export async function loadApplication({ name, dir, forceUpgrade = false, }) {
|
|
149
|
-
name = `@aigne/${name}`;
|
|
150
|
-
dir ??= join(homedir(), ".aigne", "registry.npmjs.org", name);
|
|
151
|
-
let check = forceUpgrade ? undefined : await isInstallationAvailable(dir);
|
|
152
|
-
if (check?.available) {
|
|
153
|
-
const aigne = await safeLoadAIGNE(dir).catch((error) => {
|
|
154
|
-
console.warn(`⚠️ Failed to load ${name}, trying to reinstall:`, error.message);
|
|
148
|
+
export async function loadApplication(options) {
|
|
149
|
+
const { dir, packageName } = options;
|
|
150
|
+
const check = await checkInstallation(dir);
|
|
151
|
+
if (check && !check.expired) {
|
|
152
|
+
const aigne = await runAIGNEInChildProcess("loadAIGNE", dir).catch((error) => {
|
|
153
|
+
console.warn(`⚠️ Failed to load ${packageName}, trying to reinstall:`, error.message);
|
|
155
154
|
});
|
|
156
155
|
if (aigne) {
|
|
157
|
-
return {
|
|
158
|
-
aigne,
|
|
159
|
-
dir,
|
|
160
|
-
version: check.version,
|
|
161
|
-
isCache: true,
|
|
162
|
-
};
|
|
156
|
+
return { aigne, version: check.version, isCache: true };
|
|
163
157
|
}
|
|
164
|
-
check = undefined;
|
|
165
158
|
}
|
|
166
|
-
|
|
159
|
+
if (!options.install)
|
|
160
|
+
return null;
|
|
161
|
+
const result = await installApp({ dir, packageName, beta: check?.version?.includes("beta") });
|
|
162
|
+
return {
|
|
163
|
+
aigne: await runAIGNEInChildProcess("loadAIGNE", dir),
|
|
164
|
+
version: result.version,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
async function readInstallationMetadata(dir) {
|
|
168
|
+
return safeParseJSON(await readFile(join(dir, ".aigne-cli.json"), "utf-8").catch(() => "{}"));
|
|
169
|
+
}
|
|
170
|
+
async function writeInstallationMetadata(dir, metadata) {
|
|
171
|
+
await writeFile(join(dir, ".aigne-cli.json"), JSON.stringify(metadata, null, 2));
|
|
172
|
+
}
|
|
173
|
+
async function checkInstallation(dir, { cacheTimeMs = NPM_PACKAGE_CACHE_TIME_MS } = {}) {
|
|
174
|
+
const s = await stat(join(dir, "package.json")).catch(() => null);
|
|
175
|
+
if (!s)
|
|
176
|
+
return null;
|
|
177
|
+
const version = safeParseJSON(await readFile(join(dir, "package.json"), "utf-8"))?.version;
|
|
178
|
+
if (!version)
|
|
179
|
+
return null;
|
|
180
|
+
const installedAt = (await readInstallationMetadata(dir))?.installedAt;
|
|
181
|
+
if (!installedAt)
|
|
182
|
+
return null;
|
|
183
|
+
const now = Date.now();
|
|
184
|
+
const expired = now - installedAt > cacheTimeMs;
|
|
185
|
+
return { version, expired };
|
|
186
|
+
}
|
|
187
|
+
export async function installApp({ dir, packageName, beta, version, }) {
|
|
188
|
+
return await new Listr([
|
|
167
189
|
{
|
|
168
|
-
title: `Fetching ${
|
|
190
|
+
title: `Fetching ${packageName} metadata`,
|
|
169
191
|
task: async (ctx, task) => {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
const useBeta = shouldUseBetaApps();
|
|
173
|
-
if (useBeta && ctx.version.includes("beta")) {
|
|
174
|
-
task.title = `Fetching ${name} metadata (using beta version)`;
|
|
192
|
+
if (beta) {
|
|
193
|
+
task.title = `Fetching ${packageName} metadata (using beta version)`;
|
|
175
194
|
}
|
|
195
|
+
const info = await getNpmTgzInfo(packageName, { beta, version });
|
|
196
|
+
Object.assign(ctx, info);
|
|
176
197
|
},
|
|
177
198
|
},
|
|
178
199
|
{
|
|
179
|
-
title: `Downloading ${
|
|
180
|
-
skip: (ctx) => ctx.version === check?.version,
|
|
200
|
+
title: `Downloading ${packageName}`,
|
|
181
201
|
task: async (ctx, task) => {
|
|
182
|
-
task.title = `Downloading ${
|
|
183
|
-
await rm(dir, { force: true, recursive: true });
|
|
202
|
+
task.title = `Downloading ${packageName} (v${ctx.version})`;
|
|
184
203
|
await mkdir(dir, { recursive: true });
|
|
185
204
|
await downloadAndExtract(ctx.url, dir, { strip: 1 });
|
|
186
205
|
},
|
|
@@ -195,6 +214,7 @@ export async function loadApplication({ name, dir, forceUpgrade = false, }) {
|
|
|
195
214
|
task.output = last;
|
|
196
215
|
},
|
|
197
216
|
});
|
|
217
|
+
await writeInstallationMetadata(dir, { installedAt: Date.now() });
|
|
198
218
|
},
|
|
199
219
|
},
|
|
200
220
|
], {
|
|
@@ -204,25 +224,6 @@ export async function loadApplication({ name, dir, forceUpgrade = false, }) {
|
|
|
204
224
|
timer: PRESET_TIMER,
|
|
205
225
|
},
|
|
206
226
|
}).run();
|
|
207
|
-
return {
|
|
208
|
-
aigne: await safeLoadAIGNE(dir),
|
|
209
|
-
dir,
|
|
210
|
-
version: result.version,
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
async function isInstallationAvailable(dir, { cacheTimeMs = NPM_PACKAGE_CACHE_TIME_MS } = {}) {
|
|
214
|
-
const s = await stat(join(dir, "package.json")).catch(() => null);
|
|
215
|
-
if (!s)
|
|
216
|
-
return null;
|
|
217
|
-
const version = safeParseJSON(await readFile(join(dir, "package.json"), "utf-8"))?.version;
|
|
218
|
-
if (!version)
|
|
219
|
-
return null;
|
|
220
|
-
const installedAt = safeParseJSON(await readFile(join(dir, ".aigne-cli.json"), "utf-8").catch(() => "{}"))?.installedAt;
|
|
221
|
-
if (!installedAt)
|
|
222
|
-
return null;
|
|
223
|
-
const now = Date.now();
|
|
224
|
-
const available = installedAt ? now - installedAt < cacheTimeMs : false;
|
|
225
|
-
return { version, available };
|
|
226
227
|
}
|
|
227
228
|
async function installDependencies(dir, { log } = {}) {
|
|
228
229
|
await new Promise((resolve, reject) => {
|
|
@@ -250,16 +251,20 @@ async function installDependencies(dir, { log } = {}) {
|
|
|
250
251
|
}
|
|
251
252
|
});
|
|
252
253
|
});
|
|
253
|
-
await writeFile(join(dir, ".aigne-cli.json"), JSON.stringify({ installedAt: Date.now() }, null, 2));
|
|
254
254
|
}
|
|
255
|
-
export async function getNpmTgzInfo(name) {
|
|
255
|
+
export async function getNpmTgzInfo(name, { version, beta } = {}) {
|
|
256
256
|
const res = await fetch(joinURL("https://registry.npmjs.org", name));
|
|
257
257
|
if (!res.ok)
|
|
258
258
|
throw new Error(`Failed to fetch package info for ${name}: ${res.statusText}`);
|
|
259
259
|
const data = await res.json();
|
|
260
|
-
const useBeta = shouldUseBetaApps();
|
|
261
260
|
let targetVersion;
|
|
262
|
-
if (
|
|
261
|
+
if (version) {
|
|
262
|
+
if (!data.versions[version]) {
|
|
263
|
+
throw new Error(`Version ${version} of package ${name} not found`);
|
|
264
|
+
}
|
|
265
|
+
targetVersion = version;
|
|
266
|
+
}
|
|
267
|
+
else if (beta && data["dist-tags"].beta) {
|
|
263
268
|
// Use beta version if available and beta flag is set
|
|
264
269
|
targetVersion = data["dist-tags"].beta;
|
|
265
270
|
}
|
|
@@ -21,6 +21,33 @@ const chars = {
|
|
|
21
21
|
"right-mid": borderColor("┤"),
|
|
22
22
|
middle: borderColor("│"),
|
|
23
23
|
};
|
|
24
|
+
const MAX_CELL_LENGTH = 300;
|
|
25
|
+
function renderPagedTable(list, { maxCols = 6, chars }) {
|
|
26
|
+
if (!list.length)
|
|
27
|
+
return [];
|
|
28
|
+
const tables = [];
|
|
29
|
+
const head = list[0]?.map((h) => h.header) ?? [];
|
|
30
|
+
const widths = list[0]?.map((h) => h.width ?? 20) ?? [];
|
|
31
|
+
for (let i = 0; i < head.length; i += maxCols) {
|
|
32
|
+
const subHead = head.slice(i, i + maxCols);
|
|
33
|
+
const subWidths = widths.slice(i, i + maxCols);
|
|
34
|
+
const table = new Table({
|
|
35
|
+
head: subHead,
|
|
36
|
+
colWidths: subWidths,
|
|
37
|
+
wordWrap: true,
|
|
38
|
+
chars,
|
|
39
|
+
});
|
|
40
|
+
for (const row of list) {
|
|
41
|
+
table.push(row
|
|
42
|
+
.slice(i, i + maxCols)
|
|
43
|
+
.map((h) => String(h.value).length > MAX_CELL_LENGTH
|
|
44
|
+
? `${String(h.value).slice(0, MAX_CELL_LENGTH)}...`
|
|
45
|
+
: h.value));
|
|
46
|
+
}
|
|
47
|
+
tables.push(table.toString());
|
|
48
|
+
}
|
|
49
|
+
return tables;
|
|
50
|
+
}
|
|
24
51
|
export class BaseReporter {
|
|
25
52
|
name = "base";
|
|
26
53
|
async report(_report) {
|
|
@@ -43,7 +70,6 @@ export class BaseReporter {
|
|
|
43
70
|
width: 40,
|
|
44
71
|
value: r.expected ? JSON.stringify(r.expected) : "-",
|
|
45
72
|
},
|
|
46
|
-
{ header: "Error", key: "Error", width: 20, value: r.error ?? "-" },
|
|
47
73
|
{
|
|
48
74
|
header: "Evaluations",
|
|
49
75
|
key: "Evaluations",
|
|
@@ -56,6 +82,7 @@ export class BaseReporter {
|
|
|
56
82
|
width: 20,
|
|
57
83
|
value: r.evaluations.map((e) => `${e.rating}`).join(", "),
|
|
58
84
|
},
|
|
85
|
+
{ header: "Error", key: "Error", width: 20, value: r.error ?? "-" },
|
|
59
86
|
{
|
|
60
87
|
header: "Reason",
|
|
61
88
|
key: "Reason",
|
|
@@ -140,18 +167,10 @@ export class ConsoleReporter extends BaseReporter {
|
|
|
140
167
|
if (!list.length)
|
|
141
168
|
return;
|
|
142
169
|
console.log("\n=== 📋 Detailed Results ===");
|
|
143
|
-
const
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
head,
|
|
147
|
-
colWidths,
|
|
148
|
-
wordWrap: true,
|
|
149
|
-
chars,
|
|
150
|
-
});
|
|
151
|
-
for (const r of list) {
|
|
152
|
-
detailTable.push(r.map((h) => h.value));
|
|
170
|
+
const pages = renderPagedTable(list, { maxCols: 5, chars });
|
|
171
|
+
for (const page of pages) {
|
|
172
|
+
console.log(page);
|
|
153
173
|
}
|
|
154
|
-
console.log(detailTable.toString());
|
|
155
174
|
const failed = report.results.filter((r) => r.error);
|
|
156
175
|
if (failed.length) {
|
|
157
176
|
console.log(chalk.red("\n=== ❌ Failed Cases ==="));
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type Agent, AIGNE, type Message } from "@aigne/core";
|
|
2
|
+
import { type AgentRunCommonOptions } from "../yargs.js";
|
|
3
|
+
export interface AgentInChildProcess extends Pick<Agent, "name" | "description" | "alias"> {
|
|
4
|
+
inputSchema: object;
|
|
5
|
+
outputSchema: object;
|
|
6
|
+
}
|
|
7
|
+
export declare function loadAIGNEInChildProcess(...args: Parameters<typeof AIGNE.load>): Promise<{
|
|
8
|
+
agents?: AgentInChildProcess[];
|
|
9
|
+
cli?: {
|
|
10
|
+
chat?: AgentInChildProcess;
|
|
11
|
+
agents?: AgentInChildProcess[];
|
|
12
|
+
};
|
|
13
|
+
mcpServer?: {
|
|
14
|
+
agents?: AgentInChildProcess[];
|
|
15
|
+
};
|
|
16
|
+
}>;
|
|
17
|
+
export declare function invokeCLIAgentFromDirInChildProcess(options: {
|
|
18
|
+
dir: string;
|
|
19
|
+
agent: string;
|
|
20
|
+
input: Message & AgentRunCommonOptions;
|
|
21
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
2
|
+
import { AIGNE } from "@aigne/core";
|
|
3
|
+
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
4
|
+
import { loadAIGNE } from "../load-aigne.js";
|
|
5
|
+
import { runAgentWithAIGNE } from "../run-with-aigne.js";
|
|
6
|
+
import { parseAgentInput } from "../yargs.js";
|
|
7
|
+
const METHODS = {
|
|
8
|
+
loadAIGNE: loadAIGNEInChildProcess,
|
|
9
|
+
invokeCLIAgentFromDir: invokeCLIAgentFromDirInChildProcess,
|
|
10
|
+
};
|
|
11
|
+
process.on("message", async ({ method, args }) => {
|
|
12
|
+
const send = (message) => new Promise((resolve, reject) => {
|
|
13
|
+
assert(process.send);
|
|
14
|
+
process.send(message, undefined, undefined, (error) => {
|
|
15
|
+
if (error)
|
|
16
|
+
reject(error);
|
|
17
|
+
else
|
|
18
|
+
resolve(true);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
try {
|
|
22
|
+
const handler = METHODS[method];
|
|
23
|
+
if (!handler)
|
|
24
|
+
throw new Error(`Unknown method: ${method}`);
|
|
25
|
+
const result = await handler(...args);
|
|
26
|
+
await send({ method, result });
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
await send({ method, error: { message: error.message } });
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
process.exit(0);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
function serializeAgent(agent) {
|
|
36
|
+
return {
|
|
37
|
+
name: agent.name,
|
|
38
|
+
description: agent.description,
|
|
39
|
+
alias: agent.alias,
|
|
40
|
+
inputSchema: zodToJsonSchema(agent.inputSchema),
|
|
41
|
+
outputSchema: zodToJsonSchema(agent.outputSchema),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export async function loadAIGNEInChildProcess(...args) {
|
|
45
|
+
const aigne = await AIGNE.load(...args);
|
|
46
|
+
return {
|
|
47
|
+
agents: aigne.agents.map(serializeAgent),
|
|
48
|
+
cli: {
|
|
49
|
+
chat: aigne.cli.chat ? serializeAgent(aigne.cli.chat) : undefined,
|
|
50
|
+
agents: aigne.cli.agents.map(serializeAgent),
|
|
51
|
+
},
|
|
52
|
+
mcpServer: {
|
|
53
|
+
agents: aigne.mcpServer.agents.map(serializeAgent),
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export async function invokeCLIAgentFromDirInChildProcess(options) {
|
|
58
|
+
const aigne = await loadAIGNE({
|
|
59
|
+
path: options.dir,
|
|
60
|
+
modelOptions: options.input,
|
|
61
|
+
});
|
|
62
|
+
try {
|
|
63
|
+
const { chat } = aigne.cli;
|
|
64
|
+
const agent = chat && chat.name === options.agent
|
|
65
|
+
? chat
|
|
66
|
+
: aigne.cli.agents[options.agent] ||
|
|
67
|
+
aigne.agents[options.agent] ||
|
|
68
|
+
aigne.skills[options.agent] ||
|
|
69
|
+
aigne.mcpServer.agents[options.agent];
|
|
70
|
+
assert(agent, `Agent ${options.agent} not found in ${options.dir}`);
|
|
71
|
+
const input = await parseAgentInput(options.input, agent);
|
|
72
|
+
await runAgentWithAIGNE(aigne, agent, {
|
|
73
|
+
...options.input,
|
|
74
|
+
input,
|
|
75
|
+
chat: agent === chat || options.input.chat,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
await aigne.shutdown();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { invokeCLIAgentFromDirInChildProcess, loadAIGNEInChildProcess } from "./run-aigne-in-child-process-worker.js";
|
|
2
|
+
export type LoadAIGNEInChildProcessResult = Awaited<ReturnType<typeof loadAIGNEInChildProcess>>;
|
|
3
|
+
export interface ChildProcessAIGNEMethods {
|
|
4
|
+
loadAIGNE: typeof loadAIGNEInChildProcess;
|
|
5
|
+
invokeCLIAgentFromDir: typeof invokeCLIAgentFromDirInChildProcess;
|
|
6
|
+
}
|
|
7
|
+
export declare function runAIGNEInChildProcess<M extends keyof ChildProcessAIGNEMethods>(method: M, ...args: Parameters<ChildProcessAIGNEMethods[M]>): Promise<ReturnType<ChildProcessAIGNEMethods[M]>>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { fork } from "node:child_process";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
export async function runAIGNEInChildProcess(method, ...args) {
|
|
5
|
+
return await new Promise((resolve, reject) => {
|
|
6
|
+
const child = fork(join(dirname(fileURLToPath(import.meta.url)), "./run-aigne-in-child-process-worker.js"));
|
|
7
|
+
child.on("message", (event) => {
|
|
8
|
+
if (event.method !== method)
|
|
9
|
+
reject(new Error(`Unknown method: ${event.method} expected: ${method}`));
|
|
10
|
+
else if (event.error)
|
|
11
|
+
reject(new Error(`Failed to execute ${method}: ${event.error.message}`));
|
|
12
|
+
else
|
|
13
|
+
resolve(event.result);
|
|
14
|
+
});
|
|
15
|
+
child.on("exit", (code) => {
|
|
16
|
+
reject(new Error(`Child process exited with code ${code}`));
|
|
17
|
+
});
|
|
18
|
+
child.send({ method, args });
|
|
19
|
+
});
|
|
20
|
+
}
|
package/dist/utils/yargs.d.ts
CHANGED
|
@@ -50,7 +50,7 @@ export declare function inferZodType(type: ZodType, opts?: {
|
|
|
50
50
|
array?: boolean;
|
|
51
51
|
optional?: boolean;
|
|
52
52
|
};
|
|
53
|
-
export declare function withAgentInputSchema(yargs: Argv, agent: Agent): Argv<{
|
|
53
|
+
export declare function withAgentInputSchema(yargs: Argv, agent: Pick<Agent, "inputSchema">): Argv<{
|
|
54
54
|
chat: boolean;
|
|
55
55
|
} & {
|
|
56
56
|
model: string | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/cli",
|
|
3
|
-
"version": "1.49.0-beta.
|
|
3
|
+
"version": "1.49.0-beta.9",
|
|
4
4
|
"description": "Your command center for agent development",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
+
"@aigne/json-schema-to-zod": "^1.3.3",
|
|
48
49
|
"@aigne/listr2": "^1.0.10",
|
|
49
50
|
"@aigne/marked-terminal": "^7.3.2",
|
|
50
51
|
"@fast-csv/format": "^5.0.5",
|
|
@@ -82,13 +83,14 @@
|
|
|
82
83
|
"yargs": "^18.0.0",
|
|
83
84
|
"yoctocolors-cjs": "^2.1.3",
|
|
84
85
|
"zod": "^3.25.67",
|
|
85
|
-
"
|
|
86
|
-
"@aigne/
|
|
87
|
-
"@aigne/core": "^1.61.0-beta.
|
|
88
|
-
"@aigne/aigne-hub": "^0.10.0-beta.
|
|
89
|
-
"@aigne/
|
|
90
|
-
"@aigne/
|
|
91
|
-
"@aigne/
|
|
86
|
+
"zod-to-json-schema": "^3.24.6",
|
|
87
|
+
"@aigne/agent-library": "^1.21.46-beta.9",
|
|
88
|
+
"@aigne/core": "^1.61.0-beta.8",
|
|
89
|
+
"@aigne/aigne-hub": "^0.10.0-beta.9",
|
|
90
|
+
"@aigne/agentic-memory": "^1.0.46-beta.9",
|
|
91
|
+
"@aigne/default-memory": "^1.2.9-beta.9",
|
|
92
|
+
"@aigne/observability-api": "^0.11.0-beta.1",
|
|
93
|
+
"@aigne/openai": "^0.16.0-beta.9"
|
|
92
94
|
},
|
|
93
95
|
"devDependencies": {
|
|
94
96
|
"@inquirer/testing": "^2.1.50",
|
|
@@ -105,7 +107,7 @@
|
|
|
105
107
|
"rimraf": "^6.0.1",
|
|
106
108
|
"typescript": "^5.9.2",
|
|
107
109
|
"ufo": "^1.6.1",
|
|
108
|
-
"@aigne/test-utils": "^0.5.53-beta.
|
|
110
|
+
"@aigne/test-utils": "^0.5.53-beta.8"
|
|
109
111
|
},
|
|
110
112
|
"scripts": {
|
|
111
113
|
"lint": "tsc --noEmit",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { AIGNE } from "@aigne/core";
|
|
2
|
-
process.on("message", async ({ method, args }) => {
|
|
3
|
-
try {
|
|
4
|
-
if (method !== "AIGNE.load")
|
|
5
|
-
throw new Error(`Unknown method: ${method}`);
|
|
6
|
-
await AIGNE.load(...args);
|
|
7
|
-
process.send?.({ method, status: "success" });
|
|
8
|
-
}
|
|
9
|
-
catch (error) {
|
|
10
|
-
process.send?.({ method, status: "error", message: error.message });
|
|
11
|
-
}
|
|
12
|
-
process.exit(0);
|
|
13
|
-
});
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { fork } from "node:child_process";
|
|
2
|
-
import { dirname, join } from "node:path";
|
|
3
|
-
import { fileURLToPath } from "node:url";
|
|
4
|
-
import { AIGNE } from "@aigne/core";
|
|
5
|
-
export async function safeLoadAIGNE(...args) {
|
|
6
|
-
await new Promise((resolve, reject) => {
|
|
7
|
-
const child = fork(join(dirname(fileURLToPath(import.meta.url)), "./load-aigne-worker.js"), {
|
|
8
|
-
timeout: 600e3,
|
|
9
|
-
});
|
|
10
|
-
child.on("message", ({ method, message, status }) => {
|
|
11
|
-
if (method !== "AIGNE.load")
|
|
12
|
-
reject(new Error(`Unknown method: ${method}`));
|
|
13
|
-
else if (status === "error")
|
|
14
|
-
reject(new Error(`Failed to load AIGNE: ${message}`));
|
|
15
|
-
else if (status === "success")
|
|
16
|
-
resolve();
|
|
17
|
-
});
|
|
18
|
-
child.on("exit", (code) => {
|
|
19
|
-
if (code !== 0)
|
|
20
|
-
reject(new Error(`Child process exited with code ${code}`));
|
|
21
|
-
else
|
|
22
|
-
resolve();
|
|
23
|
-
});
|
|
24
|
-
child.send({ method: "AIGNE.load", args });
|
|
25
|
-
});
|
|
26
|
-
return AIGNE.load(...args);
|
|
27
|
-
}
|