@aigne/cli 1.25.1 → 1.26.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 +32 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/tracer/terminal.js +43 -19
- package/dist/type.d.ts +5 -0
- package/dist/type.js +1 -0
- package/dist/utils/listr.js +5 -1
- package/dist/utils/load-aigne.d.ts +36 -0
- package/dist/utils/load-aigne.js +102 -84
- package/package.json +24 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.26.0](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.25.1...cli-v1.26.0) (2025-07-28)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **cli:** add inquirer/prompts integrations for cli ([#286](https://github.com/AIGNE-io/aigne-framework/issues/286)) ([33af756](https://github.com/AIGNE-io/aigne-framework/commit/33af7567fe2e7f9fb4b1633127e1d54fd65cb2a8))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **observability:** uniq index on insert and perf on trace query ([#268](https://github.com/AIGNE-io/aigne-framework/issues/268)) ([bd02d2e](https://github.com/AIGNE-io/aigne-framework/commit/bd02d2ef4dadc3df7e4806746fede2faa5cc50bb))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Dependencies
|
|
17
|
+
|
|
18
|
+
* The following workspace dependencies were updated
|
|
19
|
+
* dependencies
|
|
20
|
+
* @aigne/agent-library bumped to 1.21.6
|
|
21
|
+
* @aigne/agentic-memory bumped to 1.0.6
|
|
22
|
+
* @aigne/aigne-hub bumped to 0.2.2
|
|
23
|
+
* @aigne/anthropic bumped to 0.10.2
|
|
24
|
+
* @aigne/bedrock bumped to 0.8.6
|
|
25
|
+
* @aigne/core bumped to 1.39.0
|
|
26
|
+
* @aigne/deepseek bumped to 0.7.6
|
|
27
|
+
* @aigne/default-memory bumped to 1.0.6
|
|
28
|
+
* @aigne/gemini bumped to 0.8.6
|
|
29
|
+
* @aigne/observability-api bumped to 0.8.2
|
|
30
|
+
* @aigne/ollama bumped to 0.7.6
|
|
31
|
+
* @aigne/open-router bumped to 0.7.6
|
|
32
|
+
* @aigne/openai bumped to 0.10.6
|
|
33
|
+
* @aigne/xai bumped to 0.7.6
|
|
34
|
+
|
|
3
35
|
## [1.25.1](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.25.0...cli-v1.25.1) (2025-07-24)
|
|
4
36
|
|
|
5
37
|
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./type.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./type.js";
|
package/dist/tracer/terminal.js
CHANGED
|
@@ -3,9 +3,11 @@ import { inspect } from "node:util";
|
|
|
3
3
|
import { AIAgent, ChatModel, DEFAULT_OUTPUT_KEY, } from "@aigne/core";
|
|
4
4
|
import { LogLevel, logger } from "@aigne/core/utils/logger.js";
|
|
5
5
|
import { promiseWithResolvers } from "@aigne/core/utils/promise.js";
|
|
6
|
-
import { omit } from "@aigne/core/utils/type-utils.js";
|
|
6
|
+
import { flat, omit } from "@aigne/core/utils/type-utils.js";
|
|
7
7
|
import { figures } from "@aigne/listr2";
|
|
8
8
|
import { markedTerminal } from "@aigne/marked-terminal";
|
|
9
|
+
import * as prompts from "@inquirer/prompts";
|
|
10
|
+
import { ListrInquirerPromptAdapter } from "@listr2/prompt-adapter-inquirer";
|
|
9
11
|
import chalk from "chalk";
|
|
10
12
|
import { Marked } from "marked";
|
|
11
13
|
import { AIGNEListr } from "../utils/listr.js";
|
|
@@ -27,11 +29,13 @@ export class TerminalTracer {
|
|
|
27
29
|
: undefined,
|
|
28
30
|
formatResult: (result, options) => [this.formatResult(agent, context, result, options)].filter(Boolean),
|
|
29
31
|
}, [], { concurrent: true });
|
|
30
|
-
const
|
|
32
|
+
const onStart = async ({ context, agent }) => {
|
|
33
|
+
const contextId = context.id;
|
|
34
|
+
const parentContextId = context.parentId;
|
|
31
35
|
const task = {
|
|
32
36
|
...promiseWithResolvers(),
|
|
33
37
|
listr: promiseWithResolvers(),
|
|
34
|
-
startTime:
|
|
38
|
+
startTime: Date.now(),
|
|
35
39
|
};
|
|
36
40
|
this.tasks[contextId] = task;
|
|
37
41
|
const listrTask = {
|
|
@@ -56,12 +60,32 @@ export class TerminalTracer {
|
|
|
56
60
|
else {
|
|
57
61
|
listr.add(listrTask);
|
|
58
62
|
}
|
|
63
|
+
return {
|
|
64
|
+
options: {
|
|
65
|
+
prompts: new Proxy({}, {
|
|
66
|
+
get: (_target, prop) => {
|
|
67
|
+
// biome-ignore lint/performance/noDynamicNamespaceImportAccess: we need to access prompts dynamically
|
|
68
|
+
const method = prompts[prop];
|
|
69
|
+
if (!method)
|
|
70
|
+
return undefined;
|
|
71
|
+
return async (config) => {
|
|
72
|
+
const { taskWrapper } = await task.listr.promise;
|
|
73
|
+
return taskWrapper
|
|
74
|
+
.prompt(ListrInquirerPromptAdapter)
|
|
75
|
+
.run(method, config);
|
|
76
|
+
};
|
|
77
|
+
},
|
|
78
|
+
}),
|
|
79
|
+
},
|
|
80
|
+
};
|
|
59
81
|
};
|
|
60
|
-
const
|
|
82
|
+
const onSuccess = async ({ context, agent, output }) => {
|
|
83
|
+
const contextId = context.id;
|
|
84
|
+
const parentContextId = context.parentId;
|
|
61
85
|
const task = this.tasks[contextId];
|
|
62
86
|
if (!task)
|
|
63
87
|
return;
|
|
64
|
-
task.endTime =
|
|
88
|
+
task.endTime = Date.now();
|
|
65
89
|
const { taskWrapper, ctx } = await task.listr.promise;
|
|
66
90
|
if (agent instanceof ChatModel) {
|
|
67
91
|
const { usage, model } = output;
|
|
@@ -76,27 +100,27 @@ export class TerminalTracer {
|
|
|
76
100
|
}
|
|
77
101
|
task.resolve();
|
|
78
102
|
};
|
|
79
|
-
const
|
|
103
|
+
const onError = async ({ context, agent, error }) => {
|
|
104
|
+
const contextId = context.id;
|
|
80
105
|
const task = this.tasks[contextId];
|
|
81
106
|
if (!task)
|
|
82
107
|
return;
|
|
83
|
-
task.endTime =
|
|
108
|
+
task.endTime = Date.now();
|
|
84
109
|
const { taskWrapper } = await task.listr.promise;
|
|
85
110
|
taskWrapper.title = this.formatTaskTitle(agent, { task, usage: true, time: true });
|
|
86
111
|
task.reject(error);
|
|
87
112
|
};
|
|
88
|
-
context.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
113
|
+
const result = await listr.run(() => context.invoke(agent, input, {
|
|
114
|
+
...options,
|
|
115
|
+
hooks: flat({
|
|
116
|
+
onStart,
|
|
117
|
+
onSuccess,
|
|
118
|
+
onError,
|
|
119
|
+
}, options?.hooks),
|
|
120
|
+
streaming: true,
|
|
121
|
+
newContext: false,
|
|
122
|
+
}));
|
|
123
|
+
return { result, context };
|
|
100
124
|
}
|
|
101
125
|
formatTokenUsage(usage, extra) {
|
|
102
126
|
const items = [
|
package/dist/type.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { AgentInvokeOptions as _AgentInvokeOptions, UserContext } from "@aigne/core";
|
|
2
|
+
import type * as prompts from "@inquirer/prompts";
|
|
3
|
+
export interface AgentInvokeOptions<U extends UserContext = UserContext> extends _AgentInvokeOptions<U> {
|
|
4
|
+
prompts: typeof prompts;
|
|
5
|
+
}
|
package/dist/type.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/utils/listr.js
CHANGED
|
@@ -98,7 +98,7 @@ export class AIGNEListrRenderer extends DefaultRenderer {
|
|
|
98
98
|
this._updater.clear();
|
|
99
99
|
this._logger.toStdout(logs.join(EOL));
|
|
100
100
|
}
|
|
101
|
-
let tasks = super.create(options);
|
|
101
|
+
let tasks = super.create({ ...options, prompt: false });
|
|
102
102
|
const bottomBar = this._options.aigne?.getBottomBarLogs?.({ running });
|
|
103
103
|
if (bottomBar?.length) {
|
|
104
104
|
tasks += EOL.repeat(2);
|
|
@@ -116,6 +116,10 @@ export class AIGNEListrRenderer extends DefaultRenderer {
|
|
|
116
116
|
tasks += output.split(EOL).slice(-Math.max(4, lines)).join(EOL);
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
|
+
const prompt = super["renderPrompt"]();
|
|
120
|
+
if (prompt.length) {
|
|
121
|
+
tasks += `${EOL.repeat(2)}${prompt.join(EOL)}`;
|
|
122
|
+
}
|
|
119
123
|
return tasks;
|
|
120
124
|
}
|
|
121
125
|
_wrap(str) {
|
|
@@ -1,10 +1,45 @@
|
|
|
1
1
|
import { AIGNE } from "@aigne/core";
|
|
2
|
+
import type { LoadableModel } from "@aigne/core/loader/index.js";
|
|
3
|
+
import inquirer from "inquirer";
|
|
2
4
|
import { type RunAIGNECommandOptions } from "./run-with-aigne.js";
|
|
5
|
+
export declare const decrypt: (m: string, s: string, i: string) => string;
|
|
6
|
+
export declare const encrypt: (m: string, s: string, i: string) => string;
|
|
7
|
+
export declare const encodeEncryptionKey: (key: string) => string;
|
|
8
|
+
export declare const decodeEncryptionKey: (str: string) => Uint8Array<ArrayBuffer>;
|
|
3
9
|
export interface RunOptions extends RunAIGNECommandOptions {
|
|
4
10
|
path: string;
|
|
5
11
|
entryAgent?: string;
|
|
6
12
|
cacheDir?: string;
|
|
7
13
|
}
|
|
14
|
+
type FetchResult = {
|
|
15
|
+
accessKeyId: string;
|
|
16
|
+
accessKeySecret: string;
|
|
17
|
+
};
|
|
18
|
+
export declare const fetchConfigs: ({ connectUrl, sessionId, fetchInterval, fetchTimeout, }: {
|
|
19
|
+
connectUrl: string;
|
|
20
|
+
sessionId: string;
|
|
21
|
+
fetchInterval: number;
|
|
22
|
+
fetchTimeout: number;
|
|
23
|
+
}) => Promise<any>;
|
|
24
|
+
declare function baseWrapSpinner(_: string, waiting: () => Promise<FetchResult>): Promise<FetchResult>;
|
|
25
|
+
interface CreateConnectOptions {
|
|
26
|
+
connectUrl: string;
|
|
27
|
+
openPage?: (url: string) => void;
|
|
28
|
+
fetchInterval?: number;
|
|
29
|
+
retry?: number;
|
|
30
|
+
source?: string;
|
|
31
|
+
connectAction?: string;
|
|
32
|
+
wrapSpinner?: typeof baseWrapSpinner;
|
|
33
|
+
prettyUrl?: (url: string) => string;
|
|
34
|
+
closeOnSuccess?: boolean;
|
|
35
|
+
intervalFetchConfig?: (options: {
|
|
36
|
+
sessionId: string;
|
|
37
|
+
fetchInterval: number;
|
|
38
|
+
fetchTimeout: number;
|
|
39
|
+
}) => Promise<FetchResult>;
|
|
40
|
+
}
|
|
41
|
+
export declare function createConnect({ connectUrl, openPage, fetchInterval, retry, source, connectAction, wrapSpinner, closeOnSuccess, intervalFetchConfig, }: CreateConnectOptions): Promise<FetchResult>;
|
|
42
|
+
export declare const formatModelName: (models: LoadableModel[], model: string, inquirerPrompt: typeof inquirer.prompt) => Promise<string>;
|
|
8
43
|
export declare function loadAIGNE(path: string, options?: RunOptions, checkAuthorizeOptions?: {
|
|
9
44
|
inquirerPromptFn?: (prompt: {
|
|
10
45
|
type: string;
|
|
@@ -17,3 +52,4 @@ export declare function loadAIGNE(path: string, options?: RunOptions, checkAutho
|
|
|
17
52
|
default: any;
|
|
18
53
|
}) => Promise<any>;
|
|
19
54
|
}): Promise<AIGNE<import("@aigne/core").UserContext>>;
|
|
55
|
+
export {};
|
package/dist/utils/load-aigne.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
2
|
-
import {
|
|
1
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
2
|
+
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";
|
|
@@ -14,28 +14,39 @@ import { parse, stringify } from "yaml";
|
|
|
14
14
|
import { availableMemories, availableModels } from "../constants.js";
|
|
15
15
|
import { parseModelOption } from "./run-with-aigne.js";
|
|
16
16
|
const aes = new AesCrypter();
|
|
17
|
-
const decrypt = (m, s, i) => aes.decrypt(m, crypto.pbkdf2Sync(i, s, 256, 32, "sha512").toString("hex"));
|
|
17
|
+
export const decrypt = (m, s, i) => aes.decrypt(m, crypto.pbkdf2Sync(i, s, 256, 32, "sha512").toString("hex"));
|
|
18
|
+
export const encrypt = (m, s, i) => aes.encrypt(m, crypto.pbkdf2Sync(i, s, 256, 32, "sha512").toString("hex"));
|
|
18
19
|
const escapeFn = (str) => str.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
19
|
-
const
|
|
20
|
+
const unescapeFn = (str) => (str + "===".slice((str.length + 3) % 4)).replace(/-/g, "+").replace(/_/g, "/");
|
|
21
|
+
export const encodeEncryptionKey = (key) => escapeFn(Buffer.from(key).toString("base64"));
|
|
22
|
+
export const decodeEncryptionKey = (str) => new Uint8Array(Buffer.from(unescapeFn(str), "base64"));
|
|
20
23
|
const request = async (config) => {
|
|
21
|
-
const
|
|
22
|
-
if (
|
|
23
|
-
|
|
24
|
+
const headers = {};
|
|
25
|
+
if (config.requestCount !== undefined) {
|
|
26
|
+
headers["X-Request-Count"] = config.requestCount.toString();
|
|
24
27
|
}
|
|
28
|
+
const response = await fetch(config.url, {
|
|
29
|
+
method: config.method || "GET",
|
|
30
|
+
headers,
|
|
31
|
+
});
|
|
32
|
+
if (!response.ok)
|
|
33
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
25
34
|
const data = await response.json();
|
|
26
35
|
return { data };
|
|
27
36
|
};
|
|
28
37
|
const WELLKNOWN_SERVICE_PATH_PREFIX = "/.well-known/service";
|
|
29
38
|
const ACCESS_KEY_PREFIX = "/api/access-key";
|
|
30
39
|
const ACCESS_KEY_SESSION_API = `${ACCESS_KEY_PREFIX}/session`;
|
|
31
|
-
const fetchConfigs = async ({ connectUrl, sessionId, fetchInterval, fetchTimeout, }) => {
|
|
40
|
+
export const fetchConfigs = async ({ connectUrl, sessionId, fetchInterval, fetchTimeout, }) => {
|
|
32
41
|
const sessionURL = withQuery(joinURL(connectUrl, ACCESS_KEY_SESSION_API), { sid: sessionId });
|
|
42
|
+
let requestCount = 0;
|
|
33
43
|
const condition = async () => {
|
|
34
|
-
const { data: session } = await request({ url: sessionURL });
|
|
44
|
+
const { data: session } = await request({ url: sessionURL, requestCount });
|
|
45
|
+
requestCount++;
|
|
35
46
|
return Boolean(session.accessKeyId && session.accessKeySecret);
|
|
36
47
|
};
|
|
37
48
|
await pWaitFor(condition, { interval: fetchInterval, timeout: fetchTimeout });
|
|
38
|
-
const { data: session } = await request({ url: sessionURL });
|
|
49
|
+
const { data: session } = await request({ url: sessionURL, requestCount });
|
|
39
50
|
await request({ url: sessionURL, method: "DELETE" });
|
|
40
51
|
return {
|
|
41
52
|
...session,
|
|
@@ -46,7 +57,7 @@ const fetchConfigs = async ({ connectUrl, sessionId, fetchInterval, fetchTimeout
|
|
|
46
57
|
function baseWrapSpinner(_, waiting) {
|
|
47
58
|
return Promise.resolve(waiting());
|
|
48
59
|
}
|
|
49
|
-
async function createConnect({ connectUrl, openPage, fetchInterval = 3 * 1000, retry = 1500, source = "Blocklet CLI", connectAction = "connect-cli", wrapSpinner = baseWrapSpinner, closeOnSuccess, intervalFetchConfig, }) {
|
|
60
|
+
export async function createConnect({ connectUrl, openPage, fetchInterval = 3 * 1000, retry = 1500, source = "Blocklet CLI", connectAction = "connect-cli", wrapSpinner = baseWrapSpinner, closeOnSuccess, intervalFetchConfig, }) {
|
|
50
61
|
try {
|
|
51
62
|
const startSessionURL = joinURL(connectUrl, ACCESS_KEY_SESSION_API);
|
|
52
63
|
const { data: session } = await request({ url: startSessionURL, method: "POST" });
|
|
@@ -80,13 +91,11 @@ const AGENT_HUB_PROVIDER = "aignehub";
|
|
|
80
91
|
const DEFAULT_AIGNE_HUB_MODEL = "openai/gpt-4o";
|
|
81
92
|
const DEFAULT_AIGNE_HUB_PROVIDER_MODEL = `${AGENT_HUB_PROVIDER}:${DEFAULT_AIGNE_HUB_MODEL}`;
|
|
82
93
|
const DEFAULT_URL = "https://hub.aigne.io/";
|
|
83
|
-
const formatModelName = async (models, model, inquirerPrompt) => {
|
|
84
|
-
if (process.env.NODE_ENV === "test")
|
|
85
|
-
return model;
|
|
94
|
+
export const formatModelName = async (models, model, inquirerPrompt) => {
|
|
86
95
|
if (!model)
|
|
87
96
|
return DEFAULT_AIGNE_HUB_PROVIDER_MODEL;
|
|
88
97
|
const { provider, name } = parseModelOption(model);
|
|
89
|
-
if (!provider
|
|
98
|
+
if (!provider) {
|
|
90
99
|
return DEFAULT_AIGNE_HUB_PROVIDER_MODEL;
|
|
91
100
|
}
|
|
92
101
|
const providerName = provider.replace(/-/g, "");
|
|
@@ -99,6 +108,9 @@ const formatModelName = async (models, model, inquirerPrompt) => {
|
|
|
99
108
|
if (m.apiKeyEnvName && process.env[m.apiKeyEnvName]) {
|
|
100
109
|
return model;
|
|
101
110
|
}
|
|
111
|
+
if (process.env.CI || process.env.NODE_ENV === "test") {
|
|
112
|
+
return `${AGENT_HUB_PROVIDER}:${provider}/${name}`;
|
|
113
|
+
}
|
|
102
114
|
const result = await inquirerPrompt({
|
|
103
115
|
type: "list",
|
|
104
116
|
name: "useAigneHub",
|
|
@@ -128,78 +140,84 @@ export async function loadAIGNE(path, options, checkAuthorizeOptions) {
|
|
|
128
140
|
inquirer.prompt);
|
|
129
141
|
let accessKeyOptions = {};
|
|
130
142
|
const modelName = await formatModelName(models, options?.model || "", inquirerPrompt);
|
|
131
|
-
if (
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
throw new Error("AIGNE_HUB_API_KEY key not found, need to login first");
|
|
150
|
-
}
|
|
151
|
-
accessKeyOptions = {
|
|
152
|
-
accessKey: env.AIGNE_HUB_API_KEY,
|
|
153
|
-
url: joinURL(env.AIGNE_HUB_API_URL),
|
|
154
|
-
};
|
|
143
|
+
if (process.env.CI || process.env.NODE_ENV === "test") {
|
|
144
|
+
const model = await loadModel(models, parseModelOption(modelName), undefined, accessKeyOptions);
|
|
145
|
+
return await AIGNE.load(path, { models, memories: availableMemories, model });
|
|
146
|
+
}
|
|
147
|
+
if ((modelName.toLocaleLowerCase() || "").includes(AGENT_HUB_PROVIDER)) {
|
|
148
|
+
const { origin, host } = new URL(AIGNE_HUB_URL);
|
|
149
|
+
try {
|
|
150
|
+
// aigne-hub access token
|
|
151
|
+
if (!existsSync(AIGNE_ENV_FILE)) {
|
|
152
|
+
throw new Error("AIGNE_HUB_API_KEY file not found, need to login first");
|
|
153
|
+
}
|
|
154
|
+
const data = await readFile(AIGNE_ENV_FILE, "utf8");
|
|
155
|
+
if (!data.includes("AIGNE_HUB_API_KEY")) {
|
|
156
|
+
throw new Error("AIGNE_HUB_API_KEY key not found, need to login first");
|
|
157
|
+
}
|
|
158
|
+
const envs = parse(data);
|
|
159
|
+
if (!envs[host]) {
|
|
160
|
+
throw new Error("AIGNE_HUB_API_KEY host not found, need to login first");
|
|
155
161
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
162
|
+
const env = envs[host];
|
|
163
|
+
if (!env.AIGNE_HUB_API_KEY) {
|
|
164
|
+
throw new Error("AIGNE_HUB_API_KEY key not found, need to login first");
|
|
165
|
+
}
|
|
166
|
+
accessKeyOptions = {
|
|
167
|
+
accessKey: env.AIGNE_HUB_API_KEY,
|
|
168
|
+
url: joinURL(env.AIGNE_HUB_API_URL),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
if (error instanceof Error && error.message.includes("login first")) {
|
|
173
|
+
// If none or invalid, prompt the user to proceed
|
|
174
|
+
const subscribePrompt = await inquirerPrompt({
|
|
175
|
+
type: "list",
|
|
176
|
+
name: "subscribe",
|
|
177
|
+
message: "No LLM API Keys or AIGNE Hub connections found, select your preferred way to continue:",
|
|
178
|
+
choices: [
|
|
179
|
+
{
|
|
180
|
+
name: "Connect to AIGNE Hub with just a few clicks, free credits eligible for new users (Recommended)",
|
|
181
|
+
value: true,
|
|
182
|
+
},
|
|
183
|
+
{ name: "Exit and configure my own LLM API Keys", value: false },
|
|
184
|
+
],
|
|
185
|
+
default: true,
|
|
186
|
+
});
|
|
187
|
+
if (!subscribePrompt.subscribe) {
|
|
188
|
+
console.warn("The AIGNE Hub connection has been cancelled");
|
|
189
|
+
process.exit(0);
|
|
190
|
+
}
|
|
191
|
+
const BLOCKLET_JSON_PATH = "__blocklet__.js?type=json";
|
|
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),
|
|
171
202
|
});
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
try {
|
|
181
|
-
const result = await createConnect({
|
|
182
|
-
connectUrl: connectUrl,
|
|
183
|
-
connectAction: "gen-simple-access-key",
|
|
184
|
-
source: `@aigne/cli connect to AIGNE hub`,
|
|
185
|
-
closeOnSuccess: true,
|
|
186
|
-
openPage: (pageUrl) => open(pageUrl),
|
|
187
|
-
});
|
|
188
|
-
accessKeyOptions = {
|
|
189
|
-
accessKey: result.accessKeySecret,
|
|
190
|
-
url: joinURL(origin, aigneHubMount?.mountPoint || ""),
|
|
191
|
-
};
|
|
192
|
-
// After redirection, write the AIGNE Hub access token
|
|
193
|
-
await appendFile(AIGNE_ENV_FILE, stringify({
|
|
194
|
-
[host]: {
|
|
195
|
-
AIGNE_HUB_API_KEY: accessKeyOptions.accessKey,
|
|
196
|
-
AIGNE_HUB_API_URL: accessKeyOptions.url,
|
|
197
|
-
},
|
|
198
|
-
}));
|
|
199
|
-
}
|
|
200
|
-
catch (error) {
|
|
201
|
-
console.error(error);
|
|
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 });
|
|
202
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);
|
|
203
221
|
}
|
|
204
222
|
}
|
|
205
223
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.26.0",
|
|
4
4
|
"description": "cli for AIGNE framework",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -24,11 +24,18 @@
|
|
|
24
24
|
"bunwrapper": "dist/bunwrapper.js"
|
|
25
25
|
},
|
|
26
26
|
"type": "module",
|
|
27
|
+
"main": "./dist/index.js",
|
|
28
|
+
"module": "./dist/index.js",
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
27
30
|
"exports": {
|
|
31
|
+
".": "./dist/index.js",
|
|
28
32
|
"./*": "./dist/*"
|
|
29
33
|
},
|
|
30
34
|
"typesVersions": {
|
|
31
35
|
"*": {
|
|
36
|
+
".": [
|
|
37
|
+
"./lib/dts/index.d.ts"
|
|
38
|
+
],
|
|
32
39
|
"*": [
|
|
33
40
|
"./dist/*"
|
|
34
41
|
]
|
|
@@ -38,6 +45,7 @@
|
|
|
38
45
|
"@aigne/listr2": "^1.0.10",
|
|
39
46
|
"@aigne/marked-terminal": "^7.3.2",
|
|
40
47
|
"@inquirer/prompts": "^7.6.0",
|
|
48
|
+
"@inquirer/type": "^3.0.8",
|
|
41
49
|
"@listr2/prompt-adapter-inquirer": "^3.0.1",
|
|
42
50
|
"@modelcontextprotocol/sdk": "^1.15.0",
|
|
43
51
|
"@ocap/mcrypto": "^1.21.0",
|
|
@@ -62,20 +70,20 @@
|
|
|
62
70
|
"wrap-ansi": "^9.0.0",
|
|
63
71
|
"yaml": "^2.8.0",
|
|
64
72
|
"zod": "^3.25.67",
|
|
65
|
-
"@aigne/
|
|
66
|
-
"@aigne/
|
|
67
|
-
"@aigne/aigne-hub": "^0.2.
|
|
68
|
-
"@aigne/anthropic": "^0.10.
|
|
69
|
-
"@aigne/
|
|
70
|
-
"@aigne/
|
|
71
|
-
"@aigne/
|
|
72
|
-
"@aigne/
|
|
73
|
-
"@aigne/gemini": "^0.8.
|
|
74
|
-
"@aigne/ollama": "^0.7.
|
|
75
|
-
"@aigne/
|
|
76
|
-
"@aigne/
|
|
77
|
-
"@aigne/openai": "^0.10.
|
|
78
|
-
"@aigne/xai": "^0.7.
|
|
73
|
+
"@aigne/agentic-memory": "^1.0.6",
|
|
74
|
+
"@aigne/agent-library": "^1.21.6",
|
|
75
|
+
"@aigne/aigne-hub": "^0.2.2",
|
|
76
|
+
"@aigne/anthropic": "^0.10.2",
|
|
77
|
+
"@aigne/deepseek": "^0.7.6",
|
|
78
|
+
"@aigne/bedrock": "^0.8.6",
|
|
79
|
+
"@aigne/core": "^1.39.0",
|
|
80
|
+
"@aigne/default-memory": "^1.0.6",
|
|
81
|
+
"@aigne/gemini": "^0.8.6",
|
|
82
|
+
"@aigne/ollama": "^0.7.6",
|
|
83
|
+
"@aigne/observability-api": "^0.8.2",
|
|
84
|
+
"@aigne/open-router": "^0.7.6",
|
|
85
|
+
"@aigne/openai": "^0.10.6",
|
|
86
|
+
"@aigne/xai": "^0.7.6"
|
|
79
87
|
},
|
|
80
88
|
"devDependencies": {
|
|
81
89
|
"@types/archiver": "^6.0.3",
|
|
@@ -85,6 +93,7 @@
|
|
|
85
93
|
"@types/gradient-string": "^1.1.6",
|
|
86
94
|
"@types/node": "^24.0.12",
|
|
87
95
|
"archiver": "^7.0.1",
|
|
96
|
+
"hono": "4.8.4",
|
|
88
97
|
"npm-run-all": "^4.1.5",
|
|
89
98
|
"rimraf": "^6.0.1",
|
|
90
99
|
"typescript": "^5.8.3",
|