@keyou007/agent-bot 0.1.13 → 0.1.14-alpha.1

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 (77) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +41 -44
  3. package/README.zh.md +41 -44
  4. package/config.example.yaml +4 -0
  5. package/dist/codex/CodexRuntime.js +8 -3
  6. package/dist/codex/CodexRuntime.js.map +1 -1
  7. package/dist/commands/CommandRouter.js +13 -0
  8. package/dist/commands/CommandRouter.js.map +1 -1
  9. package/dist/config/loadConfig.js +2 -0
  10. package/dist/config/loadConfig.js.map +1 -1
  11. package/dist/config/schema.js +2 -0
  12. package/dist/config/schema.js.map +1 -1
  13. package/dist/console/ConsoleTurnPresenter.js +2 -0
  14. package/dist/console/ConsoleTurnPresenter.js.map +1 -1
  15. package/dist/feishu/CardRenderer.js +428 -9
  16. package/dist/feishu/CardRenderer.js.map +1 -1
  17. package/dist/feishu/FeishuConnector.js +29 -8
  18. package/dist/feishu/FeishuConnector.js.map +1 -1
  19. package/dist/feishu/FeishuMessageClient.js +78 -8
  20. package/dist/feishu/FeishuMessageClient.js.map +1 -1
  21. package/dist/feishu/FeishuTurnPresenter.js +31 -2
  22. package/dist/feishu/FeishuTurnPresenter.js.map +1 -1
  23. package/dist/feishu/ownerAccess.js +7 -0
  24. package/dist/feishu/ownerAccess.js.map +1 -0
  25. package/dist/index.js +14 -17
  26. package/dist/index.js.map +1 -1
  27. package/dist/presentation/OutboundRouter.js +19 -1
  28. package/dist/presentation/OutboundRouter.js.map +1 -1
  29. package/dist/presentation/splitMarkdown.js +16 -4
  30. package/dist/presentation/splitMarkdown.js.map +1 -1
  31. package/dist/proxy/ProxySessionController.js +1012 -58
  32. package/dist/proxy/ProxySessionController.js.map +1 -1
  33. package/dist/startup/StartupNotifier.js +65 -16
  34. package/dist/startup/StartupNotifier.js.map +1 -1
  35. package/dist/startup/startFeishu.js +2 -2
  36. package/dist/startup/startFeishu.js.map +1 -1
  37. package/dist/state/StateStore.js +250 -67
  38. package/dist/state/StateStore.js.map +1 -1
  39. package/dist/state/migrations.js +26 -0
  40. package/dist/state/migrations.js.map +1 -1
  41. package/dist/supervision/SafeRestartNotifier.js +17 -16
  42. package/dist/supervision/SafeRestartNotifier.js.map +1 -1
  43. package/dist/supervision/SafeRestartScheduler.js +12 -7
  44. package/dist/supervision/SafeRestartScheduler.js.map +1 -1
  45. package/dist/supervision/replacementSupervisor.js +45 -4
  46. package/dist/supervision/replacementSupervisor.js.map +1 -1
  47. package/dist/supervisor.js +30 -18
  48. package/dist/supervisor.js.map +1 -1
  49. package/docs/technical-reference.md +18 -5
  50. package/docs/technical-reference.zh.md +18 -5
  51. package/npm-shrinkwrap.json +2 -2
  52. package/package.json +1 -1
  53. package/skills/agent-bot/SKILL.md +8 -2
  54. package/src/codex/CodexRuntime.ts +9 -3
  55. package/src/commands/CommandRouter.ts +13 -0
  56. package/src/commands/commandTypes.ts +2 -0
  57. package/src/config/loadConfig.ts +2 -0
  58. package/src/config/schema.ts +2 -0
  59. package/src/console/ConsoleTurnPresenter.ts +4 -1
  60. package/src/feishu/CardRenderer.ts +533 -9
  61. package/src/feishu/FeishuConnector.ts +44 -10
  62. package/src/feishu/FeishuMessageClient.ts +118 -7
  63. package/src/feishu/FeishuTurnPresenter.ts +42 -3
  64. package/src/feishu/ownerAccess.ts +7 -0
  65. package/src/feishu/types.ts +7 -0
  66. package/src/index.ts +20 -20
  67. package/src/presentation/OutboundRouter.ts +28 -3
  68. package/src/presentation/splitMarkdown.ts +26 -3
  69. package/src/proxy/ProxySessionController.ts +1177 -57
  70. package/src/startup/StartupNotifier.ts +67 -17
  71. package/src/startup/startFeishu.ts +5 -3
  72. package/src/state/StateStore.ts +394 -65
  73. package/src/state/migrations.ts +26 -0
  74. package/src/supervision/SafeRestartNotifier.ts +17 -17
  75. package/src/supervision/SafeRestartScheduler.ts +13 -6
  76. package/src/supervision/replacementSupervisor.ts +50 -4
  77. package/src/supervisor.ts +35 -16
@@ -1 +1 @@
1
- {"version":3,"file":"loadConfig.js","sourceRoot":"","sources":["../../src/config/loadConfig.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loadConfig.js","sourceRoot":"","sources":["../../src/config/loadConfig.ts"],"names":[],"mappings":"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"}
@@ -24,7 +24,9 @@ export const appConfigSchema = z.object({
24
24
  appId: z.string().optional(),
25
25
  appSecret: z.string().optional(),
26
26
  userOpenId: z.string().optional(),
27
+ respondToOwnerOnly: z.boolean().default(true),
27
28
  respondToAllGroupMessages: z.boolean().default(true),
29
+ thinkingCardLayout: z.enum(["grouped", "timeline"]).default("grouped"),
28
30
  useConsoleWhenMissingCredentials: z.boolean().default(false),
29
31
  }),
30
32
  agents: z.record(z.string().min(1), agentConfigSchema).refine((agents) => Object.keys(agents).length > 0, "At least one agent must be configured."),
@@ -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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"}
@@ -18,12 +18,14 @@ export class ConsoleTurnPresenter {
18
18
  }
19
19
  async startPendingTurn(sessionId, contextKey) {
20
20
  await this.outbound.sendText(contextKey, `Connecting to ${this.agentLabel(sessionId)}...`);
21
+ return undefined;
21
22
  }
22
23
  async failPendingTurn(sessionId, message) {
23
24
  const contextKey = this.contexts.get(sessionId);
24
25
  if (contextKey)
25
26
  await this.outbound.sendText(contextKey, `${this.agentLabel(sessionId)} failed to start: ${message}`);
26
27
  }
28
+ async interruptTurnForRecovery() { }
27
29
  async appendSteerMessage() { }
28
30
  async onEvent(event) {
29
31
  const contextKey = this.contexts.get(event.sessionId);
@@ -1 +1 @@
1
- {"version":3,"file":"ConsoleTurnPresenter.js","sourceRoot":"","sources":["../../src/console/ConsoleTurnPresenter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ConsoleTurnPresenter.js","sourceRoot":"","sources":["../../src/console/ConsoleTurnPresenter.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,12 @@ import { createHash } from "node:crypto";
2
2
  import path from "node:path";
3
3
  import { truncateMiddle, truncateText } from "../utils/markdown.js";
4
4
  import { localCardImage } from "./LocalCardImage.js";
5
+ const DIRECTORY_BROWSER_ROW_COUNT = 16;
5
6
  export class CardRenderer {
7
+ thinkingCardLayout;
8
+ constructor(options = {}) {
9
+ this.thinkingCardLayout = options.thinkingCardLayout ?? "grouped";
10
+ }
6
11
  renderExecutionSettings(view) {
7
12
  const baseAction = {
8
13
  contextKey: view.contextKey,
@@ -596,7 +601,9 @@ export class CardRenderer {
596
601
  };
597
602
  }
598
603
  renderTurn(state) {
599
- const elements = renderTurnElements(state, "hidden");
604
+ const elements = this.thinkingCardLayout === "timeline"
605
+ ? renderTurnElements(state, "hidden")
606
+ : renderGroupedTurnElements(state, "hidden");
600
607
  if (isTurnStoppable(state.status)) {
601
608
  elements.push({ tag: "hr" }, taskActionRow([{
602
609
  text: "Stop",
@@ -622,7 +629,13 @@ export class CardRenderer {
622
629
  return turnCard(title, "blue", renderTurnElements(state, "always"), renderTurnSubtitle(state));
623
630
  }
624
631
  renderActivityHistory(state, requestedPage) {
625
- const pages = activityPages(turnActivities(state));
632
+ const grouped = this.thinkingCardLayout === "grouped";
633
+ const pages = grouped
634
+ ? groupedActivityPages(turnActivities(state), state.projectCwd, {
635
+ fullActivityText: true,
636
+ includeReasoningHistory: true,
637
+ })
638
+ : activityPages(turnActivities(state));
626
639
  if (pages.length === 0) {
627
640
  return this.renderSectionsCard("思考活动历史", [{ lines: ["没有保存到活动记录。"] }]);
628
641
  }
@@ -644,7 +657,12 @@ export class CardRenderer {
644
657
  const elements = [];
645
658
  if (actions.length > 0)
646
659
  elements.push(taskActionRow(actions), { tag: "hr" });
647
- elements.push(...renderActivities(pages[page] ?? [], state.projectCwd, true));
660
+ elements.push(...(grouped
661
+ ? renderGroupedActivityGroups(pages[page] ?? [], state.projectCwd, {
662
+ fullActivityText: true,
663
+ includeReasoningHistory: true,
664
+ })
665
+ : renderActivities(pages[page] ?? [], state.projectCwd, true)));
648
666
  return sectionCard(`思考活动历史 · ${page + 1}/${pages.length}`, elements.length > 0 ? elements : [markdown("无")]);
649
667
  }
650
668
  renderSessionStarted(session) {
@@ -748,6 +766,62 @@ export class CardRenderer {
748
766
  },
749
767
  };
750
768
  }
769
+ renderSessionTaskListCard(title, sectionTitle, groups, footerLines, footerActions = []) {
770
+ const elements = [markdown(`**${sectionTitle}**`)];
771
+ if (groups.length === 0) {
772
+ elements.push(markdown("无"));
773
+ }
774
+ else {
775
+ groups.forEach((group) => {
776
+ elements.push(sessionProjectRow(group));
777
+ elements.push(...group.entries.map(sessionTaskPanel));
778
+ });
779
+ }
780
+ if (footerActions.length > 0) {
781
+ elements.push(taskActionRow(footerActions));
782
+ }
783
+ if (footerLines.length > 0) {
784
+ elements.push(markdown(footerLines.join("\n")));
785
+ }
786
+ return {
787
+ schema: "2.0",
788
+ config: {
789
+ update_multi: true,
790
+ width_mode: "fill",
791
+ },
792
+ header: {
793
+ template: "blue",
794
+ title: {
795
+ tag: "plain_text",
796
+ content: title,
797
+ },
798
+ },
799
+ body: {
800
+ vertical_spacing: "4px",
801
+ elements,
802
+ },
803
+ };
804
+ }
805
+ renderDirectoryBrowserCard(view) {
806
+ const elements = [
807
+ markdown(`**当前目录**:${inlineCode(view.directory)}`),
808
+ taskActionRow(view.currentActions),
809
+ { tag: "hr" },
810
+ ];
811
+ const entryRows = view.entries.length === 0
812
+ ? [directoryBrowserEmptyRow()]
813
+ : view.entries.slice(0, DIRECTORY_BROWSER_ROW_COUNT).map(directoryBrowserEntryRow);
814
+ while (entryRows.length < DIRECTORY_BROWSER_ROW_COUNT)
815
+ entryRows.push(directoryBrowserPlaceholderRow());
816
+ elements.push(...entryRows);
817
+ if (view.navigationActions.length > 0) {
818
+ elements.push({ tag: "hr" }, taskActionRow(view.navigationActions));
819
+ }
820
+ if (view.footerLines.length > 0) {
821
+ elements.push({ tag: "hr" }, markdown(view.footerLines.join("\n")));
822
+ }
823
+ return sectionCard("文件浏览", elements, "blue", "2px");
824
+ }
751
825
  renderResetHistoryCard(view) {
752
826
  const elements = [
753
827
  {
@@ -875,6 +949,78 @@ function renderTurnElements(state, assistantTextMode) {
875
949
  elements.push(markdown(emptyTurnText(state.status, state.agentLabel)));
876
950
  return elements;
877
951
  }
952
+ function renderGroupedTurnElements(state, assistantTextMode) {
953
+ const elements = [];
954
+ const allActivities = turnActivities(state);
955
+ const livePages = groupedActivityPages(allActivities, state.projectCwd);
956
+ const historyPages = groupedActivityPages(allActivities, state.projectCwd, {
957
+ fullActivityText: true,
958
+ includeReasoningHistory: true,
959
+ });
960
+ const visibleGroups = livePages.at(-1) ?? [];
961
+ if (state.plan.length > 0)
962
+ elements.push(planPanel(state.plan));
963
+ if (historyPages.length > 1) {
964
+ elements.push(taskActionRow([{
965
+ text: `查看历史思考(共 ${historyPages.length} 页)`,
966
+ value: {
967
+ action: "activity_history",
968
+ turnId: state.turnId,
969
+ page: String(historyPages.length - 2),
970
+ },
971
+ }]));
972
+ }
973
+ if (state.activitiesTruncated || livePages.length > 1 || historyPages.length > 1)
974
+ elements.push(markdown("…"));
975
+ elements.push(...renderGroupedActivityGroups(visibleGroups, state.projectCwd));
976
+ if (state.fileSummary.length > 0)
977
+ elements.push(fileSummaryPanel(state));
978
+ if (state.approval) {
979
+ const request = state.approval;
980
+ elements.push(markdown([
981
+ `**${request.title}**`,
982
+ request.command ? codeBlock(request.command, 800) : undefined,
983
+ request.reason,
984
+ ].filter(Boolean).join("\n")));
985
+ elements.push({
986
+ tag: "column_set",
987
+ flex_mode: "flow",
988
+ horizontal_spacing: "8px",
989
+ vertical_spacing: "8px",
990
+ columns: request.options.map((option) => ({
991
+ tag: "column",
992
+ width: "auto",
993
+ elements: [{
994
+ tag: "button",
995
+ text: { tag: "plain_text", content: approvalDecisionLabel(option.id) },
996
+ type: option.id === "accept" || option.id === "acceptForSession" ? "primary" : option.id === "cancel" ? "danger" : "default",
997
+ behaviors: [{
998
+ type: "callback",
999
+ value: {
1000
+ action: "approval",
1001
+ sessionId: state.sessionId,
1002
+ turnId: state.turnId,
1003
+ requestId: request.id,
1004
+ decision: option.id,
1005
+ },
1006
+ }],
1007
+ }],
1008
+ })),
1009
+ });
1010
+ }
1011
+ if (state.error)
1012
+ elements.push(markdown(codeBlock(state.error, 2_000)));
1013
+ const showAssistantText = state.assistantText && assistantTextMode === "always";
1014
+ if (showAssistantText) {
1015
+ if (elements.length > 0)
1016
+ elements.push({ tag: "hr" });
1017
+ const heading = state.status === "completed" ? "回答" : "回答生成中";
1018
+ elements.push(markdown(`**${heading}**\n${truncateText(state.assistantText, 3_000)}`));
1019
+ }
1020
+ if (elements.length === 0)
1021
+ elements.push(markdown(emptyTurnText(state.status, state.agentLabel)));
1022
+ return elements;
1023
+ }
878
1024
  function emptyTurnText(status, agentLabel) {
879
1025
  const label = agentLabel?.trim().replace(/[\r\n]+/g, " ") || "Agent";
880
1026
  if (status === "starting")
@@ -953,6 +1099,105 @@ function renderActivities(activities, projectCwd, fullAssistantText = false) {
953
1099
  flushReasoning();
954
1100
  return elements;
955
1101
  }
1102
+ function renderGroupedActivityGroups(groups, projectCwd, options = {}) {
1103
+ return groups.flatMap((group) => {
1104
+ if (group.kind === "activity") {
1105
+ return renderActivity(group.activity, projectCwd, options.fullActivityText === true);
1106
+ }
1107
+ if (group.tools.length === 0) {
1108
+ const reasonings = options.includeReasoningHistory
1109
+ ? group.reasonings
1110
+ : group.latestReasoning ? [group.latestReasoning] : [];
1111
+ return renderReasoningGroup(reasonings);
1112
+ }
1113
+ return [executionActivityPanel(group, projectCwd, options.includeReasoningHistory === true)];
1114
+ });
1115
+ }
1116
+ function groupTurnActivities(activities) {
1117
+ const groups = [];
1118
+ let segment = [];
1119
+ const flushSegment = () => {
1120
+ if (segment.length === 0)
1121
+ return;
1122
+ let execution;
1123
+ let executionPosition = -1;
1124
+ for (let index = 0; index < segment.length; index += 1) {
1125
+ const activity = segment[index];
1126
+ if (isRawReasoning(activity)) {
1127
+ execution ??= { kind: "execution", id: activity.id, reasonings: [], tools: [] };
1128
+ execution.reasonings.push(activity);
1129
+ execution.latestReasoning = activity;
1130
+ executionPosition = index;
1131
+ }
1132
+ else if (activity.kind === "tool") {
1133
+ execution ??= { kind: "execution", id: activity.id, reasonings: [], tools: [] };
1134
+ execution.tools.push(activity.tool);
1135
+ executionPosition = index;
1136
+ }
1137
+ }
1138
+ for (let index = 0; index < segment.length; index += 1) {
1139
+ const activity = segment[index];
1140
+ if (index === executionPosition && execution)
1141
+ groups.push(execution);
1142
+ if (!isRawReasoning(activity) && activity.kind !== "tool") {
1143
+ groups.push({ kind: "activity", activity });
1144
+ }
1145
+ }
1146
+ segment = [];
1147
+ };
1148
+ for (const activity of activities) {
1149
+ if (!isCommentaryActivity(activity)) {
1150
+ segment.push(activity);
1151
+ continue;
1152
+ }
1153
+ flushSegment();
1154
+ groups.push({ kind: "activity", activity });
1155
+ }
1156
+ flushSegment();
1157
+ return groups;
1158
+ }
1159
+ function isCommentaryActivity(activity) {
1160
+ return activity.kind === "assistant"
1161
+ || (activity.kind === "reasoning" && activity.id.startsWith("commentary:"));
1162
+ }
1163
+ function executionActivityPanel(group, projectCwd, includeReasoningHistory = false) {
1164
+ const status = executionActivityStatus(group.tools);
1165
+ const elements = [
1166
+ ...(includeReasoningHistory ? renderReasoningGroup(group.reasonings) : []),
1167
+ ...group.tools.map((tool) => toolPanel(tool, projectCwd)),
1168
+ ];
1169
+ return collapsiblePanel(executionActivityTitle(group, status), elements, {
1170
+ elementId: executionActivityPanelElementId(group.id),
1171
+ expanded: false,
1172
+ borderColor: status === "failed" ? "red" : status === "running" ? "blue" : "grey",
1173
+ compact: true,
1174
+ });
1175
+ }
1176
+ function executionActivityStatus(tools) {
1177
+ if (tools.some((tool) => tool.status === "running"))
1178
+ return "running";
1179
+ if (tools.some((tool) => tool.status === "failed"))
1180
+ return "failed";
1181
+ return "completed";
1182
+ }
1183
+ function executionActivityTitle(group, status) {
1184
+ const icon = status === "running" ? "⏳" : status === "failed" ? "❌" : "💭";
1185
+ const latestReasoning = group.latestReasoning?.text
1186
+ ? removeMarkdownBold(group.latestReasoning.text).replace(/\s+/g, " ").trim()
1187
+ : "";
1188
+ const summary = latestReasoning
1189
+ ? truncateText(latestReasoning, 90)
1190
+ : status === "running"
1191
+ ? "正在执行工具"
1192
+ : status === "failed"
1193
+ ? "工具执行失败"
1194
+ : "已执行工具";
1195
+ return `${icon} ${summary} · ${group.tools.length} 个工具`;
1196
+ }
1197
+ function executionActivityPanelElementId(activityId) {
1198
+ const digest = createHash("sha256").update(activityId).digest("hex").slice(0, 10);
1199
+ return `turn_exec_${digest}`;
1200
+ }
956
1201
  function renderReasoningGroup(activities) {
957
1202
  const sections = activities
958
1203
  .map((activity) => activity.text.trim())
@@ -969,6 +1214,9 @@ function isRawReasoning(activity) {
969
1214
  return activity.kind === "reasoning" && !activity.id.startsWith("commentary:");
970
1215
  }
971
1216
  const ACTIVITIES_PER_PAGE = 40;
1217
+ const GROUPED_TOOLS_PER_PANEL = 8;
1218
+ const GROUPED_PAGE_ACTIVITY_BYTES = 24 * 1024;
1219
+ const GROUPED_PAGE_ACTIVITY_COMPONENTS = 160;
972
1220
  const MAX_LIVE_ASSISTANT_TEXT = 2_000;
973
1221
  const ACTIVITY_TEXT_CHUNK = 2_500;
974
1222
  function activityPages(activities) {
@@ -984,6 +1232,57 @@ function activityPages(activities) {
984
1232
  }
985
1233
  return pages;
986
1234
  }
1235
+ function groupedActivityPages(activities, projectCwd, renderOptions = {}) {
1236
+ const groups = groupTurnActivities(activities).flatMap(splitGroupedExecutionActivity);
1237
+ if (groups.length === 0)
1238
+ return [];
1239
+ const newestFirst = [];
1240
+ let page = [];
1241
+ for (let index = groups.length - 1; index >= 0; index -= 1) {
1242
+ const group = groups[index];
1243
+ const candidate = [group, ...page];
1244
+ if (page.length > 0 && !groupedActivityPageFits(candidate, projectCwd, renderOptions)) {
1245
+ newestFirst.push(page);
1246
+ page = [];
1247
+ }
1248
+ page.unshift(group);
1249
+ }
1250
+ if (page.length > 0)
1251
+ newestFirst.push(page);
1252
+ return newestFirst.reverse();
1253
+ }
1254
+ function groupedActivityPageFits(groups, projectCwd, renderOptions) {
1255
+ const elements = renderGroupedActivityGroups(groups, projectCwd, renderOptions);
1256
+ return Buffer.byteLength(JSON.stringify(elements), "utf8") <= GROUPED_PAGE_ACTIVITY_BYTES
1257
+ && countCardComponents(elements) <= GROUPED_PAGE_ACTIVITY_COMPONENTS;
1258
+ }
1259
+ function countCardComponents(value) {
1260
+ if (Array.isArray(value)) {
1261
+ return value.reduce((total, entry) => total + countCardComponents(entry), 0);
1262
+ }
1263
+ if (!value || typeof value !== "object")
1264
+ return 0;
1265
+ const record = value;
1266
+ return (typeof record.tag === "string" ? 1 : 0)
1267
+ + Object.values(record).reduce((total, entry) => total + countCardComponents(entry), 0);
1268
+ }
1269
+ function splitGroupedExecutionActivity(group) {
1270
+ if (group.kind !== "execution" || group.tools.length <= GROUPED_TOOLS_PER_PANEL)
1271
+ return [group];
1272
+ const chunks = [];
1273
+ for (let index = 0; index < group.tools.length; index += GROUPED_TOOLS_PER_PANEL) {
1274
+ const tools = group.tools.slice(index, index + GROUPED_TOOLS_PER_PANEL);
1275
+ const isLast = index + GROUPED_TOOLS_PER_PANEL >= group.tools.length;
1276
+ chunks.push({
1277
+ kind: "execution",
1278
+ id: index === 0 ? group.id : tools[0]?.id ?? `${group.id}:${index}`,
1279
+ ...(isLast && group.latestReasoning ? { latestReasoning: group.latestReasoning } : {}),
1280
+ reasonings: isLast ? group.reasonings : [],
1281
+ tools,
1282
+ });
1283
+ }
1284
+ return chunks;
1285
+ }
987
1286
  function splitText(value, maxLength) {
988
1287
  if (!value)
989
1288
  return [];
@@ -1027,18 +1326,19 @@ function toolPanelElementId(toolId) {
1027
1326
  return `turn_tool_${digest}`;
1028
1327
  }
1029
1328
  function collapsiblePanel(title, content, options = {}) {
1329
+ const compact = options.compact === true;
1030
1330
  return {
1031
1331
  tag: "collapsible_panel",
1032
1332
  ...(options.elementId ? { element_id: options.elementId } : {}),
1033
1333
  direction: "vertical",
1034
- vertical_spacing: "4px",
1035
- padding: "8px",
1334
+ vertical_spacing: compact ? "2px" : "4px",
1335
+ padding: compact ? "4px 6px" : "8px",
1036
1336
  margin: "0px",
1037
1337
  expanded: options.expanded ?? false,
1038
1338
  header: {
1039
1339
  title: { tag: "plain_text", content: title },
1040
1340
  vertical_align: "center",
1041
- padding: "4px 8px 4px 8px",
1341
+ padding: compact ? "2px 4px 2px 4px" : "4px 8px 4px 8px",
1042
1342
  },
1043
1343
  border: {
1044
1344
  color: options.borderColor ?? "grey",
@@ -1047,6 +1347,64 @@ function collapsiblePanel(title, content, options = {}) {
1047
1347
  elements: typeof content === "string" ? [markdown(content)] : content,
1048
1348
  };
1049
1349
  }
1350
+ function sessionTaskPanel(entry) {
1351
+ const elements = [markdown(entry.detailLines.join("\n"))];
1352
+ if (entry.actions?.length)
1353
+ elements.push(sessionActionOverflow(entry.actions));
1354
+ return collapsiblePanel(entry.summary, elements, {
1355
+ elementId: sessionTaskPanelElementId(entry.reference),
1356
+ borderColor: entry.current ? "green" : "grey",
1357
+ compact: true,
1358
+ });
1359
+ }
1360
+ function sessionProjectRow(group) {
1361
+ return {
1362
+ tag: "column_set",
1363
+ flex_mode: "none",
1364
+ horizontal_spacing: "8px",
1365
+ vertical_align: "center",
1366
+ margin: "6px 0px 0px 0px",
1367
+ columns: [
1368
+ {
1369
+ tag: "column",
1370
+ width: "weighted",
1371
+ weight: 1,
1372
+ vertical_align: "center",
1373
+ elements: [markdown(`**${escapeCardActionText(group.title)}**`)],
1374
+ },
1375
+ ...(group.actions ?? []).map((action) => ({
1376
+ tag: "column",
1377
+ width: "auto",
1378
+ vertical_align: "center",
1379
+ elements: [sessionActionButton(action)],
1380
+ })),
1381
+ ],
1382
+ };
1383
+ }
1384
+ function sessionTaskPanelElementId(reference) {
1385
+ return `session_task_${createHash("sha256").update(reference).digest("hex").slice(0, 16)}`;
1386
+ }
1387
+ function sessionActionOverflow(actions) {
1388
+ return {
1389
+ tag: "overflow",
1390
+ options: actions.map((action) => ({
1391
+ text: { tag: "plain_text", content: action.text },
1392
+ value: JSON.stringify(action.value),
1393
+ })),
1394
+ };
1395
+ }
1396
+ function sessionActionButton(action) {
1397
+ return {
1398
+ tag: "button",
1399
+ text: { tag: "plain_text", content: action.text },
1400
+ type: action.type === "danger" ? "danger" : "default",
1401
+ size: "tiny",
1402
+ behaviors: [{
1403
+ type: "callback",
1404
+ value: action.value,
1405
+ }],
1406
+ };
1407
+ }
1050
1408
  function renderToolDetails(tool, projectCwd) {
1051
1409
  const command = tool.command ?? tool.title;
1052
1410
  const fileSummary = tool.files?.length
@@ -1412,19 +1770,80 @@ function taskActionRow(actions) {
1412
1770
  })),
1413
1771
  };
1414
1772
  }
1773
+ function directoryBrowserEntryRow(entry) {
1774
+ const label = `${directoryBrowserEntryIcon(entry.kind)} ${entry.name}`;
1775
+ return {
1776
+ tag: "column_set",
1777
+ flex_mode: "none",
1778
+ horizontal_spacing: "12px",
1779
+ vertical_align: "center",
1780
+ margin: "0px",
1781
+ columns: [
1782
+ {
1783
+ tag: "column",
1784
+ width: "weighted",
1785
+ weight: 1,
1786
+ vertical_align: "center",
1787
+ elements: entry.openAction
1788
+ ? [taskActionElement({ ...entry.openAction, text: label })]
1789
+ : [markdown(escapeCardHtml(label))],
1790
+ },
1791
+ ...(entry.actions ?? []).map((action) => ({
1792
+ tag: "column",
1793
+ width: "auto",
1794
+ vertical_align: "center",
1795
+ elements: [taskActionElement(action)],
1796
+ })),
1797
+ ],
1798
+ };
1799
+ }
1800
+ function directoryBrowserEmptyRow() {
1801
+ return directoryBrowserStaticRow("这个目录为空。");
1802
+ }
1803
+ function directoryBrowserPlaceholderRow() {
1804
+ return directoryBrowserStaticRow("\u00a0");
1805
+ }
1806
+ function directoryBrowserStaticRow(content) {
1807
+ return {
1808
+ tag: "column_set",
1809
+ flex_mode: "none",
1810
+ horizontal_spacing: "12px",
1811
+ vertical_align: "center",
1812
+ margin: "0px",
1813
+ columns: [{
1814
+ tag: "column",
1815
+ width: "weighted",
1816
+ weight: 1,
1817
+ vertical_align: "center",
1818
+ elements: [markdown(content)],
1819
+ }],
1820
+ };
1821
+ }
1822
+ function directoryBrowserEntryIcon(kind) {
1823
+ switch (kind) {
1824
+ case "directory": return "📁";
1825
+ case "drive": return "💽";
1826
+ case "image": return "🖼️";
1827
+ case "binary": return "📦";
1828
+ case "file": return "📄";
1829
+ }
1830
+ }
1415
1831
  function taskActionElement(action) {
1416
1832
  return {
1417
1833
  tag: "interactive_container",
1418
1834
  margin: "0px",
1419
1835
  padding: "0px",
1420
1836
  has_border: false,
1421
- elements: [markdown(`<font color='${action.type === "danger" ? "red" : "blue"}'>${escapeCardHtml(action.text)}</font>`)],
1837
+ elements: [markdown(`<font color='${action.type === "danger" ? "red" : "blue"}'>${escapeCardActionText(action.text)}</font>`)],
1422
1838
  behaviors: [{
1423
1839
  type: "callback",
1424
1840
  value: action.value,
1425
1841
  }],
1426
1842
  };
1427
1843
  }
1844
+ function escapeCardActionText(value) {
1845
+ return escapeCardHtml(value).replaceAll("\\", "&#92;");
1846
+ }
1428
1847
  function helpCommandRow(command) {
1429
1848
  const details = [
1430
1849
  command.usage ? `**${command.usage}**` : undefined,
@@ -1484,7 +1903,7 @@ function turnCard(title, template, elements, subtitle) {
1484
1903
  },
1485
1904
  };
1486
1905
  }
1487
- function sectionCard(title, elements, template = "blue") {
1906
+ function sectionCard(title, elements, template = "blue", verticalSpacing = "8px") {
1488
1907
  return {
1489
1908
  schema: "2.0",
1490
1909
  config: {
@@ -1501,7 +1920,7 @@ function sectionCard(title, elements, template = "blue") {
1501
1920
  },
1502
1921
  body: {
1503
1922
  direction: "vertical",
1504
- vertical_spacing: "8px",
1923
+ vertical_spacing: verticalSpacing,
1505
1924
  padding: "12px 12px 12px 12px",
1506
1925
  elements,
1507
1926
  },