@keyou007/agent-bot 0.1.24-alpha.4 → 0.1.24-alpha.6

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 (108) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/README.md +42 -6
  3. package/README.zh.md +42 -6
  4. package/SECURITY.md +12 -0
  5. package/config.example.yaml +5 -0
  6. package/dist/cli/controlProtocol.js.map +1 -1
  7. package/dist/cli/serverStatus.js +1 -0
  8. package/dist/cli/serverStatus.js.map +1 -1
  9. package/dist/cli.js +6 -1
  10. package/dist/cli.js.map +1 -1
  11. package/dist/codex/AppServerPermissions.js +34 -0
  12. package/dist/codex/AppServerPermissions.js.map +1 -0
  13. package/dist/codex/CodexLocalActivityDetector.js +37 -5
  14. package/dist/codex/CodexLocalActivityDetector.js.map +1 -1
  15. package/dist/codex/CodexRuntime.js +238 -127
  16. package/dist/codex/CodexRuntime.js.map +1 -1
  17. package/dist/codex/ProviderSwitch.js +12 -13
  18. package/dist/codex/ProviderSwitch.js.map +1 -1
  19. package/dist/codex/ThreadWriterProcess.js +19 -5
  20. package/dist/codex/ThreadWriterProcess.js.map +1 -1
  21. package/dist/config/AgentExecutionDefaultsStore.js +4 -0
  22. package/dist/config/AgentExecutionDefaultsStore.js.map +1 -1
  23. package/dist/config/loadConfig.js +4 -0
  24. package/dist/config/loadConfig.js.map +1 -1
  25. package/dist/config/schema.js +3 -0
  26. package/dist/config/schema.js.map +1 -1
  27. package/dist/feishu/CardRenderer.js +146 -72
  28. package/dist/feishu/CardRenderer.js.map +1 -1
  29. package/dist/feishu/FeishuConnector.js +1 -0
  30. package/dist/feishu/FeishuConnector.js.map +1 -1
  31. package/dist/feishu/FeishuTurnPresenter.js +121 -17
  32. package/dist/feishu/FeishuTurnPresenter.js.map +1 -1
  33. package/dist/index.js +43 -6
  34. package/dist/index.js.map +1 -1
  35. package/dist/local-files/CsvPreview.js +148 -0
  36. package/dist/local-files/CsvPreview.js.map +1 -0
  37. package/dist/local-files/LocalFileViewerServer.js +104 -14
  38. package/dist/local-files/LocalFileViewerServer.js.map +1 -1
  39. package/dist/local-files/TurnPreviewPage.js +128 -12
  40. package/dist/local-files/TurnPreviewPage.js.map +1 -1
  41. package/dist/presentation/TurnStateReducer.js +80 -6
  42. package/dist/presentation/TurnStateReducer.js.map +1 -1
  43. package/dist/proxy/ProxySessionController.js +767 -260
  44. package/dist/proxy/ProxySessionController.js.map +1 -1
  45. package/dist/proxy/SessionOperationQueue.js +14 -0
  46. package/dist/proxy/SessionOperationQueue.js.map +1 -0
  47. package/dist/runtime/AcpRuntimeAdapter.js +4 -2
  48. package/dist/runtime/AcpRuntimeAdapter.js.map +1 -1
  49. package/dist/state/StateStore.js +22 -0
  50. package/dist/state/StateStore.js.map +1 -1
  51. package/dist/state/TurnPreviewJournal.js +19 -7
  52. package/dist/state/TurnPreviewJournal.js.map +1 -1
  53. package/dist/state/migrations.js +6 -0
  54. package/dist/state/migrations.js.map +1 -1
  55. package/dist/supervision/SafeRestartNotifier.js +1 -0
  56. package/dist/supervision/SafeRestartNotifier.js.map +1 -1
  57. package/dist/supervision/SafeRestartScheduler.js +19 -6
  58. package/dist/supervision/SafeRestartScheduler.js.map +1 -1
  59. package/dist/terminal/TerminalCards.js +13 -0
  60. package/dist/terminal/TerminalCards.js.map +1 -0
  61. package/dist/terminal/TerminalLinks.js +76 -0
  62. package/dist/terminal/TerminalLinks.js.map +1 -0
  63. package/dist/terminal/TerminalPage.js +212 -0
  64. package/dist/terminal/TerminalPage.js.map +1 -0
  65. package/dist/terminal/TerminalProcess.js +71 -0
  66. package/dist/terminal/TerminalProcess.js.map +1 -0
  67. package/dist/terminal/TerminalServer.js +639 -0
  68. package/dist/terminal/TerminalServer.js.map +1 -0
  69. package/docs/technical-reference.md +53 -3
  70. package/docs/technical-reference.zh.md +52 -2
  71. package/npm-shrinkwrap.json +55 -5
  72. package/package.json +11 -4
  73. package/skills/agent-bot/SKILL.md +15 -2
  74. package/src/cli/controlProtocol.ts +2 -1
  75. package/src/cli/serverStatus.ts +1 -0
  76. package/src/cli.ts +6 -1
  77. package/src/codex/AppServerPermissions.ts +39 -0
  78. package/src/codex/CodexLocalActivityDetector.ts +34 -4
  79. package/src/codex/CodexRuntime.ts +243 -139
  80. package/src/codex/ProviderSwitch.ts +11 -12
  81. package/src/codex/ThreadWriterProcess.ts +17 -9
  82. package/src/config/AgentExecutionDefaultsStore.ts +2 -0
  83. package/src/config/loadConfig.ts +4 -0
  84. package/src/config/schema.ts +5 -1
  85. package/src/feishu/CardRenderer.ts +159 -72
  86. package/src/feishu/FeishuConnector.ts +1 -0
  87. package/src/feishu/FeishuTurnPresenter.ts +108 -16
  88. package/src/feishu/types.ts +1 -0
  89. package/src/index.ts +44 -7
  90. package/src/local-files/CsvPreview.ts +132 -0
  91. package/src/local-files/LocalFileViewerServer.ts +102 -15
  92. package/src/local-files/TurnPreviewPage.ts +131 -13
  93. package/src/presentation/TurnStateReducer.ts +87 -7
  94. package/src/presentation/turnViewTypes.ts +9 -0
  95. package/src/proxy/ProxySessionController.ts +762 -259
  96. package/src/proxy/SessionOperationQueue.ts +13 -0
  97. package/src/runtime/AcpRuntimeAdapter.ts +5 -3
  98. package/src/runtime/types.ts +10 -3
  99. package/src/state/StateStore.ts +38 -1
  100. package/src/state/TurnPreviewJournal.ts +19 -7
  101. package/src/state/migrations.ts +6 -0
  102. package/src/supervision/SafeRestartNotifier.ts +1 -0
  103. package/src/supervision/SafeRestartScheduler.ts +18 -6
  104. package/src/terminal/TerminalCards.ts +18 -0
  105. package/src/terminal/TerminalLinks.ts +61 -0
  106. package/src/terminal/TerminalPage.ts +213 -0
  107. package/src/terminal/TerminalProcess.ts +71 -0
  108. package/src/terminal/TerminalServer.ts +513 -0
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,11 @@
1
1
  import { createHash } from "node:crypto";
2
+ import { approvalActivityId } from "../presentation/TurnStateReducer.js";
2
3
  import path from "node:path";
3
4
  import { truncateMiddle, truncateText } from "../utils/markdown.js";
4
5
  import { localCardImage } from "./LocalCardImage.js";
5
6
  const EXECUTION_SETTING_EFFECTS = {
6
7
  agent: "只影响新建任务,不切换当前任务。",
7
- provider: "只影响当前任务,需空闲时切换。",
8
+ provider: "只影响当前任务;运行中选择将在本轮结束后生效。",
8
9
  model: "只影响当前任务,下一轮生效。",
9
10
  thinking: "只影响当前任务,下一轮生效。",
10
11
  permission: "只影响当前任务,下一轮生效。",
@@ -199,6 +200,9 @@ export class CardRenderer {
199
200
  ...(outputWasTruncated ? ["输出过长,已保留开头和结尾并截断中间内容。"] : []),
200
201
  ].join("\n")),
201
202
  ];
203
+ if (view.terminalUrl) {
204
+ elements.push(markdown(`[Open Terminal](${view.terminalUrl}) · 独立终端,需在本会话由所有者授权`));
205
+ }
202
206
  if (view.status === "running" && view.jobId && view.contextKey) {
203
207
  elements.push({
204
208
  tag: "button",
@@ -234,6 +238,7 @@ export class CardRenderer {
234
238
  `**思考强度 / 权限**:${inlineCode(view.currentEffort ?? "自动")} / ${inlineCode(permissionModeLabel(view.currentPermissionMode))}`,
235
239
  ]
236
240
  : []),
241
+ ...(view.pendingNotice ? [view.pendingNotice] : []),
237
242
  ...(view.notice ? [view.notice] : []),
238
243
  ...(view.warning ? [`**提示**:${escapeCardHtml(view.warning)}`] : []),
239
244
  ].join("\n")),
@@ -267,7 +272,8 @@ export class CardRenderer {
267
272
  inlineCode(provider.id),
268
273
  provider.isDefault ? " · 默认" : "",
269
274
  ].join(""),
270
- current: provider.id === view.currentProvider,
275
+ current: provider.id === view.currentProvider && !view.pendingFailed,
276
+ currentLabel: view.pendingNotice ? "待生效" : undefined,
271
277
  action: {
272
278
  text: "Switch",
273
279
  value: {
@@ -284,18 +290,24 @@ export class CardRenderer {
284
290
  elements.push(markdown("当前运行时未返回可用模型。"));
285
291
  }
286
292
  else {
287
- elements.push(...view.models.map((model) => settingsOptionRow({
293
+ const page = paginateModels(view.models, view.currentModel, view.modelPage, {
294
+ action: "settings_tab_open", ...baseAction, tab: "model", provider: view.currentProvider ?? "",
295
+ });
296
+ elements.push(...page.models.map((model) => settingsOptionRow({
288
297
  label: `${inlineCode(model.id)}${model.isDefault ? " · 默认" : ""}`,
289
- current: model.id === view.currentModel,
298
+ current: model.id === view.currentModel && !view.pendingFailed,
299
+ currentLabel: view.pendingNotice ? "待生效" : undefined,
290
300
  action: {
291
301
  text: "Switch",
292
302
  value: {
293
303
  action: "settings_model_select",
294
304
  ...baseAction,
305
+ provider: view.currentProvider ?? "",
295
306
  model: model.id,
296
307
  },
297
308
  },
298
309
  })));
310
+ elements.push(...page.navigation);
299
311
  }
300
312
  }
301
313
  else if (view.activeTab === "thinking") {
@@ -310,11 +322,13 @@ export class CardRenderer {
310
322
  elements.push(...view.reasoningOptions.map((option) => settingsOptionRow({
311
323
  label: inlineCode(option.value),
312
324
  current: option.value === view.currentEffort,
325
+ currentLabel: view.pendingNotice ? "待生效" : undefined,
313
326
  action: {
314
327
  text: "Switch",
315
328
  value: {
316
329
  action: "settings_thinking_select",
317
330
  ...baseAction,
331
+ provider: view.currentProvider ?? "",
318
332
  model: currentModel,
319
333
  effort: option.value,
320
334
  },
@@ -326,6 +340,7 @@ export class CardRenderer {
326
340
  elements.push(...["auto", "confirm"].map((mode) => settingsOptionRow({
327
341
  label: `${inlineCode(mode)} · ${permissionModeLabel(mode)}`,
328
342
  current: mode === view.currentPermissionMode,
343
+ currentLabel: view.pendingNotice ? "待生效" : undefined,
329
344
  action: {
330
345
  text: "Switch",
331
346
  value: {
@@ -337,7 +352,7 @@ export class CardRenderer {
337
352
  })));
338
353
  }
339
354
  elements.push(markdown(`> ${EXECUTION_SETTING_EFFECTS[view.activeTab]}`));
340
- return sectionCard("运行设置", elements, view.warning ? "orange" : view.notice ? "green" : "blue");
355
+ return sectionCard("运行设置", elements, view.warning || view.pendingFailed ? "orange" : view.notice ? "green" : "blue");
341
356
  }
342
357
  renderProviderSelector(view) {
343
358
  const elements = [
@@ -470,7 +485,14 @@ export class CardRenderer {
470
485
  elements.push(markdown("当前运行时未返回可用模型。"));
471
486
  }
472
487
  else {
473
- elements.push(...view.models.map((model) => {
488
+ const page = paginateModels(view.models, view.currentModel, view.modelPage, {
489
+ action: view.unifiedSettings ? "provider_model_open" : "model_open",
490
+ sessionId: view.sessionId,
491
+ contextKey: view.contextKey,
492
+ ...(view.modelProvider ? { provider: view.modelProvider } : {}),
493
+ ...(view.permissionMode ? { permissionMode: view.permissionMode } : {}),
494
+ });
495
+ elements.push(...page.models.map((model) => {
474
496
  const isCurrent = model.id === view.currentModel;
475
497
  return {
476
498
  tag: "column_set",
@@ -506,6 +528,7 @@ export class CardRenderer {
506
528
  ],
507
529
  };
508
530
  }));
531
+ elements.push(...page.navigation);
509
532
  }
510
533
  if (view.unifiedSettings) {
511
534
  elements.push({ tag: "hr" }, taskActionRow([{
@@ -665,6 +688,24 @@ export class CardRenderer {
665
688
  }
666
689
  return sectionCard("Agent Bot 更新提醒", elements, view.status === "completed" ? "green" : view.status === "cancelled" ? "grey" : "blue");
667
690
  }
691
+ renderTerminalAuthorization(view) {
692
+ const action = (decision) => ({ action: "terminal_authorize", contextKey: view.contextKey, requestId: view.requestId, token: view.approvalToken, decision });
693
+ const elements = [markdown(`**目录**:${inlineCode(view.cwd)}\n**终端**:${inlineCode(view.reopenToken)}`)];
694
+ if (view.state === "pending") {
695
+ elements.push(markdown(`**验证码**:${inlineCode(view.code)}\n仅 AgentBot 所有者可授权。授权后,该浏览器可在本机执行任意命令,拥有 AgentBot 的系统用户权限。请核对网页验证码,仅批准本人发起的请求。5 分钟内有效。${view.recovery ? (view.shellStarted ? "恢复原 Shell,不创建新终端;授权后旧网页失去访问权限。拒绝不影响原终端。" : "继续打开同一个终端;授权后旧网页失去访问权限,Shell 在连接成功后启动。拒绝不影响原授权。") : "不执行原卡片命令。"}`), taskActionRow([{ text: "Allow", value: action("allow") }, { text: "Deny", type: "danger", value: action("deny") }, { text: "刷新", value: action("refresh") }]));
696
+ }
697
+ else if (view.state === "closed") {
698
+ elements.push(markdown(`**状态**:${view.message ? escapeCardHtml(view.message) : "已关闭"}\n原终端已结束时,请从命令卡片创建新终端。`));
699
+ }
700
+ else {
701
+ const waiting = view.state === "approved";
702
+ const label = waiting ? "打开终端" : "重新打开终端";
703
+ elements.push(markdown(`**状态**:${waiting ? "已授权,等待网页连接" : view.connected ? "已连接" : "网页已断开,Shell 仍在运行"}\n${waiting ? "请返回原网页连接;原网页已关闭时,点击下方“打开终端”。Shell 尚未启动。" : "点击下方“重新打开终端”恢复原 Shell。前台连接时不因空闲关闭;后台空闲 30 分钟或网页断开 3 分钟后会自动关闭 Shell,成功重连取消断开计时并重置空闲计时;“关闭终端”会中断其中的命令。"}`));
704
+ elements.push(markdown(`[${label}](${view.reopenUrl}) · 新网页需核对验证码重新授权${waiting ? ",连接成功后启动 Shell" : ",恢复原 Shell"}`));
705
+ elements.push(taskActionRow([{ text: "关闭终端", type: "danger", value: action("close") }, { text: "刷新", value: action("refresh") }]));
706
+ }
707
+ return sectionCard(view.state === "pending" ? "网页终端授权" : "网页终端管理", elements, view.state === "closed" ? "grey" : view.state === "pending" ? "orange" : "blue");
708
+ }
668
709
  renderSafeRestartStatus(view) {
669
710
  const actionable = view.phase !== "restarting" && view.phase !== "cancelled" && view.phase !== "superseded";
670
711
  const countdown = view.phase === "countdown"
@@ -692,6 +733,7 @@ export class CardRenderer {
692
733
  `**重启原因**:${inlineCode(view.reason)}`,
693
734
  `**重启倒计时**:${countdown}`,
694
735
  `**待投递结果**:${view.pendingFinalDeliveries} 条`,
736
+ ...(view.activeTerminals ? [`**活动终端**:${view.activeTerminals} 个,请在网页或原会话的终端管理卡中关闭。ForceRestart 会中断终端。`] : []),
695
737
  ];
696
738
  const elements = [markdown(lines.join("\n"))];
697
739
  if (view.waitingTasks.length > 0) {
@@ -1308,38 +1350,8 @@ function renderTurnElements(state, assistantTextMode) {
1308
1350
  elements.push(...renderActivities(visibleActivities, state.projectCwd));
1309
1351
  if (state.fileSummary.length > 0)
1310
1352
  elements.push(fileSummaryPanel(state));
1311
- if (state.approval) {
1312
- const request = state.approval;
1313
- elements.push(markdown([
1314
- `**${request.title}**`,
1315
- request.command ? codeBlock(request.command, 800) : undefined,
1316
- request.reason,
1317
- ].filter(Boolean).join("\n")));
1318
- elements.push({
1319
- tag: "column_set",
1320
- flex_mode: "flow",
1321
- horizontal_spacing: "8px",
1322
- columns: request.options.map((option) => ({
1323
- tag: "column",
1324
- width: "auto",
1325
- elements: [{
1326
- tag: "button",
1327
- text: { tag: "plain_text", content: request.kind === "mode_change" ? option.label : approvalDecisionLabel(option.id) },
1328
- type: option.id === "accept" || option.id === "acceptForSession" ? "primary" : option.id === "cancel" ? "danger" : "default",
1329
- behaviors: [{
1330
- type: "callback",
1331
- value: {
1332
- action: "approval",
1333
- sessionId: state.sessionId,
1334
- turnId: state.turnId,
1335
- requestId: request.id,
1336
- decision: option.id,
1337
- },
1338
- }],
1339
- }],
1340
- })),
1341
- });
1342
- }
1353
+ if (state.approval)
1354
+ elements.push(...renderApprovalElements(state, state.approval));
1343
1355
  if (state.error)
1344
1356
  elements.push(markdown(codeBlock(state.error, 2_000)));
1345
1357
  const showAssistantText = state.assistantText && assistantTextMode === "always";
@@ -1379,38 +1391,8 @@ function renderGroupedTurnElements(state, assistantTextMode) {
1379
1391
  elements.push(...renderGroupedActivityGroups(visibleGroups, state.projectCwd));
1380
1392
  if (state.fileSummary.length > 0)
1381
1393
  elements.push(fileSummaryPanel(state));
1382
- if (state.approval) {
1383
- const request = state.approval;
1384
- elements.push(markdown([
1385
- `**${request.title}**`,
1386
- request.command ? codeBlock(request.command, 800) : undefined,
1387
- request.reason,
1388
- ].filter(Boolean).join("\n")));
1389
- elements.push({
1390
- tag: "column_set",
1391
- flex_mode: "flow",
1392
- horizontal_spacing: "8px",
1393
- columns: request.options.map((option) => ({
1394
- tag: "column",
1395
- width: "auto",
1396
- elements: [{
1397
- tag: "button",
1398
- text: { tag: "plain_text", content: request.kind === "mode_change" ? option.label : approvalDecisionLabel(option.id) },
1399
- type: option.id === "accept" || option.id === "acceptForSession" ? "primary" : option.id === "cancel" ? "danger" : "default",
1400
- behaviors: [{
1401
- type: "callback",
1402
- value: {
1403
- action: "approval",
1404
- sessionId: state.sessionId,
1405
- turnId: state.turnId,
1406
- requestId: request.id,
1407
- decision: option.id,
1408
- },
1409
- }],
1410
- }],
1411
- })),
1412
- });
1413
- }
1394
+ if (state.approval)
1395
+ elements.push(...renderApprovalElements(state, state.approval));
1414
1396
  if (state.error)
1415
1397
  elements.push(markdown(codeBlock(state.error, 2_000)));
1416
1398
  const showAssistantText = state.assistantText && assistantTextMode === "always";
@@ -1424,6 +1406,84 @@ function renderGroupedTurnElements(state, assistantTextMode) {
1424
1406
  elements.push(markdown(emptyTurnText(state.status, state.agentLabel)));
1425
1407
  return elements;
1426
1408
  }
1409
+ function renderApprovalElements(state, request) {
1410
+ const elements = [];
1411
+ const command = request.command?.trim();
1412
+ if (command && request.kind !== "mode_change") {
1413
+ elements.push(markdown("**命令执行确认**"));
1414
+ const reason = request.reason?.trim()
1415
+ || (request.title.trim() !== command ? request.title.trim() : "");
1416
+ if (reason && reason !== command) {
1417
+ const preview = approvalTextPreview(reason, 1_000, escapeApprovalText);
1418
+ elements.push(markdown(escapeApprovalText(preview)));
1419
+ if (preview !== reason)
1420
+ elements.push(markdown("<font color='grey'>说明较长,请在 Preview 中查看完整内容。</font>"));
1421
+ }
1422
+ const display = displayToolCommand(command) ?? command;
1423
+ const summary = truncateText(display.replace(/\s+/gu, " "), 64);
1424
+ const preview = approvalTextPreview(command, 2_200);
1425
+ elements.push(collapsiblePanel(`查看命令 · ${summary}`, [
1426
+ markdown(codeBlock(preview, preview.length)),
1427
+ ...(preview !== command ? [markdown("<font color='grey'>命令过长,卡片仅显示开头。请在 Preview 中查看完整命令后再授权。</font>")] : []),
1428
+ ], {
1429
+ elementId: `approval_${createHash("sha256").update(request.id).digest("hex").slice(0, 11)}`,
1430
+ compact: true,
1431
+ borderColor: "grey",
1432
+ }));
1433
+ }
1434
+ else {
1435
+ elements.push(markdown([
1436
+ `**${request.title}**`,
1437
+ request.command ? codeBlock(request.command, 800) : undefined,
1438
+ request.reason,
1439
+ ].filter(Boolean).join("\n")));
1440
+ }
1441
+ if (request.automatic) {
1442
+ elements.push(markdown("自动执行模式:正在自动同意。"));
1443
+ return elements;
1444
+ }
1445
+ elements.push({
1446
+ tag: "column_set",
1447
+ flex_mode: "flow",
1448
+ horizontal_spacing: "8px",
1449
+ columns: request.options.map((option) => ({
1450
+ tag: "column",
1451
+ width: "auto",
1452
+ elements: [{
1453
+ tag: "button",
1454
+ text: { tag: "plain_text", content: request.kind === "mode_change" ? option.label : approvalDecisionLabel(option.id) },
1455
+ type: option.id === "accept" || option.id === "acceptForSession" ? "primary" : option.id === "cancel" ? "danger" : "default",
1456
+ behaviors: [{
1457
+ type: "callback",
1458
+ value: {
1459
+ action: "approval",
1460
+ sessionId: state.sessionId,
1461
+ turnId: state.turnId,
1462
+ requestId: request.id,
1463
+ decision: option.id,
1464
+ },
1465
+ }],
1466
+ }],
1467
+ })),
1468
+ });
1469
+ return elements;
1470
+ }
1471
+ function approvalTextPreview(value, maxBytes, encode = (text) => text) {
1472
+ if (Buffer.byteLength(JSON.stringify(encode(value)), "utf8") <= maxBytes)
1473
+ return value;
1474
+ let bytes = 5;
1475
+ let result = "";
1476
+ for (const character of value) {
1477
+ bytes += Buffer.byteLength(JSON.stringify(encode(character)), "utf8") - 2;
1478
+ if (bytes > maxBytes)
1479
+ break;
1480
+ result += character;
1481
+ }
1482
+ return `${result}...`;
1483
+ }
1484
+ function escapeApprovalText(value) {
1485
+ return escapeCardHtml(value).replace(/[\\`*_[\]#]/gu, (character) => `&#${character.codePointAt(0)};`);
1486
+ }
1427
1487
  function emptyTurnText(status, agentLabel) {
1428
1488
  const label = agentLabel?.trim().replace(/[\r\n]+/g, " ") || "Agent";
1429
1489
  if (status === "starting")
@@ -1767,7 +1827,8 @@ function removeMarkdownBold(value) {
1767
1827
  }
1768
1828
  function turnActivities(state) {
1769
1829
  if (state.activities?.length)
1770
- return state.activities;
1830
+ return state.approval
1831
+ ? state.activities.filter((a) => a.id !== approvalActivityId(state.turnId, state.approval.id)) : state.activities;
1771
1832
  const activities = [];
1772
1833
  if (state.progressText) {
1773
1834
  activities.push({ kind: "reasoning", id: "legacy-progress", text: state.progressText });
@@ -1817,6 +1878,8 @@ function collapsiblePanel(title, content, options = {}) {
1817
1878
  }
1818
1879
  function sessionTaskPanel(entry) {
1819
1880
  const elements = [markdown(entry.detailLines.join("\n"))];
1881
+ if (entry.stopAction)
1882
+ elements.push(sessionActionButton(entry.stopAction));
1820
1883
  if (entry.actions?.length)
1821
1884
  elements.push(sessionActionOverflow(entry.actions));
1822
1885
  return collapsiblePanel(entry.summary, elements, {
@@ -2318,6 +2381,17 @@ function acpPermissionOptionLabel(option) {
2318
2381
  };
2319
2382
  return labels[option.kind] ?? (/^[\x20-\x7E]+$/.test(option.name) ? option.name : "Select");
2320
2383
  }
2384
+ const MODEL_PAGE_SIZE = 20;
2385
+ function paginateModels(models, currentModel, requestedPage, action) {
2386
+ const totalPages = Math.max(1, Math.ceil(models.length / MODEL_PAGE_SIZE));
2387
+ const currentPage = Math.floor(models.findIndex((model) => model.id === currentModel) / MODEL_PAGE_SIZE);
2388
+ const page = Math.max(0, Math.min(requestedPage ?? currentPage, totalPages - 1));
2389
+ const navigation = totalPages > 1 ? [taskActionRow([
2390
+ ...(page > 0 ? [{ text: "上一页", value: { ...action, page: String(page - 1) } }] : []),
2391
+ ...(page < totalPages - 1 ? [{ text: "下一页", value: { ...action, page: String(page + 1) } }] : []),
2392
+ ], `第 ${page + 1}/${totalPages} 页 · 共 ${models.length} 个模型`)] : [];
2393
+ return { models: models.slice(page * MODEL_PAGE_SIZE, (page + 1) * MODEL_PAGE_SIZE), navigation };
2394
+ }
2321
2395
  function settingsTabRow(activeTab, baseAction, showAgentTab, showRuntimeTabs) {
2322
2396
  const tabs = [
2323
2397
  ...(showAgentTab ? [{ id: "agent", label: "Agent" }] : []),
@@ -2396,7 +2470,7 @@ function settingsOptionRow(input) {
2396
2470
  tag: "column",
2397
2471
  width: "auto",
2398
2472
  vertical_align: "center",
2399
- elements: input.current ? [markdown("✅ 当前")] : [taskActionElement(input.action)],
2473
+ elements: input.current ? [markdown(`✅ ${input.currentLabel ?? "当前"}`)] : [taskActionElement(input.action)],
2400
2474
  },
2401
2475
  ],
2402
2476
  };