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.
- package/dist/access-control.js +2 -2
- package/dist/dialog-instance-registry.js +3 -4
- package/dist/dialog.d.ts +2 -2
- package/dist/dialog.js +3 -3
- package/dist/docs/dialog-system.md +3 -2
- package/dist/docs/dialog-system.zh.md +3 -2
- package/dist/docs/diligence-push.md +19 -12
- package/dist/docs/diligence-push.zh.md +11 -9
- package/dist/docs/dominds-terminology.md +3 -3
- package/dist/docs/encapsulated-taskdoc.md +11 -2
- package/dist/docs/encapsulated-taskdoc.zh.md +10 -1
- package/dist/docs/llm-provider-isolation.md +1 -1
- package/dist/docs/llm-provider-isolation.zh.md +1 -1
- package/dist/docs/team_mgmt-toolset.md +2 -1
- package/dist/docs/team_mgmt-toolset.zh.md +2 -1
- package/dist/docs/volcengine-coding-plan-openai-compatible.zh.md +11 -10
- package/dist/llm/api-quirks.d.ts +0 -2
- package/dist/llm/api-quirks.js +1 -3
- package/dist/llm/client.d.ts +1 -0
- package/dist/llm/defaults.yaml +45 -6
- package/dist/llm/gen/anthropic.d.ts +0 -6
- package/dist/llm/gen/anthropic.js +21 -468
- package/dist/llm/gen/openai-compatible.d.ts +14 -1
- package/dist/llm/gen/openai-compatible.js +482 -19
- package/dist/llm/gen.d.ts +4 -2
- package/dist/llm/kernel-driver/drive.js +164 -114
- package/dist/llm/kernel-driver/runtime.js +36 -11
- package/dist/llm/kernel-driver/tellask-special.js +12 -9
- package/dist/minds/system-prompt-parts.js +8 -8
- package/dist/persistence.d.ts +2 -3
- package/dist/persistence.js +53 -76
- package/dist/problems.js +2 -1
- package/dist/runtime/driver-messages.js +4 -4
- package/dist/server/websocket-handler.js +17 -3
- package/dist/team.d.ts +2 -1
- package/dist/team.js +11 -1
- package/dist/tools/ctrl.js +48 -11
- package/dist/tools/prompts/control/en/principles.md +3 -3
- package/dist/tools/prompts/control/en/scenarios.md +4 -0
- package/dist/tools/prompts/control/en/tools.md +6 -3
- package/dist/tools/prompts/control/zh/principles.md +3 -3
- package/dist/tools/prompts/control/zh/scenarios.md +4 -0
- package/dist/tools/prompts/control/zh/tools.md +6 -3
- package/dist/tools/team_mgmt-manual.js +4 -4
- package/dist/tools/team_mgmt.js +15 -5
- package/dist/utils/task-package.d.ts +16 -0
- package/dist/utils/task-package.js +132 -55
- package/dist/utils/taskdoc.js +21 -16
- package/package.json +3 -3
- package/webapp/dist/assets/{_basePickBy-BYnYcdaa.js → _basePickBy-CGhMqD96.js} +3 -3
- package/webapp/dist/assets/{_basePickBy-BYnYcdaa.js.map → _basePickBy-CGhMqD96.js.map} +1 -1
- package/webapp/dist/assets/{_baseUniq-CHLBB955.js → _baseUniq-XCMW7z1Y.js} +2 -2
- package/webapp/dist/assets/{_baseUniq-CHLBB955.js.map → _baseUniq-XCMW7z1Y.js.map} +1 -1
- package/webapp/dist/assets/{arc-DQXtgZdO.js → arc-B6fzk0T5.js} +2 -2
- package/webapp/dist/assets/{arc-DQXtgZdO.js.map → arc-B6fzk0T5.js.map} +1 -1
- package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-CzP5Yf9x.js → architectureDiagram-2XIMDMQ5-DmSI_GUt.js} +7 -7
- package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-CzP5Yf9x.js.map → architectureDiagram-2XIMDMQ5-DmSI_GUt.js.map} +1 -1
- package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-sOx5Byq8.js → blockDiagram-WCTKOSBZ-Bp0nb8IZ.js} +7 -7
- package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-sOx5Byq8.js.map → blockDiagram-WCTKOSBZ-Bp0nb8IZ.js.map} +1 -1
- package/webapp/dist/assets/{c4Diagram-IC4MRINW-D8-GiS6c.js → c4Diagram-IC4MRINW-gYpylqGb.js} +3 -3
- package/webapp/dist/assets/{c4Diagram-IC4MRINW-D8-GiS6c.js.map → c4Diagram-IC4MRINW-gYpylqGb.js.map} +1 -1
- package/webapp/dist/assets/{channel-Bvke0iMP.js → channel-BmQ3YyUn.js} +2 -2
- package/webapp/dist/assets/{channel-Bvke0iMP.js.map → channel-BmQ3YyUn.js.map} +1 -1
- package/webapp/dist/assets/{chunk-4BX2VUAB-C9pln2M7.js → chunk-4BX2VUAB-B5pwFRwA.js} +2 -2
- package/webapp/dist/assets/{chunk-4BX2VUAB-C9pln2M7.js.map → chunk-4BX2VUAB-B5pwFRwA.js.map} +1 -1
- package/webapp/dist/assets/{chunk-55IACEB6-BLDXNtAM.js → chunk-55IACEB6-CZf6oMWM.js} +2 -2
- package/webapp/dist/assets/{chunk-55IACEB6-BLDXNtAM.js.map → chunk-55IACEB6-CZf6oMWM.js.map} +1 -1
- package/webapp/dist/assets/{chunk-FMBD7UC4-dYd3QdHa.js → chunk-FMBD7UC4-yZWCDzVz.js} +2 -2
- package/webapp/dist/assets/{chunk-FMBD7UC4-dYd3QdHa.js.map → chunk-FMBD7UC4-yZWCDzVz.js.map} +1 -1
- package/webapp/dist/assets/{chunk-JSJVCQXG-SqHEmHHd.js → chunk-JSJVCQXG-Cg1ST73M.js} +2 -2
- package/webapp/dist/assets/{chunk-JSJVCQXG-SqHEmHHd.js.map → chunk-JSJVCQXG-Cg1ST73M.js.map} +1 -1
- package/webapp/dist/assets/{chunk-KX2RTZJC-CRXgzI2d.js → chunk-KX2RTZJC-ByGtlX9q.js} +2 -2
- package/webapp/dist/assets/{chunk-KX2RTZJC-CRXgzI2d.js.map → chunk-KX2RTZJC-ByGtlX9q.js.map} +1 -1
- package/webapp/dist/assets/{chunk-NQ4KR5QH-IMA2JZhH.js → chunk-NQ4KR5QH-DoXvfhSY.js} +4 -4
- package/webapp/dist/assets/{chunk-NQ4KR5QH-IMA2JZhH.js.map → chunk-NQ4KR5QH-DoXvfhSY.js.map} +1 -1
- package/webapp/dist/assets/{chunk-QZHKN3VN-DBaGWjY3.js → chunk-QZHKN3VN-2gX2qsHB.js} +2 -2
- package/webapp/dist/assets/{chunk-QZHKN3VN-DBaGWjY3.js.map → chunk-QZHKN3VN-2gX2qsHB.js.map} +1 -1
- package/webapp/dist/assets/{chunk-WL4C6EOR-QLmsLbcS.js → chunk-WL4C6EOR-L-9bPNxS.js} +6 -6
- package/webapp/dist/assets/{chunk-WL4C6EOR-QLmsLbcS.js.map → chunk-WL4C6EOR-L-9bPNxS.js.map} +1 -1
- package/webapp/dist/assets/{classDiagram-VBA2DB6C-jN4lhUtx.js → classDiagram-VBA2DB6C-B79Oe3Df.js} +7 -7
- package/webapp/dist/assets/{classDiagram-VBA2DB6C-jN4lhUtx.js.map → classDiagram-VBA2DB6C-B79Oe3Df.js.map} +1 -1
- package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-jN4lhUtx.js → classDiagram-v2-RAHNMMFH-B79Oe3Df.js} +7 -7
- package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-jN4lhUtx.js.map → classDiagram-v2-RAHNMMFH-B79Oe3Df.js.map} +1 -1
- package/webapp/dist/assets/{clone-DPC4Vt09.js → clone-DvlY9Sdn.js} +2 -2
- package/webapp/dist/assets/{clone-DPC4Vt09.js.map → clone-DvlY9Sdn.js.map} +1 -1
- package/webapp/dist/assets/{cose-bilkent-S5V4N54A-BtVgObsc.js → cose-bilkent-S5V4N54A-CtkGd0W6.js} +2 -2
- package/webapp/dist/assets/{cose-bilkent-S5V4N54A-BtVgObsc.js.map → cose-bilkent-S5V4N54A-CtkGd0W6.js.map} +1 -1
- package/webapp/dist/assets/{dagre-KLK3FWXG-Bv6mn-UV.js → dagre-KLK3FWXG-B3W6QTXQ.js} +7 -7
- package/webapp/dist/assets/{dagre-KLK3FWXG-Bv6mn-UV.js.map → dagre-KLK3FWXG-B3W6QTXQ.js.map} +1 -1
- package/webapp/dist/assets/{diagram-E7M64L7V-D2OPgDkq.js → diagram-E7M64L7V-B6-J_E5Q.js} +8 -8
- package/webapp/dist/assets/{diagram-E7M64L7V-D2OPgDkq.js.map → diagram-E7M64L7V-B6-J_E5Q.js.map} +1 -1
- package/webapp/dist/assets/{diagram-IFDJBPK2-CZpDu-e5.js → diagram-IFDJBPK2-C-PH_Yx3.js} +7 -7
- package/webapp/dist/assets/{diagram-IFDJBPK2-CZpDu-e5.js.map → diagram-IFDJBPK2-C-PH_Yx3.js.map} +1 -1
- package/webapp/dist/assets/{diagram-P4PSJMXO-BkMbbW0p.js → diagram-P4PSJMXO-CB5xXDup.js} +7 -7
- package/webapp/dist/assets/{diagram-P4PSJMXO-BkMbbW0p.js.map → diagram-P4PSJMXO-CB5xXDup.js.map} +1 -1
- package/webapp/dist/assets/{erDiagram-INFDFZHY-Kf17ek1z.js → erDiagram-INFDFZHY-CuAhTGVU.js} +5 -5
- package/webapp/dist/assets/{erDiagram-INFDFZHY-Kf17ek1z.js.map → erDiagram-INFDFZHY-CuAhTGVU.js.map} +1 -1
- package/webapp/dist/assets/{flowDiagram-PKNHOUZH-Cort4hNL.js → flowDiagram-PKNHOUZH-D3cIOfGj.js} +7 -7
- package/webapp/dist/assets/{flowDiagram-PKNHOUZH-Cort4hNL.js.map → flowDiagram-PKNHOUZH-D3cIOfGj.js.map} +1 -1
- package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-DcXFKB1Y.js → ganttDiagram-A5KZAMGK-CSFhVYXV.js} +3 -3
- package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-DcXFKB1Y.js.map → ganttDiagram-A5KZAMGK-CSFhVYXV.js.map} +1 -1
- package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-BORnqZ0-.js → gitGraphDiagram-K3NZZRJ6-CiEaxACG.js} +8 -8
- package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-BORnqZ0-.js.map → gitGraphDiagram-K3NZZRJ6-CiEaxACG.js.map} +1 -1
- package/webapp/dist/assets/{graph-D4Uth-MK.js → graph-CYGALRuy.js} +3 -3
- package/webapp/dist/assets/{graph-D4Uth-MK.js.map → graph-CYGALRuy.js.map} +1 -1
- package/webapp/dist/assets/{index-YBIJr7jH.js → index-BTazqQrV.js} +186 -58
- package/webapp/dist/assets/index-BTazqQrV.js.map +1 -0
- package/webapp/dist/assets/{infoDiagram-LFFYTUFH-DDjsEPg3.js → infoDiagram-LFFYTUFH-CiWJjQyU.js} +6 -6
- package/webapp/dist/assets/{infoDiagram-LFFYTUFH-DDjsEPg3.js.map → infoDiagram-LFFYTUFH-CiWJjQyU.js.map} +1 -1
- package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-Bb2sPnCX.js → ishikawaDiagram-PHBUUO56-MlIIUO7o.js} +2 -2
- package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-Bb2sPnCX.js.map → ishikawaDiagram-PHBUUO56-MlIIUO7o.js.map} +1 -1
- package/webapp/dist/assets/{journeyDiagram-4ABVD52K-BtRY6eBa.js → journeyDiagram-4ABVD52K-BBqwkA3d.js} +5 -5
- package/webapp/dist/assets/{journeyDiagram-4ABVD52K-BtRY6eBa.js.map → journeyDiagram-4ABVD52K-BBqwkA3d.js.map} +1 -1
- package/webapp/dist/assets/{kanban-definition-K7BYSVSG-aGmxT2H9.js → kanban-definition-K7BYSVSG-BS4GzDbo.js} +3 -3
- package/webapp/dist/assets/{kanban-definition-K7BYSVSG-aGmxT2H9.js.map → kanban-definition-K7BYSVSG-BS4GzDbo.js.map} +1 -1
- package/webapp/dist/assets/{layout-BuLicmwh.js → layout-DaJO-1DW.js} +5 -5
- package/webapp/dist/assets/{layout-BuLicmwh.js.map → layout-DaJO-1DW.js.map} +1 -1
- package/webapp/dist/assets/{linear-DIPh96mp.js → linear-SWy2Cl7G.js} +2 -2
- package/webapp/dist/assets/{linear-DIPh96mp.js.map → linear-SWy2Cl7G.js.map} +1 -1
- package/webapp/dist/assets/{mindmap-definition-YRQLILUH-ofWsysn9.js → mindmap-definition-YRQLILUH-B_gNrT3l.js} +4 -4
- package/webapp/dist/assets/{mindmap-definition-YRQLILUH-ofWsysn9.js.map → mindmap-definition-YRQLILUH-B_gNrT3l.js.map} +1 -1
- package/webapp/dist/assets/{pieDiagram-SKSYHLDU-DQqCTITO.js → pieDiagram-SKSYHLDU-CVh3lLBA.js} +8 -8
- package/webapp/dist/assets/{pieDiagram-SKSYHLDU-DQqCTITO.js.map → pieDiagram-SKSYHLDU-CVh3lLBA.js.map} +1 -1
- package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-DxWc0avu.js → quadrantDiagram-337W2JSQ-D0zAkVD7.js} +3 -3
- package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-DxWc0avu.js.map → quadrantDiagram-337W2JSQ-D0zAkVD7.js.map} +1 -1
- package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-DHgYfzwt.js → requirementDiagram-Z7DCOOCP--CTFD60w.js} +4 -4
- package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-DHgYfzwt.js.map → requirementDiagram-Z7DCOOCP--CTFD60w.js.map} +1 -1
- package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-Cuhwe80W.js → sankeyDiagram-WA2Y5GQK-XZnViaAX.js} +2 -2
- package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-Cuhwe80W.js.map → sankeyDiagram-WA2Y5GQK-XZnViaAX.js.map} +1 -1
- package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-DqSNoro8.js → sequenceDiagram-2WXFIKYE-BWAMhn_x.js} +4 -4
- package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-DqSNoro8.js.map → sequenceDiagram-2WXFIKYE-BWAMhn_x.js.map} +1 -1
- package/webapp/dist/assets/{stateDiagram-RAJIS63D-D1mvuJi6.js → stateDiagram-RAJIS63D--jsLD0Dg.js} +9 -9
- package/webapp/dist/assets/{stateDiagram-RAJIS63D-D1mvuJi6.js.map → stateDiagram-RAJIS63D--jsLD0Dg.js.map} +1 -1
- package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-BCYX5Gy-.js → stateDiagram-v2-FVOUBMTO-DUG9vyI5.js} +5 -5
- package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-BCYX5Gy-.js.map → stateDiagram-v2-FVOUBMTO-DUG9vyI5.js.map} +1 -1
- package/webapp/dist/assets/{timeline-definition-YZTLITO2-DDLYGao7.js → timeline-definition-YZTLITO2-BROLp1hL.js} +3 -3
- package/webapp/dist/assets/{timeline-definition-YZTLITO2-DDLYGao7.js.map → timeline-definition-YZTLITO2-BROLp1hL.js.map} +1 -1
- package/webapp/dist/assets/{treemap-KZPCXAKY-DXkv1e6y.js → treemap-KZPCXAKY-BXuIlbYo.js} +5 -5
- package/webapp/dist/assets/{treemap-KZPCXAKY-DXkv1e6y.js.map → treemap-KZPCXAKY-BXuIlbYo.js.map} +1 -1
- package/webapp/dist/assets/{vennDiagram-LZ73GAT5-DMxsg9P0.js → vennDiagram-LZ73GAT5-BXWd8gBB.js} +2 -2
- package/webapp/dist/assets/{vennDiagram-LZ73GAT5-DMxsg9P0.js.map → vennDiagram-LZ73GAT5-BXWd8gBB.js.map} +1 -1
- package/webapp/dist/assets/{xychartDiagram-JWTSCODW-BJ2qipzT.js → xychartDiagram-JWTSCODW-DR5z9o6h.js} +3 -3
- package/webapp/dist/assets/{xychartDiagram-JWTSCODW-BJ2qipzT.js.map → xychartDiagram-JWTSCODW-DR5z9o6h.js.map} +1 -1
- package/webapp/dist/index.html +1 -1
- 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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
1384
|
-
|
|
1385
|
-
|
|
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
|
-
|
|
1400
|
-
|
|
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 =
|
|
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 && {
|
|
1447
|
-
|
|
1448
|
-
|
|
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
|
-
|
|
1470
|
-
|
|
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
|
}
|