dominds 1.4.2 → 1.5.2
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/README.md +24 -0
- package/README.zh.md +24 -0
- package/dist/apps/app-json.js +38 -3
- package/dist/apps/dialog-run-controls.js +4 -0
- package/dist/apps/enabled-apps.js +8 -1
- package/dist/apps/installed-file.js +207 -0
- package/dist/apps/run-app-json.js +6 -6
- package/dist/apps/runtime-port.js +91 -0
- package/dist/apps/runtime.js +316 -68
- package/dist/apps-host/client.js +153 -3
- package/dist/apps-host/host.js +339 -2
- package/dist/apps-host/ipc-types.js +215 -30
- package/dist/cli/install.js +21 -1
- package/dist/dialog-fork.js +609 -0
- package/dist/dialog.js +2 -2
- package/dist/docs/agent-priming.md +38 -0
- package/dist/docs/agent-priming.zh.md +34 -0
- package/dist/docs/app-constitution.md +153 -2
- package/dist/docs/app-constitution.zh.md +153 -2
- package/dist/docs/dialog-persistence.md +31 -0
- package/dist/docs/dialog-persistence.zh.md +31 -0
- package/dist/docs/dialog-system.md +29 -0
- package/dist/docs/dialog-system.zh.md +29 -0
- package/dist/docs/kernel-app-architecture.md +286 -0
- package/dist/docs/kernel-app-architecture.zh.md +285 -0
- package/dist/llm/defaults.yaml +16 -0
- package/dist/llm/driver-entry.js +28 -0
- package/dist/llm/driver-v2/context-health.js +121 -0
- package/dist/llm/driver-v2/context.js +56 -0
- package/dist/llm/driver-v2/core.js +1545 -0
- package/dist/llm/driver-v2/index.js +26 -0
- package/dist/llm/driver-v2/orchestrator.js +158 -0
- package/dist/llm/driver-v2/policy.js +129 -0
- package/dist/llm/driver-v2/restore-dialog-hierarchy.js +73 -0
- package/dist/llm/driver-v2/round.js +366 -0
- package/dist/llm/driver-v2/runtime-utils.js +365 -0
- package/dist/llm/driver-v2/saying-events.js +20 -0
- package/dist/llm/driver-v2/subdialog-txn.js +42 -0
- package/dist/llm/driver-v2/supdialog-response.js +400 -0
- package/dist/llm/driver-v2/tellask-bridge.js +1148 -0
- package/dist/llm/driver-v2/types.js +10 -0
- package/dist/llm/driver-v2-ref-only/context-health.js +121 -0
- package/dist/llm/driver-v2-ref-only/context.js +17 -0
- package/dist/llm/driver-v2-ref-only/core.js +1710 -0
- package/dist/llm/driver-v2-ref-only/index.js +26 -0
- package/dist/llm/driver-v2-ref-only/orchestrator.js +158 -0
- package/dist/llm/driver-v2-ref-only/policy.js +129 -0
- package/dist/llm/driver-v2-ref-only/restore-dialog-hierarchy.js +73 -0
- package/dist/llm/driver-v2-ref-only/round.js +366 -0
- package/dist/llm/driver-v2-ref-only/runtime-utils.js +473 -0
- package/dist/llm/driver-v2-ref-only/saying-events.js +18 -0
- package/dist/llm/driver-v2-ref-only/subdialog-txn.js +42 -0
- package/dist/llm/driver-v2-ref-only/supdialog-response.js +453 -0
- package/dist/llm/driver-v2-ref-only/tellask-bridge.js +1178 -0
- package/dist/llm/driver-v2-ref-only/types.js +10 -0
- package/dist/llm/gen/anthropic.js +68 -15
- package/dist/llm/gen/codex.js +59 -10
- package/dist/llm/gen/openai-compatible.js +38 -9
- package/dist/llm/gen/openai.js +58 -11
- package/dist/llm/gen/tool-output-limit.js +50 -0
- package/dist/llm/kernel-driver/subdialog.js +23 -12
- package/dist/llm/kernel-driver/tellask-special.js +20 -4
- package/dist/minds/load.js +7 -0
- package/dist/persistence.js +216 -30
- package/dist/priming.js +171 -18
- package/dist/server/api-routes.js +82 -0
- package/dist/server/setup-routes.js +15 -0
- package/dist/shared/types/storage.js +77 -0
- package/dist/static/assets/{_basePickBy-B2o4z1Hf.js → _basePickBy-B-A5XrWM.js} +3 -3
- package/dist/static/assets/{_basePickBy-B2o4z1Hf.js.map → _basePickBy-B-A5XrWM.js.map} +1 -1
- package/dist/static/assets/{_baseUniq-CLmcxjdl.js → _baseUniq-BANLb0cu.js} +2 -2
- package/dist/static/assets/{_baseUniq-CLmcxjdl.js.map → _baseUniq-BANLb0cu.js.map} +1 -1
- package/dist/static/assets/{arc-CymD_KN7.js → arc-CYZYnojf.js} +2 -2
- package/dist/static/assets/{arc-CymD_KN7.js.map → arc-CYZYnojf.js.map} +1 -1
- package/dist/static/assets/{architectureDiagram-VXUJARFQ-DJQfSJUH.js → architectureDiagram-VXUJARFQ-Cxf4pmYG.js} +7 -7
- package/dist/static/assets/{architectureDiagram-VXUJARFQ-DJQfSJUH.js.map → architectureDiagram-VXUJARFQ-Cxf4pmYG.js.map} +1 -1
- package/dist/static/assets/{blockDiagram-VD42YOAC-pHVz60D0.js → blockDiagram-VD42YOAC-wvs0G30c.js} +7 -7
- package/dist/static/assets/{blockDiagram-VD42YOAC-pHVz60D0.js.map → blockDiagram-VD42YOAC-wvs0G30c.js.map} +1 -1
- package/dist/static/assets/{c4Diagram-YG6GDRKO-B0WnCfAT.js → c4Diagram-YG6GDRKO-BKFNexn4.js} +3 -3
- package/dist/static/assets/{c4Diagram-YG6GDRKO-B0WnCfAT.js.map → c4Diagram-YG6GDRKO-BKFNexn4.js.map} +1 -1
- package/dist/static/assets/{channel-CX9BlKil.js → channel-_1qpxJWy.js} +2 -2
- package/dist/static/assets/{channel-CX9BlKil.js.map → channel-_1qpxJWy.js.map} +1 -1
- package/dist/static/assets/{chunk-4BX2VUAB-lXArRj3o.js → chunk-4BX2VUAB-BIdC0phm.js} +2 -2
- package/dist/static/assets/{chunk-4BX2VUAB-lXArRj3o.js.map → chunk-4BX2VUAB-BIdC0phm.js.map} +1 -1
- package/dist/static/assets/{chunk-55IACEB6-CdqwynH9.js → chunk-55IACEB6-BNvGenQ9.js} +2 -2
- package/dist/static/assets/{chunk-55IACEB6-CdqwynH9.js.map → chunk-55IACEB6-BNvGenQ9.js.map} +1 -1
- package/dist/static/assets/{chunk-B4BG7PRW-Y-uXcJst.js → chunk-B4BG7PRW-jmf-1Wv7.js} +5 -5
- package/dist/static/assets/{chunk-B4BG7PRW-Y-uXcJst.js.map → chunk-B4BG7PRW-jmf-1Wv7.js.map} +1 -1
- package/dist/static/assets/{chunk-DI55MBZ5-C5xSbRST.js → chunk-DI55MBZ5-nmEmcikR.js} +4 -4
- package/dist/static/assets/{chunk-DI55MBZ5-C5xSbRST.js.map → chunk-DI55MBZ5-nmEmcikR.js.map} +1 -1
- package/dist/static/assets/{chunk-FMBD7UC4-5uefwCjI.js → chunk-FMBD7UC4-kGysaq_j.js} +2 -2
- package/dist/static/assets/{chunk-FMBD7UC4-5uefwCjI.js.map → chunk-FMBD7UC4-kGysaq_j.js.map} +1 -1
- package/dist/static/assets/{chunk-QN33PNHL-DzWVcvpI.js → chunk-QN33PNHL-8JwMLFIJ.js} +2 -2
- package/dist/static/assets/{chunk-QN33PNHL-DzWVcvpI.js.map → chunk-QN33PNHL-8JwMLFIJ.js.map} +1 -1
- package/dist/static/assets/{chunk-QZHKN3VN-BrrvAZdP.js → chunk-QZHKN3VN-DZleEj00.js} +2 -2
- package/dist/static/assets/{chunk-QZHKN3VN-BrrvAZdP.js.map → chunk-QZHKN3VN-DZleEj00.js.map} +1 -1
- package/dist/static/assets/{chunk-TZMSLE5B-DyKOlPTY.js → chunk-TZMSLE5B-CXxl_uqH.js} +2 -2
- package/dist/static/assets/{chunk-TZMSLE5B-DyKOlPTY.js.map → chunk-TZMSLE5B-CXxl_uqH.js.map} +1 -1
- package/dist/static/assets/{classDiagram-2ON5EDUG-FCrnlCWC.js → classDiagram-2ON5EDUG-C-7R0QB6.js} +6 -6
- package/dist/static/assets/{classDiagram-2ON5EDUG-FCrnlCWC.js.map → classDiagram-2ON5EDUG-C-7R0QB6.js.map} +1 -1
- package/dist/static/assets/{classDiagram-v2-WZHVMYZB-FCrnlCWC.js → classDiagram-v2-WZHVMYZB-C-7R0QB6.js} +6 -6
- package/dist/static/assets/{classDiagram-v2-WZHVMYZB-FCrnlCWC.js.map → classDiagram-v2-WZHVMYZB-C-7R0QB6.js.map} +1 -1
- package/dist/static/assets/{clone-BlI81KqZ.js → clone-BwOKYSj8.js} +2 -2
- package/dist/static/assets/{clone-BlI81KqZ.js.map → clone-BwOKYSj8.js.map} +1 -1
- package/dist/static/assets/{cose-bilkent-S5V4N54A-yM7S2atz.js → cose-bilkent-S5V4N54A-BCBalM7p.js} +2 -2
- package/dist/static/assets/{cose-bilkent-S5V4N54A-yM7S2atz.js.map → cose-bilkent-S5V4N54A-BCBalM7p.js.map} +1 -1
- package/dist/static/assets/{dagre-6UL2VRFP-BcweuZHt.js → dagre-6UL2VRFP-uV2ekQoj.js} +7 -7
- package/dist/static/assets/{dagre-6UL2VRFP-BcweuZHt.js.map → dagre-6UL2VRFP-uV2ekQoj.js.map} +1 -1
- package/dist/static/assets/{diagram-PSM6KHXK-D4-QwLW1.js → diagram-PSM6KHXK-D-ZMog1-.js} +8 -8
- package/dist/static/assets/{diagram-PSM6KHXK-D4-QwLW1.js.map → diagram-PSM6KHXK-D-ZMog1-.js.map} +1 -1
- package/dist/static/assets/{diagram-QEK2KX5R-BVbuejJn.js → diagram-QEK2KX5R-BThSELUH.js} +7 -7
- package/dist/static/assets/{diagram-QEK2KX5R-BVbuejJn.js.map → diagram-QEK2KX5R-BThSELUH.js.map} +1 -1
- package/dist/static/assets/{diagram-S2PKOQOG-pB6N6Tq_.js → diagram-S2PKOQOG-Di-YN5cd.js} +7 -7
- package/dist/static/assets/{diagram-S2PKOQOG-pB6N6Tq_.js.map → diagram-S2PKOQOG-Di-YN5cd.js.map} +1 -1
- package/dist/static/assets/{erDiagram-Q2GNP2WA-DLKmthuw.js → erDiagram-Q2GNP2WA-lBZ9DITn.js} +5 -5
- package/dist/static/assets/{erDiagram-Q2GNP2WA-DLKmthuw.js.map → erDiagram-Q2GNP2WA-lBZ9DITn.js.map} +1 -1
- package/dist/static/assets/{flowDiagram-NV44I4VS-BsBhWukh.js → flowDiagram-NV44I4VS-C_60PNQR.js} +6 -6
- package/dist/static/assets/{flowDiagram-NV44I4VS-BsBhWukh.js.map → flowDiagram-NV44I4VS-C_60PNQR.js.map} +1 -1
- package/dist/static/assets/{ganttDiagram-JELNMOA3-Debz-J-C.js → ganttDiagram-JELNMOA3-Dvqq-VHJ.js} +3 -3
- package/dist/static/assets/{ganttDiagram-JELNMOA3-Debz-J-C.js.map → ganttDiagram-JELNMOA3-Dvqq-VHJ.js.map} +1 -1
- package/dist/static/assets/{gitGraphDiagram-V2S2FVAM-BnAPFBGR.js → gitGraphDiagram-V2S2FVAM-BTj8orRe.js} +8 -8
- package/dist/static/assets/{gitGraphDiagram-V2S2FVAM-BnAPFBGR.js.map → gitGraphDiagram-V2S2FVAM-BTj8orRe.js.map} +1 -1
- package/dist/static/assets/{graph-DbzWiBNK.js → graph-BqCzR2Nl.js} +3 -3
- package/dist/static/assets/{graph-DbzWiBNK.js.map → graph-BqCzR2Nl.js.map} +1 -1
- package/dist/static/assets/{index-B-8J28g7.js → index-DrTqAfFy.js} +386 -201
- package/dist/static/assets/index-DrTqAfFy.js.map +1 -0
- package/dist/static/assets/{infoDiagram-HS3SLOUP-CZ5hWoxV.js → infoDiagram-HS3SLOUP-DlC6wsrv.js} +6 -6
- package/dist/static/assets/{infoDiagram-HS3SLOUP-CZ5hWoxV.js.map → infoDiagram-HS3SLOUP-DlC6wsrv.js.map} +1 -1
- package/dist/static/assets/{journeyDiagram-XKPGCS4Q-CKN3oSxk.js → journeyDiagram-XKPGCS4Q-Dg_RgtQX.js} +5 -5
- package/dist/static/assets/{journeyDiagram-XKPGCS4Q-CKN3oSxk.js.map → journeyDiagram-XKPGCS4Q-Dg_RgtQX.js.map} +1 -1
- package/dist/static/assets/{kanban-definition-3W4ZIXB7-BQCMklfJ.js → kanban-definition-3W4ZIXB7-DuGS3lId.js} +3 -3
- package/dist/static/assets/{kanban-definition-3W4ZIXB7-BQCMklfJ.js.map → kanban-definition-3W4ZIXB7-DuGS3lId.js.map} +1 -1
- package/dist/static/assets/{layout-C5B58szc.js → layout-FDz2bstZ.js} +5 -5
- package/dist/static/assets/{layout-C5B58szc.js.map → layout-FDz2bstZ.js.map} +1 -1
- package/dist/static/assets/{linear-_32fut6G.js → linear-CzsdvPGb.js} +2 -2
- package/dist/static/assets/{linear-_32fut6G.js.map → linear-CzsdvPGb.js.map} +1 -1
- package/dist/static/assets/{mindmap-definition-VGOIOE7T-C_goMzjx.js → mindmap-definition-VGOIOE7T-WsAF5UNp.js} +4 -4
- package/dist/static/assets/{mindmap-definition-VGOIOE7T-C_goMzjx.js.map → mindmap-definition-VGOIOE7T-WsAF5UNp.js.map} +1 -1
- package/dist/static/assets/{pieDiagram-ADFJNKIX-BQ2n0cOB.js → pieDiagram-ADFJNKIX-DJpRJ5ei.js} +8 -8
- package/dist/static/assets/{pieDiagram-ADFJNKIX-BQ2n0cOB.js.map → pieDiagram-ADFJNKIX-DJpRJ5ei.js.map} +1 -1
- package/dist/static/assets/{quadrantDiagram-AYHSOK5B-BLg7_neg.js → quadrantDiagram-AYHSOK5B-CMyIzTkY.js} +3 -3
- package/dist/static/assets/{quadrantDiagram-AYHSOK5B-BLg7_neg.js.map → quadrantDiagram-AYHSOK5B-CMyIzTkY.js.map} +1 -1
- package/dist/static/assets/{requirementDiagram-UZGBJVZJ-DwkJt0zi.js → requirementDiagram-UZGBJVZJ-D_yqVXGu.js} +4 -4
- package/dist/static/assets/{requirementDiagram-UZGBJVZJ-DwkJt0zi.js.map → requirementDiagram-UZGBJVZJ-D_yqVXGu.js.map} +1 -1
- package/dist/static/assets/{sankeyDiagram-TZEHDZUN-DmxmatUB.js → sankeyDiagram-TZEHDZUN-D4-cF724.js} +2 -2
- package/dist/static/assets/{sankeyDiagram-TZEHDZUN-DmxmatUB.js.map → sankeyDiagram-TZEHDZUN-D4-cF724.js.map} +1 -1
- package/dist/static/assets/{sequenceDiagram-WL72ISMW-KHU_eApU.js → sequenceDiagram-WL72ISMW-B7J3gWYN.js} +4 -4
- package/dist/static/assets/{sequenceDiagram-WL72ISMW-KHU_eApU.js.map → sequenceDiagram-WL72ISMW-B7J3gWYN.js.map} +1 -1
- package/dist/static/assets/{stateDiagram-FKZM4ZOC-B3DBCxAL.js → stateDiagram-FKZM4ZOC-DwEYYCcu.js} +9 -9
- package/dist/static/assets/{stateDiagram-FKZM4ZOC-B3DBCxAL.js.map → stateDiagram-FKZM4ZOC-DwEYYCcu.js.map} +1 -1
- package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-C-uIk7gh.js → stateDiagram-v2-4FDKWEC3-D4LOOQV5.js} +5 -5
- package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-C-uIk7gh.js.map → stateDiagram-v2-4FDKWEC3-D4LOOQV5.js.map} +1 -1
- package/dist/static/assets/{timeline-definition-IT6M3QCI-SysEcQCC.js → timeline-definition-IT6M3QCI-CyG-TJ_A.js} +3 -3
- package/dist/static/assets/{timeline-definition-IT6M3QCI-SysEcQCC.js.map → timeline-definition-IT6M3QCI-CyG-TJ_A.js.map} +1 -1
- package/dist/static/assets/{treemap-GDKQZRPO-d0AbKEc4.js → treemap-GDKQZRPO-yY4GiKmU.js} +5 -5
- package/dist/static/assets/{treemap-GDKQZRPO-d0AbKEc4.js.map → treemap-GDKQZRPO-yY4GiKmU.js.map} +1 -1
- package/dist/static/assets/{xychartDiagram-PRI3JC2R-CmSQMxUh.js → xychartDiagram-PRI3JC2R-5TYN_q15.js} +3 -3
- package/dist/static/assets/{xychartDiagram-PRI3JC2R-CmSQMxUh.js.map → xychartDiagram-PRI3JC2R-5TYN_q15.js.map} +1 -1
- package/dist/static/index.html +1 -1
- package/dist/team.js +33 -4
- package/dist/tools/app-reminders.js +280 -0
- package/dist/tools/prompts/memory/en/errors.md +155 -0
- package/dist/tools/prompts/memory/en/index.md +47 -0
- package/dist/tools/prompts/memory/en/principles.md +79 -0
- package/dist/tools/prompts/memory/en/scenarios.md +174 -0
- package/dist/tools/prompts/memory/en/tools.md +154 -0
- package/dist/tools/prompts/memory/zh/errors.md +155 -0
- package/dist/tools/prompts/memory/zh/index.md +47 -0
- package/dist/tools/prompts/memory/zh/principles.md +79 -0
- package/dist/tools/prompts/memory/zh/scenarios.md +174 -0
- package/dist/tools/prompts/memory/zh/tools.md +154 -0
- package/dist/tools/ripgrep.js +197 -63
- package/package.json +2 -2
- package/dist/static/assets/index-B-8J28g7.js.map +0 -1
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createDriverV2RuntimeState = createDriverV2RuntimeState;
|
|
4
|
+
function createDriverV2RuntimeState() {
|
|
5
|
+
return {
|
|
6
|
+
driveCount: 0,
|
|
7
|
+
totalGenIterations: 0,
|
|
8
|
+
usedLegacyDriveCore: false,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AnthropicGen = void 0;
|
|
4
|
+
exports.buildAnthropicRequestMessagesWrapper = buildAnthropicRequestMessagesWrapper;
|
|
4
5
|
exports.consumeAnthropicStream = consumeAnthropicStream;
|
|
5
6
|
exports.reconstructAnthropicContextWrapper = reconstructAnthropicContextWrapper;
|
|
6
7
|
exports.reconstructAnthropicContextWrapperAsync = reconstructAnthropicContextWrapperAsync;
|
|
@@ -14,6 +15,7 @@ const log_1 = require("../../log");
|
|
|
14
15
|
const text_1 = require("../../shared/i18n/text");
|
|
15
16
|
const runtime_language_1 = require("../../shared/runtime-language");
|
|
16
17
|
const artifacts_1 = require("./artifacts");
|
|
18
|
+
const tool_output_limit_1 = require("./tool-output-limit");
|
|
17
19
|
const log = (0, log_1.createLogger)('llm/anthropic');
|
|
18
20
|
const ANTHROPIC_JSON_RESPONSE_TOOL_NAME = 'dominds_json_response';
|
|
19
21
|
const ANTHROPIC_JSON_RESPONSE_TOOL_DESCRIPTION = 'Return the final answer as a JSON object. Do not include any non-JSON text.';
|
|
@@ -21,6 +23,50 @@ const ANTHROPIC_JSON_RESPONSE_TOOL_INPUT_SCHEMA = {
|
|
|
21
23
|
type: 'object',
|
|
22
24
|
additionalProperties: true,
|
|
23
25
|
};
|
|
26
|
+
function limitAnthropicToolOutputText(text, msg, limitChars) {
|
|
27
|
+
const limited = (0, tool_output_limit_1.truncateProviderToolOutputText)(text, limitChars);
|
|
28
|
+
if (limited.truncated) {
|
|
29
|
+
log.warn('ANTH tool output truncated before provider request', undefined, {
|
|
30
|
+
callId: msg.id,
|
|
31
|
+
toolName: msg.name,
|
|
32
|
+
originalChars: limited.originalChars,
|
|
33
|
+
limitChars: limited.limitChars,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return limited.text;
|
|
37
|
+
}
|
|
38
|
+
function limitAnthropicToolOutputBlocks(content, msg, limitChars) {
|
|
39
|
+
let remainingChars = limitChars;
|
|
40
|
+
let truncated = false;
|
|
41
|
+
const limited = [];
|
|
42
|
+
for (const block of content) {
|
|
43
|
+
if (block.type !== 'text') {
|
|
44
|
+
limited.push(block);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (remainingChars <= 0) {
|
|
48
|
+
truncated = true;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
const next = (0, tool_output_limit_1.truncateProviderToolOutputText)(block.text, remainingChars);
|
|
52
|
+
limited.push({ type: 'text', text: next.text });
|
|
53
|
+
remainingChars -= next.text.length;
|
|
54
|
+
if (next.truncated) {
|
|
55
|
+
truncated = true;
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (truncated) {
|
|
60
|
+
const originalChars = content.reduce((sum, block) => sum + (block.type === 'text' ? block.text.length : 0), 0);
|
|
61
|
+
log.warn('ANTH tool output blocks truncated before provider request', undefined, {
|
|
62
|
+
callId: msg.id,
|
|
63
|
+
toolName: msg.name,
|
|
64
|
+
originalTextChars: originalChars,
|
|
65
|
+
limitChars,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return limited;
|
|
69
|
+
}
|
|
24
70
|
function isRecord(value) {
|
|
25
71
|
return typeof value === 'object' && value !== null;
|
|
26
72
|
}
|
|
@@ -192,13 +238,13 @@ function normalizeToolCallPairs(context) {
|
|
|
192
238
|
}
|
|
193
239
|
return out;
|
|
194
240
|
}
|
|
195
|
-
async function funcResultToAnthropicToolResultBlock(chatMsg) {
|
|
241
|
+
async function funcResultToAnthropicToolResultBlock(chatMsg, limitChars) {
|
|
196
242
|
const items = chatMsg.contentItems;
|
|
197
243
|
if (!Array.isArray(items) || items.length === 0) {
|
|
198
244
|
return {
|
|
199
245
|
type: 'tool_result',
|
|
200
246
|
tool_use_id: chatMsg.id,
|
|
201
|
-
content: chatMsg.content,
|
|
247
|
+
content: limitAnthropicToolOutputText(chatMsg.content, chatMsg, limitChars),
|
|
202
248
|
};
|
|
203
249
|
}
|
|
204
250
|
const content = [];
|
|
@@ -243,23 +289,23 @@ async function funcResultToAnthropicToolResultBlock(chatMsg) {
|
|
|
243
289
|
return {
|
|
244
290
|
type: 'tool_result',
|
|
245
291
|
tool_use_id: chatMsg.id,
|
|
246
|
-
content: chatMsg.content,
|
|
292
|
+
content: limitAnthropicToolOutputText(chatMsg.content, chatMsg, limitChars),
|
|
247
293
|
};
|
|
248
294
|
}
|
|
249
295
|
return {
|
|
250
296
|
type: 'tool_result',
|
|
251
297
|
tool_use_id: chatMsg.id,
|
|
252
|
-
content,
|
|
298
|
+
content: limitAnthropicToolOutputBlocks(content, chatMsg, limitChars),
|
|
253
299
|
};
|
|
254
300
|
}
|
|
255
|
-
async function chatMessageToContentBlocksAsync(chatMsg) {
|
|
301
|
+
async function chatMessageToContentBlocksAsync(chatMsg, limitChars) {
|
|
256
302
|
if (chatMsg.type !== 'func_result_msg') {
|
|
257
303
|
return chatMessageToContentBlocks(chatMsg);
|
|
258
304
|
}
|
|
259
|
-
return [await funcResultToAnthropicToolResultBlock(chatMsg)];
|
|
305
|
+
return [await funcResultToAnthropicToolResultBlock(chatMsg, limitChars)];
|
|
260
306
|
}
|
|
261
|
-
async function chatMessageToAnthropicAsync(chatMsg) {
|
|
262
|
-
const contentBlocks = await chatMessageToContentBlocksAsync(chatMsg);
|
|
307
|
+
async function chatMessageToAnthropicAsync(chatMsg, limitChars) {
|
|
308
|
+
const contentBlocks = await chatMessageToContentBlocksAsync(chatMsg, limitChars);
|
|
263
309
|
if (contentBlocks.length === 0) {
|
|
264
310
|
throw new Error(`No content blocks generated for message: ${JSON.stringify(chatMsg)}`);
|
|
265
311
|
}
|
|
@@ -272,37 +318,44 @@ async function chatMessageToAnthropicAsync(chatMsg) {
|
|
|
272
318
|
content: contentBlocks.length === 1 ? contentBlocks : contentBlocks,
|
|
273
319
|
};
|
|
274
320
|
}
|
|
275
|
-
async function buildAnthropicRequestMessages(context) {
|
|
321
|
+
async function buildAnthropicRequestMessages(context, providerConfig) {
|
|
276
322
|
// We keep the async path for func_result_msg because it may contain image artifacts.
|
|
277
323
|
const normalized = normalizeToolCallPairs(context);
|
|
278
324
|
const messages = [];
|
|
325
|
+
const toolResultMaxChars = (0, tool_output_limit_1.resolveProviderToolResultMaxChars)(providerConfig);
|
|
279
326
|
let lastToolUseId = null;
|
|
280
327
|
for (const msg of normalized) {
|
|
281
328
|
if (msg.type === 'func_call_msg') {
|
|
282
|
-
messages.push(await chatMessageToAnthropicAsync(msg));
|
|
329
|
+
messages.push(await chatMessageToAnthropicAsync(msg, toolResultMaxChars));
|
|
283
330
|
lastToolUseId = msg.id;
|
|
284
331
|
continue;
|
|
285
332
|
}
|
|
286
333
|
if (msg.type === 'func_result_msg') {
|
|
287
334
|
if (lastToolUseId === msg.id) {
|
|
288
|
-
messages.push(await chatMessageToAnthropicAsync(msg));
|
|
335
|
+
messages.push(await chatMessageToAnthropicAsync(msg, toolResultMaxChars));
|
|
289
336
|
}
|
|
290
337
|
else {
|
|
291
338
|
messages.push({
|
|
292
339
|
role: 'user',
|
|
293
340
|
content: [
|
|
294
|
-
{
|
|
341
|
+
{
|
|
342
|
+
type: 'text',
|
|
343
|
+
text: limitAnthropicToolOutputText(`[orphaned_tool_output:${msg.name}:${msg.id}] ${msg.content}`, msg, toolResultMaxChars),
|
|
344
|
+
},
|
|
295
345
|
],
|
|
296
346
|
});
|
|
297
347
|
}
|
|
298
348
|
lastToolUseId = null;
|
|
299
349
|
continue;
|
|
300
350
|
}
|
|
301
|
-
messages.push(await chatMessageToAnthropicAsync(msg));
|
|
351
|
+
messages.push(await chatMessageToAnthropicAsync(msg, toolResultMaxChars));
|
|
302
352
|
lastToolUseId = null;
|
|
303
353
|
}
|
|
304
354
|
return assembleAnthropicTurns(messages);
|
|
305
355
|
}
|
|
356
|
+
async function buildAnthropicRequestMessagesWrapper(context, providerConfig) {
|
|
357
|
+
return await buildAnthropicRequestMessages(context, providerConfig);
|
|
358
|
+
}
|
|
306
359
|
/**
|
|
307
360
|
* Reconstruct Anthropic context from persisted messages.
|
|
308
361
|
* Relies on natural storage order - func_result always follows func_call.
|
|
@@ -859,7 +912,7 @@ class AnthropicGen {
|
|
|
859
912
|
if (!apiKey)
|
|
860
913
|
throw new Error(`Missing API key env var ${providerConfig.apiKeyEnvVar}`);
|
|
861
914
|
const client = new sdk_1.Anthropic({ apiKey, baseURL: providerConfig.baseUrl });
|
|
862
|
-
const requestMessages = await buildAnthropicRequestMessages(context);
|
|
915
|
+
const requestMessages = await buildAnthropicRequestMessages(context, providerConfig);
|
|
863
916
|
const anthropicParams = agent.model_params?.anthropic || {};
|
|
864
917
|
const forceJsonResponse = resolveAnthropicJsonResponseEnabled(agent);
|
|
865
918
|
const maxTokens = agent.model_params?.max_tokens;
|
|
@@ -909,7 +962,7 @@ class AnthropicGen {
|
|
|
909
962
|
if (!apiKey)
|
|
910
963
|
throw new Error(`Missing API key env var ${providerConfig.apiKeyEnvVar}`);
|
|
911
964
|
const client = new sdk_1.Anthropic({ apiKey, baseURL: providerConfig.baseUrl });
|
|
912
|
-
const requestMessages = await buildAnthropicRequestMessages(context);
|
|
965
|
+
const requestMessages = await buildAnthropicRequestMessages(context, providerConfig);
|
|
913
966
|
const anthropicParams = agent.model_params?.anthropic || {};
|
|
914
967
|
const forceJsonResponse = resolveAnthropicJsonResponseEnabled(agent);
|
|
915
968
|
const maxTokens = agent.model_params?.max_tokens;
|
package/dist/llm/gen/codex.js
CHANGED
|
@@ -38,8 +38,52 @@ const log_1 = require("../../log");
|
|
|
38
38
|
const text_1 = require("../../shared/i18n/text");
|
|
39
39
|
const runtime_language_1 = require("../../shared/runtime-language");
|
|
40
40
|
const artifacts_1 = require("./artifacts");
|
|
41
|
+
const tool_output_limit_1 = require("./tool-output-limit");
|
|
41
42
|
const log = (0, log_1.createLogger)('llm/codex');
|
|
42
43
|
const codexFallbackInstructions = 'You are Codex CLI.';
|
|
44
|
+
function limitCodexToolOutputText(text, msg, limitChars) {
|
|
45
|
+
const limited = (0, tool_output_limit_1.truncateProviderToolOutputText)(text, limitChars);
|
|
46
|
+
if (limited.truncated) {
|
|
47
|
+
log.warn('CODEX tool output truncated before provider request', undefined, {
|
|
48
|
+
callId: msg.id,
|
|
49
|
+
toolName: msg.name,
|
|
50
|
+
originalChars: limited.originalChars,
|
|
51
|
+
limitChars: limited.limitChars,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return limited.text;
|
|
55
|
+
}
|
|
56
|
+
function limitCodexToolOutputItems(output, msg, limitChars) {
|
|
57
|
+
let remainingChars = limitChars;
|
|
58
|
+
let truncated = false;
|
|
59
|
+
const limited = [];
|
|
60
|
+
for (const item of output) {
|
|
61
|
+
if (item.type !== 'input_text') {
|
|
62
|
+
limited.push(item);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (remainingChars <= 0) {
|
|
66
|
+
truncated = true;
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
const next = (0, tool_output_limit_1.truncateProviderToolOutputText)(item.text, remainingChars);
|
|
70
|
+
limited.push({ type: 'input_text', text: next.text });
|
|
71
|
+
remainingChars -= next.text.length;
|
|
72
|
+
if (next.truncated) {
|
|
73
|
+
truncated = true;
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (truncated) {
|
|
78
|
+
const originalChars = output.reduce((sum, item) => sum + (item.type === 'input_text' ? item.text.length : 0), 0);
|
|
79
|
+
log.warn('CODEX tool output items truncated before provider request', undefined, {
|
|
80
|
+
callId: msg.id,
|
|
81
|
+
toolName: msg.name,
|
|
82
|
+
originalTextChars: originalChars,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return limited;
|
|
86
|
+
}
|
|
43
87
|
function isRecord(value) {
|
|
44
88
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
45
89
|
}
|
|
@@ -307,10 +351,11 @@ function normalizeToolCallPairs(context) {
|
|
|
307
351
|
}
|
|
308
352
|
return out;
|
|
309
353
|
}
|
|
310
|
-
async function buildCodexFunctionCallOutput(msg) {
|
|
354
|
+
async function buildCodexFunctionCallOutput(msg, limitChars) {
|
|
311
355
|
const items = msg.contentItems;
|
|
312
|
-
if (!Array.isArray(items) || items.length === 0)
|
|
313
|
-
return msg.content;
|
|
356
|
+
if (!Array.isArray(items) || items.length === 0) {
|
|
357
|
+
return limitCodexToolOutputText(msg.content, msg, limitChars);
|
|
358
|
+
}
|
|
314
359
|
const out = [];
|
|
315
360
|
for (const item of items) {
|
|
316
361
|
if (item.type === 'input_text') {
|
|
@@ -344,11 +389,14 @@ async function buildCodexFunctionCallOutput(msg) {
|
|
|
344
389
|
const _exhaustive = item;
|
|
345
390
|
out.push({ type: 'input_text', text: `[unknown content item: ${String(_exhaustive)}]` });
|
|
346
391
|
}
|
|
347
|
-
return out.length > 0
|
|
392
|
+
return out.length > 0
|
|
393
|
+
? limitCodexToolOutputItems(out, msg, limitChars)
|
|
394
|
+
: limitCodexToolOutputText(msg.content, msg, limitChars);
|
|
348
395
|
}
|
|
349
|
-
async function buildCodexInput(context) {
|
|
396
|
+
async function buildCodexInput(context, providerConfig) {
|
|
350
397
|
const normalized = normalizeToolCallPairs(context);
|
|
351
398
|
const input = [];
|
|
399
|
+
const toolResultMaxChars = (0, tool_output_limit_1.resolveProviderToolResultMaxChars)(providerConfig);
|
|
352
400
|
let lastFuncCallId = null;
|
|
353
401
|
for (const msg of normalized) {
|
|
354
402
|
if (msg.type === 'func_call_msg') {
|
|
@@ -366,11 +414,11 @@ async function buildCodexInput(context) {
|
|
|
366
414
|
input.push({
|
|
367
415
|
type: 'function_call_output',
|
|
368
416
|
call_id: msg.id,
|
|
369
|
-
output: await buildCodexFunctionCallOutput(msg),
|
|
417
|
+
output: await buildCodexFunctionCallOutput(msg, toolResultMaxChars),
|
|
370
418
|
});
|
|
371
419
|
}
|
|
372
420
|
else {
|
|
373
|
-
input.push(messageItem('user', `[orphaned_tool_output:${msg.name}:${msg.id}] ${msg.content}
|
|
421
|
+
input.push(messageItem('user', limitCodexToolOutputText(`[orphaned_tool_output:${msg.name}:${msg.id}] ${msg.content}`, msg, toolResultMaxChars)));
|
|
374
422
|
}
|
|
375
423
|
lastFuncCallId = null;
|
|
376
424
|
continue;
|
|
@@ -383,7 +431,7 @@ async function buildCodexInput(context) {
|
|
|
383
431
|
}
|
|
384
432
|
return input;
|
|
385
433
|
}
|
|
386
|
-
async function buildCodexRequest(agent, instructions, assistantPrelude, funcTools, context) {
|
|
434
|
+
async function buildCodexRequest(providerConfig, agent, instructions, assistantPrelude, funcTools, context) {
|
|
387
435
|
if (!agent.model) {
|
|
388
436
|
throw new Error(`Internal error: Model is undefined for agent '${agent.id}'`);
|
|
389
437
|
}
|
|
@@ -392,7 +440,7 @@ async function buildCodexRequest(agent, instructions, assistantPrelude, funcTool
|
|
|
392
440
|
// Codex backend rejects system messages; pass extra instructions as prior assistant context.
|
|
393
441
|
input.push(messageItem('assistant', assistantPrelude));
|
|
394
442
|
}
|
|
395
|
-
input.push(...(await buildCodexInput(context)));
|
|
443
|
+
input.push(...(await buildCodexInput(context, providerConfig)));
|
|
396
444
|
const codexParams = agent.model_params?.codex ?? agent.model_params?.openai;
|
|
397
445
|
let reasoning = null;
|
|
398
446
|
const parallelToolCalls = codexParams?.parallel_tool_calls ?? true;
|
|
@@ -416,6 +464,7 @@ async function buildCodexRequest(agent, instructions, assistantPrelude, funcTool
|
|
|
416
464
|
tool_choice: 'auto',
|
|
417
465
|
parallel_tool_calls: parallelToolCalls,
|
|
418
466
|
reasoning,
|
|
467
|
+
...(codexParams?.service_tier !== undefined ? { service_tier: codexParams.service_tier } : {}),
|
|
419
468
|
store: false,
|
|
420
469
|
stream: true,
|
|
421
470
|
include,
|
|
@@ -442,7 +491,7 @@ class CodexGen {
|
|
|
442
491
|
throw new Error(`Internal error: Model is undefined for agent '${agent.id}'`);
|
|
443
492
|
}
|
|
444
493
|
const resolvedInstructions = await resolveCodexInstructions(agent.model, systemPrompt, codexAuth.loadCodexPrompt);
|
|
445
|
-
const payload = await buildCodexRequest(agent, resolvedInstructions.instructions, resolvedInstructions.assistantPrelude, funcTools, context);
|
|
494
|
+
const payload = await buildCodexRequest(providerConfig, agent, resolvedInstructions.instructions, resolvedInstructions.assistantPrelude, funcTools, context);
|
|
446
495
|
let sayingStarted = false;
|
|
447
496
|
let thinkingStarted = false;
|
|
448
497
|
let sawOutputText = false;
|
|
@@ -20,7 +20,20 @@ const log_1 = require("../../log");
|
|
|
20
20
|
const text_1 = require("../../shared/i18n/text");
|
|
21
21
|
const runtime_language_1 = require("../../shared/runtime-language");
|
|
22
22
|
const artifacts_1 = require("./artifacts");
|
|
23
|
+
const tool_output_limit_1 = require("./tool-output-limit");
|
|
23
24
|
const log = (0, log_1.createLogger)('llm/openai-compatible');
|
|
25
|
+
function limitOpenAiCompatibleToolOutputText(text, msg, limitChars) {
|
|
26
|
+
const limited = (0, tool_output_limit_1.truncateProviderToolOutputText)(text, limitChars);
|
|
27
|
+
if (limited.truncated) {
|
|
28
|
+
log.warn('OPENAI-COMPATIBLE tool output truncated before provider request', undefined, {
|
|
29
|
+
callId: msg.id,
|
|
30
|
+
toolName: msg.name,
|
|
31
|
+
originalChars: limited.originalChars,
|
|
32
|
+
limitChars: limited.limitChars,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
return limited.text;
|
|
36
|
+
}
|
|
24
37
|
function isRecord(value) {
|
|
25
38
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
26
39
|
}
|
|
@@ -134,13 +147,23 @@ function chatMessageToChatCompletionMessage(msg) {
|
|
|
134
147
|
}
|
|
135
148
|
}
|
|
136
149
|
}
|
|
137
|
-
async function funcResultToChatCompletionMessages(msg) {
|
|
150
|
+
async function funcResultToChatCompletionMessages(msg, limitChars) {
|
|
138
151
|
const items = msg.contentItems;
|
|
139
152
|
if (!Array.isArray(items) || items.length === 0) {
|
|
140
|
-
return [
|
|
153
|
+
return [
|
|
154
|
+
{
|
|
155
|
+
role: 'tool',
|
|
156
|
+
tool_call_id: msg.id,
|
|
157
|
+
content: limitOpenAiCompatibleToolOutputText(msg.content, msg, limitChars),
|
|
158
|
+
},
|
|
159
|
+
];
|
|
141
160
|
}
|
|
142
161
|
const out = [];
|
|
143
|
-
out.push({
|
|
162
|
+
out.push({
|
|
163
|
+
role: 'tool',
|
|
164
|
+
tool_call_id: msg.id,
|
|
165
|
+
content: limitOpenAiCompatibleToolOutputText(msg.content, msg, limitChars),
|
|
166
|
+
});
|
|
144
167
|
const parts = [];
|
|
145
168
|
let sawImageUrl = false;
|
|
146
169
|
let sawAnyImage = false;
|
|
@@ -203,20 +226,20 @@ async function funcResultToChatCompletionMessages(msg) {
|
|
|
203
226
|
}
|
|
204
227
|
return out;
|
|
205
228
|
}
|
|
206
|
-
async function orphanedFuncResultToChatCompletionMessages(msg) {
|
|
229
|
+
async function orphanedFuncResultToChatCompletionMessages(msg, limitChars) {
|
|
207
230
|
const items = msg.contentItems;
|
|
208
231
|
if (!Array.isArray(items) || items.length === 0) {
|
|
209
232
|
return [
|
|
210
233
|
{
|
|
211
234
|
role: 'user',
|
|
212
|
-
content: `[orphaned_tool_output:${msg.name}:${msg.id}] ${msg.content}`,
|
|
235
|
+
content: limitOpenAiCompatibleToolOutputText(`[orphaned_tool_output:${msg.name}:${msg.id}] ${msg.content}`, msg, limitChars),
|
|
213
236
|
},
|
|
214
237
|
];
|
|
215
238
|
}
|
|
216
239
|
const parts = [
|
|
217
240
|
{
|
|
218
241
|
type: 'text',
|
|
219
|
-
text: `[orphaned_tool_output:${msg.name}:${msg.id}] ${msg.content}`,
|
|
242
|
+
text: limitOpenAiCompatibleToolOutputText(`[orphaned_tool_output:${msg.name}:${msg.id}] ${msg.content}`, msg, limitChars),
|
|
220
243
|
},
|
|
221
244
|
];
|
|
222
245
|
let sawImageUrl = false;
|
|
@@ -267,7 +290,9 @@ async function orphanedFuncResultToChatCompletionMessages(msg) {
|
|
|
267
290
|
.trim();
|
|
268
291
|
return [{ role: 'user', content: text }];
|
|
269
292
|
}
|
|
270
|
-
return [
|
|
293
|
+
return [
|
|
294
|
+
{ role: 'user', content: limitOpenAiCompatibleToolOutputText(msg.content, msg, limitChars) },
|
|
295
|
+
];
|
|
271
296
|
}
|
|
272
297
|
function normalizeToolCallPairs(context) {
|
|
273
298
|
// Providers differ in how strictly they validate tool call/result ordering. Many
|
|
@@ -364,6 +389,7 @@ async function buildChatCompletionMessages(systemPrompt, context, options) {
|
|
|
364
389
|
const normalized = normalizeToolCallPairs(context);
|
|
365
390
|
const input = [];
|
|
366
391
|
const reasoningContentMode = options?.reasoningContentMode === true;
|
|
392
|
+
const toolResultMaxChars = (0, tool_output_limit_1.resolveProviderToolResultMaxChars)(options?.providerConfig);
|
|
367
393
|
let pendingReasoningContent;
|
|
368
394
|
const takePendingReasoningContent = () => {
|
|
369
395
|
const current = pendingReasoningContent;
|
|
@@ -408,11 +434,11 @@ async function buildChatCompletionMessages(systemPrompt, context, options) {
|
|
|
408
434
|
// tool call. If it doesn't, downgrade to a plain text message so the request remains valid.
|
|
409
435
|
if (lastFuncCallId === msg.id) {
|
|
410
436
|
flushPendingReasoningAsAssistantMessage();
|
|
411
|
-
input.push(...(await funcResultToChatCompletionMessages(msg)));
|
|
437
|
+
input.push(...(await funcResultToChatCompletionMessages(msg, toolResultMaxChars)));
|
|
412
438
|
}
|
|
413
439
|
else {
|
|
414
440
|
flushPendingReasoningAsAssistantMessage();
|
|
415
|
-
input.push(...(await orphanedFuncResultToChatCompletionMessages(msg)));
|
|
441
|
+
input.push(...(await orphanedFuncResultToChatCompletionMessages(msg, toolResultMaxChars)));
|
|
416
442
|
}
|
|
417
443
|
lastFuncCallId = null;
|
|
418
444
|
continue;
|
|
@@ -518,6 +544,7 @@ class OpenAiCompatibleGen {
|
|
|
518
544
|
const reasoningContentMode = resolveOpenAiCompatibleReasoningContentMode(providerConfig, agent);
|
|
519
545
|
const messages = await buildChatCompletionMessages(systemPrompt, context, {
|
|
520
546
|
reasoningContentMode,
|
|
547
|
+
providerConfig,
|
|
521
548
|
});
|
|
522
549
|
const openAiParams = agent.model_params?.openai || {};
|
|
523
550
|
const maxTokens = agent.model_params?.max_tokens;
|
|
@@ -532,6 +559,7 @@ class OpenAiCompatibleGen {
|
|
|
532
559
|
messages,
|
|
533
560
|
stream: true,
|
|
534
561
|
stream_options: { include_usage: true },
|
|
562
|
+
...(openAiParams.service_tier !== undefined && { service_tier: openAiParams.service_tier }),
|
|
535
563
|
...(openAiParams.temperature !== undefined && { temperature: openAiParams.temperature }),
|
|
536
564
|
...(openAiParams.top_p !== undefined && { top_p: openAiParams.top_p }),
|
|
537
565
|
...(openAiParams.stop !== undefined && { stop: openAiParams.stop }),
|
|
@@ -720,6 +748,7 @@ class OpenAiCompatibleGen {
|
|
|
720
748
|
const reasoningContentMode = resolveOpenAiCompatibleReasoningContentMode(providerConfig, agent);
|
|
721
749
|
const messages = await buildChatCompletionMessages(systemPrompt, context, {
|
|
722
750
|
reasoningContentMode,
|
|
751
|
+
providerConfig,
|
|
723
752
|
});
|
|
724
753
|
const openAiParams = agent.model_params?.openai || {};
|
|
725
754
|
const maxTokens = agent.model_params?.max_tokens;
|
package/dist/llm/gen/openai.js
CHANGED
|
@@ -15,7 +15,51 @@ const log_1 = require("../../log");
|
|
|
15
15
|
const text_1 = require("../../shared/i18n/text");
|
|
16
16
|
const runtime_language_1 = require("../../shared/runtime-language");
|
|
17
17
|
const artifacts_1 = require("./artifacts");
|
|
18
|
+
const tool_output_limit_1 = require("./tool-output-limit");
|
|
18
19
|
const log = (0, log_1.createLogger)('llm/openai');
|
|
20
|
+
function limitOpenAiToolOutputText(text, msg, limitChars) {
|
|
21
|
+
const limited = (0, tool_output_limit_1.truncateProviderToolOutputText)(text, limitChars);
|
|
22
|
+
if (limited.truncated) {
|
|
23
|
+
log.warn('OPENAI tool output truncated before provider request', undefined, {
|
|
24
|
+
callId: msg.id,
|
|
25
|
+
toolName: msg.name,
|
|
26
|
+
originalChars: limited.originalChars,
|
|
27
|
+
limitChars: limited.limitChars,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return limited.text;
|
|
31
|
+
}
|
|
32
|
+
function limitOpenAiToolOutputItems(output, msg, limitChars) {
|
|
33
|
+
let remainingChars = limitChars;
|
|
34
|
+
let truncated = false;
|
|
35
|
+
const limited = [];
|
|
36
|
+
for (const item of output) {
|
|
37
|
+
if (item.type !== 'input_text') {
|
|
38
|
+
limited.push(item);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (remainingChars <= 0) {
|
|
42
|
+
truncated = true;
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
const next = (0, tool_output_limit_1.truncateProviderToolOutputText)(item.text, remainingChars);
|
|
46
|
+
limited.push({ type: 'input_text', text: next.text });
|
|
47
|
+
remainingChars -= next.text.length;
|
|
48
|
+
if (next.truncated) {
|
|
49
|
+
truncated = true;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (truncated) {
|
|
54
|
+
const originalChars = output.reduce((sum, item) => sum + (item.type === 'input_text' ? item.text.length : 0), 0);
|
|
55
|
+
log.warn('OPENAI tool output items truncated before provider request', undefined, {
|
|
56
|
+
callId: msg.id,
|
|
57
|
+
toolName: msg.name,
|
|
58
|
+
originalTextChars: originalChars,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return limited;
|
|
62
|
+
}
|
|
19
63
|
function isRecord(value) {
|
|
20
64
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
21
65
|
}
|
|
@@ -139,13 +183,13 @@ function thinkingMessageToOpenAiReasoningItem(msg) {
|
|
|
139
183
|
}
|
|
140
184
|
return out;
|
|
141
185
|
}
|
|
142
|
-
async function
|
|
186
|
+
async function funcResultToOpenAiInputItemWithLimit(msg, limitChars) {
|
|
143
187
|
const items = msg.contentItems;
|
|
144
188
|
if (!Array.isArray(items) || items.length === 0) {
|
|
145
189
|
return {
|
|
146
190
|
type: 'function_call_output',
|
|
147
191
|
call_id: msg.id,
|
|
148
|
-
output: msg.content,
|
|
192
|
+
output: limitOpenAiToolOutputText(msg.content, msg, limitChars),
|
|
149
193
|
};
|
|
150
194
|
}
|
|
151
195
|
const output = [];
|
|
@@ -189,13 +233,13 @@ async function funcResultToOpenAiInputItem(msg) {
|
|
|
189
233
|
return {
|
|
190
234
|
type: 'function_call_output',
|
|
191
235
|
call_id: msg.id,
|
|
192
|
-
output: msg.content,
|
|
236
|
+
output: limitOpenAiToolOutputText(msg.content, msg, limitChars),
|
|
193
237
|
};
|
|
194
238
|
}
|
|
195
239
|
return {
|
|
196
240
|
type: 'function_call_output',
|
|
197
241
|
call_id: msg.id,
|
|
198
|
-
output,
|
|
242
|
+
output: limitOpenAiToolOutputItems(output, msg, limitChars),
|
|
199
243
|
};
|
|
200
244
|
}
|
|
201
245
|
function normalizeToolCallPairs(context) {
|
|
@@ -284,9 +328,10 @@ function mergeAdjacentOpenAiMessages(input) {
|
|
|
284
328
|
}
|
|
285
329
|
return merged;
|
|
286
330
|
}
|
|
287
|
-
async function buildOpenAiRequestInput(context) {
|
|
331
|
+
async function buildOpenAiRequestInput(context, providerConfig) {
|
|
288
332
|
const normalized = normalizeToolCallPairs(context);
|
|
289
333
|
const input = [];
|
|
334
|
+
const toolResultMaxChars = (0, tool_output_limit_1.resolveProviderToolResultMaxChars)(providerConfig);
|
|
290
335
|
let lastFuncCallId = null;
|
|
291
336
|
for (const msg of normalized) {
|
|
292
337
|
if (msg.type === 'func_call_msg') {
|
|
@@ -298,13 +343,13 @@ async function buildOpenAiRequestInput(context) {
|
|
|
298
343
|
// Many OpenAI-compatible providers require the tool result to directly follow the matching
|
|
299
344
|
// tool call. If it doesn't, downgrade to a plain text message so the request remains valid.
|
|
300
345
|
if (lastFuncCallId === msg.id) {
|
|
301
|
-
input.push(await
|
|
346
|
+
input.push(await funcResultToOpenAiInputItemWithLimit(msg, toolResultMaxChars));
|
|
302
347
|
}
|
|
303
348
|
else {
|
|
304
349
|
input.push({
|
|
305
350
|
type: 'message',
|
|
306
351
|
role: 'user',
|
|
307
|
-
content: `[orphaned_tool_output:${msg.name}:${msg.id}] ${msg.content}`,
|
|
352
|
+
content: limitOpenAiToolOutputText(`[orphaned_tool_output:${msg.name}:${msg.id}] ${msg.content}`, msg, toolResultMaxChars),
|
|
308
353
|
});
|
|
309
354
|
}
|
|
310
355
|
lastFuncCallId = null;
|
|
@@ -349,8 +394,8 @@ function resolveOpenAiJsonResponseEnabled(agent, openAiParams) {
|
|
|
349
394
|
return openAiParams.json_response;
|
|
350
395
|
return agent.model_params?.json_response === true;
|
|
351
396
|
}
|
|
352
|
-
async function buildOpenAiRequestInputWrapper(context) {
|
|
353
|
-
return await buildOpenAiRequestInput(context);
|
|
397
|
+
async function buildOpenAiRequestInputWrapper(context, providerConfig) {
|
|
398
|
+
return await buildOpenAiRequestInput(context, providerConfig);
|
|
354
399
|
}
|
|
355
400
|
function extractOutputMessageText(item) {
|
|
356
401
|
if (!isRecord(item) || item.type !== 'message')
|
|
@@ -484,7 +529,7 @@ class OpenAiGen {
|
|
|
484
529
|
throw new Error(`Internal error: Model is undefined for agent '${agent.id}'`);
|
|
485
530
|
}
|
|
486
531
|
const client = new openai_1.default({ apiKey, baseURL: providerConfig.baseUrl });
|
|
487
|
-
const requestInput = await buildOpenAiRequestInput(context);
|
|
532
|
+
const requestInput = await buildOpenAiRequestInput(context, providerConfig);
|
|
488
533
|
const openAiParams = agent.model_params?.openai || {};
|
|
489
534
|
const maxTokens = agent.model_params?.max_tokens;
|
|
490
535
|
const jsonResponseEnabled = resolveOpenAiJsonResponseEnabled(agent, openAiParams);
|
|
@@ -501,6 +546,7 @@ class OpenAiGen {
|
|
|
501
546
|
parallel_tool_calls: parallelToolCalls,
|
|
502
547
|
store: false,
|
|
503
548
|
stream: true,
|
|
549
|
+
...(openAiParams.service_tier !== undefined && { service_tier: openAiParams.service_tier }),
|
|
504
550
|
...(openAiParams.temperature !== undefined && { temperature: openAiParams.temperature }),
|
|
505
551
|
...(openAiParams.top_p !== undefined && { top_p: openAiParams.top_p }),
|
|
506
552
|
...(openAiParams.reasoning_effort !== undefined && {
|
|
@@ -938,7 +984,7 @@ class OpenAiGen {
|
|
|
938
984
|
throw new Error(`Internal error: Model is undefined for agent '${agent.id}'`);
|
|
939
985
|
}
|
|
940
986
|
const client = new openai_1.default({ apiKey, baseURL: providerConfig.baseUrl });
|
|
941
|
-
const requestInput = await buildOpenAiRequestInput(context);
|
|
987
|
+
const requestInput = await buildOpenAiRequestInput(context, providerConfig);
|
|
942
988
|
const openAiParams = agent.model_params?.openai || {};
|
|
943
989
|
const maxTokens = agent.model_params?.max_tokens;
|
|
944
990
|
const jsonResponseEnabled = resolveOpenAiJsonResponseEnabled(agent, openAiParams);
|
|
@@ -955,6 +1001,7 @@ class OpenAiGen {
|
|
|
955
1001
|
parallel_tool_calls: parallelToolCalls,
|
|
956
1002
|
store: false,
|
|
957
1003
|
stream: false,
|
|
1004
|
+
...(openAiParams.service_tier !== undefined && { service_tier: openAiParams.service_tier }),
|
|
958
1005
|
...(openAiParams.temperature !== undefined && { temperature: openAiParams.temperature }),
|
|
959
1006
|
...(openAiParams.top_p !== undefined && { top_p: openAiParams.top_p }),
|
|
960
1007
|
...(openAiParams.reasoning_effort !== undefined && {
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveProviderToolResultMaxChars = resolveProviderToolResultMaxChars;
|
|
4
|
+
exports.truncateProviderToolOutputText = truncateProviderToolOutputText;
|
|
5
|
+
const DEFAULT_PROVIDER_TOOL_OUTPUT_CHAR_LIMITS = {
|
|
6
|
+
codex: 8 * 1024 * 1024,
|
|
7
|
+
openai: 8 * 1024 * 1024,
|
|
8
|
+
'openai-compatible': 4 * 1024 * 1024,
|
|
9
|
+
anthropic: 4 * 1024 * 1024,
|
|
10
|
+
mock: 8 * 1024 * 1024,
|
|
11
|
+
};
|
|
12
|
+
function buildProviderToolOutputSuffix(originalChars, limitChars) {
|
|
13
|
+
return `\n[tool_output_truncated_for_provider original_chars=${originalChars} limit_chars=${limitChars}]`;
|
|
14
|
+
}
|
|
15
|
+
function resolveProviderToolResultMaxChars(providerConfig) {
|
|
16
|
+
const configured = providerConfig?.tool_result_max_chars;
|
|
17
|
+
if (typeof configured === 'number' && Number.isInteger(configured) && configured > 0) {
|
|
18
|
+
return configured;
|
|
19
|
+
}
|
|
20
|
+
if (!providerConfig) {
|
|
21
|
+
return DEFAULT_PROVIDER_TOOL_OUTPUT_CHAR_LIMITS['openai'];
|
|
22
|
+
}
|
|
23
|
+
return DEFAULT_PROVIDER_TOOL_OUTPUT_CHAR_LIMITS[providerConfig.apiType];
|
|
24
|
+
}
|
|
25
|
+
function truncateProviderToolOutputText(text, limitChars = DEFAULT_PROVIDER_TOOL_OUTPUT_CHAR_LIMITS['openai']) {
|
|
26
|
+
if (text.length <= limitChars) {
|
|
27
|
+
return {
|
|
28
|
+
text,
|
|
29
|
+
truncated: false,
|
|
30
|
+
originalChars: text.length,
|
|
31
|
+
limitChars,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const suffix = buildProviderToolOutputSuffix(text.length, limitChars);
|
|
35
|
+
if (suffix.length >= limitChars) {
|
|
36
|
+
return {
|
|
37
|
+
text: suffix.slice(0, limitChars),
|
|
38
|
+
truncated: true,
|
|
39
|
+
originalChars: text.length,
|
|
40
|
+
limitChars,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const keepChars = limitChars - suffix.length;
|
|
44
|
+
return {
|
|
45
|
+
text: `${text.slice(0, keepChars)}${suffix}`,
|
|
46
|
+
truncated: true,
|
|
47
|
+
originalChars: text.length,
|
|
48
|
+
limitChars,
|
|
49
|
+
};
|
|
50
|
+
}
|