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
@@ -16,7 +16,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
16
16
  };
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.OpenAiCompatibleGen = void 0;
19
+ exports.resolveOpenAiCompatibleToolChoice = resolveOpenAiCompatibleToolChoice;
19
20
  exports.buildOpenAiCompatibleExtraParamsForTest = buildOpenAiCompatibleExtraParamsForTest;
21
+ exports.wrapOpenAiCompatibleRejectedRequestErrorForTest = wrapOpenAiCompatibleRejectedRequestErrorForTest;
20
22
  exports.buildOpenAiCompatibleRequestMessagesWrapper = buildOpenAiCompatibleRequestMessagesWrapper;
21
23
  exports.consumeOpenAiCompatibleChatCompletionStreamForTest = consumeOpenAiCompatibleChatCompletionStreamForTest;
22
24
  exports.chatCompletionToChatMessagesForTest = chatCompletionToChatMessagesForTest;
@@ -28,6 +30,8 @@ const path_1 = __importDefault(require("path"));
28
30
  const log_1 = require("../../log");
29
31
  const i18n_text_1 = require("../../runtime/i18n-text");
30
32
  const work_language_1 = require("../../runtime/work-language");
33
+ const dominds_running_version_1 = require("../../server/dominds-running-version");
34
+ const api_quirks_1 = require("../api-quirks");
31
35
  const gen_1 = require("../gen");
32
36
  const stop_reason_i18n_1 = require("../stop-reason-i18n");
33
37
  const artifacts_1 = require("./artifacts");
@@ -38,15 +42,60 @@ const tool_result_image_ingest_1 = require("./tool-result-image-ingest");
38
42
  const log = (0, log_1.createLogger)('llm/openai-compatible');
39
43
  const OPENAI_COMPAT_CAPTURE_SSE_ENV = 'DOMINDS_OPENAI_COMPAT_CAPTURE_SSE';
40
44
  const OPENAI_COMPAT_CAPTURE_DIR_ENV = 'DOMINDS_OPENAI_COMPAT_CAPTURE_DIR';
45
+ const OPENAI_COMPAT_REJECTED_DIR_ENV = 'DOMINDS_OPENAI_COMPAT_REJECTED_DIR';
41
46
  const OPENAI_COMPATIBLE_MALFORMED_BATCH_TOOL_CALL_ERROR_CODE = 'OPENAI_COMPATIBLE_MALFORMED_BATCH_TOOL_CALL';
42
- function resolveOpenAiCompatibleToolChoice(funcTools, requestContext) {
47
+ const OPENAI_COMPATIBLE_REJECTED_REQUEST_ERROR_CODE = 'OPENAI_COMPATIBLE_REJECTED_REQUEST';
48
+ const KIMI_CODE_API_QUIRK = 'kimi-code';
49
+ const KIMI_CODE_REASONING_EFFORTS = new Set(['low', 'medium', 'high']);
50
+ const KIMI_CLI_CLOAK_API_QUIRK = 'kimi-cli-cloak';
51
+ const KIMI_CLI_USER_AGENT = 'KimiCLI/1.41.0';
52
+ const DISABLE_ASSISTANT_TOOL_CALL_REASONING_CONTENT_API_QUIRK = 'disable-assistant-tool-call-reasoning-content';
53
+ const JSON_SCHEMA_COMBINATOR_KEYS = new Set([
54
+ 'anyOf',
55
+ 'oneOf',
56
+ 'allOf',
57
+ 'not',
58
+ 'if',
59
+ 'then',
60
+ 'else',
61
+ '$ref',
62
+ ]);
63
+ const JSON_SCHEMA_BRANCH_ARRAY_KEYS = ['anyOf', 'oneOf', 'allOf'];
64
+ const JSON_SCHEMA_OBJECT_KEYS = new Set([
65
+ 'properties',
66
+ 'additionalProperties',
67
+ 'patternProperties',
68
+ 'propertyNames',
69
+ 'required',
70
+ 'minProperties',
71
+ 'maxProperties',
72
+ ]);
73
+ const JSON_SCHEMA_ARRAY_KEYS = new Set([
74
+ 'items',
75
+ 'prefixItems',
76
+ 'minItems',
77
+ 'maxItems',
78
+ 'uniqueItems',
79
+ 'contains',
80
+ ]);
81
+ const JSON_SCHEMA_STRING_KEYS = new Set(['minLength', 'maxLength', 'pattern', 'format']);
82
+ const JSON_SCHEMA_NUMERIC_KEYS = new Set([
83
+ 'minimum',
84
+ 'maximum',
85
+ 'multipleOf',
86
+ 'exclusiveMinimum',
87
+ 'exclusiveMaximum',
88
+ ]);
89
+ function resolveOpenAiCompatibleToolChoice(funcTools, requestContext, modelInfo) {
43
90
  const requirement = requestContext.toolUseRequirement ?? 'auto';
44
91
  if (funcTools.length === 0) {
45
92
  if (requirement === 'required') {
46
93
  throw new Error(`OpenAI-compatible request invariant violation: toolUseRequirement=required but no tools are available (dialog=${requestContext.dialogSelfId})`);
47
94
  }
48
- return 'none';
95
+ return modelInfo?.supports_tool_choice === false ? undefined : 'none';
49
96
  }
97
+ if (modelInfo?.supports_tool_choice === false)
98
+ return undefined;
50
99
  if (requirement === 'none')
51
100
  return 'none';
52
101
  if (requirement === 'required')
@@ -56,6 +105,23 @@ function resolveOpenAiCompatibleToolChoice(funcTools, requestContext) {
56
105
  function resolveOpenAiCompatibleRequestTools(funcTools, requestContext) {
57
106
  return (requestContext.toolUseRequirement ?? 'auto') === 'none' ? [] : [...funcTools];
58
107
  }
108
+ function resolveOpenAiCompatibleRequestModelInfo(providerConfig, agent, requestContext) {
109
+ const requestModelKey = requestContext.modelKey;
110
+ const modelKey = typeof requestModelKey === 'string' && requestModelKey.trim() !== ''
111
+ ? requestModelKey
112
+ : agent.model;
113
+ if (typeof modelKey !== 'string' || modelKey.trim() === '')
114
+ return undefined;
115
+ return providerConfig.models[modelKey];
116
+ }
117
+ function resolveOpenAiCompatibleParallelToolCalls(args) {
118
+ if (args.openAiParams.parallel_tool_calls !== undefined) {
119
+ return args.openAiParams.parallel_tool_calls;
120
+ }
121
+ if (isKimiCodeProvider(args.providerConfig))
122
+ return undefined;
123
+ return true;
124
+ }
59
125
  function isOpenAiCompatibleSseCaptureEnabled() {
60
126
  const configured = process.env[OPENAI_COMPAT_CAPTURE_SSE_ENV]?.trim().toLowerCase();
61
127
  return configured === '1' || configured === 'true' || configured === 'yes' || configured === 'on';
@@ -66,12 +132,25 @@ function resolveOpenAiCompatibleCaptureDir() {
66
132
  return path_1.default.resolve(configured);
67
133
  return path_1.default.resolve(process.cwd(), '.dialogs', 'debug', 'openai-compatible-sse');
68
134
  }
135
+ function resolveOpenAiCompatibleRejectedDir() {
136
+ const configured = process.env[OPENAI_COMPAT_REJECTED_DIR_ENV]?.trim();
137
+ if (configured && configured.length > 0)
138
+ return path_1.default.resolve(configured);
139
+ return path_1.default.resolve(process.cwd(), '.dialogs', 'debug', 'openai-compatible-rejected');
140
+ }
69
141
  function sanitizeCapturePathPart(value) {
70
142
  const sanitized = value.replace(/[^a-zA-Z0-9_.-]+/g, '_').replace(/^_+|_+$/g, '');
71
143
  if (sanitized.length === 0)
72
144
  return 'unknown';
73
145
  return sanitized.slice(0, 96);
74
146
  }
147
+ function formatRejectedCaptureFailureDetail(error) {
148
+ const raw = error instanceof Error ? error.message : String(error);
149
+ const compact = raw.replace(/\s+/g, ' ').trim();
150
+ if (compact.length === 0)
151
+ return 'unknown debug capture failure';
152
+ return compact.slice(0, 500);
153
+ }
75
154
  function buildOpenAiCompatibleCaptureId(context) {
76
155
  const now = new Date().toISOString().replace(/[:.]/g, '-');
77
156
  const suffix = Math.random().toString(36).slice(2, 10);
@@ -84,6 +163,19 @@ function buildOpenAiCompatibleCaptureId(context) {
84
163
  suffix,
85
164
  ].join('__');
86
165
  }
166
+ function buildOpenAiCompatibleRejectedCaptureId(context) {
167
+ const now = new Date().toISOString().replace(/[:.]/g, '-');
168
+ const suffix = Math.random().toString(36).slice(2, 10);
169
+ return [
170
+ now,
171
+ sanitizeCapturePathPart(context.providerKey ?? context.providerName),
172
+ sanitizeCapturePathPart(context.model),
173
+ sanitizeCapturePathPart(context.dialogSelfId),
174
+ `g${String(context.genseq)}`,
175
+ context.requestKind,
176
+ suffix,
177
+ ].join('__');
178
+ }
87
179
  function redactHttpHeader(name, value) {
88
180
  const normalized = name.toLowerCase();
89
181
  if (normalized === 'authorization' ||
@@ -206,6 +298,52 @@ async function startOpenAiCompatibleCapture(context, input, init) {
206
298
  });
207
299
  return record;
208
300
  }
301
+ async function writeOpenAiCompatibleRejectedCapture(args) {
302
+ const captureRoot = resolveOpenAiCompatibleRejectedDir();
303
+ const id = buildOpenAiCompatibleRejectedCaptureId(args.context);
304
+ const dir = path_1.default.join(captureRoot, id);
305
+ await promises_1.default.mkdir(dir, { recursive: true });
306
+ const record = {
307
+ id,
308
+ dir,
309
+ metaPath: path_1.default.join(dir, 'meta.json'),
310
+ requestPayloadPath: path_1.default.join(dir, 'request-payload.json'),
311
+ };
312
+ await writeCaptureJson(record.requestPayloadPath, args.payload);
313
+ await writeCaptureJson(record.metaPath, {
314
+ id,
315
+ capturedAt: new Date().toISOString(),
316
+ context: args.context,
317
+ request: {
318
+ payloadPath: record.requestPayloadPath,
319
+ },
320
+ error: {
321
+ name: args.error instanceof Error ? args.error.name : undefined,
322
+ message: args.context.upstreamMessage,
323
+ status: args.context.status,
324
+ code: args.context.code,
325
+ },
326
+ });
327
+ return record;
328
+ }
329
+ async function tryWriteOpenAiCompatibleRejectedCapture(args) {
330
+ try {
331
+ return { kind: 'captured', record: await writeOpenAiCompatibleRejectedCapture(args) };
332
+ }
333
+ catch (error) {
334
+ const detail = formatRejectedCaptureFailureDetail(error);
335
+ log.error('OPENAI-COMPATIBLE rejected request debug capture failed', error, {
336
+ providerKey: args.context.providerKey,
337
+ providerName: args.context.providerName,
338
+ model: args.context.model,
339
+ rootId: args.context.dialogRootId,
340
+ selfId: args.context.dialogSelfId,
341
+ genseq: args.context.genseq,
342
+ requestKind: args.context.requestKind,
343
+ });
344
+ return { kind: 'capture_failed', detail };
345
+ }
346
+ }
209
347
  function parseSseFrameData(frame) {
210
348
  const lines = frame.split(/\r?\n/);
211
349
  const eventLine = lines.find((line) => line.startsWith('event:'));
@@ -438,6 +576,16 @@ function createOpenAiCompatibleClient(args) {
438
576
  apiKey: args.apiKey,
439
577
  baseURL: args.providerConfig.baseUrl,
440
578
  };
579
+ if (isKimiCliCloakProvider(args.providerConfig)) {
580
+ options.defaultHeaders = {
581
+ 'User-Agent': KIMI_CLI_USER_AGENT,
582
+ };
583
+ }
584
+ else if (isKimiCodeProvider(args.providerConfig)) {
585
+ options.defaultHeaders = {
586
+ 'User-Agent': `Dominds/${dominds_running_version_1.DOMINDS_RUNNING_VERSION || 'dev'}`,
587
+ };
588
+ }
441
589
  if (args.providerConfig.apiType === 'openai-compatible' &&
442
590
  isOpenAiCompatibleSseCaptureEnabled()) {
443
591
  options.fetch = buildOpenAiCompatibleCaptureFetch({
@@ -466,6 +614,129 @@ function limitOpenAiCompatibleToolOutputText(text, msg, limitChars) {
466
614
  function isRecord(value) {
467
615
  return typeof value === 'object' && value !== null && !Array.isArray(value);
468
616
  }
617
+ function isKimiCodeProvider(providerConfig) {
618
+ return (0, api_quirks_1.normalizeProviderApiQuirks)(providerConfig).has(KIMI_CODE_API_QUIRK);
619
+ }
620
+ function isKimiCliCloakProvider(providerConfig) {
621
+ return (0, api_quirks_1.normalizeProviderApiQuirks)(providerConfig).has(KIMI_CLI_CLOAK_API_QUIRK);
622
+ }
623
+ function isKimiCodeReasoningEffort(value) {
624
+ return typeof value === 'string' && KIMI_CODE_REASONING_EFFORTS.has(value);
625
+ }
626
+ function isKimiCodeThinkingMode(value) {
627
+ return (value === 'auto' || value === 'off' || value === 'low' || value === 'medium' || value === 'high');
628
+ }
629
+ function cloneJsonSchemaValue(value) {
630
+ if (Array.isArray(value))
631
+ return value.map((item) => cloneJsonSchemaValue(item));
632
+ if (isRecord(value)) {
633
+ const out = {};
634
+ for (const [key, child] of Object.entries(value)) {
635
+ out[key] = cloneJsonSchemaValue(child);
636
+ }
637
+ return out;
638
+ }
639
+ return value;
640
+ }
641
+ function hasAnyOwnKey(value, keys) {
642
+ for (const key of keys) {
643
+ if (Object.prototype.hasOwnProperty.call(value, key))
644
+ return true;
645
+ }
646
+ return false;
647
+ }
648
+ function inferJsonSchemaTypeFromValues(values) {
649
+ const inferred = new Set();
650
+ for (const value of values) {
651
+ if (typeof value === 'boolean')
652
+ inferred.add('boolean');
653
+ else if (typeof value === 'number')
654
+ inferred.add(Number.isInteger(value) ? 'integer' : 'number');
655
+ else if (typeof value === 'string')
656
+ inferred.add('string');
657
+ else if (value === null)
658
+ inferred.add('null');
659
+ else if (Array.isArray(value))
660
+ inferred.add('array');
661
+ else if (isRecord(value))
662
+ inferred.add('object');
663
+ else
664
+ return 'string';
665
+ }
666
+ if (inferred.size === 1) {
667
+ const only = [...inferred][0];
668
+ return only ?? 'string';
669
+ }
670
+ if (inferred.size === 2 && inferred.has('integer') && inferred.has('number')) {
671
+ return 'number';
672
+ }
673
+ return 'string';
674
+ }
675
+ function inferJsonSchemaTypeFromStructure(value) {
676
+ if (hasAnyOwnKey(value, JSON_SCHEMA_OBJECT_KEYS))
677
+ return 'object';
678
+ if (hasAnyOwnKey(value, JSON_SCHEMA_ARRAY_KEYS))
679
+ return 'array';
680
+ if (hasAnyOwnKey(value, JSON_SCHEMA_STRING_KEYS))
681
+ return 'string';
682
+ if (hasAnyOwnKey(value, JSON_SCHEMA_NUMERIC_KEYS))
683
+ return 'number';
684
+ return 'string';
685
+ }
686
+ function normalizeOpenAiCompatibleKimiCodeJsonSchemaProperty(value) {
687
+ if (!isRecord(value))
688
+ return;
689
+ if (!Object.prototype.hasOwnProperty.call(value, 'type') &&
690
+ !hasAnyOwnKey(value, JSON_SCHEMA_COMBINATOR_KEYS)) {
691
+ const enumValues = value.enum;
692
+ if (Array.isArray(enumValues) && enumValues.length > 0) {
693
+ value.type = inferJsonSchemaTypeFromValues(enumValues);
694
+ }
695
+ else if (Object.prototype.hasOwnProperty.call(value, 'const')) {
696
+ value.type = inferJsonSchemaTypeFromValues([value.const]);
697
+ }
698
+ else {
699
+ value.type = inferJsonSchemaTypeFromStructure(value);
700
+ }
701
+ }
702
+ normalizeOpenAiCompatibleKimiCodeJsonSchemaContainer(value);
703
+ }
704
+ function normalizeOpenAiCompatibleKimiCodeJsonSchemaContainer(value) {
705
+ if (!isRecord(value))
706
+ return;
707
+ const properties = value.properties;
708
+ if (isRecord(properties)) {
709
+ for (const property of Object.values(properties)) {
710
+ normalizeOpenAiCompatibleKimiCodeJsonSchemaProperty(property);
711
+ }
712
+ }
713
+ const items = value.items;
714
+ if (isRecord(items)) {
715
+ normalizeOpenAiCompatibleKimiCodeJsonSchemaProperty(items);
716
+ }
717
+ else if (Array.isArray(items)) {
718
+ for (const item of items) {
719
+ normalizeOpenAiCompatibleKimiCodeJsonSchemaProperty(item);
720
+ }
721
+ }
722
+ const additionalProperties = value.additionalProperties;
723
+ if (isRecord(additionalProperties)) {
724
+ normalizeOpenAiCompatibleKimiCodeJsonSchemaProperty(additionalProperties);
725
+ }
726
+ for (const key of JSON_SCHEMA_BRANCH_ARRAY_KEYS) {
727
+ const branches = value[key];
728
+ if (!Array.isArray(branches))
729
+ continue;
730
+ for (const branch of branches) {
731
+ normalizeOpenAiCompatibleKimiCodeJsonSchemaProperty(branch);
732
+ }
733
+ }
734
+ }
735
+ function normalizeOpenAiCompatibleKimiCodeJsonSchema(value) {
736
+ const cloned = cloneJsonSchemaValue(value);
737
+ normalizeOpenAiCompatibleKimiCodeJsonSchemaContainer(cloned);
738
+ return cloned;
739
+ }
469
740
  function isLlmRequestContext(value) {
470
741
  return (isRecord(value) &&
471
742
  typeof value.dialogSelfId === 'string' &&
@@ -531,8 +802,14 @@ function buildReasoningPayloadFromText(text) {
531
802
  };
532
803
  }
533
804
  function buildOpenAiCompatibleExtraParams(args) {
805
+ if (args.providerConfig !== undefined && isKimiCodeProvider(args.providerConfig)) {
806
+ return buildKimiCodeOpenAiCompatibleExtraParams(args);
807
+ }
534
808
  const model = args.agent.model ?? '';
535
809
  const thinking = args.openAiParams.thinking;
810
+ if (typeof thinking === 'string') {
811
+ throw new Error(`Invalid openai-compatible model_params: string thinking mode '${thinking}' requires apiQuirks: ${KIMI_CODE_API_QUIRK} for model '${model}'.`);
812
+ }
536
813
  const reasoningEffort = args.openAiParams.reasoning_effort;
537
814
  const thinkingDisabled = thinking === false || (isRecord(thinking) && thinking.type === 'disabled');
538
815
  if (thinkingDisabled && reasoningEffort !== undefined) {
@@ -546,9 +823,119 @@ function buildOpenAiCompatibleExtraParams(args) {
546
823
  ...(reasoningEffort !== undefined ? { reasoning_effort: reasoningEffort } : {}),
547
824
  };
548
825
  }
826
+ function buildKimiCodeOpenAiCompatibleExtraParams(args) {
827
+ const model = args.agent.model ?? '';
828
+ const thinking = args.openAiParams.thinking;
829
+ const reasoningEffort = args.openAiParams.reasoning_effort;
830
+ const promptCacheKey = args.requestContext?.promptCacheKey?.trim();
831
+ if (reasoningEffort !== undefined && !isKimiCodeReasoningEffort(reasoningEffort)) {
832
+ throw new Error(`Invalid Kimi Code openai-compatible model_params: reasoning_effort=${reasoningEffort} is not supported for model '${model}'; expected low|medium|high.`);
833
+ }
834
+ const base = promptCacheKey !== undefined && promptCacheKey.length > 0
835
+ ? { prompt_cache_key: promptCacheKey }
836
+ : {};
837
+ if (thinking === undefined) {
838
+ return {
839
+ ...base,
840
+ ...(reasoningEffort !== undefined
841
+ ? { thinking: { type: 'enabled' }, reasoning_effort: reasoningEffort }
842
+ : {}),
843
+ };
844
+ }
845
+ if (thinking === 'auto' || thinking === 'off') {
846
+ if (reasoningEffort !== undefined) {
847
+ throw new Error(`Invalid Kimi Code openai-compatible model_params: thinking=${thinking} conflicts with reasoning_effort=${reasoningEffort} for model '${model}'.`);
848
+ }
849
+ if (thinking === 'auto')
850
+ return base;
851
+ return {
852
+ ...base,
853
+ thinking: { type: 'disabled' },
854
+ };
855
+ }
856
+ if (isKimiCodeThinkingMode(thinking)) {
857
+ if (reasoningEffort !== undefined && reasoningEffort !== thinking) {
858
+ throw new Error(`Invalid Kimi Code openai-compatible model_params: thinking=${thinking} conflicts with reasoning_effort=${reasoningEffort} for model '${model}'.`);
859
+ }
860
+ return {
861
+ ...base,
862
+ thinking: { type: 'enabled' },
863
+ reasoning_effort: thinking,
864
+ };
865
+ }
866
+ const thinkingDisabled = thinking === false || (isRecord(thinking) && thinking.type === 'disabled');
867
+ if (thinkingDisabled && reasoningEffort !== undefined) {
868
+ throw new Error(`Invalid Kimi Code openai-compatible model_params: thinking disabled conflicts with reasoning_effort=${reasoningEffort} for model '${model}'.`);
869
+ }
870
+ const thinkingPayload = typeof thinking === 'boolean' ? { type: thinking ? 'enabled' : 'disabled' } : thinking;
871
+ return {
872
+ ...base,
873
+ ...(thinkingPayload !== undefined ? { thinking: thinkingPayload } : {}),
874
+ ...(reasoningEffort !== undefined ? { reasoning_effort: reasoningEffort } : {}),
875
+ };
876
+ }
877
+ async function wrapOpenAiCompatibleRejectedRequestError(args) {
878
+ const status = (0, failure_classifier_1.readErrorStatus)(args.error);
879
+ if (status !== 400)
880
+ return args.error;
881
+ const providerKey = args.requestContext.providerKey ?? args.providerConfig.name;
882
+ const modelKey = args.requestContext.modelKey ?? args.agent.model ?? 'unknown';
883
+ const code = (0, failure_classifier_1.readErrorCode)(args.error);
884
+ const upstreamMessage = args.error instanceof Error ? args.error.message : String(args.error);
885
+ const captureContext = {
886
+ providerKey,
887
+ providerName: args.providerConfig.name.trim().length > 0 ? args.providerConfig.name : providerKey,
888
+ model: modelKey,
889
+ dialogRootId: args.requestContext.dialogRootId,
890
+ dialogSelfId: args.requestContext.dialogSelfId,
891
+ requestKind: args.requestKind,
892
+ genseq: args.genseq,
893
+ status,
894
+ ...(code !== undefined && { code }),
895
+ upstreamMessage,
896
+ };
897
+ const capture = await tryWriteOpenAiCompatibleRejectedCapture({
898
+ context: captureContext,
899
+ payload: args.payload,
900
+ error: args.error,
901
+ });
902
+ const captureMessageLines = capture.kind === 'captured'
903
+ ? [
904
+ `debugPath=${capture.record.dir}`,
905
+ `requestPayloadPath=${capture.record.requestPayloadPath}`,
906
+ ]
907
+ : [`debugCaptureError=${capture.detail}`];
908
+ const message = [
909
+ `OPENAI-compatible provider rejected ${args.requestKind} request with HTTP 400.`,
910
+ `provider=${providerKey}`,
911
+ `model=${modelKey}`,
912
+ `rootId=${args.requestContext.dialogRootId}`,
913
+ `selfId=${args.requestContext.dialogSelfId}`,
914
+ `genseq=${String(args.genseq)}`,
915
+ `upstream=${upstreamMessage}`,
916
+ ...captureMessageLines,
917
+ ].join('\n');
918
+ const wrapped = new Error(message);
919
+ wrapped.name = 'OpenAiCompatibleRejectedRequestError';
920
+ wrapped.cause = args.error;
921
+ wrapped.status = status;
922
+ wrapped.statusCode = status;
923
+ wrapped.code = code ?? OPENAI_COMPATIBLE_REJECTED_REQUEST_ERROR_CODE;
924
+ if (capture.kind === 'captured') {
925
+ wrapped.debugPath = capture.record.dir;
926
+ wrapped.requestPayloadPath = capture.record.requestPayloadPath;
927
+ }
928
+ else {
929
+ wrapped.debugCaptureError = capture.detail;
930
+ }
931
+ return wrapped;
932
+ }
549
933
  function buildOpenAiCompatibleExtraParamsForTest(args) {
550
934
  return buildOpenAiCompatibleExtraParams(args);
551
935
  }
936
+ async function wrapOpenAiCompatibleRejectedRequestErrorForTest(args) {
937
+ return await wrapOpenAiCompatibleRejectedRequestError(args);
938
+ }
552
939
  function extractThinkingReasoningText(msg) {
553
940
  const fromSummary = msg.reasoning?.summary.map((part) => part.text).join('') ?? '';
554
941
  const fromContent = msg.reasoning?.content?.map((part) => part.text).join('') ?? '';
@@ -573,10 +960,18 @@ function attachReasoningContent(message, reasoningContent) {
573
960
  reasoning_content: reasoningContent,
574
961
  };
575
962
  }
576
- function funcToolToChatCompletionTool(funcTool) {
963
+ function shouldAttachReasoningContentToAssistantToolCalls(providerConfig) {
964
+ if (providerConfig === undefined)
965
+ return true;
966
+ return !(0, api_quirks_1.normalizeProviderApiQuirks)(providerConfig).has(DISABLE_ASSISTANT_TOOL_CALL_REASONING_CONTENT_API_QUIRK);
967
+ }
968
+ function funcToolToChatCompletionTool(funcTool, providerConfig) {
577
969
  // MCP schemas are passed through to providers. Chat Completions expects a narrower JSON schema
578
970
  // shape; runtime compatibility is handled by provider validation + the driver stop policy.
579
- const parameters = funcTool.parameters;
971
+ const rawParameters = funcTool.parameters;
972
+ const parameters = (providerConfig !== undefined && isKimiCodeProvider(providerConfig)
973
+ ? normalizeOpenAiCompatibleKimiCodeJsonSchema(rawParameters)
974
+ : rawParameters);
580
975
  const description = (0, i18n_text_1.getTextForLanguage)({ i18n: funcTool.descriptionI18n, fallback: funcTool.description }, (0, work_language_1.getWorkLanguage)());
581
976
  return {
582
977
  type: 'function',
@@ -602,7 +997,6 @@ function chatMessageToChatCompletionMessage(msg) {
602
997
  case 'func_call_msg':
603
998
  return {
604
999
  role: 'assistant',
605
- content: null,
606
1000
  tool_calls: [
607
1001
  {
608
1002
  id: msg.id,
@@ -956,7 +1350,9 @@ async function buildChatCompletionMessages(systemPrompt, context, requestContext
956
1350
  const input = [];
957
1351
  const toolResultMaxChars = (0, tool_output_limit_1.resolveProviderToolResultMaxChars)(options?.providerConfig);
958
1352
  const allowedImageKeys = (0, tool_result_image_ingest_1.selectLatestImagesWithinBudget)(normalized, tool_result_image_ingest_1.OPENAI_COMPATIBLE_TOOL_RESULT_IMAGE_BUDGET_BYTES);
1353
+ const attachToolCallReasoning = shouldAttachReasoningContentToAssistantToolCalls(options?.providerConfig);
959
1354
  let pendingReasoningContent;
1355
+ let assistantTurnReasoningContent;
960
1356
  const takePendingReasoningContent = () => {
961
1357
  const current = pendingReasoningContent;
962
1358
  pendingReasoningContent = undefined;
@@ -970,10 +1366,16 @@ async function buildChatCompletionMessages(systemPrompt, context, requestContext
970
1366
  ? `${pendingReasoningContent}\n${value}`
971
1367
  : value;
972
1368
  };
1369
+ const noteAssistantTurnReasoningContent = (value) => {
1370
+ if (!value)
1371
+ return;
1372
+ assistantTurnReasoningContent = value;
1373
+ };
973
1374
  const flushPendingReasoningAsAssistantMessage = () => {
974
1375
  const reasoningContent = takePendingReasoningContent();
975
1376
  if (!reasoningContent)
976
1377
  return;
1378
+ noteAssistantTurnReasoningContent(reasoningContent);
977
1379
  input.push(attachReasoningContent({
978
1380
  role: 'assistant',
979
1381
  content: '',
@@ -989,7 +1391,12 @@ async function buildChatCompletionMessages(systemPrompt, context, requestContext
989
1391
  }
990
1392
  if (msg.type === 'func_call_msg') {
991
1393
  const mapped = chatMessageToChatCompletionMessage(msg);
992
- input.push(attachReasoningContent(mapped, takePendingReasoningContent()));
1394
+ const pending = takePendingReasoningContent();
1395
+ noteAssistantTurnReasoningContent(pending);
1396
+ const reasoningContent = attachToolCallReasoning
1397
+ ? (pending ?? assistantTurnReasoningContent)
1398
+ : undefined;
1399
+ input.push(attachReasoningContent(mapped, reasoningContent));
993
1400
  continue;
994
1401
  }
995
1402
  if (msg.type === 'func_result_msg') {
@@ -997,6 +1404,12 @@ async function buildChatCompletionMessages(systemPrompt, context, requestContext
997
1404
  input.push(...(await funcResultToChatCompletionMessages(msg, toolResultMaxChars, requestContext, options?.providerConfig, allowedImageKeys, options?.onToolResultImageIngest)));
998
1405
  continue;
999
1406
  }
1407
+ if (msg.type === 'environment_msg' ||
1408
+ msg.type === 'prompting_msg' ||
1409
+ msg.type === 'tellask_result_msg' ||
1410
+ msg.type === 'tellask_carryover_msg') {
1411
+ assistantTurnReasoningContent = undefined;
1412
+ }
1000
1413
  const mapped = (msg.type === 'prompting_msg' ||
1001
1414
  msg.type === 'tellask_result_msg' ||
1002
1415
  msg.type === 'tellask_carryover_msg') &&
@@ -1004,7 +1417,9 @@ async function buildChatCompletionMessages(systemPrompt, context, requestContext
1004
1417
  msg.contentItems.length > 0
1005
1418
  ? await userLikeMessageToChatCompletionMessageWithImages(msg, requestContext, options?.providerConfig, allowedImageKeys, options?.onUserImageIngest)
1006
1419
  : chatMessageToChatCompletionMessage(msg);
1007
- input.push(attachReasoningContent(mapped, takePendingReasoningContent()));
1420
+ const reasoningContent = takePendingReasoningContent();
1421
+ noteAssistantTurnReasoningContent(reasoningContent);
1422
+ input.push(attachReasoningContent(mapped, reasoningContent));
1008
1423
  }
1009
1424
  flushPendingReasoningAsAssistantMessage();
1010
1425
  return mergeAdjacentMessages(input);
@@ -1360,12 +1775,19 @@ class OpenAiCompatibleGen {
1360
1775
  onUserImageIngest: receiver.userImageIngest,
1361
1776
  });
1362
1777
  const openAiParams = agent.model_params?.['openai-compatible'] || {};
1363
- const parallelToolCalls = openAiParams.parallel_tool_calls ?? true;
1778
+ const parallelToolCalls = resolveOpenAiCompatibleParallelToolCalls({
1779
+ providerConfig,
1780
+ openAiParams,
1781
+ });
1364
1782
  const responseFormat = buildChatCompletionResponseFormat(openAiParams);
1365
1783
  const requestTools = resolveOpenAiCompatibleRequestTools(funcTools, requestContext);
1784
+ const modelInfo = resolveOpenAiCompatibleRequestModelInfo(providerConfig, agent, requestContext);
1785
+ const toolChoice = resolveOpenAiCompatibleToolChoice(requestTools, requestContext, modelInfo);
1366
1786
  const openAiCompatibleExtraParams = buildOpenAiCompatibleExtraParams({
1787
+ providerConfig,
1367
1788
  agent,
1368
1789
  openAiParams,
1790
+ requestContext,
1369
1791
  });
1370
1792
  const payload = {
1371
1793
  model: agent.model,
@@ -1380,9 +1802,11 @@ class OpenAiCompatibleGen {
1380
1802
  ...(openAiParams.top_p !== undefined && { top_p: openAiParams.top_p }),
1381
1803
  ...openAiCompatibleExtraParams,
1382
1804
  ...(responseFormat !== undefined && { response_format: responseFormat }),
1383
- ...(requestTools.length > 0 ? { tools: requestTools.map(funcToolToChatCompletionTool) } : {}),
1384
- tool_choice: resolveOpenAiCompatibleToolChoice(requestTools, requestContext),
1385
- parallel_tool_calls: parallelToolCalls,
1805
+ ...(requestTools.length > 0
1806
+ ? { tools: requestTools.map((tool) => funcToolToChatCompletionTool(tool, providerConfig)) }
1807
+ : {}),
1808
+ ...(toolChoice !== undefined && { tool_choice: toolChoice }),
1809
+ ...(parallelToolCalls !== undefined && { parallel_tool_calls: parallelToolCalls }),
1386
1810
  };
1387
1811
  try {
1388
1812
  const stream = await client.chat.completions.create(payload, {
@@ -1396,8 +1820,23 @@ class OpenAiCompatibleGen {
1396
1820
  });
1397
1821
  }
1398
1822
  catch (error) {
1399
- log.warn('OPENAI-COMPATIBLE streaming error', error);
1400
- throw error;
1823
+ const enrichedError = await wrapOpenAiCompatibleRejectedRequestError({
1824
+ error,
1825
+ providerConfig,
1826
+ agent,
1827
+ requestContext,
1828
+ genseq,
1829
+ requestKind: 'stream',
1830
+ payload,
1831
+ });
1832
+ log.warn('OPENAI-COMPATIBLE streaming error', enrichedError, {
1833
+ providerKey: requestContext.providerKey ?? providerConfig.name,
1834
+ model: requestContext.modelKey ?? agent.model,
1835
+ rootId: requestContext.dialogRootId,
1836
+ selfId: requestContext.dialogSelfId,
1837
+ genseq,
1838
+ });
1839
+ throw enrichedError;
1401
1840
  }
1402
1841
  }
1403
1842
  async genMoreMessages(providerConfig, agent, systemPrompt, funcTools, requestContext, context, genseq, abortSignal) {
@@ -1425,12 +1864,19 @@ class OpenAiCompatibleGen {
1425
1864
  },
1426
1865
  });
1427
1866
  const openAiParams = agent.model_params?.['openai-compatible'] || {};
1428
- const parallelToolCalls = openAiParams.parallel_tool_calls ?? true;
1867
+ const parallelToolCalls = resolveOpenAiCompatibleParallelToolCalls({
1868
+ providerConfig,
1869
+ openAiParams,
1870
+ });
1429
1871
  const responseFormat = buildChatCompletionResponseFormat(openAiParams);
1430
1872
  const requestTools = resolveOpenAiCompatibleRequestTools(funcTools, requestContext);
1873
+ const modelInfo = resolveOpenAiCompatibleRequestModelInfo(providerConfig, agent, requestContext);
1874
+ const toolChoice = resolveOpenAiCompatibleToolChoice(requestTools, requestContext, modelInfo);
1431
1875
  const openAiCompatibleExtraParams = buildOpenAiCompatibleExtraParams({
1876
+ providerConfig,
1432
1877
  agent,
1433
1878
  openAiParams,
1879
+ requestContext,
1434
1880
  });
1435
1881
  const payload = {
1436
1882
  model: agent.model,
@@ -1443,9 +1889,11 @@ class OpenAiCompatibleGen {
1443
1889
  ...(openAiParams.top_p !== undefined && { top_p: openAiParams.top_p }),
1444
1890
  ...openAiCompatibleExtraParams,
1445
1891
  ...(responseFormat !== undefined && { response_format: responseFormat }),
1446
- ...(requestTools.length > 0 && { tools: requestTools.map(funcToolToChatCompletionTool) }),
1447
- tool_choice: resolveOpenAiCompatibleToolChoice(requestTools, requestContext),
1448
- parallel_tool_calls: parallelToolCalls,
1892
+ ...(requestTools.length > 0 && {
1893
+ tools: requestTools.map((tool) => funcToolToChatCompletionTool(tool, providerConfig)),
1894
+ }),
1895
+ ...(toolChoice !== undefined && { tool_choice: toolChoice }),
1896
+ ...(parallelToolCalls !== undefined && { parallel_tool_calls: parallelToolCalls }),
1449
1897
  };
1450
1898
  try {
1451
1899
  const response = await client.chat.completions.create(payload, {
@@ -1466,8 +1914,23 @@ class OpenAiCompatibleGen {
1466
1914
  };
1467
1915
  }
1468
1916
  catch (error) {
1469
- log.warn('OPENAI-COMPATIBLE batch error', error);
1470
- throw error;
1917
+ const enrichedError = await wrapOpenAiCompatibleRejectedRequestError({
1918
+ error,
1919
+ providerConfig,
1920
+ agent,
1921
+ requestContext,
1922
+ genseq,
1923
+ requestKind: 'batch',
1924
+ payload,
1925
+ });
1926
+ log.warn('OPENAI-COMPATIBLE batch error', enrichedError, {
1927
+ providerKey: requestContext.providerKey ?? providerConfig.name,
1928
+ model: requestContext.modelKey ?? agent.model,
1929
+ rootId: requestContext.dialogRootId,
1930
+ selfId: requestContext.dialogSelfId,
1931
+ genseq,
1932
+ });
1933
+ throw enrichedError;
1471
1934
  }
1472
1935
  }
1473
1936
  }