@aigne/cli 1.59.0-beta.2 → 1.59.0-beta.20

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 CHANGED
@@ -1,5 +1,355 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.59.0-beta.20](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.59.0-beta.19...cli-v1.59.0-beta.20) (2026-01-10)
4
+
5
+
6
+ ### Dependencies
7
+
8
+ * The following workspace dependencies were updated
9
+ * dependencies
10
+ * @aigne/afs-local-fs bumped to 1.4.0-beta.16
11
+ * @aigne/agent-library bumped to 1.24.0-beta.17
12
+ * @aigne/agentic-memory bumped to 1.1.6-beta.15
13
+ * @aigne/aigne-hub bumped to 0.10.16-beta.20
14
+ * @aigne/core bumped to 1.72.0-beta.15
15
+ * @aigne/default-memory bumped to 1.4.0-beta.14
16
+ * @aigne/openai bumped to 0.16.16-beta.15
17
+ * @aigne/secrets bumped to 0.1.6-beta.15
18
+ * devDependencies
19
+ * @aigne/test-utils bumped to 0.5.69-beta.15
20
+
21
+ ## [1.59.0-beta.19](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.59.0-beta.18...cli-v1.59.0-beta.19) (2026-01-09)
22
+
23
+
24
+ ### Bug Fixes
25
+
26
+ * **cli:** cache approved commands in run-skill to avoid redundant prompts ([d07fe6d](https://github.com/AIGNE-io/aigne-framework/commit/d07fe6d049cd063e750e5b3fe231c74dae26bc9d))
27
+
28
+
29
+ ### Dependencies
30
+
31
+ * The following workspace dependencies were updated
32
+ * dependencies
33
+ * @aigne/afs-local-fs bumped to 1.4.0-beta.15
34
+ * @aigne/agent-library bumped to 1.24.0-beta.16
35
+ * @aigne/agentic-memory bumped to 1.1.6-beta.14
36
+ * @aigne/aigne-hub bumped to 0.10.16-beta.19
37
+ * @aigne/core bumped to 1.72.0-beta.14
38
+ * @aigne/default-memory bumped to 1.4.0-beta.13
39
+ * @aigne/openai bumped to 0.16.16-beta.14
40
+ * @aigne/secrets bumped to 0.1.6-beta.14
41
+ * devDependencies
42
+ * @aigne/test-utils bumped to 0.5.69-beta.14
43
+
44
+ ## [1.59.0-beta.18](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.59.0-beta.17...cli-v1.59.0-beta.18) (2026-01-08)
45
+
46
+
47
+ ### Bug Fixes
48
+
49
+ * **cli:** ask user retry when model request respond error ([#884](https://github.com/AIGNE-io/aigne-framework/issues/884)) ([60aabbb](https://github.com/AIGNE-io/aigne-framework/commit/60aabbb34be6104f25f0383c2279f7f089268631))
50
+
51
+
52
+ ### Dependencies
53
+
54
+ * The following workspace dependencies were updated
55
+ * dependencies
56
+ * @aigne/aigne-hub bumped to 0.10.16-beta.18
57
+
58
+ ## [1.59.0-beta.17](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.59.0-beta.16...cli-v1.59.0-beta.17) (2026-01-08)
59
+
60
+
61
+ ### Features
62
+
63
+ * **afs,bash:** add physical path mapping for AFS modules in bash execution ([#881](https://github.com/AIGNE-io/aigne-framework/issues/881)) ([50dbda2](https://github.com/AIGNE-io/aigne-framework/commit/50dbda224bd666d951494d2449779830d8db57fc))
64
+
65
+
66
+ ### Bug Fixes
67
+
68
+ * bump version ([696560f](https://github.com/AIGNE-io/aigne-framework/commit/696560fa2673eddcb4d00ac0523fbbbde7273cb3))
69
+
70
+
71
+ ### Dependencies
72
+
73
+ * The following workspace dependencies were updated
74
+ * dependencies
75
+ * @aigne/afs bumped to 1.4.0-beta.7
76
+ * @aigne/afs-history bumped to 1.2.0-beta.8
77
+ * @aigne/afs-local-fs bumped to 1.4.0-beta.14
78
+ * @aigne/agent-library bumped to 1.24.0-beta.15
79
+ * @aigne/agentic-memory bumped to 1.1.6-beta.13
80
+ * @aigne/aigne-hub bumped to 0.10.16-beta.17
81
+ * @aigne/core bumped to 1.72.0-beta.13
82
+ * @aigne/default-memory bumped to 1.4.0-beta.12
83
+ * @aigne/observability-api bumped to 0.11.14-beta.2
84
+ * @aigne/openai bumped to 0.16.16-beta.13
85
+ * @aigne/secrets bumped to 0.1.6-beta.13
86
+ * devDependencies
87
+ * @aigne/test-utils bumped to 0.5.69-beta.13
88
+
89
+ ## [1.59.0-beta.16](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.59.0-beta.15...cli-v1.59.0-beta.16) (2026-01-07)
90
+
91
+
92
+ ### Dependencies
93
+
94
+ * The following workspace dependencies were updated
95
+ * dependencies
96
+ * @aigne/afs-local-fs bumped to 1.4.0-beta.13
97
+
98
+ ## [1.59.0-beta.15](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.59.0-beta.14...cli-v1.59.0-beta.15) (2026-01-07)
99
+
100
+
101
+ ### Dependencies
102
+
103
+ * The following workspace dependencies were updated
104
+ * dependencies
105
+ * @aigne/afs-local-fs bumped to 1.4.0-beta.12
106
+ * @aigne/agent-library bumped to 1.24.0-beta.14
107
+ * @aigne/agentic-memory bumped to 1.1.6-beta.12
108
+ * @aigne/aigne-hub bumped to 0.10.16-beta.16
109
+ * @aigne/core bumped to 1.72.0-beta.12
110
+ * @aigne/default-memory bumped to 1.4.0-beta.11
111
+ * @aigne/openai bumped to 0.16.16-beta.12
112
+ * @aigne/secrets bumped to 0.1.6-beta.12
113
+ * devDependencies
114
+ * @aigne/test-utils bumped to 0.5.69-beta.12
115
+
116
+ ## [1.59.0-beta.14](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.59.0-beta.13...cli-v1.59.0-beta.14) (2026-01-06)
117
+
118
+
119
+ ### Bug Fixes
120
+
121
+ * **core:** preserve Agent Skill in session compact and support complex tool result content ([#876](https://github.com/AIGNE-io/aigne-framework/issues/876)) ([edb86ae](https://github.com/AIGNE-io/aigne-framework/commit/edb86ae2b9cfe56a8f08b276f843606e310566cf))
122
+
123
+
124
+ ### Dependencies
125
+
126
+ * The following workspace dependencies were updated
127
+ * dependencies
128
+ * @aigne/afs bumped to 1.4.0-beta.6
129
+ * @aigne/afs-history bumped to 1.2.0-beta.7
130
+ * @aigne/afs-local-fs bumped to 1.4.0-beta.11
131
+ * @aigne/agent-library bumped to 1.24.0-beta.13
132
+ * @aigne/agentic-memory bumped to 1.1.6-beta.11
133
+ * @aigne/aigne-hub bumped to 0.10.16-beta.15
134
+ * @aigne/core bumped to 1.72.0-beta.11
135
+ * @aigne/default-memory bumped to 1.4.0-beta.10
136
+ * @aigne/openai bumped to 0.16.16-beta.11
137
+ * @aigne/secrets bumped to 0.1.6-beta.11
138
+ * devDependencies
139
+ * @aigne/test-utils bumped to 0.5.69-beta.11
140
+
141
+ ## [1.59.0-beta.13](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.59.0-beta.12...cli-v1.59.0-beta.13) (2026-01-06)
142
+
143
+
144
+ ### Features
145
+
146
+ * **core:** add cross session user memory support ([#873](https://github.com/AIGNE-io/aigne-framework/issues/873)) ([f377aa1](https://github.com/AIGNE-io/aigne-framework/commit/f377aa17f2cf8004fd3225ade4a37fd90af1292f))
147
+
148
+
149
+ ### Bug Fixes
150
+
151
+ * **cli:** add askUserQuestion for run-skill command ([9c621e7](https://github.com/AIGNE-io/aigne-framework/commit/9c621e7c55501d129e71966da79514717a4579ab))
152
+
153
+
154
+ ### Dependencies
155
+
156
+ * The following workspace dependencies were updated
157
+ * dependencies
158
+ * @aigne/afs-history bumped to 1.2.0-beta.6
159
+ * @aigne/afs-local-fs bumped to 1.4.0-beta.10
160
+ * @aigne/agent-library bumped to 1.24.0-beta.12
161
+ * @aigne/agentic-memory bumped to 1.1.6-beta.10
162
+ * @aigne/aigne-hub bumped to 0.10.16-beta.14
163
+ * @aigne/core bumped to 1.72.0-beta.10
164
+ * @aigne/default-memory bumped to 1.4.0-beta.9
165
+ * @aigne/openai bumped to 0.16.16-beta.10
166
+ * @aigne/secrets bumped to 0.1.6-beta.10
167
+ * devDependencies
168
+ * @aigne/test-utils bumped to 0.5.69-beta.10
169
+
170
+ ## [1.59.0-beta.12](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.59.0-beta.11...cli-v1.59.0-beta.12) (2026-01-02)
171
+
172
+
173
+ ### Features
174
+
175
+ * **cli:** add run-skill command ([#868](https://github.com/AIGNE-io/aigne-framework/issues/868)) ([f62ffe2](https://github.com/AIGNE-io/aigne-framework/commit/f62ffe21acc49ec1a68349fbb35a13d0fadd239a))
176
+
177
+
178
+ ### Bug Fixes
179
+
180
+ * **cli:** add chat aliases for interactive option ([#867](https://github.com/AIGNE-io/aigne-framework/issues/867)) ([91f27fd](https://github.com/AIGNE-io/aigne-framework/commit/91f27fd874b8c4b2ded2d7cd46e2821f70943c69))
181
+ * **cli:** rename cmd option --chat to --interactive ([#865](https://github.com/AIGNE-io/aigne-framework/issues/865)) ([480eca4](https://github.com/AIGNE-io/aigne-framework/commit/480eca49a7381a330024f1f0026bbc5f89b57bbb))
182
+
183
+
184
+ ### Dependencies
185
+
186
+ * The following workspace dependencies were updated
187
+ * dependencies
188
+ * @aigne/afs-local-fs bumped to 1.4.0-beta.9
189
+ * @aigne/agent-library bumped to 1.24.0-beta.11
190
+ * @aigne/agentic-memory bumped to 1.1.6-beta.9
191
+ * @aigne/aigne-hub bumped to 0.10.16-beta.13
192
+ * @aigne/core bumped to 1.72.0-beta.9
193
+ * @aigne/default-memory bumped to 1.4.0-beta.8
194
+ * @aigne/openai bumped to 0.16.16-beta.9
195
+ * @aigne/secrets bumped to 0.1.6-beta.9
196
+ * devDependencies
197
+ * @aigne/test-utils bumped to 0.5.69-beta.9
198
+
199
+ ## [1.59.0-beta.11](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.59.0-beta.10...cli-v1.59.0-beta.11) (2025-12-31)
200
+
201
+
202
+ ### Features
203
+
204
+ * add session compact support for AIAgent ([#863](https://github.com/AIGNE-io/aigne-framework/issues/863)) ([9010918](https://github.com/AIGNE-io/aigne-framework/commit/9010918cd3f18b02b5c60ddc9ed5c34b568d0b28))
205
+
206
+
207
+ ### Dependencies
208
+
209
+ * The following workspace dependencies were updated
210
+ * dependencies
211
+ * @aigne/afs bumped to 1.4.0-beta.5
212
+ * @aigne/afs-history bumped to 1.2.0-beta.5
213
+ * @aigne/afs-local-fs bumped to 1.4.0-beta.8
214
+ * @aigne/agent-library bumped to 1.24.0-beta.10
215
+ * @aigne/agentic-memory bumped to 1.1.6-beta.8
216
+ * @aigne/aigne-hub bumped to 0.10.16-beta.12
217
+ * @aigne/core bumped to 1.72.0-beta.8
218
+ * @aigne/default-memory bumped to 1.4.0-beta.7
219
+ * @aigne/openai bumped to 0.16.16-beta.8
220
+ * @aigne/secrets bumped to 0.1.6-beta.8
221
+ * devDependencies
222
+ * @aigne/test-utils bumped to 0.5.69-beta.8
223
+
224
+ ## [1.59.0-beta.10](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.59.0-beta.9...cli-v1.59.0-beta.10) (2025-12-26)
225
+
226
+
227
+ ### Dependencies
228
+
229
+ * The following workspace dependencies were updated
230
+ * dependencies
231
+ * @aigne/agent-library bumped to 1.24.0-beta.9
232
+ * @aigne/aigne-hub bumped to 0.10.16-beta.11
233
+
234
+ ## [1.59.0-beta.9](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.59.0-beta.8...cli-v1.59.0-beta.9) (2025-12-26)
235
+
236
+
237
+ ### Features
238
+
239
+ * **core:** add session history support ([#858](https://github.com/AIGNE-io/aigne-framework/issues/858)) ([28a070e](https://github.com/AIGNE-io/aigne-framework/commit/28a070ed33b821d1fd344b899706d817ca992b9f))
240
+
241
+
242
+ ### Dependencies
243
+
244
+ * The following workspace dependencies were updated
245
+ * dependencies
246
+ * @aigne/afs bumped to 1.4.0-beta.4
247
+ * @aigne/afs-history bumped to 1.2.0-beta.4
248
+ * @aigne/afs-local-fs bumped to 1.4.0-beta.7
249
+ * @aigne/agent-library bumped to 1.24.0-beta.8
250
+ * @aigne/agentic-memory bumped to 1.1.6-beta.7
251
+ * @aigne/aigne-hub bumped to 0.10.16-beta.10
252
+ * @aigne/core bumped to 1.72.0-beta.7
253
+ * @aigne/default-memory bumped to 1.4.0-beta.6
254
+ * @aigne/openai bumped to 0.16.16-beta.7
255
+ * @aigne/secrets bumped to 0.1.6-beta.7
256
+ * devDependencies
257
+ * @aigne/test-utils bumped to 0.5.69-beta.7
258
+
259
+ ## [1.59.0-beta.8](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.59.0-beta.7...cli-v1.59.0-beta.8) (2025-12-25)
260
+
261
+
262
+ ### Dependencies
263
+
264
+ * The following workspace dependencies were updated
265
+ * dependencies
266
+ * @aigne/afs-local-fs bumped to 1.4.0-beta.6
267
+ * @aigne/agent-library bumped to 1.24.0-beta.7
268
+ * @aigne/agentic-memory bumped to 1.1.6-beta.6
269
+ * @aigne/aigne-hub bumped to 0.10.16-beta.9
270
+ * @aigne/core bumped to 1.72.0-beta.6
271
+ * @aigne/default-memory bumped to 1.3.6-beta.6
272
+ * @aigne/openai bumped to 0.16.16-beta.6
273
+ * @aigne/secrets bumped to 0.1.6-beta.6
274
+ * devDependencies
275
+ * @aigne/test-utils bumped to 0.5.69-beta.6
276
+
277
+ ## [1.59.0-beta.7](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.59.0-beta.6...cli-v1.59.0-beta.7) (2025-12-25)
278
+
279
+
280
+ ### Dependencies
281
+
282
+ * The following workspace dependencies were updated
283
+ * dependencies
284
+ * @aigne/aigne-hub bumped to 0.10.16-beta.8
285
+
286
+ ## [1.59.0-beta.6](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.59.0-beta.5...cli-v1.59.0-beta.6) (2025-12-25)
287
+
288
+
289
+ ### Dependencies
290
+
291
+ * The following workspace dependencies were updated
292
+ * dependencies
293
+ * @aigne/agent-library bumped to 1.24.0-beta.6
294
+ * @aigne/aigne-hub bumped to 0.10.16-beta.7
295
+
296
+ ## [1.59.0-beta.5](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.59.0-beta.4...cli-v1.59.0-beta.5) (2025-12-25)
297
+
298
+
299
+ ### Dependencies
300
+
301
+ * The following workspace dependencies were updated
302
+ * dependencies
303
+ * @aigne/afs-local-fs bumped to 1.4.0-beta.5
304
+ * @aigne/agent-library bumped to 1.24.0-beta.5
305
+ * @aigne/agentic-memory bumped to 1.1.6-beta.5
306
+ * @aigne/aigne-hub bumped to 0.10.16-beta.6
307
+ * @aigne/core bumped to 1.72.0-beta.5
308
+ * @aigne/default-memory bumped to 1.3.6-beta.5
309
+ * @aigne/openai bumped to 0.16.16-beta.5
310
+ * @aigne/secrets bumped to 0.1.6-beta.5
311
+ * devDependencies
312
+ * @aigne/test-utils bumped to 0.5.69-beta.5
313
+
314
+ ## [1.59.0-beta.4](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.59.0-beta.3...cli-v1.59.0-beta.4) (2025-12-24)
315
+
316
+
317
+ ### Features
318
+
319
+ * add Agent Skill support ([#787](https://github.com/AIGNE-io/aigne-framework/issues/787)) ([f04fbe7](https://github.com/AIGNE-io/aigne-framework/commit/f04fbe76ec24cf3c59c74adf92d87b0c3784a8f7))
320
+
321
+
322
+ ### Bug Fixes
323
+
324
+ * **cli:** improve terminal outputs ([#847](https://github.com/AIGNE-io/aigne-framework/issues/847)) ([329e91b](https://github.com/AIGNE-io/aigne-framework/commit/329e91bc3323f72fc8a2d278ff5e6bba9adbd6e0))
325
+
326
+
327
+ ### Dependencies
328
+
329
+ * The following workspace dependencies were updated
330
+ * dependencies
331
+ * @aigne/afs bumped to 1.4.0-beta.3
332
+ * @aigne/afs-history bumped to 1.2.0-beta.3
333
+ * @aigne/afs-local-fs bumped to 1.4.0-beta.4
334
+ * @aigne/agent-library bumped to 1.24.0-beta.4
335
+ * @aigne/agentic-memory bumped to 1.1.6-beta.4
336
+ * @aigne/aigne-hub bumped to 0.10.16-beta.5
337
+ * @aigne/core bumped to 1.72.0-beta.4
338
+ * @aigne/default-memory bumped to 1.3.6-beta.4
339
+ * @aigne/openai bumped to 0.16.16-beta.4
340
+ * @aigne/secrets bumped to 0.1.6-beta.4
341
+ * devDependencies
342
+ * @aigne/test-utils bumped to 0.5.69-beta.4
343
+
344
+ ## [1.59.0-beta.3](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.59.0-beta.2...cli-v1.59.0-beta.3) (2025-12-22)
345
+
346
+
347
+ ### Dependencies
348
+
349
+ * The following workspace dependencies were updated
350
+ * dependencies
351
+ * @aigne/aigne-hub bumped to 0.10.16-beta.4
352
+
3
353
  ## [1.59.0-beta.2](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.58.1-beta.2...cli-v1.59.0-beta.2) (2025-12-19)
4
354
 
5
355
 
@@ -8,6 +8,7 @@ import { createEvalCommand } from "./eval.js";
8
8
  import { createHubCommand } from "./hub.js";
9
9
  import { createObservabilityCommand } from "./observe.js";
10
10
  import { createRunCommand } from "./run.js";
11
+ import { createRunSkillCommand } from "./run-skill.js";
11
12
  import { createServeMCPCommand } from "./serve-mcp.js";
12
13
  import { createTestCommand } from "./test.js";
13
14
  export function createAIGNECommand(options) {
@@ -17,6 +18,7 @@ export function createAIGNECommand(options) {
17
18
  .version(AIGNE_CLI_VERSION)
18
19
  // default command: when user runs `aigne` without subcommand, behave like `aigne run`
19
20
  .command(createRunCommand(options))
21
+ .command(createRunSkillCommand())
20
22
  .command(createEvalCommand(options))
21
23
  .command(createTestCommand(options))
22
24
  .command(createCreateCommand())
@@ -1,5 +1,7 @@
1
1
  import assert from "node:assert";
2
+ import { DEFAULT_USER_ID } from "@aigne/cli/constants.js";
2
3
  import { logger } from "@aigne/core/utils/logger.js";
4
+ import { v7 } from "@aigne/uuid";
3
5
  import { runAgentWithAIGNE } from "../../utils/run-with-aigne.js";
4
6
  import { parseAgentInput, withAgentInputSchema, } from "../../utils/yargs.js";
5
7
  import { serveMCPServerFromDir } from "../serve-mcp.js";
@@ -96,7 +98,9 @@ export async function invokeAgent(options) {
96
98
  await runAgentWithAIGNE(aigne, agent, {
97
99
  ...options.input,
98
100
  input,
99
- chat: options.input.chat,
101
+ interactive: options.input.interactive,
102
+ sessionId: options.input.sessionId || v7(),
103
+ userId: DEFAULT_USER_ID,
100
104
  });
101
105
  }
102
106
  finally {
@@ -0,0 +1,6 @@
1
+ import type { CommandModule } from "yargs";
2
+ import { type AgentRunCommonOptions } from "../utils/yargs.js";
3
+ export declare function createRunSkillCommand(): CommandModule<unknown, {
4
+ skill?: string[];
5
+ interactive?: boolean;
6
+ } & AgentRunCommonOptions>;
@@ -0,0 +1,102 @@
1
+ import { basename, resolve } from "node:path";
2
+ import { AFSHistory } from "@aigne/afs-history";
3
+ import { LocalFS } from "@aigne/afs-local-fs";
4
+ import AgentSkillManager from "@aigne/agent-library/agent-skill-manager";
5
+ import AskUserQuestion from "@aigne/agent-library/ask-user-question";
6
+ import BashAgent from "@aigne/agent-library/bash";
7
+ import { AIGNE, FunctionAgent } from "@aigne/core";
8
+ import { z } from "zod";
9
+ import { loadChatModel } from "../utils/aigne-hub/model.js";
10
+ import { withAgentInputSchema } from "../utils/yargs.js";
11
+ import { invokeAgent } from "./app/agent.js";
12
+ export function createRunSkillCommand() {
13
+ return {
14
+ command: ["run-skill"],
15
+ describe: "Run Agent Skill for the specified path",
16
+ builder: async (yargs) => {
17
+ return withAgentInputSchema(yargs
18
+ .option("skill", {
19
+ array: true,
20
+ type: "string",
21
+ describe: "Path to the Agent Skill directory",
22
+ })
23
+ .option("interactive", {
24
+ describe: "Run in interactive chat mode",
25
+ type: "boolean",
26
+ default: false,
27
+ alias: ["chat"],
28
+ })
29
+ .demandOption("skill"), {
30
+ inputSchema: z.object({
31
+ message: z.string(),
32
+ }),
33
+ optionalInputs: ["message"],
34
+ });
35
+ },
36
+ handler: async (options) => {
37
+ if (!Array.isArray(options.skill) || options.skill.length === 0) {
38
+ throw new Error("At least one skill path must be provided.");
39
+ }
40
+ const model = await loadChatModel({
41
+ model: options.model || "aignehub/anthropic/claude-sonnet-4-5",
42
+ });
43
+ const aigne = new AIGNE({ model });
44
+ const approvedCmds = new Set();
45
+ const agent = new AgentSkillManager({
46
+ inputKey: "message",
47
+ taskRenderMode: "collapse",
48
+ skills: [
49
+ new BashAgent({
50
+ sandbox: false,
51
+ permissions: {
52
+ defaultMode: "ask",
53
+ guard: FunctionAgent.from(async (input, options) => {
54
+ if (approvedCmds.has(input.script || "")) {
55
+ return {
56
+ approved: true,
57
+ };
58
+ }
59
+ const confirm = options.prompts?.confirm;
60
+ if (!confirm)
61
+ throw new Error("No confirm prompt available for permission guard.");
62
+ const approved = await confirm({ message: `Run command ${input.script}?` });
63
+ if (approved && input.script) {
64
+ approvedCmds.add(input.script);
65
+ }
66
+ return {
67
+ approved,
68
+ };
69
+ }),
70
+ },
71
+ }),
72
+ new AskUserQuestion(),
73
+ ],
74
+ afs: {
75
+ modules: [
76
+ new AFSHistory({}),
77
+ new LocalFS({
78
+ name: "workspace",
79
+ localPath: process.cwd(),
80
+ description: `\
81
+ Current working directory. All temporary files should be written here using absolute AFS paths (e.g., /modules/workspace/temp.py).
82
+ Note: Bash is already running in this directory, so do NOT use 'cd /modules/workspace' in scripts. Use relative paths directly (e.g., python temp.py).`,
83
+ }),
84
+ ...options.skill.map((path) => new LocalFS({
85
+ name: basename(resolve(path)),
86
+ localPath: path,
87
+ description: "Contains Agent Skills. Use 'Skill' tool to invoke skills from this module.",
88
+ agentSkills: true,
89
+ })),
90
+ ],
91
+ },
92
+ });
93
+ await invokeAgent({
94
+ aigne,
95
+ agent,
96
+ input: {
97
+ ...options,
98
+ },
99
+ });
100
+ },
101
+ };
102
+ }
@@ -5,5 +5,5 @@ export declare function createRunCommand({ aigneFilePath, }?: {
5
5
  version?: boolean;
6
6
  path?: string;
7
7
  entryAgent?: string;
8
- chat?: boolean;
8
+ interactive?: boolean;
9
9
  }>;
@@ -38,10 +38,11 @@ export function createRunCommand({ aigneFilePath, } = {}) {
38
38
  alias: "v",
39
39
  describe: "Show version number",
40
40
  })
41
- .option("chat", {
42
- describe: "Run chat loop in terminal",
41
+ .option("interactive", {
42
+ describe: "Run in interactive chat mode",
43
43
  type: "boolean",
44
44
  default: false,
45
+ alias: ["chat"],
45
46
  })
46
47
  .help(false)
47
48
  .version(false)
@@ -60,15 +61,16 @@ export function createRunCommand({ aigneFilePath, } = {}) {
60
61
  }
61
62
  }
62
63
  const path = aigneFilePath || options.path || ".";
63
- if (!(await findAIGNEFile(path).catch((error) => {
64
- if (options._[0] !== "run") {
65
- yargsInstance?.showHelp();
66
- }
67
- else {
68
- throw error;
69
- }
70
- return false;
71
- }))) {
64
+ if (!isUrl(path) &&
65
+ !(await findAIGNEFile(path).catch((error) => {
66
+ if (options._[0] !== "run") {
67
+ yargsInstance?.showHelp();
68
+ }
69
+ else {
70
+ throw error;
71
+ }
72
+ return false;
73
+ }))) {
72
74
  return;
73
75
  }
74
76
  // Parse model options for loading application
@@ -88,7 +90,7 @@ export function createRunCommand({ aigneFilePath, } = {}) {
88
90
  // Allow user to run all of agents in the AIGNE instances
89
91
  const allAgents = flat(aigne.agents, aigne.skills, aigne.cli.chat, aigne.mcpServer.agents);
90
92
  for (const agent of allAgents) {
91
- subYargs.command(agentCommandModule({ aigne, agent, chat: options.chat }));
93
+ subYargs.command(agentCommandModule({ aigne, agent, chat: options.interactive }));
92
94
  }
93
95
  for (const cliAgent of aigne.cli.agents ?? []) {
94
96
  subYargs.command(cliAgentCommandModule({
@@ -3,3 +3,4 @@ export declare const AIGNE_CLI_VERSION: any;
3
3
  export declare const availableMemories: (typeof DefaultMemory)[];
4
4
  export declare const AIGNE_HUB_CREDITS_NOT_ENOUGH_ERROR_TYPE = "NOT_ENOUGH";
5
5
  export declare const CHAT_MODEL_OPTIONS: string[];
6
+ export declare const DEFAULT_USER_ID = "cli-user";
package/dist/constants.js CHANGED
@@ -17,3 +17,4 @@ export const CHAT_MODEL_OPTIONS = [
17
17
  "preferInputFileType",
18
18
  "reasoningEffort",
19
19
  ];
20
+ export const DEFAULT_USER_ID = "cli-user";
@@ -154,6 +154,7 @@ export class TerminalTracer {
154
154
  }
155
155
  task.resolve();
156
156
  };
157
+ let retryPromptPromise;
157
158
  const onError = async ({ context, agent, error, ...event }) => {
158
159
  if ("type" in error && error.type === AIGNE_HUB_CREDITS_NOT_ENOUGH_ERROR_TYPE) {
159
160
  if (!Object.hasOwn(error, CREDITS_ERROR_PROCESSED_FLAG)) {
@@ -168,6 +169,23 @@ export class TerminalTracer {
168
169
  }
169
170
  }
170
171
  }
172
+ if (agent instanceof ChatModel) {
173
+ retryPromptPromise ??= this.proxiedPrompts
174
+ .select({
175
+ message: chalk.red(`Error: ${error.message}`),
176
+ choices: [
177
+ { value: "retry", name: "Retry" },
178
+ { value: "exit", name: "Exit" },
179
+ ],
180
+ })
181
+ .then((result) => ({ retry: result === "retry" }))
182
+ .finally(() => {
183
+ retryPromptPromise = undefined;
184
+ });
185
+ const { retry } = await retryPromptPromise;
186
+ if (retry)
187
+ return { retry: true };
188
+ }
171
189
  const contextId = context.id;
172
190
  const task = this.tasks[contextId];
173
191
  if (!task)
@@ -6,6 +6,7 @@ export declare function terminalInput({ render: r, ...options }?: {
6
6
  required?: boolean;
7
7
  validate?: (input: string) => string | boolean | Promise<string | boolean>;
8
8
  render?: typeof render;
9
+ clear?: boolean;
9
10
  }): Promise<string>;
10
11
  export declare function TerminalInput(props: {
11
12
  message?: string;
@@ -12,10 +12,14 @@ export async function terminalInput({ render: r = render, ...options } = {}) {
12
12
  process.addListener("SIGINT", handleSigInt);
13
13
  const clean = () => process.removeListener("SIGINT", handleSigInt);
14
14
  const app = r(_jsx(TerminalInput, { ...options, onSubmit: (value) => {
15
+ if (options.clear)
16
+ app.clear();
15
17
  app.unmount();
16
18
  resolve(value);
17
19
  clean();
18
20
  }, onError: (error) => {
21
+ if (options.clear)
22
+ app.clear();
19
23
  app.unmount();
20
24
  reject(error);
21
25
  clean();
@@ -1,5 +1,5 @@
1
1
  import { logger } from "@aigne/core/utils/logger.js";
2
- import { AIGNE_ENV_FILE } from "../constants.js";
2
+ import { AIGNE_ENV_FILE, isTest } from "../constants.js";
3
3
  import FileStore from "./file.js";
4
4
  import KeyringStore from "./keytar.js";
5
5
  import { migrateFileToKeyring } from "./migrate.js";
@@ -32,7 +32,7 @@ const getSecretStore = async () => {
32
32
  cachedSecretStore = await createSecretStore({
33
33
  filepath: AIGNE_ENV_FILE,
34
34
  serviceName: "aigne-hub",
35
- // forceKeytarUnavailable: true,
35
+ forceKeytarUnavailable: Boolean(isTest),
36
36
  });
37
37
  }
38
38
  return cachedSecretStore;
@@ -1,4 +1,4 @@
1
- import type { AgentResponseStream, Message } from "@aigne/core";
1
+ import { type AgentResponseStream, type Message } from "@aigne/core";
2
2
  import type { PromiseOrValue } from "@aigne/core/utils/type-utils.js";
3
3
  import { DefaultRenderer, Listr, type ListrDefaultRendererOptions, ListrLogger, type ListrSimpleRendererOptions, type ListrTaskWrapper, SimpleRenderer, Spinner } from "@aigne/listr2";
4
4
  import type { createLogUpdate } from "log-update";
@@ -22,7 +22,9 @@ export declare class AIGNEListr extends Listr<object, typeof AIGNEListrRenderer,
22
22
  renderImage?: boolean;
23
23
  }) => string | Promise<string>;
24
24
  }, ...[task, options, parentTask]: ConstructorParameters<typeof Listr<object, typeof AIGNEListrRenderer, typeof AIGNEListrFallbackRenderer>>);
25
+ private needLogResult;
25
26
  run(stream: () => PromiseOrValue<AgentResponseStream<Message>>): Promise<Message>;
27
+ private marked;
26
28
  private extractStream;
27
29
  }
28
30
  export interface AIGNEListrRendererOptions extends ListrDefaultRendererOptions {
@@ -1,8 +1,12 @@
1
1
  import { EOL } from "node:os";
2
2
  import { format } from "node:util";
3
+ import { isAgentResponseProgress } from "@aigne/core";
3
4
  import { LogLevel, logger } from "@aigne/core/utils/logger.js";
4
5
  import { mergeAgentResponseChunk } from "@aigne/core/utils/stream-utils.js";
5
6
  import { color, DefaultRenderer, figures, Listr, ListrDefaultRendererLogLevels, ListrLogger, SimpleRenderer, Spinner, } from "@aigne/listr2";
7
+ import { markedTerminal } from "@aigne/marked-terminal";
8
+ import chalk from "chalk";
9
+ import { Marked } from "marked";
6
10
  import wrap from "wrap-ansi";
7
11
  export class AIGNEListr extends Listr {
8
12
  myOptions;
@@ -15,13 +19,12 @@ export class AIGNEListr extends Listr {
15
19
  getStdoutLogs: () => {
16
20
  return this.logs.splice(0);
17
21
  },
18
- getBottomBarLogs: (options) => {
19
- if (!options?.running)
20
- return [];
21
- const r = this.myOptions.formatResult(this.result);
22
- if (typeof r !== "string")
23
- throw new Error("Must return a string result for running task");
24
- return [r];
22
+ getBottomBarLogs: (_options) => {
23
+ // if (!options?.running) return [];
24
+ // const r = this.myOptions.formatResult(this.result);
25
+ // if (typeof r !== "string") throw new Error("Must return a string result for running task");
26
+ // return [r];
27
+ return [];
25
28
  },
26
29
  };
27
30
  super(task, {
@@ -55,6 +58,7 @@ export class AIGNEListr extends Listr {
55
58
  this.myOptions = myOptions;
56
59
  this.spinner = new Spinner();
57
60
  }
61
+ needLogResult = true;
58
62
  async run(stream) {
59
63
  const originalLog = logger.logMessage;
60
64
  const originalConsole = { ...console };
@@ -81,7 +85,9 @@ export class AIGNEListr extends Listr {
81
85
  throw this.error;
82
86
  return { ...this.result };
83
87
  });
84
- console.log(await this.myOptions.formatResult(this.result, { running: false, renderImage: true }));
88
+ if (this.needLogResult) {
89
+ console.log(await this.myOptions.formatResult(this.result, { running: false, renderImage: true }));
90
+ }
85
91
  return result;
86
92
  }
87
93
  finally {
@@ -90,11 +96,56 @@ export class AIGNEListr extends Listr {
90
96
  this.spinner.stop();
91
97
  }
92
98
  }
99
+ marked = new Marked().use({
100
+ // marked-terminal does not support code block meta, so we need to strip it
101
+ walkTokens: (token) => {
102
+ if (token.type === "code") {
103
+ if (typeof token.lang === "string") {
104
+ token.lang = token.lang.trim().split(/\s+/)[0];
105
+ }
106
+ }
107
+ },
108
+ }, markedTerminal({ forceHyperLink: false }, {
109
+ theme: {
110
+ string: chalk.green,
111
+ },
112
+ }));
93
113
  async extractStream(stream) {
94
114
  try {
95
115
  this.result = {};
96
116
  for await (const value of stream) {
97
117
  mergeAgentResponseChunk(this.result, value);
118
+ if (isAgentResponseProgress(value) && value.progress.event === "message") {
119
+ const { message } = value.progress;
120
+ const rendered = [];
121
+ if (message.role === "user" || message.role === "agent") {
122
+ if (message.role === "agent" && message.toolCalls) {
123
+ for (const call of message.toolCalls) {
124
+ rendered.push(`${chalk.bold.gray(`[${call.function.name}]`)} ${chalk.gray(`${JSON.stringify(call.function.arguments).slice(0, 200)}...`)}`);
125
+ }
126
+ }
127
+ else if (typeof message.content === "string") {
128
+ rendered.push(this.marked.parse(message.content, { async: false }).trim());
129
+ }
130
+ else if (Array.isArray(message.content)) {
131
+ for (const msg of message.content) {
132
+ if (msg.type === "text") {
133
+ if (msg.isThinking) {
134
+ rendered.push(chalk.dim(chalk.grey(chalk.italic(`[Thinking] ${msg.text}`))));
135
+ }
136
+ else {
137
+ rendered.push(this.marked.parse(msg.text, { async: false }).trim());
138
+ }
139
+ }
140
+ }
141
+ }
142
+ }
143
+ if (rendered.length) {
144
+ const prefix = message.role === "user" ? chalk.blue.bold(">") : chalk.green.bold("•");
145
+ console.log(`${prefix} ${rendered.join("\n")}\n`);
146
+ this.needLogResult = false;
147
+ }
148
+ }
98
149
  }
99
150
  return this.result;
100
151
  }
@@ -55,12 +55,12 @@ export async function loadAIGNE({ path, modelOptions, imageModelOptions, skipMod
55
55
  availableModules: [
56
56
  {
57
57
  module: "history",
58
- create: (options) => import("@aigne/afs-history").then((m) => new m.AFSHistory(options)),
58
+ load: (options) => import("@aigne/afs-history").then((m) => new m.AFSHistory(options.parsed)),
59
59
  },
60
60
  {
61
61
  module: "local-fs",
62
62
  alias: ["system-fs"],
63
- create: (options) => import("@aigne/afs-local-fs").then((m) => new m.LocalFS(options)),
63
+ load: (options) => import("@aigne/afs-local-fs").then((m) => m.LocalFS.load(options)),
64
64
  },
65
65
  ],
66
66
  },
@@ -1,6 +1,8 @@
1
1
  import { type Message, type UserAgent } from "@aigne/core";
2
2
  export declare const DEFAULT_CHAT_INPUT_KEY = "message";
3
3
  export interface ChatLoopOptions {
4
+ userId?: string;
5
+ sessionId?: string;
4
6
  initialCall?: Message | string;
5
7
  welcome?: string;
6
8
  defaultQuestion?: string;
@@ -19,6 +19,7 @@ export async function runChatLoopInTerminal(userAgent, options = {}) {
19
19
  const question = await terminalInput({
20
20
  message: "💬",
21
21
  default: i === 0 ? options?.defaultQuestion : undefined,
22
+ clear: true,
22
23
  });
23
24
  if (!question?.trim())
24
25
  continue;
@@ -74,7 +75,7 @@ async function callAgent(userAgent, input, options) {
74
75
  const tracer = new TerminalTracer(userAgent.context, options);
75
76
  await tracer.run(userAgent, typeof input === "string"
76
77
  ? { ...options.input, [options.inputKey || DEFAULT_CHAT_INPUT_KEY]: input }
77
- : { ...options.input, ...input });
78
+ : { ...options.input, ...input }, { userContext: { sessionId: options.sessionId, userId: options.userId } });
78
79
  }
79
80
  const COMMANDS = {
80
81
  "/exit": () => ({ exit: true }),
@@ -15,7 +15,9 @@ export declare function runWithAIGNE(agentCreator: ((aigne: AIGNE) => PromiseOrV
15
15
  modelOptions?: ChatModelInputOptions;
16
16
  outputKey?: string;
17
17
  }): Promise<void>;
18
- export declare function runAgentWithAIGNE(aigne: AIGNE, agent: Agent, { outputKey, outputFileKey, chatLoopOptions, ...options }?: {
18
+ export declare function runAgentWithAIGNE(aigne: AIGNE, agent: Agent, { userId, sessionId, outputKey, outputFileKey, chatLoopOptions, ...options }?: {
19
+ userId?: string;
20
+ sessionId?: string;
19
21
  outputKey?: string;
20
22
  outputFileKey?: string;
21
23
  chatLoopOptions?: ChatLoopOptions;
@@ -84,7 +84,7 @@ export async function runWithAIGNE(agentCreator, { aigne, argv = process.argv, c
84
84
  process.exit(1);
85
85
  });
86
86
  }
87
- export async function runAgentWithAIGNE(aigne, agent, { outputKey, outputFileKey, chatLoopOptions, ...options } = {}) {
87
+ export async function runAgentWithAIGNE(aigne, agent, { userId, sessionId, outputKey, outputFileKey, chatLoopOptions, ...options } = {}) {
88
88
  if (options.output) {
89
89
  const outputPath = isAbsolute(options.output)
90
90
  ? options.output
@@ -102,9 +102,9 @@ export async function runAgentWithAIGNE(aigne, agent, { outputKey, outputFileKey
102
102
  }
103
103
  await writeFile(outputPath, "", "utf8");
104
104
  }
105
- if (options.chat) {
105
+ if (options.interactive) {
106
106
  if (!isatty(process.stdout.fd)) {
107
- throw new Error("--chat mode requires a TTY terminal");
107
+ throw new Error("--interactive mode requires a TTY terminal");
108
108
  }
109
109
  const userAgent = agent instanceof UserAgent ? agent : aigne.invoke(agent);
110
110
  await runChatLoopInTerminal(userAgent, {
@@ -112,6 +112,8 @@ export async function runAgentWithAIGNE(aigne, agent, { outputKey, outputFileKey
112
112
  outputKey,
113
113
  inputFileKey: agent instanceof AIAgent ? agent.inputFileKey : undefined,
114
114
  input: options.input,
115
+ sessionId,
116
+ userId,
115
117
  });
116
118
  return;
117
119
  }
@@ -4,7 +4,9 @@ import type { Argv } from "yargs";
4
4
  import { ZodType } from "zod";
5
5
  export type InferArgv<T> = T extends Argv<infer U> ? U : never;
6
6
  export declare const withRunAgentCommonOptions: (yargs: Argv) => Argv<{
7
- chat: boolean;
7
+ interactive: boolean;
8
+ } & {
9
+ "session-id": string | undefined;
8
10
  } & {
9
11
  model: string | undefined;
10
12
  } & {
@@ -55,7 +57,9 @@ export declare function inferZodType(type: ZodType, opts?: {
55
57
  export declare function withAgentInputSchema(yargs: Argv, options: Pick<Agent, "inputSchema"> & {
56
58
  optionalInputs?: string[];
57
59
  }): Argv<{
58
- chat: boolean;
60
+ interactive: boolean;
61
+ } & {
62
+ "session-id": string | undefined;
59
63
  } & {
60
64
  model: string | undefined;
61
65
  } & {
@@ -11,10 +11,15 @@ import { parse } from "yaml";
11
11
  import z, { ZodAny, ZodArray, ZodBoolean, ZodError, ZodNumber, ZodObject, ZodString, ZodType, ZodUnknown, } from "zod";
12
12
  const MODEL_OPTIONS_GROUP_NAME = "Model Options";
13
13
  export const withRunAgentCommonOptions = (yargs) => yargs
14
- .option("chat", {
15
- describe: "Run chat loop in terminal",
14
+ .option("interactive", {
15
+ describe: "Run in interactive chat mode",
16
16
  type: "boolean",
17
17
  default: false,
18
+ alias: ["chat"],
19
+ })
20
+ .option("session-id", {
21
+ describe: "Session ID for chat-based agents to maintain context across interactions",
22
+ type: "string",
18
23
  })
19
24
  .option("model", {
20
25
  group: MODEL_OPTIONS_GROUP_NAME,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/cli",
3
- "version": "1.59.0-beta.2",
3
+ "version": "1.59.0-beta.20",
4
4
  "description": "Your command center for agent development",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -48,6 +48,7 @@
48
48
  "@aigne/json-schema-to-zod": "^1.3.3",
49
49
  "@aigne/listr2": "^1.0.10",
50
50
  "@aigne/marked-terminal": "^7.3.2",
51
+ "@aigne/uuid": "^13.0.1",
51
52
  "@fast-csv/format": "^5.0.5",
52
53
  "@inquirer/core": "^10.2.2",
53
54
  "@inquirer/figures": "^1.0.13",
@@ -89,17 +90,17 @@
89
90
  "yoctocolors-cjs": "^2.1.3",
90
91
  "zod": "^3.25.67",
91
92
  "zod-to-json-schema": "^3.24.6",
92
- "@aigne/afs": "^1.4.0-beta.2",
93
- "@aigne/afs-local-fs": "^1.4.0-beta.3",
94
- "@aigne/afs-history": "^1.2.0-beta.2",
95
- "@aigne/agent-library": "^1.24.0-beta.3",
96
- "@aigne/agentic-memory": "^1.1.6-beta.3",
97
- "@aigne/core": "^1.72.0-beta.3",
98
- "@aigne/default-memory": "^1.3.6-beta.3",
99
- "@aigne/aigne-hub": "^0.10.16-beta.3",
100
- "@aigne/observability-api": "^0.11.14-beta.1",
101
- "@aigne/openai": "^0.16.16-beta.3",
102
- "@aigne/secrets": "^0.1.6-beta.3"
93
+ "@aigne/afs": "^1.4.0-beta.7",
94
+ "@aigne/afs-local-fs": "^1.4.0-beta.16",
95
+ "@aigne/afs-history": "^1.2.0-beta.8",
96
+ "@aigne/agentic-memory": "^1.1.6-beta.15",
97
+ "@aigne/agent-library": "^1.24.0-beta.17",
98
+ "@aigne/core": "^1.72.0-beta.15",
99
+ "@aigne/aigne-hub": "^0.10.16-beta.20",
100
+ "@aigne/openai": "^0.16.16-beta.15",
101
+ "@aigne/observability-api": "^0.11.14-beta.2",
102
+ "@aigne/secrets": "^0.1.6-beta.15",
103
+ "@aigne/default-memory": "^1.4.0-beta.14"
103
104
  },
104
105
  "devDependencies": {
105
106
  "@inquirer/testing": "^2.1.50",
@@ -116,14 +117,14 @@
116
117
  "rimraf": "^6.0.1",
117
118
  "typescript": "^5.9.2",
118
119
  "ufo": "^1.6.1",
119
- "@aigne/test-utils": "^0.5.69-beta.3"
120
+ "@aigne/test-utils": "^0.5.69-beta.15"
120
121
  },
121
122
  "scripts": {
122
123
  "lint": "tsc --noEmit",
123
124
  "build": "tsc --build tsconfig.build.json",
124
125
  "clean": "rimraf dist test/coverage templates/coverage",
125
- "test": "run-s test:src test:templates",
126
- "test:coverage": "run-s test:src:coverage test:templates:coverage",
126
+ "test": "npm run test:src && npm run test:templates",
127
+ "test:coverage": "npm run test:src:coverage && npm run test:templates:coverage",
127
128
  "test:src": "bun --cwd test test",
128
129
  "test:src:coverage": "bun --cwd test test --coverage --coverage-reporter=lcov --coverage-reporter=text",
129
130
  "test:templates": "cd templates && node --test",
@@ -42,7 +42,7 @@ echo "Hello, what can you help me with?" | aigne run
42
42
  use the following command to start an interactive chat session:
43
43
 
44
44
  ```bash
45
- aigne run --chat
45
+ aigne run --interactive
46
46
  ```
47
47
 
48
48
  help: