@ai-zen/cli 1.0.0-alpha.1 → 1.0.0-alpha.10

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.
Files changed (112) hide show
  1. package/CHANGELOG.md +157 -0
  2. package/README.md +24 -25
  3. package/README.zh.md +24 -25
  4. package/dist/agent-creator.d.ts +11 -0
  5. package/dist/agent-creator.d.ts.map +1 -1
  6. package/dist/agent-creator.js +20 -11
  7. package/dist/agent-creator.js.map +1 -1
  8. package/dist/auto-migrate-confirm.d.ts +43 -0
  9. package/dist/auto-migrate-confirm.d.ts.map +1 -0
  10. package/dist/auto-migrate-confirm.js +46 -0
  11. package/dist/auto-migrate-confirm.js.map +1 -0
  12. package/dist/config.d.ts +15 -1
  13. package/dist/config.d.ts.map +1 -1
  14. package/dist/config.js +15 -1
  15. package/dist/config.js.map +1 -1
  16. package/dist/conversation-commands/registry.d.ts.map +1 -1
  17. package/dist/conversation-commands/registry.js +2 -1
  18. package/dist/conversation-commands/registry.js.map +1 -1
  19. package/dist/conversation-persist-plugin.js +1 -1
  20. package/dist/conversation-persist-plugin.js.map +1 -1
  21. package/dist/conversation-repository.js +1 -1
  22. package/dist/conversation-repository.js.map +1 -1
  23. package/dist/handoff-service.d.ts +19 -0
  24. package/dist/handoff-service.d.ts.map +1 -0
  25. package/dist/handoff-service.js +87 -0
  26. package/dist/handoff-service.js.map +1 -0
  27. package/dist/index.js +21 -3
  28. package/dist/index.js.map +1 -1
  29. package/dist/session-pointer.d.ts +22 -9
  30. package/dist/session-pointer.d.ts.map +1 -1
  31. package/dist/session-pointer.js +55 -23
  32. package/dist/session-pointer.js.map +1 -1
  33. package/dist/tui/chat-session.d.ts +60 -54
  34. package/dist/tui/chat-session.d.ts.map +1 -1
  35. package/dist/tui/chat-session.js +121 -85
  36. package/dist/tui/chat-session.js.map +1 -1
  37. package/dist/tui/components.d.ts +5 -2
  38. package/dist/tui/components.d.ts.map +1 -1
  39. package/dist/tui/components.js +2 -2
  40. package/dist/tui/components.js.map +1 -1
  41. package/dist/tui/config-wizard/types.d.ts +9 -0
  42. package/dist/tui/config-wizard/types.d.ts.map +1 -1
  43. package/dist/tui/config-wizard/wizard.d.ts.map +1 -1
  44. package/dist/tui/config-wizard/wizard.js +4 -3
  45. package/dist/tui/config-wizard/wizard.js.map +1 -1
  46. package/dist/tui/highlight.d.ts +3 -2
  47. package/dist/tui/highlight.d.ts.map +1 -1
  48. package/dist/tui/highlight.js +3 -2
  49. package/dist/tui/highlight.js.map +1 -1
  50. package/dist/tui/index.d.ts +1 -0
  51. package/dist/tui/index.d.ts.map +1 -1
  52. package/dist/tui/index.js +5 -5
  53. package/dist/tui/index.js.map +1 -1
  54. package/dist/tui/screens/chat-commands.d.ts +10 -2
  55. package/dist/tui/screens/chat-commands.d.ts.map +1 -1
  56. package/dist/tui/screens/chat-commands.js +53 -15
  57. package/dist/tui/screens/chat-commands.js.map +1 -1
  58. package/dist/tui/screens/chat.d.ts +0 -4
  59. package/dist/tui/screens/chat.d.ts.map +1 -1
  60. package/dist/tui/screens/chat.js +146 -77
  61. package/dist/tui/screens/chat.js.map +1 -1
  62. package/dist/tui/screens/frame-buffer.d.ts +47 -0
  63. package/dist/tui/screens/frame-buffer.d.ts.map +1 -0
  64. package/dist/tui/screens/frame-buffer.js +78 -0
  65. package/dist/tui/screens/frame-buffer.js.map +1 -0
  66. package/dist/tui/screens/index.d.ts +6 -6
  67. package/dist/tui/screens/index.d.ts.map +1 -1
  68. package/dist/tui/screens/index.js +5 -5
  69. package/dist/tui/screens/index.js.map +1 -1
  70. package/dist/tui/screens/layout.d.ts +5 -3
  71. package/dist/tui/screens/layout.d.ts.map +1 -1
  72. package/dist/tui/screens/layout.js +3 -8
  73. package/dist/tui/screens/layout.js.map +1 -1
  74. package/dist/tui/screens/lines.d.ts +12 -41
  75. package/dist/tui/screens/lines.d.ts.map +1 -1
  76. package/dist/tui/screens/lines.js +87 -95
  77. package/dist/tui/screens/lines.js.map +1 -1
  78. package/dist/tui/screens/messages-view.d.ts +10 -0
  79. package/dist/tui/screens/messages-view.d.ts.map +1 -0
  80. package/dist/tui/screens/messages-view.js +115 -0
  81. package/dist/tui/screens/messages-view.js.map +1 -0
  82. package/dist/tui/screens/notice.d.ts +32 -0
  83. package/dist/tui/screens/notice.d.ts.map +1 -0
  84. package/dist/tui/screens/notice.js +46 -0
  85. package/dist/tui/screens/notice.js.map +1 -0
  86. package/dist/tui/screens/render.d.ts +2 -4
  87. package/dist/tui/screens/render.d.ts.map +1 -1
  88. package/dist/tui/screens/render.js +7 -43
  89. package/dist/tui/screens/render.js.map +1 -1
  90. package/dist/tui/text.d.ts +5 -0
  91. package/dist/tui/text.d.ts.map +1 -1
  92. package/dist/tui/text.js +7 -0
  93. package/dist/tui/text.js.map +1 -1
  94. package/dist/tui/theme.d.ts +7 -1
  95. package/dist/tui/theme.d.ts.map +1 -1
  96. package/dist/tui/theme.js +15 -3
  97. package/dist/tui/theme.js.map +1 -1
  98. package/dist/types.d.ts +6 -3
  99. package/dist/types.d.ts.map +1 -1
  100. package/package.json +3 -3
  101. package/dist/auto-migrate-confirm-plugin.d.ts +0 -58
  102. package/dist/auto-migrate-confirm-plugin.d.ts.map +0 -1
  103. package/dist/auto-migrate-confirm-plugin.js +0 -61
  104. package/dist/auto-migrate-confirm-plugin.js.map +0 -1
  105. package/dist/migration-service.d.ts +0 -15
  106. package/dist/migration-service.d.ts.map +0 -1
  107. package/dist/migration-service.js +0 -59
  108. package/dist/migration-service.js.map +0 -1
  109. package/dist/tui/screens/state.d.ts +0 -13
  110. package/dist/tui/screens/state.d.ts.map +0 -1
  111. package/dist/tui/screens/state.js +0 -75
  112. package/dist/tui/screens/state.js.map +0 -1
@@ -1,61 +0,0 @@
1
- /**
2
- * AutoMigrateConfirmPlugin — 自动迁移「二次确认」插件(CLI 层)。
3
- *
4
- * 背景:SDK 的 `AutoMigratePlugin` 在 `usage.prompt_tokens` 超过阈值时**静默**触发迁移,
5
- * 而迁移会保存当前对话并以交接文档开启新会话。为让用户对这次「上下文切换」有知情权与
6
- * 否决权,CLI 在自动迁移前补一道二次确认。
7
- *
8
- * 职责边界(沿用 SDK 的分工,不重复实现「何时迁移」的语义):
9
- * - 是否触发:本插件先向用户确认,得到许可后委托基类的 `onAfterSend` 完成阈值判断与迁移调用;
10
- * - 实际迁移:仍由共享的 `TaskMigrationService` 实例执行(与 /migrate 手动迁移同一条链路)。
11
- * 因此本插件的增量仅有一处:在超阈值与调用迁移之间插入一次确认。
12
- *
13
- * 交互约定:
14
- * - 仅在 stdin 与 stdout **均为 TTY**(人类交互终端)时询问;
15
- * - 非交互环境(管道、重定向、e2e 脚本)没有确认通道,保持既有行为——直接自动迁移,
16
- * 不阻塞等待输入、不额外输出,管道语义不变;
17
- * - 确认框默认「是」(回车即迁移),与 /migrate 手动迁移的默认值保持一致;
18
- * - 用户拒绝时仅跳过**本次**迁移,不记录任何隐式状态:只要仍处于超限状态,下次发送后
19
- * 会再次询问;跳过不影响当前对话(历史未被剔除,语义与迁移前一致)。
20
- */
21
- import { AutoMigratePlugin } from "@ai-zen/agents-sdk";
22
- /** 默认交互判定:仅当 stdin 与 stdout 均为 TTY 时才具备确认通道 */
23
- export function canPromptUser() {
24
- return Boolean(process.stdin.isTTY && process.stdout.isTTY);
25
- }
26
- /**
27
- * 自动迁移二次确认插件。
28
- *
29
- * 继承 SDK 的 `AutoMigratePlugin` 以复用其触发语义(阈值判断 + 委托共享迁移服务),
30
- * 仅在「超阈值」与「调用迁移」之间插入一次用户确认。
31
- */
32
- export class AutoMigrateConfirmPlugin extends AutoMigratePlugin {
33
- confirmOptions;
34
- constructor(options) {
35
- super({ service: options.service, maxTokens: options.maxTokens });
36
- this.confirmOptions = options;
37
- }
38
- async onAfterSend(ctx) {
39
- const { maxTokens, shouldConfirm = canPromptUser, confirm, log = () => { } } = this.confirmOptions;
40
- const promptTokens = ctx.agent.lastUsage?.prompt_tokens;
41
- // 未超阈值(或无用量信息):无需询问,交由基类按原语义处理
42
- if (promptTokens == null || promptTokens <= maxTokens) {
43
- await super.onAfterSend(ctx);
44
- return;
45
- }
46
- // 非交互环境:没有确认通道,保持既有「静默自动迁移」行为,不阻塞、不额外输出
47
- if (!shouldConfirm()) {
48
- await super.onAfterSend(ctx);
49
- return;
50
- }
51
- const confirmed = await confirm({ promptTokens, maxTokens });
52
- if (!confirmed) {
53
- log("⏭️ 已跳过本次任务迁移,继续当前对话。");
54
- log("💡 上下文仍接近上限:可随时输入 /migrate 手动迁移;若继续增长至严重超限,对话会被安全护栏中断。");
55
- return;
56
- }
57
- // 用户已确认:交由基类完成「触发 + 委托共享迁移服务」的原逻辑
58
- await super.onAfterSend(ctx);
59
- }
60
- }
61
- //# sourceMappingURL=auto-migrate-confirm-plugin.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auto-migrate-confirm-plugin.js","sourceRoot":"","sources":["../src/auto-migrate-confirm-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AA2BvD,+CAA+C;AAC/C,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,wBAAyB,SAAQ,iBAAiB;IAC5C,cAAc,CAA4B;IAE3D,YAAY,OAAkC;QAC5C,KAAK,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;QAClE,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,GAAgB;QAChC,MAAM,EAAE,SAAS,EAAE,aAAa,GAAG,aAAa,EAAE,OAAO,EAAE,GAAG,GAAG,GAAG,EAAE,GAAE,CAAC,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC;QAElG,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,aAAa,CAAC;QAExD,+BAA+B;QAC/B,IAAI,YAAY,IAAI,IAAI,IAAI,YAAY,IAAI,SAAS,EAAE,CAAC;YACtD,MAAM,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YAC7B,OAAO;QACT,CAAC;QAED,wCAAwC;QACxC,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;YACrB,MAAM,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YAC7B,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,CAAC;QAC7D,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,GAAG,CAAC,sBAAsB,CAAC,CAAC;YAC5B,GAAG,CAAC,wDAAwD,CAAC,CAAC;YAC9D,OAAO;QACT,CAAC;QAED,kCAAkC;QAClC,MAAM,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;CACF"}
@@ -1,15 +0,0 @@
1
- import { TaskMigrationService } from "@ai-zen/agents-sdk";
2
- import type { ConversationContext } from "./types.js";
3
- /**
4
- * 创建 CLI 迁移服务实例(自动迁移与手动迁移共用同一个实例)。
5
- *
6
- * 迁移前后处理统一收敛于此:保存旧对话 / 开启新会话 / 落盘草稿。
7
- * 自动迁移由 AutoMigratePlugin 触发,手动迁移由 /migrate 命令触发,
8
- * 两者都委托给本服务实例的 migrate(),从而保证行为一致、避免重复实现。
9
- *
10
- * @param ctx 当前会话上下文(先建后回填 migrationService;钩子直接引用该对象)
11
- */
12
- export declare function createMigrationService(ctx: ConversationContext, options?: {
13
- log?: (text: string) => void;
14
- }): TaskMigrationService;
15
- //# sourceMappingURL=migration-service.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"migration-service.d.ts","sourceRoot":"","sources":["../src/migration-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAyB,MAAM,oBAAoB,CAAC;AAOjF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,mBAAmB,EACxB,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAAO,GAC7C,oBAAoB,CAgDtB"}
@@ -1,59 +0,0 @@
1
- import { TaskMigrationService } from "@ai-zen/agents-sdk";
2
- import { saveConversation, conversationRepository, generateConversationId, } from "./conversation-repository.js";
3
- import { writeLastSession } from "./session-pointer.js";
4
- /**
5
- * 创建 CLI 迁移服务实例(自动迁移与手动迁移共用同一个实例)。
6
- *
7
- * 迁移前后处理统一收敛于此:保存旧对话 / 开启新会话 / 落盘草稿。
8
- * 自动迁移由 AutoMigratePlugin 触发,手动迁移由 /migrate 命令触发,
9
- * 两者都委托给本服务实例的 migrate(),从而保证行为一致、避免重复实现。
10
- *
11
- * @param ctx 当前会话上下文(先建后回填 migrationService;钩子直接引用该对象)
12
- */
13
- export function createMigrationService(ctx, options = {}) {
14
- // 进度/结果一律经 `log` 上报(TUI 走 Ink notice 块),不再直接 console.log 污染画面
15
- const log = options.log ?? (() => { });
16
- return new TaskMigrationService({
17
- // CLI 采用物理剔除模式:迁移后不保留历史消息,仅保留系统提示 + 交接断点。
18
- strategy: "prune",
19
- onBeforeMigrate: async (mctx) => {
20
- // 自动迁移由 AutoMigratePlugin 传入 promptTokens/maxTokens;手动迁移为 undefined。
21
- const isAuto = mctx.promptTokens != null && mctx.maxTokens != null;
22
- log(isAuto
23
- ? `📋 检测到上下文即将超限(${mctx.promptTokens}/${mctx.maxTokens} tokens),正在自动生成交接文档以延续对话…`
24
- : "📋 正在生成任务交接文档…");
25
- // 迁移前 agent.messages 仍是完整旧历史,先保存旧对话
26
- await saveConversation(ctx);
27
- log(`✅ 原对话已保存:${ctx.currentName}`);
28
- },
29
- onMigrated: async (mctx) => {
30
- // 迁移开启新会话:分配新的会话 id 与名称
31
- const id = generateConversationId();
32
- ctx.currentId = id;
33
- ctx.currentName = id;
34
- log(`🚀 任务迁移完成,已开启新会话(共 ${mctx.agent.messages.length} 条消息)`);
35
- log("💡 新助手已通过交接文档了解此前的工作,可继续提问。");
36
- // 迁移后立即把新开场白落盘为独立会话文件,并更新「上一轮会话 id」指针,
37
- // 避免迁移发生在 onAfterSend(ConversationPersistPlugin 的 onInnerLoopEnd
38
- // 已不再触发)导致迁移后的新对话未被及时落盘、用户中途退出时丢失。
39
- try {
40
- const existing = await conversationRepository.read(id);
41
- const now = new Date().toISOString();
42
- await conversationRepository.write({
43
- id,
44
- agentId: ctx.agentId || "default",
45
- modelId: ctx.modelId,
46
- messages: mctx.agent.messages,
47
- cwd: process.cwd(),
48
- createdAt: existing?.createdAt ?? now,
49
- updatedAt: now,
50
- });
51
- await writeLastSession(id);
52
- }
53
- catch (err) {
54
- log(`⚠️ 迁移后会话落盘失败:${err?.message ?? err}`);
55
- }
56
- },
57
- });
58
- }
59
- //# sourceMappingURL=migration-service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"migration-service.js","sourceRoot":"","sources":["../src/migration-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAyB,MAAM,oBAAoB,CAAC;AACjF,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGxD;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CACpC,GAAwB,EACxB,UAA4C,EAAE;IAE9C,8DAA8D;IAC9D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACtC,OAAO,IAAI,oBAAoB,CAAC;QAC9B,0CAA0C;QAC1C,QAAQ,EAAE,OAAO;QACjB,eAAe,EAAE,KAAK,EAAE,IAAsB,EAAE,EAAE;YAChD,qEAAqE;YACrE,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC;YACnE,GAAG,CACD,MAAM;gBACJ,CAAC,CAAC,iBAAiB,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,SAAS,2BAA2B;gBACjF,CAAC,CAAC,gBAAgB,CACrB,CAAC;YACF,oCAAoC;YACpC,MAAM,gBAAgB,CAAC,GAAG,CAAC,CAAC;YAC5B,GAAG,CAAC,YAAY,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACrC,CAAC;QACD,UAAU,EAAE,KAAK,EAAE,IAAsB,EAAE,EAAE;YAC3C,wBAAwB;YACxB,MAAM,EAAE,GAAG,sBAAsB,EAAE,CAAC;YACpC,GAAG,CAAC,SAAS,GAAG,EAAE,CAAC;YACnB,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC;YAErB,GAAG,CAAC,sBAAsB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,OAAO,CAAC,CAAC;YAC7D,GAAG,CAAC,6BAA6B,CAAC,CAAC;YAEnC,uCAAuC;YACvC,iEAAiE;YACjE,mCAAmC;YACnC,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACvD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;gBACrC,MAAM,sBAAsB,CAAC,KAAK,CAAC;oBACjC,EAAE;oBACF,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,SAAS;oBACjC,OAAO,EAAE,GAAG,CAAC,OAAO;oBACpB,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ;oBAC7B,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;oBAClB,SAAS,EAAE,QAAQ,EAAE,SAAS,IAAI,GAAG;oBACrC,SAAS,EAAE,GAAG;iBACf,CAAC,CAAC;gBACH,MAAM,gBAAgB,CAAC,EAAE,CAAC,CAAC;YAC7B,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,GAAG,CAAC,gBAAgB,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -1,13 +0,0 @@
1
- import { ChatEvent } from "../chat-session.js";
2
- import { Block, LiveAssistant } from "./lines.js";
3
- export interface ChatState {
4
- blocks: Block[];
5
- live: LiveAssistant | null;
6
- }
7
- export type ChatAction = ChatEvent | {
8
- type: "clear";
9
- };
10
- export declare let blockSeq: number;
11
- export declare const nextId: () => number;
12
- export declare function chatReducer(state: ChatState, action: ChatAction): ChatState;
13
- //# sourceMappingURL=state.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/state.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIlD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAEvD,eAAO,IAAI,QAAQ,QAAI,CAAC;AACxB,eAAO,MAAM,MAAM,cAAmB,CAAC;AAEvC,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,SAAS,CAmE3E"}
@@ -1,75 +0,0 @@
1
- export let blockSeq = 0;
2
- export const nextId = () => ++blockSeq;
3
- export function chatReducer(state, action) {
4
- switch (action.type) {
5
- case "clear":
6
- return { blocks: [], live: null };
7
- case "user":
8
- return {
9
- blocks: [...state.blocks, { id: nextId(), kind: "user", text: action.text }],
10
- live: { reasoning: "", content: "", tools: [], sub: null, roundBase: 0 },
11
- };
12
- case "assistant-start":
13
- // 每次 API 请求(含一轮内并行调用后的后续轮次)都会触发:把本轮工具调用的
14
- // 起始下标锚到当前已收集的工具数,使新一轮 index 从 0 起也落到新的一行。
15
- return {
16
- ...state,
17
- live: state.live
18
- ? { ...state.live, roundBase: state.live.tools.length }
19
- : { reasoning: "", content: "", tools: [], sub: null, roundBase: 0 },
20
- };
21
- case "reasoning":
22
- return state.live
23
- ? { ...state, live: { ...state.live, reasoning: state.live.reasoning + action.text } }
24
- : state;
25
- case "content":
26
- return state.live
27
- ? { ...state, live: { ...state.live, content: state.live.content + action.text } }
28
- : state;
29
- case "tool": {
30
- if (!state.live)
31
- return state;
32
- // 落到「本轮起始下标 + 本轮内 index」:同一轮内的分片按 index 归并(并行调用
33
- // 各占一行),跨轮的同 index 因 roundBase 不同而分段,不再相互拼接。
34
- const pos = (state.live.roundBase ?? 0) + Math.max(0, action.index ?? 0);
35
- const tools = [...state.live.tools];
36
- // 保持数组稠密(避免稀疏空位在渲染时被 for...of 迭代为 undefined)
37
- while (tools.length < pos)
38
- tools.push({ name: "", args: "" });
39
- const prev = tools[pos] ?? { name: "", args: "" };
40
- tools[pos] = {
41
- name: prev.name + (action.name ?? ""),
42
- args: prev.args + (action.args ?? ""),
43
- };
44
- return { ...state, live: { ...state.live, tools } };
45
- }
46
- case "subagent-start":
47
- return state.live ? { ...state, live: { ...state.live, sub: action.name } } : state;
48
- case "subagent-end":
49
- return state.live ? { ...state, live: { ...state.live, sub: null } } : state;
50
- case "notice":
51
- return {
52
- ...state,
53
- blocks: [...state.blocks, { id: nextId(), kind: "notice", tone: "info", text: action.text }],
54
- };
55
- case "error":
56
- return {
57
- ...state,
58
- blocks: [...state.blocks, { id: nextId(), kind: "notice", tone: "error", text: action.text }],
59
- };
60
- case "done": {
61
- if (!state.live)
62
- return state;
63
- const { reasoning, content, tools } = state.live;
64
- // 请求失败时 live 可能为空壳(无思考/内容/工具)——不产生空白的 AI 块
65
- const isEmpty = !reasoning.trim() && !content.trim() && !tools.some((t) => t.name);
66
- if (isEmpty)
67
- return { ...state, live: null };
68
- const finished = { id: nextId(), kind: "assistant", reasoning, content, tools };
69
- return { blocks: [...state.blocks, finished], live: null };
70
- }
71
- default:
72
- return state;
73
- }
74
- }
75
- //# sourceMappingURL=state.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/tui/screens/state.ts"],"names":[],"mappings":"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"}