@aigne/cli 1.27.1-0 → 1.27.1-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.
- package/dist/cli.d.ts +6 -1
- package/dist/cli.js +1 -1
- package/dist/commands/app.js +169 -64
- package/dist/commands/connect.d.ts +1 -1
- package/dist/commands/create.d.ts +1 -1
- package/dist/commands/observe.d.ts +1 -1
- package/dist/commands/serve-mcp.d.ts +1 -1
- package/dist/commands/test.d.ts +1 -1
- package/dist/utils/run-with-aigne.d.ts +1 -0
- package/dist/utils/run-with-aigne.js +4 -3
- package/package.json +6 -6
package/dist/cli.d.ts
CHANGED
package/dist/cli.js
CHANGED
|
@@ -16,7 +16,7 @@ function getAIGNEFilePath() {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
const aigneFilePath = getAIGNEFilePath();
|
|
19
|
-
createAIGNECommand({ aigneFilePath })
|
|
19
|
+
export default createAIGNECommand({ aigneFilePath })
|
|
20
20
|
.parseAsync(hideBin([...process.argv.slice(0, 2), ...process.argv.slice(aigneFilePath ? 3 : 2)]))
|
|
21
21
|
.catch((error) => {
|
|
22
22
|
console.log(""); // Add an empty line for better readability
|
package/dist/commands/app.js
CHANGED
|
@@ -1,66 +1,153 @@
|
|
|
1
1
|
import assert from "node:assert";
|
|
2
2
|
import { spawnSync } from "node:child_process";
|
|
3
|
-
import { mkdir, readFile, stat } from "node:fs/promises";
|
|
3
|
+
import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
|
-
import { join } from "node:path";
|
|
6
|
-
import {
|
|
5
|
+
import { extname, join } from "node:path";
|
|
6
|
+
import { isatty } from "node:tty";
|
|
7
|
+
import { AIAgent, AIGNE, readAllString } from "@aigne/core";
|
|
8
|
+
import { pick } from "@aigne/core/utils/type-utils.js";
|
|
9
|
+
import { Listr, PRESET_TIMER } from "@aigne/listr2";
|
|
7
10
|
import { joinURL } from "ufo";
|
|
8
|
-
import {
|
|
11
|
+
import { parse } from "yaml";
|
|
12
|
+
import { ZodObject } from "zod";
|
|
9
13
|
import { availableModels } from "../constants.js";
|
|
10
14
|
import { downloadAndExtract } from "../utils/download.js";
|
|
11
|
-
import {
|
|
15
|
+
import { loadAIGNE } from "../utils/load-aigne.js";
|
|
16
|
+
import { runAgentWithAIGNE, stdinHasData } from "../utils/run-with-aigne.js";
|
|
12
17
|
const NPM_PACKAGE_CACHE_TIME_MS = 1000 * 60 * 60 * 24; // 1 day
|
|
18
|
+
const builtinApps = [
|
|
19
|
+
{
|
|
20
|
+
name: "doc-smith",
|
|
21
|
+
describe: "Generate professional documents by doc-smith",
|
|
22
|
+
aliases: ["docsmith", "doc"],
|
|
23
|
+
},
|
|
24
|
+
];
|
|
13
25
|
export function createAppCommands() {
|
|
14
|
-
return
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
yargs.demandOption(option);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}, async (argv) => {
|
|
35
|
-
try {
|
|
36
|
-
await runAgentWithAIGNE(aigne, agent, { input: argv });
|
|
37
|
-
}
|
|
38
|
-
finally {
|
|
39
|
-
await aigne.shutdown();
|
|
26
|
+
return builtinApps.map((app) => ({
|
|
27
|
+
command: app.name,
|
|
28
|
+
describe: app.describe,
|
|
29
|
+
aliases: app.aliases,
|
|
30
|
+
builder: async (yargs) => {
|
|
31
|
+
const { aigne, dir, version } = await loadApplication({ name: "doc-smith" });
|
|
32
|
+
for (const agent of aigne.agents) {
|
|
33
|
+
const inputSchema = Object.entries(agent.inputSchema instanceof ZodObject ? agent.inputSchema.shape : {});
|
|
34
|
+
yargs.command(agent.name, agent.description || "", (yargs) => {
|
|
35
|
+
for (const [option, config] of inputSchema) {
|
|
36
|
+
yargs.option(option, {
|
|
37
|
+
// TODO: support more types
|
|
38
|
+
type: "string",
|
|
39
|
+
description: config.description,
|
|
40
|
+
});
|
|
41
|
+
if (!(config.isNullable() || config.isOptional())) {
|
|
42
|
+
yargs.demandOption(option);
|
|
40
43
|
}
|
|
44
|
+
}
|
|
45
|
+
yargs
|
|
46
|
+
.option("input", {
|
|
47
|
+
type: "array",
|
|
48
|
+
description: "Input to the agent, use @<file> to read from a file",
|
|
49
|
+
alias: ["i"],
|
|
50
|
+
})
|
|
51
|
+
.option("format", {
|
|
52
|
+
type: "string",
|
|
53
|
+
description: 'Input format, can be "json" or "yaml"',
|
|
54
|
+
choices: ["json", "yaml"],
|
|
41
55
|
});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
56
|
+
}, async (argv) => {
|
|
57
|
+
try {
|
|
58
|
+
const aigne = await loadAIGNE(dir);
|
|
59
|
+
const _agent = aigne.agents[agent.name];
|
|
60
|
+
assert(_agent, `Agent ${agent.name} not found in ${app.name}`);
|
|
61
|
+
const input = pick(argv, inputSchema.map(([key]) => key));
|
|
62
|
+
const rawInput = argv.input ||
|
|
63
|
+
(isatty(process.stdin.fd) || !(await stdinHasData())
|
|
64
|
+
? null
|
|
65
|
+
: [await readAllString(process.stdin)].filter(Boolean));
|
|
66
|
+
if (rawInput) {
|
|
67
|
+
for (let raw of rawInput) {
|
|
68
|
+
let format = argv.format;
|
|
69
|
+
if (raw.startsWith("@")) {
|
|
70
|
+
raw = await readFile(raw.slice(1), "utf8");
|
|
71
|
+
if (!format) {
|
|
72
|
+
const ext = extname(raw);
|
|
73
|
+
if (ext === ".json")
|
|
74
|
+
format = "json";
|
|
75
|
+
else if (ext === ".yaml" || ext === ".yml")
|
|
76
|
+
format = "yaml";
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const inputKey = agent instanceof AIAgent ? agent.inputKey : undefined;
|
|
80
|
+
if (format === "json") {
|
|
81
|
+
Object.assign(input, JSON.parse(raw));
|
|
82
|
+
}
|
|
83
|
+
else if (format === "yaml") {
|
|
84
|
+
Object.assign(input, parse(raw));
|
|
85
|
+
}
|
|
86
|
+
else if (inputKey) {
|
|
87
|
+
Object.assign(input, { [inputKey]: raw });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
await runAgentWithAIGNE(aigne, _agent, { input });
|
|
92
|
+
}
|
|
93
|
+
finally {
|
|
94
|
+
await aigne.shutdown();
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
yargs.version(`${app.name} v${version}`);
|
|
99
|
+
return yargs.demandCommand();
|
|
47
100
|
},
|
|
48
|
-
|
|
101
|
+
handler: () => { },
|
|
102
|
+
}));
|
|
49
103
|
}
|
|
50
|
-
async function loadApplication({ name }) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
104
|
+
async function loadApplication({ name, }) {
|
|
105
|
+
name = `@aigne/${name}`;
|
|
106
|
+
const dir = join(homedir(), ".aigne", "registry.npmjs.org", name);
|
|
107
|
+
const check = await isInstallationAvailable(dir);
|
|
108
|
+
if (check?.available) {
|
|
109
|
+
return {
|
|
110
|
+
aigne: await AIGNE.load(dir, { models: availableModels() }),
|
|
111
|
+
dir,
|
|
112
|
+
version: check.version,
|
|
113
|
+
};
|
|
58
114
|
}
|
|
59
|
-
|
|
115
|
+
const result = await new Listr([
|
|
116
|
+
{
|
|
117
|
+
title: "Fetching application metadata",
|
|
118
|
+
task: async (ctx) => {
|
|
119
|
+
const info = await getNpmTgzInfo(name);
|
|
120
|
+
Object.assign(ctx, info);
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
title: "Downloading application",
|
|
125
|
+
skip: (ctx) => ctx.version === check?.version,
|
|
126
|
+
task: async (ctx) => {
|
|
127
|
+
await downloadApplication({ url: ctx.url, dir });
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
title: "Installing dependencies",
|
|
132
|
+
skip: (ctx) => ctx.version === check?.version,
|
|
133
|
+
task: async () => {
|
|
134
|
+
await installDependencies(dir);
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
], {
|
|
138
|
+
rendererOptions: {
|
|
139
|
+
collapseSubtasks: false,
|
|
140
|
+
showErrorMessage: false,
|
|
141
|
+
timer: PRESET_TIMER,
|
|
142
|
+
},
|
|
143
|
+
}).run();
|
|
144
|
+
return {
|
|
145
|
+
aigne: await AIGNE.load(dir, { models: availableModels() }),
|
|
146
|
+
dir,
|
|
147
|
+
version: result.version,
|
|
148
|
+
};
|
|
60
149
|
}
|
|
61
|
-
async function
|
|
62
|
-
const nameWithOrg = `@aigne/${name}`;
|
|
63
|
-
const dir = join(homedir(), ".aigne", "registry.npmjs.org", nameWithOrg);
|
|
150
|
+
async function isInstallationAvailable(dir, { cacheTimeMs = NPM_PACKAGE_CACHE_TIME_MS } = {}) {
|
|
64
151
|
const s = await stat(join(dir, "package.json")).catch((error) => {
|
|
65
152
|
if (error.code === "ENOENT") {
|
|
66
153
|
return null;
|
|
@@ -68,21 +155,31 @@ async function shouldDownloadNewVersion(name, { cacheTimeMs = NPM_PACKAGE_CACHE_
|
|
|
68
155
|
throw error;
|
|
69
156
|
});
|
|
70
157
|
if (!s)
|
|
71
|
-
return
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
158
|
+
return null;
|
|
159
|
+
const version = safeParseJSON(await readFile(join(dir, "package.json"), "utf-8"))?.version;
|
|
160
|
+
if (!version)
|
|
161
|
+
return null;
|
|
162
|
+
const installedAt = safeParseJSON(await readFile(join(dir, ".aigne-cli.json"), "utf-8").catch(() => "{}"))?.installedAt;
|
|
163
|
+
if (!installedAt)
|
|
164
|
+
return null;
|
|
77
165
|
const now = Date.now();
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
166
|
+
const available = installedAt ? now - installedAt < cacheTimeMs : false;
|
|
167
|
+
return { version, available };
|
|
168
|
+
}
|
|
169
|
+
async function downloadApplication({ url, dir }) {
|
|
170
|
+
await mkdir(dir, { recursive: true });
|
|
171
|
+
await downloadAndExtract(url, dir, { strip: 1 });
|
|
172
|
+
}
|
|
173
|
+
async function installDependencies(dir) {
|
|
174
|
+
const { stderr, status } = spawnSync("npm", ["install", "--omit", "dev"], {
|
|
175
|
+
cwd: dir,
|
|
176
|
+
stdio: "pipe",
|
|
177
|
+
});
|
|
178
|
+
if (status !== 0) {
|
|
179
|
+
console.error(stderr.toString());
|
|
180
|
+
throw new Error(`Failed to install dependencies in ${dir}`);
|
|
84
181
|
}
|
|
85
|
-
|
|
182
|
+
await writeFile(join(dir, ".aigne-cli.json"), JSON.stringify({ installedAt: Date.now() }, null, 2));
|
|
86
183
|
}
|
|
87
184
|
async function getNpmTgzInfo(name) {
|
|
88
185
|
const res = await fetch(joinURL("https://registry.npmjs.org", name));
|
|
@@ -90,9 +187,17 @@ async function getNpmTgzInfo(name) {
|
|
|
90
187
|
throw new Error(`Failed to fetch package info for ${name}: ${res.statusText}`);
|
|
91
188
|
const data = await res.json();
|
|
92
189
|
const latestVersion = data["dist-tags"].latest;
|
|
93
|
-
const
|
|
190
|
+
const url = data.versions[latestVersion].dist.tarball;
|
|
94
191
|
return {
|
|
95
192
|
version: latestVersion,
|
|
96
|
-
|
|
193
|
+
url,
|
|
97
194
|
};
|
|
98
195
|
}
|
|
196
|
+
function safeParseJSON(raw) {
|
|
197
|
+
try {
|
|
198
|
+
return JSON.parse(raw);
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
@@ -2,5 +2,5 @@ import type { CommandModule } from "yargs";
|
|
|
2
2
|
interface ConnectOptions {
|
|
3
3
|
url?: string;
|
|
4
4
|
}
|
|
5
|
-
export declare function createConnectCommand(): CommandModule<
|
|
5
|
+
export declare function createConnectCommand(): CommandModule<unknown, ConnectOptions>;
|
|
6
6
|
export {};
|
|
@@ -2,5 +2,5 @@ import type { CommandModule } from "yargs";
|
|
|
2
2
|
interface CreateOptions {
|
|
3
3
|
path: string;
|
|
4
4
|
}
|
|
5
|
-
export declare function createCreateCommand(): CommandModule<
|
|
5
|
+
export declare function createCreateCommand(): CommandModule<unknown, CreateOptions>;
|
|
6
6
|
export {};
|
package/dist/commands/test.d.ts
CHANGED
|
@@ -7,10 +7,11 @@ import { exists } from "@aigne/agent-library/utils/fs.js";
|
|
|
7
7
|
import { AIAgent, AIGNE, DEFAULT_OUTPUT_KEY, readAllString, UserAgent, } from "@aigne/core";
|
|
8
8
|
import { loadModel } from "@aigne/core/loader/index.js";
|
|
9
9
|
import { getLevelFromEnv, LogLevel, logger } from "@aigne/core/utils/logger.js";
|
|
10
|
-
import { flat, isEmpty, tryOrThrow
|
|
10
|
+
import { flat, isEmpty, tryOrThrow } from "@aigne/core/utils/type-utils.js";
|
|
11
11
|
import chalk from "chalk";
|
|
12
12
|
import { parse } from "yaml";
|
|
13
13
|
import yargs from "yargs";
|
|
14
|
+
import { hideBin } from "yargs/helpers";
|
|
14
15
|
import { ZodError, ZodObject, z } from "zod";
|
|
15
16
|
import { availableModels } from "../constants.js";
|
|
16
17
|
import { TerminalTracer } from "../tracer/terminal.js";
|
|
@@ -157,7 +158,7 @@ export async function runWithAIGNE(agentCreator, { argv = process.argv, chatLoop
|
|
|
157
158
|
})
|
|
158
159
|
.alias("h", "help")
|
|
159
160
|
.alias("v", "version")
|
|
160
|
-
.parseAsync(argv)
|
|
161
|
+
.parseAsync(hideBin(argv))
|
|
161
162
|
.catch((error) => {
|
|
162
163
|
console.error(`${chalk.red("Error:")} ${error.message}`);
|
|
163
164
|
process.exit(1);
|
|
@@ -209,7 +210,7 @@ export async function runAgentWithAIGNE(aigne, agent, { outputKey, chatLoopOptio
|
|
|
209
210
|
}
|
|
210
211
|
return { result };
|
|
211
212
|
}
|
|
212
|
-
async function stdinHasData() {
|
|
213
|
+
export async function stdinHasData() {
|
|
213
214
|
const stats = await promisify(fstat)(0);
|
|
214
215
|
return stats.isFIFO() || stats.isFile();
|
|
215
216
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/cli",
|
|
3
|
-
"version": "1.27.1-
|
|
3
|
+
"version": "1.27.1-1",
|
|
4
4
|
"description": "cli for AIGNE framework",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -70,20 +70,20 @@
|
|
|
70
70
|
"yaml": "^2.8.0",
|
|
71
71
|
"yargs": "^18.0.0",
|
|
72
72
|
"zod": "^3.25.67",
|
|
73
|
-
"@aigne/agent-library": "^1.21.6",
|
|
74
73
|
"@aigne/agentic-memory": "^1.0.6",
|
|
75
|
-
"@aigne/
|
|
76
|
-
"@aigne/anthropic": "^0.10.2",
|
|
74
|
+
"@aigne/agent-library": "^1.21.6",
|
|
77
75
|
"@aigne/bedrock": "^0.8.6",
|
|
76
|
+
"@aigne/aigne-hub": "^0.3.0",
|
|
78
77
|
"@aigne/core": "^1.39.0",
|
|
79
78
|
"@aigne/deepseek": "^0.7.6",
|
|
79
|
+
"@aigne/anthropic": "^0.10.2",
|
|
80
80
|
"@aigne/default-memory": "^1.0.6",
|
|
81
81
|
"@aigne/gemini": "^0.8.6",
|
|
82
|
-
"@aigne/
|
|
82
|
+
"@aigne/observability-api": "^0.8.2",
|
|
83
83
|
"@aigne/open-router": "^0.7.6",
|
|
84
84
|
"@aigne/openai": "^0.10.6",
|
|
85
85
|
"@aigne/xai": "^0.7.6",
|
|
86
|
-
"@aigne/
|
|
86
|
+
"@aigne/ollama": "^0.7.6"
|
|
87
87
|
},
|
|
88
88
|
"devDependencies": {
|
|
89
89
|
"@types/archiver": "^6.0.3",
|