dominds 1.22.0 → 1.23.0

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 (145) hide show
  1. package/dist/access-control.js +2 -2
  2. package/dist/dialog-instance-registry.js +3 -4
  3. package/dist/dialog.d.ts +2 -2
  4. package/dist/dialog.js +3 -3
  5. package/dist/docs/dialog-system.md +3 -2
  6. package/dist/docs/dialog-system.zh.md +3 -2
  7. package/dist/docs/diligence-push.md +19 -12
  8. package/dist/docs/diligence-push.zh.md +11 -9
  9. package/dist/docs/dominds-terminology.md +3 -3
  10. package/dist/docs/encapsulated-taskdoc.md +11 -2
  11. package/dist/docs/encapsulated-taskdoc.zh.md +10 -1
  12. package/dist/docs/llm-provider-isolation.md +1 -1
  13. package/dist/docs/llm-provider-isolation.zh.md +1 -1
  14. package/dist/docs/team_mgmt-toolset.md +2 -1
  15. package/dist/docs/team_mgmt-toolset.zh.md +2 -1
  16. package/dist/docs/volcengine-coding-plan-openai-compatible.zh.md +11 -10
  17. package/dist/llm/api-quirks.d.ts +0 -2
  18. package/dist/llm/api-quirks.js +1 -3
  19. package/dist/llm/client.d.ts +1 -0
  20. package/dist/llm/defaults.yaml +45 -6
  21. package/dist/llm/gen/anthropic.d.ts +0 -6
  22. package/dist/llm/gen/anthropic.js +21 -468
  23. package/dist/llm/gen/openai-compatible.d.ts +14 -1
  24. package/dist/llm/gen/openai-compatible.js +482 -19
  25. package/dist/llm/gen.d.ts +4 -2
  26. package/dist/llm/kernel-driver/drive.js +164 -114
  27. package/dist/llm/kernel-driver/runtime.js +36 -11
  28. package/dist/llm/kernel-driver/tellask-special.js +12 -9
  29. package/dist/minds/system-prompt-parts.js +8 -8
  30. package/dist/persistence.d.ts +2 -3
  31. package/dist/persistence.js +53 -76
  32. package/dist/problems.js +2 -1
  33. package/dist/runtime/driver-messages.js +4 -4
  34. package/dist/server/websocket-handler.js +17 -3
  35. package/dist/team.d.ts +2 -1
  36. package/dist/team.js +11 -1
  37. package/dist/tools/ctrl.js +48 -11
  38. package/dist/tools/prompts/control/en/principles.md +3 -3
  39. package/dist/tools/prompts/control/en/scenarios.md +4 -0
  40. package/dist/tools/prompts/control/en/tools.md +6 -3
  41. package/dist/tools/prompts/control/zh/principles.md +3 -3
  42. package/dist/tools/prompts/control/zh/scenarios.md +4 -0
  43. package/dist/tools/prompts/control/zh/tools.md +6 -3
  44. package/dist/tools/team_mgmt-manual.js +4 -4
  45. package/dist/tools/team_mgmt.js +15 -5
  46. package/dist/utils/task-package.d.ts +16 -0
  47. package/dist/utils/task-package.js +132 -55
  48. package/dist/utils/taskdoc.js +21 -16
  49. package/package.json +3 -3
  50. package/webapp/dist/assets/{_basePickBy-BYnYcdaa.js → _basePickBy-CGhMqD96.js} +3 -3
  51. package/webapp/dist/assets/{_basePickBy-BYnYcdaa.js.map → _basePickBy-CGhMqD96.js.map} +1 -1
  52. package/webapp/dist/assets/{_baseUniq-CHLBB955.js → _baseUniq-XCMW7z1Y.js} +2 -2
  53. package/webapp/dist/assets/{_baseUniq-CHLBB955.js.map → _baseUniq-XCMW7z1Y.js.map} +1 -1
  54. package/webapp/dist/assets/{arc-DQXtgZdO.js → arc-B6fzk0T5.js} +2 -2
  55. package/webapp/dist/assets/{arc-DQXtgZdO.js.map → arc-B6fzk0T5.js.map} +1 -1
  56. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-CzP5Yf9x.js → architectureDiagram-2XIMDMQ5-DmSI_GUt.js} +7 -7
  57. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-CzP5Yf9x.js.map → architectureDiagram-2XIMDMQ5-DmSI_GUt.js.map} +1 -1
  58. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-sOx5Byq8.js → blockDiagram-WCTKOSBZ-Bp0nb8IZ.js} +7 -7
  59. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-sOx5Byq8.js.map → blockDiagram-WCTKOSBZ-Bp0nb8IZ.js.map} +1 -1
  60. package/webapp/dist/assets/{c4Diagram-IC4MRINW-D8-GiS6c.js → c4Diagram-IC4MRINW-gYpylqGb.js} +3 -3
  61. package/webapp/dist/assets/{c4Diagram-IC4MRINW-D8-GiS6c.js.map → c4Diagram-IC4MRINW-gYpylqGb.js.map} +1 -1
  62. package/webapp/dist/assets/{channel-Bvke0iMP.js → channel-BmQ3YyUn.js} +2 -2
  63. package/webapp/dist/assets/{channel-Bvke0iMP.js.map → channel-BmQ3YyUn.js.map} +1 -1
  64. package/webapp/dist/assets/{chunk-4BX2VUAB-C9pln2M7.js → chunk-4BX2VUAB-B5pwFRwA.js} +2 -2
  65. package/webapp/dist/assets/{chunk-4BX2VUAB-C9pln2M7.js.map → chunk-4BX2VUAB-B5pwFRwA.js.map} +1 -1
  66. package/webapp/dist/assets/{chunk-55IACEB6-BLDXNtAM.js → chunk-55IACEB6-CZf6oMWM.js} +2 -2
  67. package/webapp/dist/assets/{chunk-55IACEB6-BLDXNtAM.js.map → chunk-55IACEB6-CZf6oMWM.js.map} +1 -1
  68. package/webapp/dist/assets/{chunk-FMBD7UC4-dYd3QdHa.js → chunk-FMBD7UC4-yZWCDzVz.js} +2 -2
  69. package/webapp/dist/assets/{chunk-FMBD7UC4-dYd3QdHa.js.map → chunk-FMBD7UC4-yZWCDzVz.js.map} +1 -1
  70. package/webapp/dist/assets/{chunk-JSJVCQXG-SqHEmHHd.js → chunk-JSJVCQXG-Cg1ST73M.js} +2 -2
  71. package/webapp/dist/assets/{chunk-JSJVCQXG-SqHEmHHd.js.map → chunk-JSJVCQXG-Cg1ST73M.js.map} +1 -1
  72. package/webapp/dist/assets/{chunk-KX2RTZJC-CRXgzI2d.js → chunk-KX2RTZJC-ByGtlX9q.js} +2 -2
  73. package/webapp/dist/assets/{chunk-KX2RTZJC-CRXgzI2d.js.map → chunk-KX2RTZJC-ByGtlX9q.js.map} +1 -1
  74. package/webapp/dist/assets/{chunk-NQ4KR5QH-IMA2JZhH.js → chunk-NQ4KR5QH-DoXvfhSY.js} +4 -4
  75. package/webapp/dist/assets/{chunk-NQ4KR5QH-IMA2JZhH.js.map → chunk-NQ4KR5QH-DoXvfhSY.js.map} +1 -1
  76. package/webapp/dist/assets/{chunk-QZHKN3VN-DBaGWjY3.js → chunk-QZHKN3VN-2gX2qsHB.js} +2 -2
  77. package/webapp/dist/assets/{chunk-QZHKN3VN-DBaGWjY3.js.map → chunk-QZHKN3VN-2gX2qsHB.js.map} +1 -1
  78. package/webapp/dist/assets/{chunk-WL4C6EOR-QLmsLbcS.js → chunk-WL4C6EOR-L-9bPNxS.js} +6 -6
  79. package/webapp/dist/assets/{chunk-WL4C6EOR-QLmsLbcS.js.map → chunk-WL4C6EOR-L-9bPNxS.js.map} +1 -1
  80. package/webapp/dist/assets/{classDiagram-VBA2DB6C-jN4lhUtx.js → classDiagram-VBA2DB6C-B79Oe3Df.js} +7 -7
  81. package/webapp/dist/assets/{classDiagram-VBA2DB6C-jN4lhUtx.js.map → classDiagram-VBA2DB6C-B79Oe3Df.js.map} +1 -1
  82. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-jN4lhUtx.js → classDiagram-v2-RAHNMMFH-B79Oe3Df.js} +7 -7
  83. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-jN4lhUtx.js.map → classDiagram-v2-RAHNMMFH-B79Oe3Df.js.map} +1 -1
  84. package/webapp/dist/assets/{clone-DPC4Vt09.js → clone-DvlY9Sdn.js} +2 -2
  85. package/webapp/dist/assets/{clone-DPC4Vt09.js.map → clone-DvlY9Sdn.js.map} +1 -1
  86. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-BtVgObsc.js → cose-bilkent-S5V4N54A-CtkGd0W6.js} +2 -2
  87. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-BtVgObsc.js.map → cose-bilkent-S5V4N54A-CtkGd0W6.js.map} +1 -1
  88. package/webapp/dist/assets/{dagre-KLK3FWXG-Bv6mn-UV.js → dagre-KLK3FWXG-B3W6QTXQ.js} +7 -7
  89. package/webapp/dist/assets/{dagre-KLK3FWXG-Bv6mn-UV.js.map → dagre-KLK3FWXG-B3W6QTXQ.js.map} +1 -1
  90. package/webapp/dist/assets/{diagram-E7M64L7V-D2OPgDkq.js → diagram-E7M64L7V-B6-J_E5Q.js} +8 -8
  91. package/webapp/dist/assets/{diagram-E7M64L7V-D2OPgDkq.js.map → diagram-E7M64L7V-B6-J_E5Q.js.map} +1 -1
  92. package/webapp/dist/assets/{diagram-IFDJBPK2-CZpDu-e5.js → diagram-IFDJBPK2-C-PH_Yx3.js} +7 -7
  93. package/webapp/dist/assets/{diagram-IFDJBPK2-CZpDu-e5.js.map → diagram-IFDJBPK2-C-PH_Yx3.js.map} +1 -1
  94. package/webapp/dist/assets/{diagram-P4PSJMXO-BkMbbW0p.js → diagram-P4PSJMXO-CB5xXDup.js} +7 -7
  95. package/webapp/dist/assets/{diagram-P4PSJMXO-BkMbbW0p.js.map → diagram-P4PSJMXO-CB5xXDup.js.map} +1 -1
  96. package/webapp/dist/assets/{erDiagram-INFDFZHY-Kf17ek1z.js → erDiagram-INFDFZHY-CuAhTGVU.js} +5 -5
  97. package/webapp/dist/assets/{erDiagram-INFDFZHY-Kf17ek1z.js.map → erDiagram-INFDFZHY-CuAhTGVU.js.map} +1 -1
  98. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-Cort4hNL.js → flowDiagram-PKNHOUZH-D3cIOfGj.js} +7 -7
  99. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-Cort4hNL.js.map → flowDiagram-PKNHOUZH-D3cIOfGj.js.map} +1 -1
  100. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-DcXFKB1Y.js → ganttDiagram-A5KZAMGK-CSFhVYXV.js} +3 -3
  101. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-DcXFKB1Y.js.map → ganttDiagram-A5KZAMGK-CSFhVYXV.js.map} +1 -1
  102. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-BORnqZ0-.js → gitGraphDiagram-K3NZZRJ6-CiEaxACG.js} +8 -8
  103. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-BORnqZ0-.js.map → gitGraphDiagram-K3NZZRJ6-CiEaxACG.js.map} +1 -1
  104. package/webapp/dist/assets/{graph-D4Uth-MK.js → graph-CYGALRuy.js} +3 -3
  105. package/webapp/dist/assets/{graph-D4Uth-MK.js.map → graph-CYGALRuy.js.map} +1 -1
  106. package/webapp/dist/assets/{index-YBIJr7jH.js → index-BTazqQrV.js} +186 -58
  107. package/webapp/dist/assets/index-BTazqQrV.js.map +1 -0
  108. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-DDjsEPg3.js → infoDiagram-LFFYTUFH-CiWJjQyU.js} +6 -6
  109. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-DDjsEPg3.js.map → infoDiagram-LFFYTUFH-CiWJjQyU.js.map} +1 -1
  110. package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-Bb2sPnCX.js → ishikawaDiagram-PHBUUO56-MlIIUO7o.js} +2 -2
  111. package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-Bb2sPnCX.js.map → ishikawaDiagram-PHBUUO56-MlIIUO7o.js.map} +1 -1
  112. package/webapp/dist/assets/{journeyDiagram-4ABVD52K-BtRY6eBa.js → journeyDiagram-4ABVD52K-BBqwkA3d.js} +5 -5
  113. package/webapp/dist/assets/{journeyDiagram-4ABVD52K-BtRY6eBa.js.map → journeyDiagram-4ABVD52K-BBqwkA3d.js.map} +1 -1
  114. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-aGmxT2H9.js → kanban-definition-K7BYSVSG-BS4GzDbo.js} +3 -3
  115. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-aGmxT2H9.js.map → kanban-definition-K7BYSVSG-BS4GzDbo.js.map} +1 -1
  116. package/webapp/dist/assets/{layout-BuLicmwh.js → layout-DaJO-1DW.js} +5 -5
  117. package/webapp/dist/assets/{layout-BuLicmwh.js.map → layout-DaJO-1DW.js.map} +1 -1
  118. package/webapp/dist/assets/{linear-DIPh96mp.js → linear-SWy2Cl7G.js} +2 -2
  119. package/webapp/dist/assets/{linear-DIPh96mp.js.map → linear-SWy2Cl7G.js.map} +1 -1
  120. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-ofWsysn9.js → mindmap-definition-YRQLILUH-B_gNrT3l.js} +4 -4
  121. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-ofWsysn9.js.map → mindmap-definition-YRQLILUH-B_gNrT3l.js.map} +1 -1
  122. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-DQqCTITO.js → pieDiagram-SKSYHLDU-CVh3lLBA.js} +8 -8
  123. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-DQqCTITO.js.map → pieDiagram-SKSYHLDU-CVh3lLBA.js.map} +1 -1
  124. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-DxWc0avu.js → quadrantDiagram-337W2JSQ-D0zAkVD7.js} +3 -3
  125. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-DxWc0avu.js.map → quadrantDiagram-337W2JSQ-D0zAkVD7.js.map} +1 -1
  126. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-DHgYfzwt.js → requirementDiagram-Z7DCOOCP--CTFD60w.js} +4 -4
  127. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-DHgYfzwt.js.map → requirementDiagram-Z7DCOOCP--CTFD60w.js.map} +1 -1
  128. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-Cuhwe80W.js → sankeyDiagram-WA2Y5GQK-XZnViaAX.js} +2 -2
  129. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-Cuhwe80W.js.map → sankeyDiagram-WA2Y5GQK-XZnViaAX.js.map} +1 -1
  130. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-DqSNoro8.js → sequenceDiagram-2WXFIKYE-BWAMhn_x.js} +4 -4
  131. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-DqSNoro8.js.map → sequenceDiagram-2WXFIKYE-BWAMhn_x.js.map} +1 -1
  132. package/webapp/dist/assets/{stateDiagram-RAJIS63D-D1mvuJi6.js → stateDiagram-RAJIS63D--jsLD0Dg.js} +9 -9
  133. package/webapp/dist/assets/{stateDiagram-RAJIS63D-D1mvuJi6.js.map → stateDiagram-RAJIS63D--jsLD0Dg.js.map} +1 -1
  134. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-BCYX5Gy-.js → stateDiagram-v2-FVOUBMTO-DUG9vyI5.js} +5 -5
  135. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-BCYX5Gy-.js.map → stateDiagram-v2-FVOUBMTO-DUG9vyI5.js.map} +1 -1
  136. package/webapp/dist/assets/{timeline-definition-YZTLITO2-DDLYGao7.js → timeline-definition-YZTLITO2-BROLp1hL.js} +3 -3
  137. package/webapp/dist/assets/{timeline-definition-YZTLITO2-DDLYGao7.js.map → timeline-definition-YZTLITO2-BROLp1hL.js.map} +1 -1
  138. package/webapp/dist/assets/{treemap-KZPCXAKY-DXkv1e6y.js → treemap-KZPCXAKY-BXuIlbYo.js} +5 -5
  139. package/webapp/dist/assets/{treemap-KZPCXAKY-DXkv1e6y.js.map → treemap-KZPCXAKY-BXuIlbYo.js.map} +1 -1
  140. package/webapp/dist/assets/{vennDiagram-LZ73GAT5-DMxsg9P0.js → vennDiagram-LZ73GAT5-BXWd8gBB.js} +2 -2
  141. package/webapp/dist/assets/{vennDiagram-LZ73GAT5-DMxsg9P0.js.map → vennDiagram-LZ73GAT5-BXWd8gBB.js.map} +1 -1
  142. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-BJ2qipzT.js → xychartDiagram-JWTSCODW-DR5z9o6h.js} +3 -3
  143. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-BJ2qipzT.js.map → xychartDiagram-JWTSCODW-DR5z9o6h.js.map} +1 -1
  144. package/webapp/dist/index.html +1 -1
  145. package/webapp/dist/assets/index-YBIJr7jH.js.map +0 -1
package/dist/llm/gen.d.ts CHANGED
@@ -56,7 +56,6 @@ export interface LlmRequestContext {
56
56
  modelKey?: string;
57
57
  promptCacheKey?: string;
58
58
  toolUseRequirement?: 'none' | 'auto' | 'required';
59
- knownFunctionCallIds?: ReadonlySet<string>;
60
59
  }
61
60
  export type ToolResultImageIngest = {
62
61
  toolCallId: string;
@@ -146,7 +145,10 @@ export interface LlmStreamReceiver {
146
145
  sayingStart: () => Promise<void>;
147
146
  sayingChunk: (chunk: string) => Promise<void>;
148
147
  sayingFinish: () => Promise<void>;
149
- funcCall: (callId: string, name: string, args: string) => Promise<void>;
148
+ funcCall: (callId: string, name: string, args: string, ids?: {
149
+ rawCallId?: string;
150
+ effectiveCallId?: string;
151
+ }) => Promise<void>;
150
152
  webSearchCall?: (call: LlmWebSearchCall) => Promise<void>;
151
153
  nativeToolCall?: (call: OpenAiResponsesNativeToolCall) => Promise<void>;
152
154
  toolResultImageIngest?: (ingest: ToolResultImageIngest) => Promise<void>;
@@ -555,10 +555,11 @@ function resolveMemberDiligencePushMax(team, agentId) {
555
555
  function emitDiligenceBudgetEvent(dlg, options) {
556
556
  const maxInjectCount = Math.max(0, Math.floor(options.maxInjectCount));
557
557
  const remainingCount = Math.max(0, Math.floor(options.nextRemainingBudget));
558
+ const injectedCount = maxInjectCount > 0 ? Math.max(0, maxInjectCount - remainingCount) : 0;
558
559
  (0, evt_registry_1.postDialogEvent)(dlg, {
559
560
  type: 'diligence_budget_evt',
560
561
  maxInjectCount,
561
- injectedCount: Math.max(0, maxInjectCount - remainingCount),
562
+ injectedCount,
562
563
  remainingCount,
563
564
  disableDiligencePush: dlg.disableDiligencePush,
564
565
  });
@@ -873,111 +874,154 @@ function shouldImmediatelyFollowUpToolOutcome(tool, outcome) {
873
874
  }
874
875
  return shouldImmediatelyFollowUpSuccessfulToolResult(tool);
875
876
  }
876
- async function loadKnownFunctionCallIds(dialog) {
877
+ function trimOptionalCallId(value) {
878
+ if (typeof value !== 'string')
879
+ return undefined;
880
+ const trimmed = value.trim();
881
+ return trimmed === '' ? undefined : trimmed;
882
+ }
883
+ function resolveRawCallId(call) {
884
+ return trimOptionalCallId(call.rawId) ?? call.id;
885
+ }
886
+ function reserveKnownFunctionCallId(reservation, callId) {
887
+ const normalized = trimOptionalCallId(callId);
888
+ if (normalized !== undefined) {
889
+ reservation.knownCallIds.add(normalized);
890
+ }
891
+ }
892
+ async function loadKnownFunctionCallIdsForCurrentCourse(dialog) {
877
893
  const known = new Set();
878
- for (const msg of dialog.msgs) {
879
- if (msg.type === 'func_call_msg') {
880
- const callId = msg.id.trim();
881
- if (callId !== '') {
882
- known.add(callId);
883
- }
894
+ const addKnown = (callId) => {
895
+ const normalized = trimOptionalCallId(callId);
896
+ if (normalized !== undefined) {
897
+ known.add(normalized);
884
898
  }
885
- }
886
- const latest = await persistence_1.DialogPersistence.loadDialogLatest(dialog.id, dialog.status);
887
- const maxCourse = latest?.currentCourse ?? dialog.currentCourse;
888
- for (let course = 1; course <= maxCourse; course += 1) {
889
- const events = await persistence_1.DialogPersistence.loadCourseEvents(dialog.id, course, dialog.status);
890
- for (const event of events) {
891
- if (event.type === 'func_call_record' || event.type === 'tellask_call_record') {
892
- const callId = event.id.trim();
893
- if (callId !== '') {
894
- known.add(callId);
895
- }
899
+ };
900
+ const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
901
+ const events = await persistence_1.DialogPersistence.loadCourseEvents(dialog.id, course, dialog.status);
902
+ for (const event of events) {
903
+ if (event.type === 'func_call_record' || event.type === 'tellask_call_record') {
904
+ addKnown(event.id);
905
+ if (event.type === 'func_call_record') {
906
+ addKnown(event.rawId);
907
+ addKnown(event.effectiveId);
896
908
  }
897
909
  }
898
910
  }
899
911
  return known;
900
912
  }
901
- async function loadKnownFunctionCallIdsForProviderQuirks(dialog, providerConfig) {
902
- if (!(0, api_quirks_1.normalizeProviderApiQuirks)(providerConfig).has(api_quirks_1.VOLCANO_TOOL_USE_API_QUIRK)) {
903
- return undefined;
913
+ function allocateDuplicateEffectiveCallId(args) {
914
+ const base = args.rawCallId.trim();
915
+ if (base === '') {
916
+ throw new Error('kernel-driver function call id invariant violation: empty raw callId');
917
+ }
918
+ let suffix = args.reservation.nextDuplicateSuffixByRawId.get(base) ?? 2;
919
+ for (;;) {
920
+ const candidate = `${base}__dominds_c${String(args.course)}_g${String(args.genseq)}_${String(suffix)}`;
921
+ suffix += 1;
922
+ if (!args.reservation.knownCallIds.has(candidate)) {
923
+ args.reservation.nextDuplicateSuffixByRawId.set(base, suffix);
924
+ return candidate;
925
+ }
904
926
  }
905
- return await loadKnownFunctionCallIds(dialog);
906
927
  }
907
- function formatDuplicateFunctionCallResult(args) {
908
- const language = (0, work_language_1.getWorkLanguage)();
909
- if (language === 'zh') {
910
- return [
911
- `错误:本次函数调用被拒绝,因为 callId \`${args.callId}\` 已经被使用过。`,
912
- '',
913
- `不要复用已有 callId 调用 \`${args.callName}\`。如果仍需要调用工具,请重新发起一次带全新 callId 的函数调用。`,
914
- ].join('\n');
915
- }
916
- return [
917
- `Error: this function call was rejected because callId \`${args.callId}\` has already been used.`,
918
- '',
919
- `Do not reuse an existing callId for \`${args.callName}\`. If you still need the tool, issue a new function call with a fresh callId.`,
920
- ].join('\n');
928
+ function allocateEffectiveFunctionCallId(args) {
929
+ const rawCallId = args.rawCallId.trim();
930
+ if (rawCallId === '') {
931
+ throw new Error('kernel-driver function call id invariant violation: empty raw callId');
932
+ }
933
+ const duplicateRawCallId = args.reservation.knownCallIds.has(rawCallId) ||
934
+ args.reservation.seenRawIdsThisRound.has(rawCallId);
935
+ if (!duplicateRawCallId) {
936
+ args.reservation.knownCallIds.add(rawCallId);
937
+ args.reservation.seenRawIdsThisRound.add(rawCallId);
938
+ return { effectiveCallId: rawCallId, duplicateRawCallId: false };
939
+ }
940
+ const effectiveCallId = allocateDuplicateEffectiveCallId({
941
+ reservation: args.reservation,
942
+ rawCallId,
943
+ course: args.course,
944
+ genseq: args.genseq,
945
+ });
946
+ args.reservation.knownCallIds.add(effectiveCallId);
947
+ args.reservation.seenRawIdsThisRound.add(rawCallId);
948
+ log_1.log.warn('Mapped duplicate raw function call id to unique effective id', undefined, {
949
+ course: args.course,
950
+ genseq: args.genseq,
951
+ rawCallId,
952
+ effectiveCallId,
953
+ });
954
+ return { effectiveCallId, duplicateRawCallId: true };
921
955
  }
922
- async function splitPreRejectedFunctionCalls(args) {
923
- const knownCallIds = await loadKnownFunctionCallIds(args.dlg);
924
- const seenThisRound = new Set();
925
- const executableCalls = [];
926
- const preRejectedCalls = [];
927
- for (let callIndex = 0; callIndex < args.funcCalls.length; callIndex += 1) {
928
- const call = args.funcCalls[callIndex];
929
- if (!call) {
930
- throw new Error(`kernel-driver function call invariant violation: missing call ${callIndex}`);
956
+ async function normalizeGeneratedFunctionCallIds(args) {
957
+ const reservation = {
958
+ knownCallIds: new Set(await loadKnownFunctionCallIdsForCurrentCourse(args.dialog)),
959
+ seenRawIdsThisRound: new Set(),
960
+ nextDuplicateSuffixByRawId: new Map(),
961
+ };
962
+ for (const call of args.calls) {
963
+ if ((0, tellask_special_1.isTellaskCallFunctionName)(call.name)) {
964
+ reserveKnownFunctionCallId(reservation, call.id);
965
+ reserveKnownFunctionCallId(reservation, call.rawId);
931
966
  }
932
- const callId = call.id.trim();
933
- const isDuplicate = callId !== '' && (knownCallIds.has(callId) || seenThisRound.has(callId));
934
- if (!isDuplicate) {
935
- if (callId !== '') {
936
- seenThisRound.add(callId);
967
+ }
968
+ return args.calls.map((call) => {
969
+ const rawCallId = resolveRawCallId(call);
970
+ if ((0, tellask_special_1.isTellaskCallFunctionName)(call.name)) {
971
+ if (rawCallId.trim() !== '') {
972
+ reservation.seenRawIdsThisRound.add(rawCallId);
937
973
  }
938
- executableCalls.push(call);
939
- continue;
974
+ return {
975
+ ...call,
976
+ rawId: rawCallId,
977
+ effectiveId: call.id,
978
+ };
940
979
  }
941
- const genseq = Number.isFinite(call.genseq) && call.genseq > 0
942
- ? Math.floor(call.genseq)
943
- : (args.dlg.activeGenSeqOrUndefined ?? 1);
944
- const result = {
945
- type: 'func_result_msg',
946
- role: 'tool',
947
- genseq,
948
- id: call.id,
949
- name: call.name,
950
- content: formatDuplicateFunctionCallResult({
951
- callId: call.id,
952
- callName: call.name,
953
- }),
980
+ const effectiveCallId = rawCallId.trim() === ''
981
+ ? call.id
982
+ : allocateEffectiveFunctionCallId({
983
+ reservation,
984
+ rawCallId,
985
+ course: args.dialog.activeGenCourseOrUndefined ?? args.dialog.currentCourse,
986
+ genseq: call.genseq,
987
+ }).effectiveCallId;
988
+ return {
989
+ ...call,
990
+ id: effectiveCallId,
991
+ rawId: rawCallId,
992
+ effectiveId: effectiveCallId,
954
993
  };
955
- log_1.log.warn('Rejected duplicate function call id from LLM output', undefined, {
956
- rootId: args.dlg.id.rootId,
957
- selfId: args.dlg.id.selfId,
958
- course: args.dlg.currentCourse,
959
- genseq,
960
- callId: call.id,
961
- callName: call.name,
962
- });
963
- preRejectedCalls.push({ callIndex, result });
964
- }
965
- return { executableCalls, preRejectedCalls };
994
+ });
966
995
  }
967
996
  async function executeFunctionCalls(args) {
968
997
  const preparedCalls = args.funcCalls.map((func) => {
969
998
  throwIfAborted(args.abortSignal, args.dlg);
970
999
  const callGenseq = func.genseq;
971
1000
  const argsStr = typeof func.arguments === 'string' ? func.arguments : JSON.stringify(func.arguments ?? {});
1001
+ const rawCallId = resolveRawCallId(func);
1002
+ const effectiveCallId = func.id;
1003
+ const normalizedFunc = {
1004
+ ...func,
1005
+ id: effectiveCallId,
1006
+ rawId: rawCallId,
1007
+ effectiveId: effectiveCallId,
1008
+ };
972
1009
  const tool = args.agentTools.find((t) => t.type === 'func' && t.name === func.name);
973
1010
  const preparedInvocationArgs = tool !== undefined ? (0, tool_1.resolveFuncToolInvocationArguments)(tool, argsStr) : null;
974
- return { func, callGenseq, argsStr, tool, preparedInvocationArgs };
1011
+ return {
1012
+ func: normalizedFunc,
1013
+ originalFunc: func,
1014
+ callGenseq,
1015
+ argsStr,
1016
+ tool,
1017
+ preparedInvocationArgs,
1018
+ };
975
1019
  });
976
1020
  for (const prepared of preparedCalls) {
977
1021
  throwIfAborted(args.abortSignal, args.dlg);
978
- await args.dlg.persistFunctionCall(prepared.func.id, prepared.func.name, prepared.argsStr, prepared.callGenseq);
1022
+ await args.dlg.persistFunctionCall(prepared.func.id, prepared.func.name, prepared.argsStr, prepared.callGenseq, prepared.func.rawId);
979
1023
  }
980
- const functionPromises = preparedCalls.map(async ({ func, callGenseq, argsStr, tool, preparedInvocationArgs, }) => {
1024
+ const functionPromises = preparedCalls.map(async ({ func, originalFunc, callGenseq, argsStr, tool, preparedInvocationArgs, }) => {
981
1025
  throwIfAborted(args.abortSignal, args.dlg);
982
1026
  let result;
983
1027
  let outcome = 'success';
@@ -988,6 +1032,8 @@ async function executeFunctionCalls(args) {
988
1032
  result = {
989
1033
  type: 'func_result_msg',
990
1034
  id: func.id,
1035
+ rawId: func.rawId,
1036
+ effectiveId: func.effectiveId,
991
1037
  name: func.name,
992
1038
  content: output.content,
993
1039
  role: 'tool',
@@ -1006,6 +1052,8 @@ async function executeFunctionCalls(args) {
1006
1052
  result = {
1007
1053
  type: 'func_result_msg',
1008
1054
  id: func.id,
1055
+ rawId: func.rawId,
1056
+ effectiveId: func.effectiveId,
1009
1057
  name: func.name,
1010
1058
  content: (0, tool_1.toolFailure)(`Invalid arguments: ${errorText}`).content,
1011
1059
  role: 'tool',
@@ -1021,6 +1069,8 @@ async function executeFunctionCalls(args) {
1021
1069
  result = {
1022
1070
  type: 'func_result_msg',
1023
1071
  id: func.id,
1072
+ rawId: func.rawId,
1073
+ effectiveId: func.effectiveId,
1024
1074
  name: func.name,
1025
1075
  content: output.content,
1026
1076
  contentItems: Array.isArray(output.contentItems)
@@ -1037,6 +1087,8 @@ async function executeFunctionCalls(args) {
1037
1087
  result = {
1038
1088
  type: 'func_result_msg',
1039
1089
  id: func.id,
1090
+ rawId: func.rawId,
1091
+ effectiveId: func.effectiveId,
1040
1092
  name: func.name,
1041
1093
  content: failureOutput.content,
1042
1094
  role: 'tool',
@@ -1047,6 +1099,8 @@ async function executeFunctionCalls(args) {
1047
1099
  result = {
1048
1100
  type: 'func_result_msg',
1049
1101
  id: func.id,
1102
+ rawId: func.rawId,
1103
+ effectiveId: func.effectiveId,
1050
1104
  name: func.name,
1051
1105
  content: interruptedOutput.content,
1052
1106
  role: 'tool',
@@ -1061,7 +1115,7 @@ async function executeFunctionCalls(args) {
1061
1115
  if (rethrowError !== undefined) {
1062
1116
  throw rethrowError;
1063
1117
  }
1064
- return { outcome, result };
1118
+ return { func, originalFunc, outcome, result };
1065
1119
  });
1066
1120
  return await Promise.all(functionPromises);
1067
1121
  }
@@ -1075,11 +1129,7 @@ async function executeFunctionRound(args) {
1075
1129
  };
1076
1130
  }
1077
1131
  throwIfAborted(args.abortSignal, args.dlg);
1078
- const { executableCalls, preRejectedCalls } = await splitPreRejectedFunctionCalls({
1079
- dlg: args.dlg,
1080
- funcCalls: args.funcCalls,
1081
- });
1082
- const preRejectedResultByCall = new Map(preRejectedCalls.map((entry) => [entry.callIndex, entry.result]));
1132
+ const executableCalls = [...args.funcCalls];
1083
1133
  const allowTellaskBack = args.allowTellaskFunctions && args.dlg.id.rootId !== args.dlg.id.selfId;
1084
1134
  const allowedSpecials = args.allowTellaskFunctions
1085
1135
  ? new Set([
@@ -1109,6 +1159,7 @@ async function executeFunctionRound(args) {
1109
1159
  funcCalls: tellaskRound.normalCalls,
1110
1160
  abortSignal: args.abortSignal,
1111
1161
  });
1162
+ const genericExecutionByOriginalCall = new Map(genericExecutions.map((execution) => [execution.originalFunc, execution]));
1112
1163
  const funcToolByName = new Map(args.agentTools
1113
1164
  .filter((tool) => tool.type === 'func')
1114
1165
  .map((tool) => [tool.name, tool]));
@@ -1139,12 +1190,13 @@ async function executeFunctionRound(args) {
1139
1190
  const tellaskCallMsgById = new Map(tellaskRound.tellaskCallMessages.map((msg) => [msg.id, msg]));
1140
1191
  const specialCallIds = new Set(tellaskRound.handledCallIds);
1141
1192
  for (let callIndex = 0; callIndex < args.funcCalls.length; callIndex += 1) {
1142
- const call = args.funcCalls[callIndex];
1143
- if (!call) {
1193
+ const originalCall = args.funcCalls[callIndex];
1194
+ if (!originalCall) {
1144
1195
  throw new Error(`kernel-driver function call invariant violation: missing call ${callIndex}`);
1145
1196
  }
1146
- const preRejectedResult = preRejectedResultByCall.get(callIndex);
1147
- const tellaskCallMsg = preRejectedResult ? undefined : tellaskCallMsgById.get(call.id);
1197
+ const execution = genericExecutionByOriginalCall.get(originalCall);
1198
+ const call = execution?.func ?? originalCall;
1199
+ const tellaskCallMsg = tellaskCallMsgById.get(call.id);
1148
1200
  if (tellaskCallMsg) {
1149
1201
  pairedMessages.push(tellaskCallMsg);
1150
1202
  }
@@ -1155,14 +1207,12 @@ async function executeFunctionRound(args) {
1155
1207
  role: 'assistant',
1156
1208
  genseq: call.genseq,
1157
1209
  id: call.id,
1210
+ ...(call.rawId !== undefined ? { rawId: call.rawId } : {}),
1211
+ ...(call.effectiveId !== undefined ? { effectiveId: call.effectiveId } : {}),
1158
1212
  name: call.name,
1159
1213
  arguments: originalArgsStr,
1160
1214
  });
1161
1215
  }
1162
- if (preRejectedResult) {
1163
- pairedMessages.push(preRejectedResult);
1164
- continue;
1165
- }
1166
1216
  const result = resultByCallId.get(call.id);
1167
1217
  if (result) {
1168
1218
  pairedMessages.push(result);
@@ -1174,35 +1224,27 @@ async function executeFunctionRound(args) {
1174
1224
  throw new Error(`kernel-driver function result invariant violation: missing result for call id '${call.id}' (${call.name})`);
1175
1225
  }
1176
1226
  return {
1177
- hasImmediateFollowupToolCalls: hasImmediateFollowupToolCalls ||
1178
- tellaskRound.hasInvalidTellaskCalls ||
1179
- preRejectedCalls.length > 0,
1227
+ hasImmediateFollowupToolCalls: hasImmediateFollowupToolCalls || tellaskRound.hasInvalidTellaskCalls,
1180
1228
  shouldStopAfterReplyTool: tellaskRound.shouldStopAfterReplyTool,
1181
1229
  pairedMessages,
1182
1230
  tellaskToolOutputs: [...tellaskRound.toolOutputs],
1183
1231
  };
1184
1232
  }
1185
- async function resetDiligenceBudgetAfterQ4H(dlg, team) {
1233
+ async function preserveDiligenceBudgetAcrossQ4H(dlg) {
1186
1234
  try {
1187
1235
  if (!(await dlg.hasPendingQ4H())) {
1188
1236
  return;
1189
1237
  }
1190
- const configuredMax = resolveMemberDiligencePushMax(team, dlg.agentId);
1191
- if (typeof configuredMax === 'number' && Number.isFinite(configuredMax)) {
1192
- const next = Math.floor(configuredMax);
1193
- dlg.diligencePushRemainingBudget =
1194
- next > 0 ? next : Math.max(0, Math.floor(dlg.diligencePushRemainingBudget));
1195
- }
1196
- else {
1197
- dlg.diligencePushRemainingBudget = Math.max(0, Math.floor(dlg.diligencePushRemainingBudget));
1198
- }
1238
+ // Q4H is a suspension boundary, not a reason to reapply member defaults. Keep the dialog's
1239
+ // own remaining budget as the source of truth so operator-adjusted budgets survive Q4H.
1240
+ dlg.diligencePushRemainingBudget = Math.max(0, Math.floor(dlg.diligencePushRemainingBudget));
1199
1241
  void persistence_1.DialogPersistence.mutateDialogLatest(dlg.id, () => ({
1200
1242
  kind: 'patch',
1201
1243
  patch: { diligencePushRemainingBudget: dlg.diligencePushRemainingBudget },
1202
1244
  }));
1203
1245
  }
1204
1246
  catch (err) {
1205
- log_1.log.error('kernel-driver failed to reset Diligence Push budget after Q4H', err, {
1247
+ log_1.log.error('kernel-driver failed to preserve Diligence Push budget after Q4H', err, {
1206
1248
  dialogId: dlg.id.valueOf(),
1207
1249
  });
1208
1250
  throw err;
@@ -1218,7 +1260,7 @@ async function maybeContinueWithDiligencePrompt(args) {
1218
1260
  });
1219
1261
  if (!suspension.canDrive) {
1220
1262
  if (suspension.q4h) {
1221
- await resetDiligenceBudgetAfterQ4H(dlg, team);
1263
+ await preserveDiligenceBudgetAcrossQ4H(dlg);
1222
1264
  }
1223
1265
  return { kind: 'break' };
1224
1266
  }
@@ -1991,13 +2033,17 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
1991
2033
  streamAttemptSayingContent = currentSayingContent;
1992
2034
  streamAttemptSayingGenseq = sayingMessage.genseq;
1993
2035
  },
1994
- funcCall: async (callId, name, argsStr) => {
2036
+ funcCall: async (callId, name, argsStr, ids) => {
1995
2037
  throwIfAborted(abortSignal, dlg);
2038
+ const rawCallId = trimOptionalCallId(ids?.rawCallId) ?? callId;
2039
+ const effectiveCallId = trimOptionalCallId(ids?.effectiveCallId) ?? callId;
1996
2040
  streamedFuncCalls.push({
1997
2041
  type: 'func_call_msg',
1998
2042
  role: 'assistant',
1999
2043
  genseq: dlg.activeGenSeq,
2000
- id: callId,
2044
+ id: effectiveCallId,
2045
+ rawId: rawCallId,
2046
+ effectiveId: effectiveCallId,
2001
2047
  name,
2002
2048
  arguments: argsStr,
2003
2049
  });
@@ -2051,7 +2097,6 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
2051
2097
  sawNativeToolSideChannelOutput = false;
2052
2098
  streamedFuncCalls.length = 0;
2053
2099
  newMsgs.length = 0;
2054
- const knownFunctionCallIds = await loadKnownFunctionCallIdsForProviderQuirks(dlg, providerCfg);
2055
2100
  const promptCacheKey = prepareLlmRequestContextKey();
2056
2101
  const streamResult = await llmGen.genToReceiver(providerCfg, agent, systemPrompt, funcTools, {
2057
2102
  dialogSelfId: dlg.id.selfId,
@@ -2060,7 +2105,6 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
2060
2105
  modelKey: model,
2061
2106
  promptCacheKey,
2062
2107
  toolUseRequirement: resolveToolUseRequirement(dlg, policy),
2063
- knownFunctionCallIds,
2064
2108
  }, ctxMsgs, receiver, dlg.activeGenSeq, abortSignal);
2065
2109
  const hasFinishedMessageContent = newMsgs.some((msg) => (msg.type === 'thinking_msg' || msg.type === 'saying_msg') &&
2066
2110
  msg.content.trim() !== '');
@@ -2209,6 +2253,12 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
2209
2253
  dlg.setFbrConclusionToolsEnabled(false);
2210
2254
  break;
2211
2255
  }
2256
+ const normalizedStreamedFuncCalls = await normalizeGeneratedFunctionCallIds({
2257
+ calls: streamedFuncCalls,
2258
+ dialog: dlg,
2259
+ });
2260
+ streamedFuncCalls.length = 0;
2261
+ streamedFuncCalls.push(...normalizedStreamedFuncCalls);
2212
2262
  for (const call of streamedFuncCalls) {
2213
2263
  const rawCallGenseq = call.genseq;
2214
2264
  if (!Number.isFinite(rawCallGenseq) || rawCallGenseq <= 0)
@@ -2317,7 +2367,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
2317
2367
  allowPendingSideDialogs: routed.hasImmediateFollowupToolCalls,
2318
2368
  });
2319
2369
  if (!suspensionAfterToolRound.canDrive) {
2320
- await resetDiligenceBudgetAfterQ4H(dlg, team);
2370
+ await preserveDiligenceBudgetAcrossQ4H(dlg);
2321
2371
  break;
2322
2372
  }
2323
2373
  // Start an immediate post-tool generation only when this round produced tool outputs that
@@ -133,7 +133,10 @@ async function maybePrepareDiligenceAutoContinuePrompt(options) {
133
133
  }
134
134
  const resolved = await resolveRtwsDiligenceConfig();
135
135
  if (resolved.kind === 'disabled') {
136
- return { kind: 'disabled', nextRemainingBudget: options.remainingBudget };
136
+ const normalizedRemaining = typeof options.remainingBudget === 'number' && Number.isFinite(options.remainingBudget)
137
+ ? Math.max(0, Math.floor(options.remainingBudget))
138
+ : 0;
139
+ return { kind: 'disabled', nextRemainingBudget: normalizedRemaining };
137
140
  }
138
141
  const maxInjectCount = typeof options.diligencePushMax === 'number' && Number.isFinite(options.diligencePushMax)
139
142
  ? Math.floor(options.diligencePushMax)
@@ -142,10 +145,16 @@ async function maybePrepareDiligenceAutoContinuePrompt(options) {
142
145
  ? Math.max(0, Math.floor(options.remainingBudget))
143
146
  : 0;
144
147
  const bypassBudget = options.ignoreBudgetExhaustion === true;
145
- if (maxInjectCount < 1) {
146
- if (!bypassBudget) {
147
- return { kind: 'disabled', nextRemainingBudget: 0 };
148
+ // `diligencePushMax` is only the per-member default used when a dialog instance is created or
149
+ // reset. Runtime business decisions must be based on this dialog's persisted remaining budget so
150
+ // operator-added budget (for example 51/0) keeps working even when the team default is zero.
151
+ if (normalizedRemaining < 1 && !bypassBudget) {
152
+ if (maxInjectCount > 0) {
153
+ return { kind: 'budget_exhausted', maxInjectCount, nextRemainingBudget: 0 };
148
154
  }
155
+ return { kind: 'disabled', nextRemainingBudget: 0 };
156
+ }
157
+ if (normalizedRemaining < 1) {
149
158
  const prompt = {
150
159
  content: (0, driver_messages_1.formatDiligenceAutoContinuePrompt)((0, work_language_1.getWorkLanguage)(), resolved.diligenceText),
151
160
  msgId: (0, id_1.generateShortId)(),
@@ -159,7 +168,7 @@ async function maybePrepareDiligenceAutoContinuePrompt(options) {
159
168
  nextRemainingBudget: 0,
160
169
  };
161
170
  }
162
- const currentRemaining = Math.min(normalizedRemaining, maxInjectCount);
171
+ const currentRemaining = normalizedRemaining;
163
172
  if (currentRemaining < 1 && !bypassBudget) {
164
173
  return { kind: 'budget_exhausted', maxInjectCount, nextRemainingBudget: 0 };
165
174
  }
@@ -266,6 +275,13 @@ function readErrorCode(error) {
266
275
  }
267
276
  return undefined;
268
277
  }
278
+ function readErrorStringField(error, field) {
279
+ if (!isPlainObject(error)) {
280
+ return undefined;
281
+ }
282
+ const value = error[field];
283
+ return typeof value === 'string' && value.trim().length > 0 ? value : undefined;
284
+ }
269
285
  function isRetriableLlmErrorCode(code) {
270
286
  if (!code)
271
287
  return false;
@@ -717,24 +733,30 @@ async function runLlmRequestWithRetry(params) {
717
733
  const cause = readErrorCause(err);
718
734
  const causeCode = readErrorCode(cause);
719
735
  const causeMessage = cause === undefined || cause === null ? undefined : (0, log_1.extractErrorDetails)(cause).message;
736
+ const debugCaptureError = readErrorStringField(err, 'debugCaptureError');
737
+ const debugPath = readErrorStringField(err, 'debugPath');
738
+ const requestPayloadPath = readErrorStringField(err, 'requestPayloadPath');
720
739
  const attemptNo = attempt + 1;
721
740
  const retryStrategy = failure.kind === 'retriable' ? (failure.retryStrategy ?? 'conservative') : undefined;
722
741
  const retryMode = resolveRetryModeFromHandling(handledFailure.handling);
723
742
  log_1.log.warn('LLM request attempt failed', err, {
724
743
  provider: params.provider,
725
- dialogId: params.dlg.id.valueOf(),
726
- rootId: params.dlg.id.rootId,
727
- selfId: params.dlg.id.selfId,
744
+ failureKind: failure.kind,
745
+ status: failure.status,
746
+ code: failure.code,
747
+ debugPath,
748
+ requestPayloadPath,
749
+ debugCaptureError,
728
750
  retryStrategy,
729
751
  retryMode,
730
752
  attemptNumber: attemptNo,
753
+ dialogId: params.dlg.id.valueOf(),
754
+ rootId: params.dlg.id.rootId,
755
+ selfId: params.dlg.id.selfId,
731
756
  aggressiveRetryCount,
732
757
  aggressiveRetryMaxRetries: params.aggressiveRetryMaxRetries,
733
- failureKind: failure.kind,
734
758
  quirkHandling: handledFailure.handling.kind,
735
759
  quirkSource: handledFailure.handling.sourceQuirk,
736
- status: failure.status,
737
- code: failure.code,
738
760
  errorCode,
739
761
  causeCode,
740
762
  causeMessage,
@@ -751,6 +773,9 @@ async function runLlmRequestWithRetry(params) {
751
773
  detail: {
752
774
  dialogId: params.dlg.id.valueOf(),
753
775
  provider: params.provider,
776
+ debugPath,
777
+ requestPayloadPath,
778
+ debugCaptureError,
754
779
  errorText: detail,
755
780
  },
756
781
  });
@@ -2276,8 +2276,8 @@ async function processTellaskFunctionRound(args) {
2276
2276
  const resolvedTellask = resolveTellaskFunctionCalls(funcCallsForResolution, {
2277
2277
  allowedSpecials: args.allowedSpecials,
2278
2278
  });
2279
- const validByCallId = new Map(resolvedTellask.validCalls.map((handled) => [handled.originalCall.id, handled]));
2280
- const invalidByCallId = new Map(resolvedTellask.invalidCalls.map((issue) => [issue.originalCall.id, issue]));
2279
+ const validByOriginalCall = new Map(resolvedTellask.validCalls.map((handled) => [handled.originalCall, handled]));
2280
+ const invalidByOriginalCall = new Map(resolvedTellask.invalidCalls.map((issue) => [issue.originalCall, issue]));
2281
2281
  const orderedSpecialDispositions = [];
2282
2282
  for (const originalCall of args.funcCalls) {
2283
2283
  if (!isTellaskCallFunctionName(originalCall.name) ||
@@ -2308,12 +2308,12 @@ async function processTellaskFunctionRound(args) {
2308
2308
  });
2309
2309
  continue;
2310
2310
  }
2311
- const handled = validByCallId.get(originalCall.id);
2311
+ const handled = validByOriginalCall.get(originalCall);
2312
2312
  if (handled) {
2313
2313
  orderedSpecialDispositions.push({ kind: 'valid', handled });
2314
2314
  continue;
2315
2315
  }
2316
- const issue = invalidByCallId.get(originalCall.id);
2316
+ const issue = invalidByOriginalCall.get(originalCall);
2317
2317
  if (issue) {
2318
2318
  orderedSpecialDispositions.push({ kind: 'invalid', callName: originalCall.name, issue });
2319
2319
  continue;
@@ -2323,7 +2323,7 @@ async function processTellaskFunctionRound(args) {
2323
2323
  const orderedValidCalls = orderedSpecialDispositions.flatMap((entry) => entry.kind === 'valid' ? [entry.handled] : []);
2324
2324
  const orderedInvalidCalls = orderedSpecialDispositions.flatMap((entry) => entry.kind === 'invalid' ? [entry.issue] : []);
2325
2325
  const specialCallById = new Map(orderedValidCalls.map(({ call }) => [call.callId, call]));
2326
- const originalCallById = new Map(args.funcCalls.map((call) => [call.id, call]));
2326
+ const originalCallBySpecialCall = new Map(orderedValidCalls.map(({ call, originalCall }) => [call, originalCall]));
2327
2327
  const tellaskCallMessages = [];
2328
2328
  const issueResults = [];
2329
2329
  for (const disposition of orderedSpecialDispositions) {
@@ -2398,7 +2398,7 @@ async function processTellaskFunctionRound(args) {
2398
2398
  if (issueResults.some((result) => result.id === call.callId)) {
2399
2399
  continue;
2400
2400
  }
2401
- const originalCall = originalCallById.get(call.callId);
2401
+ const originalCall = originalCallBySpecialCall.get(call);
2402
2402
  if (!originalCall) {
2403
2403
  throw new Error(`kernel-driver tellask special call invariant violation: missing original call for '${call.callId}'`);
2404
2404
  }
@@ -2431,11 +2431,14 @@ async function processTellaskFunctionRound(args) {
2431
2431
  }
2432
2432
  const originatingCall = specialCallById.get(callId);
2433
2433
  if (originatingCall) {
2434
- const originalCall = originalCallById.get(callId);
2434
+ const originalCall = originalCallBySpecialCall.get(originatingCall);
2435
+ if (!originalCall) {
2436
+ throw new Error(`kernel-driver tellask result invariant violation: missing original call for '${callId}'`);
2437
+ }
2435
2438
  const result = {
2436
2439
  type: 'func_result_msg',
2437
2440
  role: 'tool',
2438
- genseq: originalCall?.genseq ?? 1,
2441
+ genseq: originalCall.genseq,
2439
2442
  id: callId,
2440
2443
  name: originatingCall.callName,
2441
2444
  content: output.content,
@@ -2451,7 +2454,7 @@ async function processTellaskFunctionRound(args) {
2451
2454
  if (tellaskFuncResultByCallId.has(call.callId)) {
2452
2455
  continue;
2453
2456
  }
2454
- const originalCall = originalCallById.get(call.callId);
2457
+ const originalCall = originalCallBySpecialCall.get(call);
2455
2458
  if (!originalCall) {
2456
2459
  throw new Error(`kernel-driver tellask call invariant violation: missing original call for '${call.callId}'`);
2457
2460
  }