jinzd-ai-cli 0.4.17 → 0.4.19

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.
@@ -75,10 +75,10 @@ async function joinHub(options, configManager, providers) {
75
75
  case "welcome":
76
76
  myRoleId = msg.roleId;
77
77
  myRoleName = msg.roleName;
78
- topic = msg.topic;
78
+ topic = msg.topic || topic;
79
79
  allRoles = msg.roles;
80
80
  hubContext = msg.context;
81
- persona = buildPersonaFromRole(myRoleId, myRoleName);
81
+ persona = msg.persona || buildPersonaFromRole(myRoleId, myRoleName);
82
82
  console.log(chalk.bold(` \u{1F4CB} Assigned role: ${chalk.cyan(myRoleName)} (${myRoleId})`));
83
83
  if (topic) {
84
84
  console.log(chalk.dim(` Topic: ${topic}`));
@@ -6,7 +6,7 @@ import { platform } from "os";
6
6
  import chalk from "chalk";
7
7
 
8
8
  // src/core/constants.ts
9
- var VERSION = "0.4.15";
9
+ var VERSION = "0.4.19";
10
10
  var APP_NAME = "ai-cli";
11
11
  var CONFIG_DIR_NAME = ".aicli";
12
12
  var CONFIG_FILE_NAME = "config.json";
@@ -7,7 +7,7 @@ import {
7
7
  ProviderNotFoundError,
8
8
  RateLimitError,
9
9
  schemaToJsonSchema
10
- } from "./chunk-NLT5FT2W.js";
10
+ } from "./chunk-PR5JZVNN.js";
11
11
  import {
12
12
  APP_NAME,
13
13
  CONFIG_DIR_NAME,
@@ -20,7 +20,7 @@ import {
20
20
  MCP_TOOL_PREFIX,
21
21
  PLUGINS_DIR_NAME,
22
22
  VERSION
23
- } from "./chunk-KOD3C2CU.js";
23
+ } from "./chunk-JNAZORS2.js";
24
24
 
25
25
  // src/config/config-manager.ts
26
26
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
@@ -8,7 +8,7 @@ import { platform } from "os";
8
8
  import chalk from "chalk";
9
9
 
10
10
  // src/core/constants.ts
11
- var VERSION = "0.4.15";
11
+ var VERSION = "0.4.19";
12
12
  var APP_NAME = "ai-cli";
13
13
  var CONFIG_DIR_NAME = ".aicli";
14
14
  var CONFIG_FILE_NAME = "config.json";
@@ -6,7 +6,7 @@ import {
6
6
  SUBAGENT_DEFAULT_MAX_ROUNDS,
7
7
  SUBAGENT_MAX_ROUNDS_LIMIT,
8
8
  runTestsTool
9
- } from "./chunk-KOD3C2CU.js";
9
+ } from "./chunk-JNAZORS2.js";
10
10
 
11
11
  // src/tools/builtin/bash.ts
12
12
  import { execSync } from "child_process";
@@ -52,6 +52,45 @@ var HubAgent = class {
52
52
  passed
53
53
  };
54
54
  }
55
+ /**
56
+ * Streaming version of speak() — yields tokens as they arrive.
57
+ * Falls back to non-streaming speak() if the provider doesn't support chatStream.
58
+ */
59
+ async speakStream(topic, history, round, maxRounds, onToken) {
60
+ const provider = this.providers.get(this.providerId);
61
+ if (!provider) {
62
+ throw new Error(`Provider "${this.providerId}" not available for agent "${this.role.id}"`);
63
+ }
64
+ if (!provider.chatStream) {
65
+ return this.speak(topic, history, round, maxRounds);
66
+ }
67
+ const systemPrompt = this.buildSystemPrompt(topic, round, maxRounds);
68
+ const messages = this.buildMessages(history);
69
+ let content = "";
70
+ const stream = provider.chatStream({
71
+ messages,
72
+ model: this.modelId,
73
+ systemPrompt,
74
+ stream: true,
75
+ temperature: 0.7,
76
+ maxTokens: 4096
77
+ });
78
+ for await (const chunk of stream) {
79
+ if (chunk.delta) {
80
+ content += chunk.delta;
81
+ onToken?.(chunk.delta);
82
+ }
83
+ }
84
+ content = content.trim();
85
+ const passed = content.toUpperCase().startsWith(PASS_MARKER) || content.toUpperCase() === PASS_MARKER;
86
+ return {
87
+ speaker: this.role.id,
88
+ speakerName: this.role.name,
89
+ content: passed ? "" : content,
90
+ timestamp: /* @__PURE__ */ new Date(),
91
+ passed
92
+ };
93
+ }
55
94
  /**
56
95
  * Generate a summary of the entire discussion from this agent's perspective.
57
96
  */
@@ -205,6 +244,8 @@ function renderRoundHeader(round, maxRounds) {
205
244
  console.log(chalk.dim(` \u2500\u2500 Round ${round}/${maxRounds} ${"\u2500".repeat(48)}`));
206
245
  console.log();
207
246
  }
247
+ var streamingRoleId = null;
248
+ var streamingBuffer = "";
208
249
  function renderAgentSpeaking(roleName, roleId) {
209
250
  const color = colorMap.get(roleId) ?? chalk.white;
210
251
  process.stdout.write(chalk.dim(" \u{1F4AD} ") + color.bold(roleName) + chalk.dim(" is thinking..."));
@@ -212,6 +253,33 @@ function renderAgentSpeaking(roleName, roleId) {
212
253
  function clearSpeakingLine() {
213
254
  process.stdout.write("\r\x1B[2K");
214
255
  }
256
+ function renderAgentStreamStart(roleName, roleId) {
257
+ clearSpeakingLine();
258
+ const color = colorMap.get(roleId) ?? chalk.white;
259
+ console.log(color.bold(` \u250C\u2500 ${roleName} `) + chalk.dim(`(${roleId})`));
260
+ process.stdout.write(color(" \u2502 "));
261
+ streamingRoleId = roleId;
262
+ streamingBuffer = "";
263
+ }
264
+ function renderAgentToken(roleId, token) {
265
+ const color = colorMap.get(roleId) ?? chalk.white;
266
+ const parts = token.split("\n");
267
+ for (let i = 0; i < parts.length; i++) {
268
+ if (i > 0) {
269
+ process.stdout.write("\n" + color(" \u2502 "));
270
+ }
271
+ process.stdout.write(parts[i]);
272
+ }
273
+ streamingBuffer += token;
274
+ }
275
+ function renderAgentStreamEnd(roleId) {
276
+ const color = colorMap.get(roleId) ?? chalk.white;
277
+ console.log();
278
+ console.log(color(" \u2514" + "\u2500".repeat(60)));
279
+ console.log();
280
+ streamingRoleId = null;
281
+ streamingBuffer = "";
282
+ }
215
283
  function renderAgentMessage(msg) {
216
284
  const color = colorMap.get(msg.speaker) ?? chalk.white;
217
285
  if (msg.passed) {
@@ -219,6 +287,10 @@ function renderAgentMessage(msg) {
219
287
  console.log();
220
288
  return;
221
289
  }
290
+ if (streamingRoleId === msg.speaker && streamingBuffer) {
291
+ renderAgentStreamEnd(msg.speaker);
292
+ return;
293
+ }
222
294
  console.log(color.bold(` \u250C\u2500 ${msg.speakerName} `) + chalk.dim(`(${msg.speaker})`));
223
295
  const lines = msg.content.split("\n");
224
296
  for (const line of lines) {
@@ -252,24 +324,42 @@ function renderSummary(summary) {
252
324
  }
253
325
  console.log();
254
326
  }
327
+ var currentSpeaker = null;
328
+ var streamHeaderPrinted = false;
255
329
  function renderHubEvent(event) {
256
330
  switch (event.type) {
257
331
  case "round_start":
258
332
  renderRoundHeader(event.round, event.maxRounds);
259
333
  break;
260
334
  case "agent_speaking":
335
+ currentSpeaker = { roleId: event.roleId, roleName: event.roleName };
336
+ streamHeaderPrinted = false;
261
337
  renderAgentSpeaking(event.roleName, event.roleId);
262
338
  break;
339
+ case "agent_token":
340
+ if (!streamHeaderPrinted) {
341
+ const roleName = currentSpeaker?.roleName ?? event.roleId;
342
+ renderAgentStreamStart(roleName, event.roleId);
343
+ streamHeaderPrinted = true;
344
+ }
345
+ renderAgentToken(event.roleId, event.token);
346
+ break;
263
347
  case "agent_spoke":
264
- clearSpeakingLine();
265
- renderAgentMessage(event.message);
348
+ if (streamHeaderPrinted) {
349
+ renderAgentStreamEnd(event.roleId);
350
+ streamHeaderPrinted = false;
351
+ } else {
352
+ clearSpeakingLine();
353
+ renderAgentMessage(event.message);
354
+ }
266
355
  break;
267
356
  case "agent_passed":
268
357
  clearSpeakingLine();
358
+ streamHeaderPrinted = false;
269
359
  break;
270
360
  case "discussion_end":
271
361
  if (event.reason === "consensus") renderConsensus();
272
- else if (event.reason === "max_rounds") renderMaxRounds(0);
362
+ else if (event.reason === "max_rounds") renderMaxRounds(event.maxRounds ?? 0);
273
363
  else renderUserInterrupt();
274
364
  break;
275
365
  case "summary":
@@ -4,7 +4,7 @@ import {
4
4
  assignRoleColors,
5
5
  renderHubBanner,
6
6
  renderHubEvent
7
- } from "./chunk-SVOWJLQJ.js";
7
+ } from "./chunk-YJ2CUK5O.js";
8
8
 
9
9
  // src/hub/discuss.ts
10
10
  var DiscussionOrchestrator = class {
@@ -57,7 +57,13 @@ var DiscussionOrchestrator = class {
57
57
  if (this.aborted) break;
58
58
  this.emit({ type: "agent_speaking", roleId: agent.role.id, roleName: agent.role.name });
59
59
  try {
60
- const message = await agent.speak(topic, this.state.messages, round, this.state.maxRounds);
60
+ const message = await agent.speakStream(
61
+ topic,
62
+ this.state.messages,
63
+ round,
64
+ this.state.maxRounds,
65
+ (token) => this.emit({ type: "agent_token", roleId: agent.role.id, token })
66
+ );
61
67
  this.state.messages.push(message);
62
68
  if (message.passed) {
63
69
  this.emit({ type: "agent_passed", roleId: agent.role.id });
@@ -83,7 +89,7 @@ var DiscussionOrchestrator = class {
83
89
  break;
84
90
  }
85
91
  if (round === this.state.maxRounds) {
86
- this.emit({ type: "discussion_end", reason: "max_rounds" });
92
+ this.emit({ type: "discussion_end", reason: "max_rounds", maxRounds: this.state.maxRounds });
87
93
  }
88
94
  }
89
95
  } catch (err) {
@@ -381,7 +387,7 @@ ${content}`);
381
387
  }
382
388
  }
383
389
  async function runTaskMode(config, providers, configManager, topic) {
384
- const { TaskOrchestrator } = await import("./task-orchestrator-FVBUXFLC.js");
390
+ const { TaskOrchestrator } = await import("./task-orchestrator-JKY2T2W3.js");
385
391
  const orchestrator = new TaskOrchestrator(config, providers, configManager);
386
392
  let interrupted = false;
387
393
  const onSigint = () => {
@@ -417,7 +423,7 @@ async function runTaskMode(config, providers, configManager, topic) {
417
423
  }
418
424
  }
419
425
  async function runDistributedDiscussion(config, providers, topic, port) {
420
- const { HubServer } = await import("./hub-server-2MT2GPJK.js");
426
+ const { HubServer } = await import("./hub-server-BYXNQGDY.js");
421
427
  const hub = new HubServer(config, providers, port);
422
428
  let interrupted = false;
423
429
  const onSigint = () => {
@@ -11,7 +11,7 @@ import {
11
11
  renderRoundHeader,
12
12
  renderSummary,
13
13
  renderUserInterrupt
14
- } from "./chunk-SVOWJLQJ.js";
14
+ } from "./chunk-YJ2CUK5O.js";
15
15
 
16
16
  // src/hub/hub-server.ts
17
17
  import { WebSocketServer } from "ws";
@@ -31,10 +31,12 @@ var HubServer = class {
31
31
  history = [];
32
32
  aborted = false;
33
33
  currentTurnResolve = null;
34
+ topic = "";
34
35
  /**
35
36
  * Start the hub server and run the discussion.
36
37
  */
37
38
  async start(topic) {
39
+ this.topic = topic;
38
40
  assignRoleColors(this.config.roles);
39
41
  this.httpServer = createServer();
40
42
  this.wss = new WebSocketServer({ server: this.httpServer });
@@ -143,8 +145,8 @@ var HubServer = class {
143
145
  type: "welcome",
144
146
  roleId: role.id,
145
147
  roleName: role.name,
146
- topic: "",
147
- // Will be sent when discussion starts
148
+ persona: role.persona,
149
+ topic: this.topic,
148
150
  roles: this.config.roles.map((r) => ({ id: r.id, name: r.name })),
149
151
  context: this.config.context
150
152
  });
@@ -167,11 +169,14 @@ var HubServer = class {
167
169
  }
168
170
  console.log();
169
171
  }
172
+ const roleMap = new Map(this.config.roles.map((r) => [r.id, r]));
170
173
  for (const agent of this.agents.values()) {
174
+ const role = roleMap.get(agent.roleId);
171
175
  this.sendTo(agent.ws, {
172
176
  type: "welcome",
173
177
  roleId: agent.roleId,
174
178
  roleName: agent.roleName,
179
+ persona: role?.persona,
175
180
  topic,
176
181
  roles: this.config.roles.map((r) => ({ id: r.id, name: r.name })),
177
182
  context: this.config.context
@@ -294,7 +299,7 @@ function sleep(ms) {
294
299
  function serializeMessage(msg) {
295
300
  return {
296
301
  ...msg,
297
- timestamp: msg.timestamp instanceof Date ? msg.timestamp : new Date(msg.timestamp)
302
+ timestamp: msg.timestamp instanceof Date ? msg.timestamp.toISOString() : msg.timestamp
298
303
  };
299
304
  }
300
305
  export {
package/dist/index.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  saveDevState,
24
24
  sessionHasMeaningfulContent,
25
25
  setupProxy
26
- } from "./chunk-OBFFL5DJ.js";
26
+ } from "./chunk-DBEYB76P.js";
27
27
  import {
28
28
  ToolRegistry,
29
29
  askUserContext,
@@ -38,7 +38,7 @@ import {
38
38
  theme,
39
39
  truncateOutput,
40
40
  undoStack
41
- } from "./chunk-NLT5FT2W.js";
41
+ } from "./chunk-PR5JZVNN.js";
42
42
  import {
43
43
  AGENTIC_BEHAVIOR_GUIDELINE,
44
44
  AUTHOR,
@@ -58,7 +58,7 @@ import {
58
58
  REPO_URL,
59
59
  SKILLS_DIR_NAME,
60
60
  VERSION
61
- } from "./chunk-KOD3C2CU.js";
61
+ } from "./chunk-JNAZORS2.js";
62
62
 
63
63
  // src/index.ts
64
64
  import { program } from "commander";
@@ -1926,7 +1926,7 @@ ${hint}` : "")
1926
1926
  description: "Run project tests and show structured report",
1927
1927
  usage: "/test [command|filter]",
1928
1928
  async execute(args, _ctx) {
1929
- const { executeTests } = await import("./run-tests-H7IVHUZO.js");
1929
+ const { executeTests } = await import("./run-tests-HP4MMQAP.js");
1930
1930
  const argStr = args.join(" ").trim();
1931
1931
  let testArgs = {};
1932
1932
  if (argStr) {
@@ -5548,7 +5548,7 @@ program.command("web").description("Start Web UI server with browser-based chat
5548
5548
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
5549
5549
  process.exit(1);
5550
5550
  }
5551
- const { startWebServer } = await import("./server-KSH5U7QY.js");
5551
+ const { startWebServer } = await import("./server-JFLTWF7Q.js");
5552
5552
  await startWebServer({ port, host: options.host });
5553
5553
  });
5554
5554
  program.command("user [action] [username]").description("Manage Web UI users (list | create <name> | delete <name> | reset-password <name> | migrate <name>)").action(async (action, username) => {
@@ -5781,7 +5781,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
5781
5781
  }),
5782
5782
  config.get("customProviders")
5783
5783
  );
5784
- const { startHub } = await import("./hub-WF6CNNUT.js");
5784
+ const { startHub } = await import("./hub-RJRNBB5G.js");
5785
5785
  await startHub(
5786
5786
  {
5787
5787
  topic: topic ?? "",
@@ -5812,7 +5812,7 @@ program.command("join").description("Join a running hub as a remote AI agent").o
5812
5812
  }),
5813
5813
  config.get("customProviders")
5814
5814
  );
5815
- const { joinHub } = await import("./agent-client-POWN3QOR.js");
5815
+ const { joinHub } = await import("./agent-client-6GX6QQDU.js");
5816
5816
  await joinHub(
5817
5817
  {
5818
5818
  port: parseInt(options.port ?? "9527", 10),
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  executeTests,
3
3
  runTestsTool
4
- } from "./chunk-SNUHVNSD.js";
4
+ } from "./chunk-6WLDJKHU.js";
5
5
  export {
6
6
  executeTests,
7
7
  runTestsTool
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  executeTests,
4
4
  runTestsTool
5
- } from "./chunk-KOD3C2CU.js";
5
+ } from "./chunk-JNAZORS2.js";
6
6
  export {
7
7
  executeTests,
8
8
  runTestsTool
@@ -18,7 +18,7 @@ import {
18
18
  renderDiff,
19
19
  runHook,
20
20
  setupProxy
21
- } from "./chunk-OBFFL5DJ.js";
21
+ } from "./chunk-DBEYB76P.js";
22
22
  import {
23
23
  AuthManager
24
24
  } from "./chunk-BYNY5JPB.js";
@@ -32,7 +32,7 @@ import {
32
32
  spawnAgentContext,
33
33
  truncateOutput,
34
34
  undoStack
35
- } from "./chunk-NLT5FT2W.js";
35
+ } from "./chunk-PR5JZVNN.js";
36
36
  import {
37
37
  AGENTIC_BEHAVIOR_GUIDELINE,
38
38
  AUTHOR,
@@ -49,7 +49,7 @@ import {
49
49
  PLUGINS_DIR_NAME,
50
50
  SKILLS_DIR_NAME,
51
51
  VERSION
52
- } from "./chunk-KOD3C2CU.js";
52
+ } from "./chunk-JNAZORS2.js";
53
53
 
54
54
  // src/web/server.ts
55
55
  import express from "express";
@@ -1490,7 +1490,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
1490
1490
  case "test": {
1491
1491
  this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
1492
1492
  try {
1493
- const { executeTests } = await import("./run-tests-H7IVHUZO.js");
1493
+ const { executeTests } = await import("./run-tests-HP4MMQAP.js");
1494
1494
  const argStr = args.join(" ").trim();
1495
1495
  let testArgs = {};
1496
1496
  if (argStr) {
@@ -4,10 +4,10 @@ import {
4
4
  getDangerLevel,
5
5
  googleSearchContext,
6
6
  truncateOutput
7
- } from "./chunk-NLT5FT2W.js";
7
+ } from "./chunk-PR5JZVNN.js";
8
8
  import {
9
9
  SUBAGENT_ALLOWED_TOOLS
10
- } from "./chunk-KOD3C2CU.js";
10
+ } from "./chunk-JNAZORS2.js";
11
11
 
12
12
  // src/hub/task-orchestrator.ts
13
13
  import { createInterface } from "readline";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jinzd-ai-cli",
3
- "version": "0.4.17",
3
+ "version": "0.4.19",
4
4
  "description": "Cross-platform REPL-style AI CLI with multi-provider support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",