@aigne/cli 1.26.0 → 1.26.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.js +2 -1
- package/dist/commands/aigne.d.ts +2 -2
- package/dist/commands/aigne.js +18 -11
- package/dist/commands/app.d.ts +2 -0
- package/dist/commands/app.js +98 -0
- package/dist/commands/connect.d.ts +6 -0
- package/dist/commands/connect.js +91 -0
- package/dist/commands/create.d.ts +6 -2
- package/dist/commands/create.js +62 -58
- package/dist/commands/observe.d.ts +7 -2
- package/dist/commands/observe.js +22 -13
- package/dist/commands/run.d.ts +6 -3
- package/dist/commands/run.js +96 -81
- package/dist/commands/serve-mcp.d.ts +10 -3
- package/dist/commands/serve-mcp.js +41 -23
- package/dist/commands/test.d.ts +7 -3
- package/dist/commands/test.js +20 -14
- package/dist/utils/download.d.ts +3 -1
- package/dist/utils/download.js +2 -2
- package/dist/utils/load-aigne.d.ts +10 -1
- package/dist/utils/load-aigne.js +57 -43
- package/dist/utils/run-with-aigne.d.ts +26 -2
- package/dist/utils/run-with-aigne.js +80 -57
- package/package.json +10 -8
package/dist/commands/run.js
CHANGED
|
@@ -12,94 +12,109 @@ import { isV1Package, toAIGNEPackage } from "../utils/agent-v1.js";
|
|
|
12
12
|
import { downloadAndExtract } from "../utils/download.js";
|
|
13
13
|
import { loadAIGNE } from "../utils/load-aigne.js";
|
|
14
14
|
import { createRunAIGNECommand, parseAgentInputByCommander, runAgentWithAIGNE, } from "../utils/run-with-aigne.js";
|
|
15
|
-
export function createRunCommand({ aigneFilePath } = {}) {
|
|
16
|
-
return
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
15
|
+
export function createRunCommand({ aigneFilePath, } = {}) {
|
|
16
|
+
return {
|
|
17
|
+
command: "run [path]",
|
|
18
|
+
describe: "Run AIGNE from the specified agent",
|
|
19
|
+
builder: (yargs) => {
|
|
20
|
+
return createRunAIGNECommand(yargs)
|
|
21
|
+
.positional("path", {
|
|
22
|
+
describe: "Path to the agents directory or URL to aigne project",
|
|
23
|
+
type: "string",
|
|
24
|
+
default: ".",
|
|
25
|
+
alias: ["url"],
|
|
26
|
+
})
|
|
27
|
+
.option("entry-agent", {
|
|
28
|
+
describe: "Name of the agent to run (defaults to the first agent found)",
|
|
29
|
+
type: "string",
|
|
30
|
+
})
|
|
31
|
+
.option("cache-dir", {
|
|
32
|
+
describe: "Directory to download the package to (defaults to the ~/.aigne/xxx)",
|
|
33
|
+
type: "string",
|
|
34
|
+
});
|
|
35
|
+
},
|
|
36
|
+
handler: async (argv) => {
|
|
37
|
+
const options = argv;
|
|
38
|
+
const path = aigneFilePath || options.path;
|
|
39
|
+
if (options.logLevel)
|
|
40
|
+
logger.level = options.logLevel;
|
|
41
|
+
const { cacheDir, dir } = prepareDirs(path, options);
|
|
42
|
+
const { aigne, agent } = await new Listr([
|
|
43
|
+
{
|
|
44
|
+
title: "Prepare environment",
|
|
45
|
+
task: (_, task) => {
|
|
46
|
+
if (cacheDir) {
|
|
47
|
+
return task.newListr([
|
|
48
|
+
{
|
|
49
|
+
title: "Download package",
|
|
50
|
+
task: () => downloadPackage(path, cacheDir),
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
title: "Extract package",
|
|
54
|
+
task: () => extractPackage(cacheDir, dir),
|
|
55
|
+
},
|
|
56
|
+
]);
|
|
57
|
+
}
|
|
58
|
+
},
|
|
42
59
|
},
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
60
|
+
{
|
|
61
|
+
title: "Initialize AIGNE",
|
|
62
|
+
task: async (ctx, task) => {
|
|
63
|
+
// Load env files in the aigne directory
|
|
64
|
+
config({ path: dir, silent: true });
|
|
65
|
+
const aigne = await loadAIGNE(dir, { ...options, model: options.model || process.env.MODEL }, {
|
|
66
|
+
inquirerPromptFn: (prompt) => {
|
|
67
|
+
return task
|
|
68
|
+
.prompt(ListrInquirerPromptAdapter)
|
|
69
|
+
.run(select, prompt)
|
|
70
|
+
.then((res) => ({ [prompt.name]: res }));
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
ctx.aigne = aigne;
|
|
74
|
+
},
|
|
58
75
|
},
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
throw new Error(`\
|
|
76
|
+
{
|
|
77
|
+
task: (ctx) => {
|
|
78
|
+
const { aigne } = ctx;
|
|
79
|
+
assert(aigne);
|
|
80
|
+
let entryAgent;
|
|
81
|
+
if (options.entryAgent) {
|
|
82
|
+
entryAgent = aigne.agents[options.entryAgent];
|
|
83
|
+
if (!entryAgent) {
|
|
84
|
+
throw new Error(`\
|
|
69
85
|
Agent "${options.entryAgent}" not found in ${aigne.rootDir}
|
|
70
86
|
|
|
71
87
|
Available agents:
|
|
72
88
|
${aigne.agents.map((agent) => ` - ${agent.name}`).join("\n")}
|
|
73
89
|
`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
entryAgent = aigne.agents[0];
|
|
94
|
+
if (!entryAgent)
|
|
95
|
+
throw new Error(`No any agent found in ${aigne.rootDir}`);
|
|
74
96
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
97
|
+
ctx.agent = entryAgent;
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
], {
|
|
101
|
+
rendererOptions: {
|
|
102
|
+
collapseSubtasks: false,
|
|
103
|
+
showErrorMessage: false,
|
|
104
|
+
timer: PRESET_TIMER,
|
|
82
105
|
},
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
await runAgentWithAIGNE(aigne, agent, { ...options, input });
|
|
96
|
-
}
|
|
97
|
-
finally {
|
|
98
|
-
await aigne.shutdown();
|
|
99
|
-
}
|
|
100
|
-
})
|
|
101
|
-
.showHelpAfterError(true)
|
|
102
|
-
.showSuggestionAfterError(true);
|
|
106
|
+
}).run();
|
|
107
|
+
assert(aigne);
|
|
108
|
+
assert(agent);
|
|
109
|
+
const input = await parseAgentInputByCommander(agent, options);
|
|
110
|
+
try {
|
|
111
|
+
await runAgentWithAIGNE(aigne, agent, { ...options, input });
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
await aigne.shutdown();
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
};
|
|
103
118
|
}
|
|
104
119
|
async function downloadPackage(url, cacheDir) {
|
|
105
120
|
await rm(cacheDir, { recursive: true, force: true });
|
|
@@ -121,7 +136,7 @@ function prepareDirs(path, options) {
|
|
|
121
136
|
if (!path.startsWith("http")) {
|
|
122
137
|
dir = isAbsolute(path) ? path : resolve(process.cwd(), path);
|
|
123
138
|
}
|
|
124
|
-
else if (options
|
|
139
|
+
else if (options?.cacheDir) {
|
|
125
140
|
dir = isAbsolute(options.cacheDir)
|
|
126
141
|
? options.cacheDir
|
|
127
142
|
: resolve(process.cwd(), options.cacheDir);
|
|
@@ -133,7 +148,7 @@ function prepareDirs(path, options) {
|
|
|
133
148
|
}
|
|
134
149
|
return { cacheDir, dir };
|
|
135
150
|
}
|
|
136
|
-
function getLocalPackagePathFromUrl(url, { subdir } = {}) {
|
|
151
|
+
export function getLocalPackagePathFromUrl(url, { subdir } = {}) {
|
|
137
152
|
const root = [homedir(), ".aigne", subdir].filter(isNonNullable);
|
|
138
153
|
const u = new URL(url);
|
|
139
154
|
return join(...root, u.hostname, u.pathname);
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import type { CommandModule } from "yargs";
|
|
2
|
+
interface ServeMCPOptions {
|
|
3
|
+
path: string;
|
|
4
|
+
host: string;
|
|
5
|
+
port?: number;
|
|
6
|
+
pathname: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function createServeMCPCommand({ aigneFilePath, }?: {
|
|
3
9
|
aigneFilePath?: string;
|
|
4
|
-
}):
|
|
10
|
+
}): CommandModule<{}, ServeMCPOptions>;
|
|
11
|
+
export {};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { isAbsolute, resolve } from "node:path";
|
|
2
2
|
import { tryOrThrow } from "@aigne/core/utils/type-utils.js";
|
|
3
|
-
import { Command } from "commander";
|
|
4
3
|
import { loadAIGNE } from "../utils/load-aigne.js";
|
|
5
4
|
import { serveMCPServer } from "../utils/serve-mcp.js";
|
|
6
5
|
const DEFAULT_PORT = () => tryOrThrow(() => {
|
|
@@ -12,26 +11,45 @@ const DEFAULT_PORT = () => tryOrThrow(() => {
|
|
|
12
11
|
throw new Error(`Invalid PORT: ${PORT}`);
|
|
13
12
|
return port;
|
|
14
13
|
}, (error) => new Error(`parse PORT error ${error.message}`));
|
|
15
|
-
export function createServeMCPCommand({ aigneFilePath } = {}) {
|
|
16
|
-
return
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
14
|
+
export function createServeMCPCommand({ aigneFilePath, } = {}) {
|
|
15
|
+
return {
|
|
16
|
+
command: "serve-mcp",
|
|
17
|
+
describe: "Serve the agents in the specified directory as a MCP server (streamable http)",
|
|
18
|
+
builder: (yargs) => {
|
|
19
|
+
return yargs
|
|
20
|
+
.option("path", {
|
|
21
|
+
describe: "Path to the agents directory or URL to aigne project",
|
|
22
|
+
type: "string",
|
|
23
|
+
default: ".",
|
|
24
|
+
alias: ["url"],
|
|
25
|
+
})
|
|
26
|
+
.option("host", {
|
|
27
|
+
describe: "Host to run the MCP server on, use 0.0.0.0 to publicly expose the server",
|
|
28
|
+
type: "string",
|
|
29
|
+
default: "localhost",
|
|
30
|
+
})
|
|
31
|
+
.option("port", {
|
|
32
|
+
describe: "Port to run the MCP server on",
|
|
33
|
+
type: "number",
|
|
34
|
+
})
|
|
35
|
+
.option("pathname", {
|
|
36
|
+
describe: "Pathname to the service",
|
|
37
|
+
type: "string",
|
|
38
|
+
default: "/mcp",
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
handler: async (options) => {
|
|
42
|
+
const path = aigneFilePath || options.path;
|
|
43
|
+
const absolutePath = isAbsolute(path) ? path : resolve(process.cwd(), path);
|
|
44
|
+
const port = options.port || DEFAULT_PORT();
|
|
45
|
+
const aigne = await loadAIGNE(absolutePath);
|
|
46
|
+
await serveMCPServer({
|
|
47
|
+
aigne,
|
|
48
|
+
host: options.host,
|
|
49
|
+
port,
|
|
50
|
+
pathname: options.pathname,
|
|
51
|
+
});
|
|
52
|
+
console.log(`MCP server is running on http://${options.host}:${port}${options.pathname}`);
|
|
53
|
+
},
|
|
54
|
+
};
|
|
37
55
|
}
|
package/dist/commands/test.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import type { CommandModule } from "yargs";
|
|
2
|
+
interface TestOptions {
|
|
3
|
+
path: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function createTestCommand({ aigneFilePath, }?: {
|
|
3
6
|
aigneFilePath?: string;
|
|
4
|
-
}):
|
|
7
|
+
}): CommandModule<{}, TestOptions>;
|
|
8
|
+
export {};
|
package/dist/commands/test.js
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
import assert from "node:assert";
|
|
2
2
|
import { spawnSync } from "node:child_process";
|
|
3
3
|
import { isAbsolute, resolve } from "node:path";
|
|
4
|
-
import { Command } from "commander";
|
|
5
4
|
import { loadAIGNE } from "../utils/load-aigne.js";
|
|
6
|
-
export function createTestCommand({ aigneFilePath } = {}) {
|
|
7
|
-
return
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
5
|
+
export function createTestCommand({ aigneFilePath, } = {}) {
|
|
6
|
+
return {
|
|
7
|
+
command: "test",
|
|
8
|
+
describe: "Run tests in the specified agents directory",
|
|
9
|
+
builder: (yargs) => {
|
|
10
|
+
return yargs.option("path", {
|
|
11
|
+
describe: "Path to the agents directory or URL to aigne project",
|
|
12
|
+
type: "string",
|
|
13
|
+
default: ".",
|
|
14
|
+
alias: ["url"],
|
|
15
|
+
});
|
|
16
|
+
},
|
|
17
|
+
handler: async (options) => {
|
|
18
|
+
const path = aigneFilePath || options.path;
|
|
19
|
+
const absolutePath = isAbsolute(path) ? path : resolve(process.cwd(), path);
|
|
20
|
+
const aigne = await loadAIGNE(absolutePath);
|
|
21
|
+
assert(aigne.rootDir);
|
|
22
|
+
spawnSync("node", ["--test"], { cwd: aigne.rootDir, stdio: "inherit" });
|
|
23
|
+
},
|
|
24
|
+
};
|
|
19
25
|
}
|
package/dist/utils/download.d.ts
CHANGED
package/dist/utils/download.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Readable } from "node:stream";
|
|
2
2
|
import { finished } from "node:stream/promises";
|
|
3
3
|
import { x } from "tar";
|
|
4
|
-
export async function downloadAndExtract(url, dir) {
|
|
4
|
+
export async function downloadAndExtract(url, dir, options = {}) {
|
|
5
5
|
const response = await fetch(url).catch((error) => {
|
|
6
6
|
throw new Error(`Failed to download package from ${url}: ${error.message}`);
|
|
7
7
|
});
|
|
@@ -12,7 +12,7 @@ export async function downloadAndExtract(url, dir) {
|
|
|
12
12
|
throw new Error(`Failed to download package from ${url}: Unexpected to get empty response`);
|
|
13
13
|
}
|
|
14
14
|
try {
|
|
15
|
-
await finished(Readable.fromWeb(response.body).pipe(x({ C: dir })));
|
|
15
|
+
await finished(Readable.fromWeb(response.body).pipe(x({ C: dir, ...options })));
|
|
16
16
|
}
|
|
17
17
|
catch (error) {
|
|
18
18
|
error.message = `Failed to extract package from ${url}: ${error.message}`;
|
|
@@ -6,6 +6,7 @@ export declare const decrypt: (m: string, s: string, i: string) => string;
|
|
|
6
6
|
export declare const encrypt: (m: string, s: string, i: string) => string;
|
|
7
7
|
export declare const encodeEncryptionKey: (key: string) => string;
|
|
8
8
|
export declare const decodeEncryptionKey: (str: string) => Uint8Array<ArrayBuffer>;
|
|
9
|
+
export declare const AIGNE_ENV_FILE: string;
|
|
9
10
|
export interface RunOptions extends RunAIGNECommandOptions {
|
|
10
11
|
path: string;
|
|
11
12
|
entryAgent?: string;
|
|
@@ -40,7 +41,14 @@ interface CreateConnectOptions {
|
|
|
40
41
|
}
|
|
41
42
|
export declare function createConnect({ connectUrl, openPage, fetchInterval, retry, source, connectAction, wrapSpinner, closeOnSuccess, intervalFetchConfig, }: CreateConnectOptions): Promise<FetchResult>;
|
|
42
43
|
export declare const formatModelName: (models: LoadableModel[], model: string, inquirerPrompt: typeof inquirer.prompt) => Promise<string>;
|
|
43
|
-
export declare function
|
|
44
|
+
export declare function connectToAIGNEHub(url: string): Promise<{
|
|
45
|
+
accessKey: string;
|
|
46
|
+
url: string;
|
|
47
|
+
} | {
|
|
48
|
+
accessKey: undefined;
|
|
49
|
+
url: undefined;
|
|
50
|
+
}>;
|
|
51
|
+
export declare function loadAIGNE(path: string, options?: RunOptions, actionOptions?: {
|
|
44
52
|
inquirerPromptFn?: (prompt: {
|
|
45
53
|
type: string;
|
|
46
54
|
name: string;
|
|
@@ -51,5 +59,6 @@ export declare function loadAIGNE(path: string, options?: RunOptions, checkAutho
|
|
|
51
59
|
}[];
|
|
52
60
|
default: any;
|
|
53
61
|
}) => Promise<any>;
|
|
62
|
+
runTest?: boolean;
|
|
54
63
|
}): Promise<AIGNE<import("@aigne/core").UserContext>>;
|
|
55
64
|
export {};
|
package/dist/utils/load-aigne.js
CHANGED
|
@@ -3,7 +3,8 @@ import { readFile, writeFile } from "node:fs/promises";
|
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { AIGNE } from "@aigne/core";
|
|
6
|
-
import { loadModel } from "@aigne/core/loader/index.js";
|
|
6
|
+
import { loadAIGNEFile, loadModel } from "@aigne/core/loader/index.js";
|
|
7
|
+
import { logger } from "@aigne/core/utils/logger.js";
|
|
7
8
|
import { AesCrypter } from "@ocap/mcrypto/lib/crypter/aes-legacy.js";
|
|
8
9
|
import crypto from "crypto";
|
|
9
10
|
import inquirer from "inquirer";
|
|
@@ -20,15 +21,16 @@ const escapeFn = (str) => str.replace(/\+/g, "-").replace(/\//g, "_").replace(/=
|
|
|
20
21
|
const unescapeFn = (str) => (str + "===".slice((str.length + 3) % 4)).replace(/-/g, "+").replace(/_/g, "/");
|
|
21
22
|
export const encodeEncryptionKey = (key) => escapeFn(Buffer.from(key).toString("base64"));
|
|
22
23
|
export const decodeEncryptionKey = (str) => new Uint8Array(Buffer.from(unescapeFn(str), "base64"));
|
|
24
|
+
const TEST_ENV = process.env.CI || process.env.NODE_ENV === "test";
|
|
25
|
+
export const AIGNE_ENV_FILE = TEST_ENV
|
|
26
|
+
? join(homedir(), ".aigne", "test-aigne-hub-connected.yaml")
|
|
27
|
+
: join(homedir(), ".aigne", "aigne-hub-connected.yaml");
|
|
23
28
|
const request = async (config) => {
|
|
24
29
|
const headers = {};
|
|
25
30
|
if (config.requestCount !== undefined) {
|
|
26
31
|
headers["X-Request-Count"] = config.requestCount.toString();
|
|
27
32
|
}
|
|
28
|
-
const response = await fetch(config.url, {
|
|
29
|
-
method: config.method || "GET",
|
|
30
|
-
headers,
|
|
31
|
-
});
|
|
33
|
+
const response = await fetch(config.url, { method: config.method || "GET", headers });
|
|
32
34
|
if (!response.ok)
|
|
33
35
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
34
36
|
const data = await response.json();
|
|
@@ -108,7 +110,7 @@ export const formatModelName = async (models, model, inquirerPrompt) => {
|
|
|
108
110
|
if (m.apiKeyEnvName && process.env[m.apiKeyEnvName]) {
|
|
109
111
|
return model;
|
|
110
112
|
}
|
|
111
|
-
if (
|
|
113
|
+
if (TEST_ENV) {
|
|
112
114
|
return `${AGENT_HUB_PROVIDER}:${provider}/${name}`;
|
|
113
115
|
}
|
|
114
116
|
const result = await inquirerPrompt({
|
|
@@ -131,21 +133,63 @@ export const formatModelName = async (models, model, inquirerPrompt) => {
|
|
|
131
133
|
return model;
|
|
132
134
|
return `${AGENT_HUB_PROVIDER}:${provider}/${name}`;
|
|
133
135
|
};
|
|
134
|
-
export async function
|
|
136
|
+
export async function connectToAIGNEHub(url) {
|
|
137
|
+
const { origin, host } = new URL(url);
|
|
138
|
+
const connectUrl = joinURL(origin, WELLKNOWN_SERVICE_PATH_PREFIX);
|
|
139
|
+
const BLOCKLET_JSON_PATH = "__blocklet__.js?type=json";
|
|
140
|
+
const blockletInfo = await fetch(joinURL(origin, BLOCKLET_JSON_PATH));
|
|
141
|
+
const blocklet = await blockletInfo.json();
|
|
142
|
+
const aigneHubMount = (blocklet?.componentMountPoints || []).find((m) => m.did === "z8ia3xzq2tMq8CRHfaXj1BTYJyYnEcHbqP8cJ");
|
|
143
|
+
try {
|
|
144
|
+
const result = await createConnect({
|
|
145
|
+
connectUrl: connectUrl,
|
|
146
|
+
connectAction: "gen-simple-access-key",
|
|
147
|
+
source: `@aigne/cli connect to AIGNE hub`,
|
|
148
|
+
closeOnSuccess: true,
|
|
149
|
+
openPage: (pageUrl) => open(pageUrl),
|
|
150
|
+
});
|
|
151
|
+
const accessKeyOptions = {
|
|
152
|
+
accessKey: result.accessKeySecret,
|
|
153
|
+
url: joinURL(origin, aigneHubMount?.mountPoint || ""),
|
|
154
|
+
};
|
|
155
|
+
// After redirection, write the AIGNE Hub access token
|
|
156
|
+
const aigneDir = join(homedir(), ".aigne");
|
|
157
|
+
if (!existsSync(aigneDir)) {
|
|
158
|
+
mkdirSync(aigneDir, { recursive: true });
|
|
159
|
+
}
|
|
160
|
+
const envs = parse(await readFile(AIGNE_ENV_FILE, "utf8").catch(() => stringify({})));
|
|
161
|
+
await writeFile(AIGNE_ENV_FILE, stringify({
|
|
162
|
+
...envs,
|
|
163
|
+
[host]: {
|
|
164
|
+
AIGNE_HUB_API_KEY: accessKeyOptions.accessKey,
|
|
165
|
+
AIGNE_HUB_API_URL: accessKeyOptions.url,
|
|
166
|
+
},
|
|
167
|
+
})).catch((err) => {
|
|
168
|
+
logger.error("Failed to write AIGNE Hub access token to .aigne/aigne-hub-connected.yaml", err.message);
|
|
169
|
+
throw err;
|
|
170
|
+
});
|
|
171
|
+
return accessKeyOptions;
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
logger.error("Failed to connect to AIGNE Hub", error.message);
|
|
175
|
+
return { accessKey: undefined, url: undefined };
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
export async function loadAIGNE(path, options, actionOptions) {
|
|
135
179
|
const models = availableModels();
|
|
136
|
-
const AIGNE_ENV_FILE = join(homedir(), ".aigne", "aigne-hub-connected.yaml");
|
|
137
180
|
const AIGNE_HUB_URL = process.env.AIGNE_HUB_API_URL || DEFAULT_URL;
|
|
138
181
|
const connectUrl = joinURL(new URL(AIGNE_HUB_URL).origin, WELLKNOWN_SERVICE_PATH_PREFIX);
|
|
139
|
-
const inquirerPrompt = (
|
|
182
|
+
const inquirerPrompt = (actionOptions?.inquirerPromptFn ??
|
|
140
183
|
inquirer.prompt);
|
|
184
|
+
const { aigne } = await loadAIGNEFile(path).catch(() => ({ aigne: null }));
|
|
141
185
|
let accessKeyOptions = {};
|
|
142
|
-
const modelName = await formatModelName(models, options?.model || ""
|
|
143
|
-
if (
|
|
186
|
+
const modelName = await formatModelName(models, options?.model || `${aigne?.model?.provider ?? ""}:${aigne?.model?.name ?? ""}`, inquirerPrompt);
|
|
187
|
+
if (TEST_ENV && !actionOptions?.runTest) {
|
|
144
188
|
const model = await loadModel(models, parseModelOption(modelName), undefined, accessKeyOptions);
|
|
145
189
|
return await AIGNE.load(path, { models, memories: availableMemories, model });
|
|
146
190
|
}
|
|
147
191
|
if ((modelName.toLocaleLowerCase() || "").includes(AGENT_HUB_PROVIDER)) {
|
|
148
|
-
const {
|
|
192
|
+
const { host } = new URL(AIGNE_HUB_URL);
|
|
149
193
|
try {
|
|
150
194
|
// aigne-hub access token
|
|
151
195
|
if (!existsSync(AIGNE_ENV_FILE)) {
|
|
@@ -188,37 +232,7 @@ export async function loadAIGNE(path, options, checkAuthorizeOptions) {
|
|
|
188
232
|
console.warn("The AIGNE Hub connection has been cancelled");
|
|
189
233
|
process.exit(0);
|
|
190
234
|
}
|
|
191
|
-
|
|
192
|
-
const blockletInfo = await fetch(joinURL(origin, BLOCKLET_JSON_PATH));
|
|
193
|
-
const blocklet = await blockletInfo.json();
|
|
194
|
-
const aigneHubMount = (blocklet?.componentMountPoints || []).find((m) => m.did === "z8ia3xzq2tMq8CRHfaXj1BTYJyYnEcHbqP8cJ");
|
|
195
|
-
try {
|
|
196
|
-
const result = await createConnect({
|
|
197
|
-
connectUrl: connectUrl,
|
|
198
|
-
connectAction: "gen-simple-access-key",
|
|
199
|
-
source: `@aigne/cli connect to AIGNE hub`,
|
|
200
|
-
closeOnSuccess: true,
|
|
201
|
-
openPage: (pageUrl) => open(pageUrl),
|
|
202
|
-
});
|
|
203
|
-
accessKeyOptions = {
|
|
204
|
-
accessKey: result.accessKeySecret,
|
|
205
|
-
url: joinURL(origin, aigneHubMount?.mountPoint || ""),
|
|
206
|
-
};
|
|
207
|
-
// After redirection, write the AIGNE Hub access token
|
|
208
|
-
const aigneDir = join(homedir(), ".aigne");
|
|
209
|
-
if (!existsSync(aigneDir)) {
|
|
210
|
-
mkdirSync(aigneDir, { recursive: true });
|
|
211
|
-
}
|
|
212
|
-
await writeFile(AIGNE_ENV_FILE, stringify({
|
|
213
|
-
[host]: {
|
|
214
|
-
AIGNE_HUB_API_KEY: accessKeyOptions.accessKey,
|
|
215
|
-
AIGNE_HUB_API_URL: accessKeyOptions.url,
|
|
216
|
-
},
|
|
217
|
-
}));
|
|
218
|
-
}
|
|
219
|
-
catch (error) {
|
|
220
|
-
console.error(error);
|
|
221
|
-
}
|
|
235
|
+
accessKeyOptions = await connectToAIGNEHub(connectUrl);
|
|
222
236
|
}
|
|
223
237
|
}
|
|
224
238
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Agent, AIGNE, type ChatModelOptions, type Message } from "@aigne/core";
|
|
2
2
|
import { LogLevel } from "@aigne/core/utils/logger.js";
|
|
3
3
|
import { type PromiseOrValue } from "@aigne/core/utils/type-utils.js";
|
|
4
|
-
import {
|
|
4
|
+
import type { Argv } from "yargs";
|
|
5
5
|
import { type ChatLoopOptions } from "./run-chat-loop.js";
|
|
6
6
|
export interface RunAIGNECommandOptions {
|
|
7
7
|
chat?: boolean;
|
|
@@ -17,7 +17,31 @@ export interface RunAIGNECommandOptions {
|
|
|
17
17
|
logLevel?: LogLevel;
|
|
18
18
|
force?: boolean;
|
|
19
19
|
}
|
|
20
|
-
export declare const createRunAIGNECommand: (
|
|
20
|
+
export declare const createRunAIGNECommand: (yargs: Argv) => Argv<{
|
|
21
|
+
chat: boolean;
|
|
22
|
+
} & {
|
|
23
|
+
model: string | undefined;
|
|
24
|
+
} & {
|
|
25
|
+
temperature: number | undefined;
|
|
26
|
+
} & {
|
|
27
|
+
"top-p": number | undefined;
|
|
28
|
+
} & {
|
|
29
|
+
"presence-penalty": number | undefined;
|
|
30
|
+
} & {
|
|
31
|
+
"frequency-penalty": number | undefined;
|
|
32
|
+
} & {
|
|
33
|
+
input: (string | number)[] | undefined;
|
|
34
|
+
} & {
|
|
35
|
+
format: string | undefined;
|
|
36
|
+
} & {
|
|
37
|
+
output: string | undefined;
|
|
38
|
+
} & {
|
|
39
|
+
"output-key": string;
|
|
40
|
+
} & {
|
|
41
|
+
force: boolean;
|
|
42
|
+
} & {
|
|
43
|
+
"log-level": LogLevel;
|
|
44
|
+
}>;
|
|
21
45
|
export declare function parseAgentInputByCommander(agent: Agent, options?: RunAIGNECommandOptions & {
|
|
22
46
|
inputKey?: string;
|
|
23
47
|
argv?: string[];
|