dominds 0.1.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/LICENSE +157 -0
- package/README.md +250 -0
- package/README.zh.md +161 -0
- package/dist/access-control.js +253 -0
- package/dist/cli/create.js +263 -0
- package/dist/cli/read.js +84 -0
- package/dist/cli/tui.js +199 -0
- package/dist/cli/webui.js +169 -0
- package/dist/cli.js +227 -0
- package/dist/dialog-factory.js +53 -0
- package/dist/dialog-global-registry.js +68 -0
- package/dist/dialog-instance-registry.js +78 -0
- package/dist/dialog-run-state.js +198 -0
- package/dist/dialog.js +1024 -0
- package/dist/evt-registry.js +103 -0
- package/dist/index.js +8 -0
- package/dist/llm/client.js +69 -0
- package/dist/llm/defaults.yaml +386 -0
- package/dist/llm/driver.js +3214 -0
- package/dist/llm/gen/anthropic.js +611 -0
- package/dist/llm/gen/codex.js +375 -0
- package/dist/llm/gen/mock.js +326 -0
- package/dist/llm/gen/openai.js +470 -0
- package/dist/llm/gen/registry.js +26 -0
- package/dist/llm/gen.js +2 -0
- package/dist/llm/tools-projection.js +37 -0
- package/dist/log.js +228 -0
- package/dist/mcp/config.js +230 -0
- package/dist/mcp/sdk-client.js +129 -0
- package/dist/mcp/server-runtime.js +57 -0
- package/dist/mcp/stdio-client.js +280 -0
- package/dist/mcp/supervisor.js +979 -0
- package/dist/mcp/tool-names.js +109 -0
- package/dist/minds/builtin/cmdr/persona.md +3 -0
- package/dist/minds/builtin/dijiang/knowledge.md +287 -0
- package/dist/minds/builtin/dijiang/persona.md +7 -0
- package/dist/minds/builtin/fuxi/persona.en.md +59 -0
- package/dist/minds/builtin/fuxi/persona.zh.md +49 -0
- package/dist/minds/builtin/pangu/persona.en.md +78 -0
- package/dist/minds/builtin/pangu/persona.zh.md +71 -0
- package/dist/minds/load.js +617 -0
- package/dist/minds/minds-i18n.js +131 -0
- package/dist/minds/system-prompt.js +281 -0
- package/dist/persistence.js +3128 -0
- package/dist/problems.js +109 -0
- package/dist/server/api-routes.js +1031 -0
- package/dist/server/auth.js +180 -0
- package/dist/server/mime-types.js +32 -0
- package/dist/server/prompts-routes.js +543 -0
- package/dist/server/server-core.js +235 -0
- package/dist/server/setup-routes.js +697 -0
- package/dist/server/static-server.js +132 -0
- package/dist/server/websocket-handler.js +1011 -0
- package/dist/server.js +164 -0
- package/dist/shared/async-fifo-mutex.js +36 -0
- package/dist/shared/diligence.js +20 -0
- package/dist/shared/dotenv.js +144 -0
- package/dist/shared/evt.js +195 -0
- package/dist/shared/i18n/driver-messages.js +267 -0
- package/dist/shared/i18n/text.js +9 -0
- package/dist/shared/i18n/tool-result-messages.js +51 -0
- package/dist/shared/rtws-cli.js +73 -0
- package/dist/shared/runtime-language.js +47 -0
- package/dist/shared/team-mgmt-manual.js +116 -0
- package/dist/shared/types/context-health.js +2 -0
- package/dist/shared/types/dialog.js +11 -0
- package/dist/shared/types/i18n.js +2 -0
- package/dist/shared/types/index.js +26 -0
- package/dist/shared/types/language.js +40 -0
- package/dist/shared/types/problems.js +2 -0
- package/dist/shared/types/prompts.js +2 -0
- package/dist/shared/types/q4h.js +7 -0
- package/dist/shared/types/run-state.js +8 -0
- package/dist/shared/types/setup.js +2 -0
- package/dist/shared/types/storage.js +10 -0
- package/dist/shared/types/tellask.js +8 -0
- package/dist/shared/types/tools-registry.js +2 -0
- package/dist/shared/types/wire.js +12 -0
- package/dist/shared/utils/fmt.js +9 -0
- package/dist/shared/utils/html.js +20 -0
- package/dist/shared/utils/id.js +18 -0
- package/dist/shared/utils/inter-dialog-format.js +101 -0
- package/dist/shared/utils/time.js +13 -0
- package/dist/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/dist/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/dist/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/dist/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/dist/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/dist/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/dist/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/dist/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/dist/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/dist/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/dist/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/dist/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/dist/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/dist/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/dist/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/dist/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/dist/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/dist/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/dist/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/dist/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/dist/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/dist/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/dist/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/dist/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/dist/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/dist/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/dist/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/dist/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/dist/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/dist/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/dist/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/dist/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/dist/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/dist/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/dist/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/dist/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/dist/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/dist/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/dist/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/dist/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/dist/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/dist/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/dist/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/dist/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/dist/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/dist/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/dist/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/dist/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/dist/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/dist/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/dist/static/assets/_baseUniq-Crfl3d5Y.js +661 -0
- package/dist/static/assets/_baseUniq-Crfl3d5Y.js.map +1 -0
- package/dist/static/assets/arc-CbA_x9GD.js +132 -0
- package/dist/static/assets/arc-CbA_x9GD.js.map +1 -0
- package/dist/static/assets/architectureDiagram-VXUJARFQ-lcFS8ZQJ.js +8685 -0
- package/dist/static/assets/architectureDiagram-VXUJARFQ-lcFS8ZQJ.js.map +1 -0
- package/dist/static/assets/blockDiagram-VD42YOAC-B3Q36qRc.js +3608 -0
- package/dist/static/assets/blockDiagram-VD42YOAC-B3Q36qRc.js.map +1 -0
- package/dist/static/assets/c4Diagram-YG6GDRKO-Mt-aq3VH.js +2482 -0
- package/dist/static/assets/c4Diagram-YG6GDRKO-Mt-aq3VH.js.map +1 -0
- package/dist/static/assets/channel-BVr1Yke-.js +8 -0
- package/dist/static/assets/channel-BVr1Yke-.js.map +1 -0
- package/dist/static/assets/chunk-4BX2VUAB-qCIn5Iic.js +17 -0
- package/dist/static/assets/chunk-4BX2VUAB-qCIn5Iic.js.map +1 -0
- package/dist/static/assets/chunk-55IACEB6-q172NeCV.js +14 -0
- package/dist/static/assets/chunk-55IACEB6-q172NeCV.js.map +1 -0
- package/dist/static/assets/chunk-B4BG7PRW-CMJmtYzq.js +1827 -0
- package/dist/static/assets/chunk-B4BG7PRW-CMJmtYzq.js.map +1 -0
- package/dist/static/assets/chunk-DI55MBZ5-DiuwwZPL.js +1916 -0
- package/dist/static/assets/chunk-DI55MBZ5-DiuwwZPL.js.map +1 -0
- package/dist/static/assets/chunk-FMBD7UC4-06sqZTTn.js +20 -0
- package/dist/static/assets/chunk-FMBD7UC4-06sqZTTn.js.map +1 -0
- package/dist/static/assets/chunk-QN33PNHL-CnpBNkpP.js +25 -0
- package/dist/static/assets/chunk-QN33PNHL-CnpBNkpP.js.map +1 -0
- package/dist/static/assets/chunk-QZHKN3VN-CNgjMR-e.js +18 -0
- package/dist/static/assets/chunk-QZHKN3VN-CNgjMR-e.js.map +1 -0
- package/dist/static/assets/chunk-TZMSLE5B-BxtzW6--.js +109 -0
- package/dist/static/assets/chunk-TZMSLE5B-BxtzW6--.js.map +1 -0
- package/dist/static/assets/classDiagram-2ON5EDUG-29huvmn-.js +23 -0
- package/dist/static/assets/classDiagram-2ON5EDUG-29huvmn-.js.map +1 -0
- package/dist/static/assets/classDiagram-v2-WZHVMYZB-29huvmn-.js +23 -0
- package/dist/static/assets/classDiagram-v2-WZHVMYZB-29huvmn-.js.map +1 -0
- package/dist/static/assets/clone-D2OgLSSn.js +9 -0
- package/dist/static/assets/clone-D2OgLSSn.js.map +1 -0
- package/dist/static/assets/cose-bilkent-S5V4N54A-BNegDCxl.js +4943 -0
- package/dist/static/assets/cose-bilkent-S5V4N54A-BNegDCxl.js.map +1 -0
- package/dist/static/assets/cytoscape.esm-Bm8DJGmZ.js +30240 -0
- package/dist/static/assets/cytoscape.esm-Bm8DJGmZ.js.map +1 -0
- package/dist/static/assets/dagre-6UL2VRFP-f1XrTRSn.js +695 -0
- package/dist/static/assets/dagre-6UL2VRFP-f1XrTRSn.js.map +1 -0
- package/dist/static/assets/defaultLocale-DVr69WTU.js +207 -0
- package/dist/static/assets/defaultLocale-DVr69WTU.js.map +1 -0
- package/dist/static/assets/diagram-PSM6KHXK-8w1WbeDi.js +849 -0
- package/dist/static/assets/diagram-PSM6KHXK-8w1WbeDi.js.map +1 -0
- package/dist/static/assets/diagram-QEK2KX5R-CF4wtMmR.js +303 -0
- package/dist/static/assets/diagram-QEK2KX5R-CF4wtMmR.js.map +1 -0
- package/dist/static/assets/diagram-S2PKOQOG-8p3Avgn2.js +213 -0
- package/dist/static/assets/diagram-S2PKOQOG-8p3Avgn2.js.map +1 -0
- package/dist/static/assets/erDiagram-Q2GNP2WA-BMKLxlM9.js +1159 -0
- package/dist/static/assets/erDiagram-Q2GNP2WA-BMKLxlM9.js.map +1 -0
- package/dist/static/assets/favicon-Cmg5RbCj.svg +8 -0
- package/dist/static/assets/flowDiagram-NV44I4VS-CgEuPNK2.js +2332 -0
- package/dist/static/assets/flowDiagram-NV44I4VS-CgEuPNK2.js.map +1 -0
- package/dist/static/assets/ganttDiagram-JELNMOA3-bJkDCf-9.js +3681 -0
- package/dist/static/assets/ganttDiagram-JELNMOA3-bJkDCf-9.js.map +1 -0
- package/dist/static/assets/gitGraphDiagram-NY62KEGX-4QE9kesp.js +1206 -0
- package/dist/static/assets/gitGraphDiagram-NY62KEGX-4QE9kesp.js.map +1 -0
- package/dist/static/assets/graph-CS0Pmm7c.js +597 -0
- package/dist/static/assets/graph-CS0Pmm7c.js.map +1 -0
- package/dist/static/assets/index-BS6HnGzC.js +112303 -0
- package/dist/static/assets/index-BS6HnGzC.js.map +1 -0
- package/dist/static/assets/index-DaIsSzC_.css +483 -0
- package/dist/static/assets/infoDiagram-WHAUD3N6-ypBcKfUs.js +34 -0
- package/dist/static/assets/infoDiagram-WHAUD3N6-ypBcKfUs.js.map +1 -0
- package/dist/static/assets/init-ZxktEp_H.js +17 -0
- package/dist/static/assets/init-ZxktEp_H.js.map +1 -0
- package/dist/static/assets/journeyDiagram-XKPGCS4Q-QnrxDowJ.js +1255 -0
- package/dist/static/assets/journeyDiagram-XKPGCS4Q-QnrxDowJ.js.map +1 -0
- package/dist/static/assets/kanban-definition-3W4ZIXB7-CfvEc4z5.js +1048 -0
- package/dist/static/assets/kanban-definition-3W4ZIXB7-CfvEc4z5.js.map +1 -0
- package/dist/static/assets/layout-8TGxpm23.js +2218 -0
- package/dist/static/assets/layout-8TGxpm23.js.map +1 -0
- package/dist/static/assets/linear-BATBPQQv.js +341 -0
- package/dist/static/assets/linear-BATBPQQv.js.map +1 -0
- package/dist/static/assets/min-B3oVH3AC.js +42 -0
- package/dist/static/assets/min-B3oVH3AC.js.map +1 -0
- package/dist/static/assets/mindmap-definition-VGOIOE7T-L7VLwwF8.js +1127 -0
- package/dist/static/assets/mindmap-definition-VGOIOE7T-L7VLwwF8.js.map +1 -0
- package/dist/static/assets/ordinal-CxptdPJm.js +77 -0
- package/dist/static/assets/ordinal-CxptdPJm.js.map +1 -0
- package/dist/static/assets/pieDiagram-ADFJNKIX-CFW3zIhM.js +241 -0
- package/dist/static/assets/pieDiagram-ADFJNKIX-CFW3zIhM.js.map +1 -0
- package/dist/static/assets/quadrantDiagram-AYHSOK5B-B7ssen3E.js +1338 -0
- package/dist/static/assets/quadrantDiagram-AYHSOK5B-B7ssen3E.js.map +1 -0
- package/dist/static/assets/requirementDiagram-UZGBJVZJ-D0v5BArv.js +1162 -0
- package/dist/static/assets/requirementDiagram-UZGBJVZJ-D0v5BArv.js.map +1 -0
- package/dist/static/assets/sankeyDiagram-TZEHDZUN-B7slncJe.js +1195 -0
- package/dist/static/assets/sankeyDiagram-TZEHDZUN-B7slncJe.js.map +1 -0
- package/dist/static/assets/sequenceDiagram-WL72ISMW-oXU2lRh_.js +3875 -0
- package/dist/static/assets/sequenceDiagram-WL72ISMW-oXU2lRh_.js.map +1 -0
- package/dist/static/assets/stateDiagram-FKZM4ZOC-CFYsEd0x.js +452 -0
- package/dist/static/assets/stateDiagram-FKZM4ZOC-CFYsEd0x.js.map +1 -0
- package/dist/static/assets/stateDiagram-v2-4FDKWEC3-C0UWaNA7.js +22 -0
- package/dist/static/assets/stateDiagram-v2-4FDKWEC3-C0UWaNA7.js.map +1 -0
- package/dist/static/assets/timeline-definition-IT6M3QCI-C3KODUrh.js +1223 -0
- package/dist/static/assets/timeline-definition-IT6M3QCI-C3KODUrh.js.map +1 -0
- package/dist/static/assets/treemap-KMMF4GRG-DAGDLhj2.js +18753 -0
- package/dist/static/assets/treemap-KMMF4GRG-DAGDLhj2.js.map +1 -0
- package/dist/static/assets/xychartDiagram-PRI3JC2R-C0J9iwTO.js +1888 -0
- package/dist/static/assets/xychartDiagram-PRI3JC2R-C0J9iwTO.js.map +1 -0
- package/dist/static/index.html +71 -0
- package/dist/static/testing/dom-observation-utils.js +425 -0
- package/dist/static/testing/e2e-test-helper.js +3119 -0
- package/dist/team.js +1160 -0
- package/dist/tellask.js +431 -0
- package/dist/tool.js +150 -0
- package/dist/tools/apply-patch.js +542 -0
- package/dist/tools/builtins.js +196 -0
- package/dist/tools/context-health.js +177 -0
- package/dist/tools/ctrl.js +478 -0
- package/dist/tools/diag.js +583 -0
- package/dist/tools/env.js +184 -0
- package/dist/tools/fs.js +818 -0
- package/dist/tools/mcp.js +138 -0
- package/dist/tools/mem.js +349 -0
- package/dist/tools/os.js +751 -0
- package/dist/tools/prompts/team_mgmt.en.md +70 -0
- package/dist/tools/prompts/team_mgmt.zh.md +70 -0
- package/dist/tools/prompts/ws_mod.en.md +86 -0
- package/dist/tools/prompts/ws_mod.zh.md +87 -0
- package/dist/tools/registry-snapshot.js +31 -0
- package/dist/tools/registry.js +121 -0
- package/dist/tools/ripgrep.js +678 -0
- package/dist/tools/team-mgmt.js +3300 -0
- package/dist/tools/txt.js +3178 -0
- package/dist/utils/id.js +72 -0
- package/dist/utils/task-doc.js +236 -0
- package/dist/utils/task-package.js +522 -0
- package/dist/utils/taskdoc-search.js +280 -0
- package/dist/utils/taskdoc.js +400 -0
- package/package.json +69 -0
|
@@ -0,0 +1,611 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AnthropicGen = void 0;
|
|
4
|
+
exports.reconstructAnthropicContextWrapper = reconstructAnthropicContextWrapper;
|
|
5
|
+
/**
|
|
6
|
+
* Module: llm/gen/anthropic
|
|
7
|
+
*
|
|
8
|
+
* Anthropic Messages API integration implementing streaming and batch generation.
|
|
9
|
+
*/
|
|
10
|
+
const sdk_1 = require("@anthropic-ai/sdk");
|
|
11
|
+
const log_1 = require("../../log");
|
|
12
|
+
const text_1 = require("../../shared/i18n/text");
|
|
13
|
+
const runtime_language_1 = require("../../shared/runtime-language");
|
|
14
|
+
const log = (0, log_1.createLogger)('llm/anthropic');
|
|
15
|
+
function isRecord(value) {
|
|
16
|
+
return typeof value === 'object' && value !== null;
|
|
17
|
+
}
|
|
18
|
+
function tryExtractApiReturnedModel(value) {
|
|
19
|
+
// NOTE: External API payload; a runtime check is unavoidable.
|
|
20
|
+
if (!isRecord(value))
|
|
21
|
+
return undefined;
|
|
22
|
+
if (!('model' in value))
|
|
23
|
+
return undefined;
|
|
24
|
+
const model = value.model;
|
|
25
|
+
if (typeof model !== 'string')
|
|
26
|
+
return undefined;
|
|
27
|
+
const trimmed = model.trim();
|
|
28
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
29
|
+
}
|
|
30
|
+
function isToolUseBlock(value) {
|
|
31
|
+
return (isRecord(value) &&
|
|
32
|
+
value.type === 'tool_use' &&
|
|
33
|
+
typeof value.id === 'string' &&
|
|
34
|
+
typeof value.name === 'string');
|
|
35
|
+
}
|
|
36
|
+
function funcToolToAnthropic(funcTool) {
|
|
37
|
+
// MCP schemas are passed through to providers. Anthropic's SDK types expect a narrower schema
|
|
38
|
+
// shape; runtime compatibility is handled by provider validation + the driver stop policy.
|
|
39
|
+
const input_schema = funcTool.parameters;
|
|
40
|
+
const description = (0, text_1.getTextForLanguage)({ i18n: funcTool.descriptionI18n, fallback: funcTool.description }, (0, runtime_language_1.getWorkLanguage)());
|
|
41
|
+
return {
|
|
42
|
+
name: funcTool.name,
|
|
43
|
+
description,
|
|
44
|
+
input_schema,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Context Reconstruction Functions
|
|
49
|
+
*
|
|
50
|
+
* Converts persisted messages to Anthropic SDK MessageParam[] format.
|
|
51
|
+
* Relies on natural storage order - func_result always follows func_call.
|
|
52
|
+
*/
|
|
53
|
+
/**
|
|
54
|
+
* Reconstruct Anthropic context from persisted messages.
|
|
55
|
+
* Relies on natural storage order - func_result always follows func_call.
|
|
56
|
+
*/
|
|
57
|
+
function reconstructAnthropicContext(persistedMessages) {
|
|
58
|
+
const reconstructed = [];
|
|
59
|
+
for (const msg of persistedMessages) {
|
|
60
|
+
// User text messages
|
|
61
|
+
if (msg.role === 'user' && !msg.type.startsWith('func_')) {
|
|
62
|
+
reconstructed.push({
|
|
63
|
+
role: 'user',
|
|
64
|
+
content: [{ type: 'text', text: msg.content }],
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
// Assistant text/thinking
|
|
68
|
+
else if (msg.role === 'assistant' &&
|
|
69
|
+
(msg.type === 'saying_msg' || msg.type === 'thinking_msg')) {
|
|
70
|
+
reconstructed.push({
|
|
71
|
+
role: 'assistant',
|
|
72
|
+
content: [{ type: 'text', text: msg.content }],
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
// Tool call -> immediately followed by tool_result (natural order)
|
|
76
|
+
else if (msg.type === 'func_call_msg') {
|
|
77
|
+
reconstructed.push({
|
|
78
|
+
role: 'assistant',
|
|
79
|
+
content: [
|
|
80
|
+
{
|
|
81
|
+
type: 'tool_use',
|
|
82
|
+
id: msg.id,
|
|
83
|
+
name: msg.name,
|
|
84
|
+
input: JSON.parse(msg.arguments || '{}'),
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
else if (msg.type === 'func_result_msg') {
|
|
90
|
+
reconstructed.push({
|
|
91
|
+
role: 'user',
|
|
92
|
+
content: [
|
|
93
|
+
{
|
|
94
|
+
type: 'tool_result',
|
|
95
|
+
tool_use_id: msg.id,
|
|
96
|
+
content: msg.content,
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return reconstructed;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Convert a single ChatMessage to content blocks for Anthropic SDK.
|
|
106
|
+
* Returns array of content blocks (may contain multiple for complex messages).
|
|
107
|
+
* Handles tool call/result pairing via id fields for proper SDK compatibility.
|
|
108
|
+
*/
|
|
109
|
+
function chatMessageToContentBlocks(chatMsg) {
|
|
110
|
+
// Handle TransientGuide messages as text content
|
|
111
|
+
if (chatMsg.type === 'transient_guide_msg') {
|
|
112
|
+
const block = { type: 'text', text: chatMsg.content };
|
|
113
|
+
return [block];
|
|
114
|
+
}
|
|
115
|
+
// Handle prompting and reporting messages
|
|
116
|
+
if (chatMsg.type === 'prompting_msg' || chatMsg.type === 'environment_msg') {
|
|
117
|
+
const block = { type: 'text', text: chatMsg.content };
|
|
118
|
+
return [block];
|
|
119
|
+
}
|
|
120
|
+
// Handle saying and thinking messages from assistant
|
|
121
|
+
if (chatMsg.type === 'saying_msg' || chatMsg.type === 'thinking_msg') {
|
|
122
|
+
const block = { type: 'text', text: chatMsg.content };
|
|
123
|
+
return [block];
|
|
124
|
+
}
|
|
125
|
+
// Handle function calls
|
|
126
|
+
if (chatMsg.type === 'func_call_msg') {
|
|
127
|
+
const parsed = JSON.parse(chatMsg.arguments || '{}');
|
|
128
|
+
if (!isRecord(parsed) || Array.isArray(parsed)) {
|
|
129
|
+
throw new Error('Invalid func_call_msg.arguments: expected JSON object');
|
|
130
|
+
}
|
|
131
|
+
const block = {
|
|
132
|
+
type: 'tool_use',
|
|
133
|
+
id: chatMsg.id,
|
|
134
|
+
name: chatMsg.name,
|
|
135
|
+
input: parsed,
|
|
136
|
+
};
|
|
137
|
+
return [block];
|
|
138
|
+
}
|
|
139
|
+
// Handle function results (LLM-native tool calls)
|
|
140
|
+
if (chatMsg.type === 'func_result_msg') {
|
|
141
|
+
const block = {
|
|
142
|
+
type: 'tool_result',
|
|
143
|
+
tool_use_id: chatMsg.id,
|
|
144
|
+
content: chatMsg.content,
|
|
145
|
+
};
|
|
146
|
+
return [block];
|
|
147
|
+
}
|
|
148
|
+
// Handle tellask call results (NOT LLM-native tool use; represented as role='user' text)
|
|
149
|
+
if (chatMsg.type === 'call_result_msg') {
|
|
150
|
+
const msg = {
|
|
151
|
+
type: 'text',
|
|
152
|
+
text: chatMsg.content,
|
|
153
|
+
};
|
|
154
|
+
return [msg];
|
|
155
|
+
}
|
|
156
|
+
// Exhaustiveness check - ensure all ChatMessage types are handled
|
|
157
|
+
throw new Error(`Unsupported ChatMessage type: ${JSON.stringify(chatMsg)}`);
|
|
158
|
+
}
|
|
159
|
+
function chatMessageToAnthropic(chatMsg) {
|
|
160
|
+
const contentBlocks = chatMessageToContentBlocks(chatMsg);
|
|
161
|
+
if (contentBlocks.length === 0) {
|
|
162
|
+
throw new Error(`No content blocks generated for message: ${JSON.stringify(chatMsg)}`);
|
|
163
|
+
}
|
|
164
|
+
// Determine the role, handling cases where role might not exist
|
|
165
|
+
let role = 'assistant'; // default
|
|
166
|
+
if ('role' in chatMsg) {
|
|
167
|
+
role = chatMsg.role === 'tool' ? 'user' : chatMsg.role;
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
role,
|
|
171
|
+
content: contentBlocks.length === 1 ? contentBlocks : contentBlocks,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
function anthropicToChatMessages(message, genseq) {
|
|
175
|
+
const results = [];
|
|
176
|
+
if (!isRecord(message)) {
|
|
177
|
+
throw new Error('Invalid Anthropic message: expected object');
|
|
178
|
+
}
|
|
179
|
+
const role = message.role;
|
|
180
|
+
const content = message.content;
|
|
181
|
+
if (role !== 'assistant' && role !== 'user') {
|
|
182
|
+
throw new Error('Invalid Anthropic message: missing role');
|
|
183
|
+
}
|
|
184
|
+
const blocks = Array.isArray(content) ? content : [];
|
|
185
|
+
const thinkingBlocks = blocks.filter((block) => isRecord(block) && block.type === 'thinking');
|
|
186
|
+
if (thinkingBlocks.length > 0 && role === 'assistant') {
|
|
187
|
+
const thinkingText = thinkingBlocks
|
|
188
|
+
.map((block) => (typeof block.thinking === 'string' ? block.thinking : ''))
|
|
189
|
+
.join('');
|
|
190
|
+
if (thinkingText) {
|
|
191
|
+
results.push({
|
|
192
|
+
type: 'thinking_msg',
|
|
193
|
+
role: 'assistant',
|
|
194
|
+
content: thinkingText,
|
|
195
|
+
genseq: genseq,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
const textContent = extractTextContent(blocks);
|
|
200
|
+
if (textContent && role === 'assistant') {
|
|
201
|
+
results.push({
|
|
202
|
+
type: 'saying_msg',
|
|
203
|
+
role,
|
|
204
|
+
content: textContent,
|
|
205
|
+
genseq: genseq,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
if (role === 'assistant') {
|
|
209
|
+
const toolBlocks = blocks.filter(isToolUseBlock);
|
|
210
|
+
toolBlocks.forEach((block) => {
|
|
211
|
+
results.push({
|
|
212
|
+
type: 'func_call_msg',
|
|
213
|
+
id: block.id,
|
|
214
|
+
name: block.name,
|
|
215
|
+
arguments: JSON.stringify(block.input),
|
|
216
|
+
role: 'assistant',
|
|
217
|
+
genseq: genseq,
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
return results;
|
|
222
|
+
}
|
|
223
|
+
function extractTextContent(blocks) {
|
|
224
|
+
return blocks
|
|
225
|
+
.map((block) => {
|
|
226
|
+
if (isRecord(block) && block.type === 'text' && typeof block.text === 'string') {
|
|
227
|
+
return block.text;
|
|
228
|
+
}
|
|
229
|
+
return '';
|
|
230
|
+
})
|
|
231
|
+
.join('');
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Validate that reconstructed context produces valid Anthropic SDK MessageParam[].
|
|
235
|
+
* Checks for proper role assignment, content block structure, and tool call/result pairing.
|
|
236
|
+
*/
|
|
237
|
+
function validateReconstructedContext(messages) {
|
|
238
|
+
for (const msg of messages) {
|
|
239
|
+
// Validate role
|
|
240
|
+
if (msg.role !== 'user' && msg.role !== 'assistant') {
|
|
241
|
+
throw new Error(`Invalid message role: ${msg.role}. Must be 'user' or 'assistant'.`);
|
|
242
|
+
}
|
|
243
|
+
// Validate content blocks
|
|
244
|
+
if (!Array.isArray(msg.content) || msg.content.length === 0) {
|
|
245
|
+
throw new Error('Message must have non-empty content array.');
|
|
246
|
+
}
|
|
247
|
+
for (const block of msg.content) {
|
|
248
|
+
// Validate content block type
|
|
249
|
+
if (!['text', 'thinking', 'tool_use', 'tool_result'].includes(block.type)) {
|
|
250
|
+
throw new Error(`Invalid content block type: ${block.type}`);
|
|
251
|
+
}
|
|
252
|
+
// Validate thinking blocks have signature
|
|
253
|
+
if (block.type === 'thinking' && !block.signature) {
|
|
254
|
+
throw new Error('Thinking blocks must have a signature.');
|
|
255
|
+
}
|
|
256
|
+
// Validate tool_use blocks have required fields
|
|
257
|
+
if (block.type === 'tool_use') {
|
|
258
|
+
if (!block.id || !block.name || block.input === undefined) {
|
|
259
|
+
throw new Error('Tool_use blocks must have id, name, and input fields.');
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
// Validate tool_result blocks have required fields
|
|
263
|
+
if (block.type === 'tool_result') {
|
|
264
|
+
// Check for tool_use_id field (Anthropic SDK uses 'tool_use_id' for ToolResultBlockParam)
|
|
265
|
+
const hasToolUseId = 'tool_use_id' in block &&
|
|
266
|
+
typeof block.tool_use_id === 'string' &&
|
|
267
|
+
block.tool_use_id.length > 0;
|
|
268
|
+
const hasContent = 'content' in block && block.content !== undefined;
|
|
269
|
+
if (!hasToolUseId || !hasContent) {
|
|
270
|
+
throw new Error('Tool_result blocks must have tool_use_id (reference to tool_use) and content fields.');
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Reconstruct Anthropic context from persisted messages with genseq tracking.
|
|
278
|
+
* This function groups messages by generation sequence and converts them to
|
|
279
|
+
* Anthropic SDK MessageParam[] format for context restoration.
|
|
280
|
+
*
|
|
281
|
+
* @param persistedMessages - Array of ChatMessage objects with genseq tracking
|
|
282
|
+
* @returns Array of MessageParam objects in Anthropic SDK format
|
|
283
|
+
*/
|
|
284
|
+
function reconstructAnthropicContextWrapper(persistedMessages) {
|
|
285
|
+
const reconstructed = reconstructAnthropicContext(persistedMessages);
|
|
286
|
+
// Validate the reconstructed context
|
|
287
|
+
try {
|
|
288
|
+
validateReconstructedContext(reconstructed);
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
log.error('Context reconstruction validation failed:', error);
|
|
292
|
+
throw new Error(`Invalid reconstructed context: ${error}`);
|
|
293
|
+
}
|
|
294
|
+
return reconstructed;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* AnthropicGen
|
|
298
|
+
*
|
|
299
|
+
* Implements `LlmGenerator` for Anthropic, mapping tool calls and text deltas
|
|
300
|
+
* and providing both streaming and non-streaming generation.
|
|
301
|
+
*/
|
|
302
|
+
class AnthropicGen {
|
|
303
|
+
get apiType() {
|
|
304
|
+
return 'anthropic';
|
|
305
|
+
}
|
|
306
|
+
async genToReceiver(providerConfig, agent, systemPrompt, funcTools, context, receiver, _genseq, abortSignal) {
|
|
307
|
+
const apiKey = process.env[providerConfig.apiKeyEnvVar];
|
|
308
|
+
if (!apiKey)
|
|
309
|
+
throw new Error(`Missing API key env var ${providerConfig.apiKeyEnvVar}`);
|
|
310
|
+
const client = new sdk_1.Anthropic({ apiKey, baseURL: providerConfig.baseUrl });
|
|
311
|
+
const requestMessages = context.map(chatMessageToAnthropic);
|
|
312
|
+
const anthropicParams = agent.model_params?.anthropic || {};
|
|
313
|
+
const maxTokens = agent.model_params?.max_tokens;
|
|
314
|
+
// Safety check: model should never be undefined at this point due to validation in driver
|
|
315
|
+
if (!agent.model) {
|
|
316
|
+
throw new Error(`Internal error: Model is undefined for agent '${agent.id}' after validation`);
|
|
317
|
+
}
|
|
318
|
+
// Get model info from provider config for output_length
|
|
319
|
+
const modelInfo = providerConfig.models[agent.model];
|
|
320
|
+
const outputLength = modelInfo?.output_length;
|
|
321
|
+
const baseParams = {
|
|
322
|
+
model: agent.model,
|
|
323
|
+
messages: requestMessages,
|
|
324
|
+
system: systemPrompt.length > 0 ? systemPrompt : undefined,
|
|
325
|
+
max_tokens: maxTokens ?? anthropicParams.max_tokens ?? outputLength ?? 1024,
|
|
326
|
+
...(funcTools.length > 0 && { tools: funcTools.map(funcToolToAnthropic) }),
|
|
327
|
+
...(anthropicParams.temperature !== undefined && {
|
|
328
|
+
temperature: anthropicParams.temperature,
|
|
329
|
+
}),
|
|
330
|
+
...(anthropicParams.top_p !== undefined && { top_p: anthropicParams.top_p }),
|
|
331
|
+
...(anthropicParams.top_k !== undefined && { top_k: anthropicParams.top_k }),
|
|
332
|
+
...(anthropicParams.stop_sequences !== undefined && {
|
|
333
|
+
stop_sequences: anthropicParams.stop_sequences,
|
|
334
|
+
}),
|
|
335
|
+
...(anthropicParams.reasoning_split !== undefined && {
|
|
336
|
+
reasoning_split: anthropicParams.reasoning_split,
|
|
337
|
+
}),
|
|
338
|
+
};
|
|
339
|
+
const streamParams = {
|
|
340
|
+
...baseParams,
|
|
341
|
+
stream: true,
|
|
342
|
+
...(abortSignal ? { signal: abortSignal } : {}),
|
|
343
|
+
};
|
|
344
|
+
const stream = client.messages.stream(streamParams);
|
|
345
|
+
// Stream lifecycle management using SDK start/stop events
|
|
346
|
+
let currentContentBlock = null;
|
|
347
|
+
let currentToolUse = null;
|
|
348
|
+
let sayingStarted = false;
|
|
349
|
+
let thinkingStarted = false;
|
|
350
|
+
let usage = { kind: 'unavailable' };
|
|
351
|
+
let returnedModel;
|
|
352
|
+
for await (const event of stream) {
|
|
353
|
+
if (abortSignal?.aborted) {
|
|
354
|
+
throw new Error('AbortError');
|
|
355
|
+
}
|
|
356
|
+
switch (event.type) {
|
|
357
|
+
case 'content_block_start': {
|
|
358
|
+
const contentBlock = event.content_block;
|
|
359
|
+
// Track tool use so we can emit function calls once JSON is complete
|
|
360
|
+
if (contentBlock.type === 'tool_use') {
|
|
361
|
+
currentToolUse = {
|
|
362
|
+
id: contentBlock.id,
|
|
363
|
+
name: contentBlock.name,
|
|
364
|
+
inputParts: [],
|
|
365
|
+
initialInput: contentBlock.input,
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
// Create and yield appropriate stream based on content block type
|
|
369
|
+
if (contentBlock.type === 'text') {
|
|
370
|
+
if (!sayingStarted) {
|
|
371
|
+
sayingStarted = true;
|
|
372
|
+
await receiver.sayingStart();
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
else if (contentBlock.type === 'thinking') {
|
|
376
|
+
if (!thinkingStarted) {
|
|
377
|
+
thinkingStarted = true;
|
|
378
|
+
await receiver.thinkingStart();
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
else if (contentBlock.type === 'tool_use') {
|
|
382
|
+
// Tool use has no streaming text output
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
// Unexpected content block type
|
|
386
|
+
log.warn('ANTH unexpected content_block_start', new Error('Unknown content block type'), {
|
|
387
|
+
blockType: contentBlock.type,
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
currentContentBlock = contentBlock;
|
|
391
|
+
break;
|
|
392
|
+
}
|
|
393
|
+
case 'content_block_delta': {
|
|
394
|
+
// Only process deltas for known content blocks
|
|
395
|
+
if (!currentContentBlock) {
|
|
396
|
+
log.warn('ANTH unexpected content_block_delta without active content block', new Error('Delta received before content_block_start'), {
|
|
397
|
+
deltaType: event.delta.type,
|
|
398
|
+
});
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
const delta = event.delta;
|
|
402
|
+
// Handle all RawContentBlockDelta types from Anthropic SDK
|
|
403
|
+
if (delta.type === 'text_delta') {
|
|
404
|
+
const textDelta = delta.text ?? '';
|
|
405
|
+
if (textDelta) {
|
|
406
|
+
await receiver.sayingChunk(textDelta);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
else if (delta.type === 'thinking_delta') {
|
|
410
|
+
// Lazily start thinking section if delta arrives before content_block_start
|
|
411
|
+
if (!thinkingStarted) {
|
|
412
|
+
thinkingStarted = true;
|
|
413
|
+
await receiver.thinkingStart();
|
|
414
|
+
}
|
|
415
|
+
const thinkingDelta = delta.thinking ?? '';
|
|
416
|
+
if (thinkingDelta) {
|
|
417
|
+
await receiver.thinkingChunk(thinkingDelta);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
else if (delta.type === 'citations_delta') {
|
|
421
|
+
// Handle CitationsDelta - typically just logging for now
|
|
422
|
+
}
|
|
423
|
+
else if (delta.type === 'signature_delta') {
|
|
424
|
+
// Handle SignatureDelta - typically just logging for now
|
|
425
|
+
}
|
|
426
|
+
else if (delta.type === 'input_json_delta') {
|
|
427
|
+
const partialJson = delta.partial_json;
|
|
428
|
+
if (currentToolUse) {
|
|
429
|
+
if (partialJson.length > 0) {
|
|
430
|
+
currentToolUse.inputParts.push(partialJson);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
else if (partialJson.length > 0) {
|
|
434
|
+
log.warn('ANTH input_json_delta without active tool_use', new Error('Input JSON delta received without active tool_use block'), {
|
|
435
|
+
hasCurrentBlock: currentContentBlock !== null,
|
|
436
|
+
blockType: currentContentBlock ? currentContentBlock.type : 'none',
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
break;
|
|
441
|
+
}
|
|
442
|
+
case 'content_block_stop': {
|
|
443
|
+
if (!currentContentBlock) {
|
|
444
|
+
break;
|
|
445
|
+
}
|
|
446
|
+
if (currentContentBlock.type === 'thinking') {
|
|
447
|
+
await receiver.thinkingFinish();
|
|
448
|
+
thinkingStarted = false;
|
|
449
|
+
}
|
|
450
|
+
if (currentContentBlock.type === 'text') {
|
|
451
|
+
await receiver.sayingFinish();
|
|
452
|
+
sayingStarted = false;
|
|
453
|
+
}
|
|
454
|
+
if (currentContentBlock.type === 'tool_use') {
|
|
455
|
+
if (!currentToolUse) {
|
|
456
|
+
log.warn('ANTH tool_use stop without active tool_use', new Error('Tool_use block stopped without active tool tracking'));
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
let argsJson = '';
|
|
460
|
+
if (currentToolUse.inputParts.length > 0) {
|
|
461
|
+
argsJson = currentToolUse.inputParts.join('');
|
|
462
|
+
}
|
|
463
|
+
else {
|
|
464
|
+
const stringified = JSON.stringify(currentToolUse.initialInput);
|
|
465
|
+
argsJson =
|
|
466
|
+
typeof stringified === 'string' && stringified.length > 0 ? stringified : '{}';
|
|
467
|
+
}
|
|
468
|
+
await receiver.funcCall(currentToolUse.id, currentToolUse.name, argsJson);
|
|
469
|
+
}
|
|
470
|
+
currentToolUse = null;
|
|
471
|
+
}
|
|
472
|
+
currentContentBlock = null;
|
|
473
|
+
break;
|
|
474
|
+
}
|
|
475
|
+
case 'message_start': {
|
|
476
|
+
if (returnedModel === undefined) {
|
|
477
|
+
returnedModel = tryExtractApiReturnedModel(event.message);
|
|
478
|
+
}
|
|
479
|
+
const startUsage = event.message.usage;
|
|
480
|
+
const cacheCreation = typeof startUsage.cache_creation_input_tokens === 'number'
|
|
481
|
+
? startUsage.cache_creation_input_tokens
|
|
482
|
+
: 0;
|
|
483
|
+
const cacheRead = typeof startUsage.cache_read_input_tokens === 'number'
|
|
484
|
+
? startUsage.cache_read_input_tokens
|
|
485
|
+
: 0;
|
|
486
|
+
const promptTokens = startUsage.input_tokens + cacheCreation + cacheRead;
|
|
487
|
+
const completionTokens = startUsage.output_tokens;
|
|
488
|
+
usage = {
|
|
489
|
+
kind: 'available',
|
|
490
|
+
promptTokens,
|
|
491
|
+
completionTokens,
|
|
492
|
+
totalTokens: promptTokens + completionTokens,
|
|
493
|
+
};
|
|
494
|
+
break;
|
|
495
|
+
}
|
|
496
|
+
case 'message_delta': {
|
|
497
|
+
const deltaUsage = event.usage;
|
|
498
|
+
const inputTokens = typeof deltaUsage.input_tokens === 'number' ? deltaUsage.input_tokens : null;
|
|
499
|
+
const cacheCreation = typeof deltaUsage.cache_creation_input_tokens === 'number'
|
|
500
|
+
? deltaUsage.cache_creation_input_tokens
|
|
501
|
+
: 0;
|
|
502
|
+
const cacheRead = typeof deltaUsage.cache_read_input_tokens === 'number'
|
|
503
|
+
? deltaUsage.cache_read_input_tokens
|
|
504
|
+
: 0;
|
|
505
|
+
if (usage.kind === 'available') {
|
|
506
|
+
const promptTokens = inputTokens !== null ? inputTokens + cacheCreation + cacheRead : usage.promptTokens;
|
|
507
|
+
const completionTokens = deltaUsage.output_tokens;
|
|
508
|
+
usage = {
|
|
509
|
+
kind: 'available',
|
|
510
|
+
promptTokens,
|
|
511
|
+
completionTokens,
|
|
512
|
+
totalTokens: promptTokens + completionTokens,
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
else if (inputTokens !== null) {
|
|
516
|
+
const promptTokens = inputTokens + cacheCreation + cacheRead;
|
|
517
|
+
const completionTokens = deltaUsage.output_tokens;
|
|
518
|
+
usage = {
|
|
519
|
+
kind: 'available',
|
|
520
|
+
promptTokens,
|
|
521
|
+
completionTokens,
|
|
522
|
+
totalTokens: promptTokens + completionTokens,
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
break;
|
|
526
|
+
}
|
|
527
|
+
case 'message_stop': {
|
|
528
|
+
currentContentBlock = null;
|
|
529
|
+
currentToolUse = null;
|
|
530
|
+
// Note: thinking_finish and saying_finish are handled via content_block_stop events
|
|
531
|
+
break;
|
|
532
|
+
}
|
|
533
|
+
// Note: input_json_delta is handled within content_block_delta as part of input_json_delta delta type
|
|
534
|
+
default: {
|
|
535
|
+
// Handle unexpected events with proper type checking
|
|
536
|
+
const unknownEvent = event;
|
|
537
|
+
const eventType = isRecord(unknownEvent) && typeof unknownEvent.type === 'string'
|
|
538
|
+
? unknownEvent.type
|
|
539
|
+
: 'unknown';
|
|
540
|
+
log.warn('ANTH unexpected llm event', new Error('Unknown event type'), {
|
|
541
|
+
eventType,
|
|
542
|
+
});
|
|
543
|
+
break;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
return { usage, llmGenModel: returnedModel };
|
|
548
|
+
}
|
|
549
|
+
async genMoreMessages(providerConfig, agent, systemPrompt, funcTools, context, genseq, abortSignal) {
|
|
550
|
+
const apiKey = process.env[providerConfig.apiKeyEnvVar];
|
|
551
|
+
if (!apiKey)
|
|
552
|
+
throw new Error(`Missing API key env var ${providerConfig.apiKeyEnvVar}`);
|
|
553
|
+
const client = new sdk_1.Anthropic({ apiKey, baseURL: providerConfig.baseUrl });
|
|
554
|
+
const requestMessages = context.map(chatMessageToAnthropic);
|
|
555
|
+
const anthropicParams = agent.model_params?.anthropic || {};
|
|
556
|
+
const maxTokens = agent.model_params?.max_tokens;
|
|
557
|
+
// Safety check: model should never be undefined at this point due to validation in driver
|
|
558
|
+
if (!agent.model) {
|
|
559
|
+
throw new Error(`Internal error: Model is undefined for agent '${agent.id}' after validation`);
|
|
560
|
+
}
|
|
561
|
+
// Get model info from provider config for output_length
|
|
562
|
+
const modelInfo = providerConfig.models[agent.model];
|
|
563
|
+
const outputLength = modelInfo?.output_length;
|
|
564
|
+
const baseParams = {
|
|
565
|
+
model: agent.model,
|
|
566
|
+
messages: requestMessages,
|
|
567
|
+
system: systemPrompt.length > 0 ? systemPrompt : undefined,
|
|
568
|
+
max_tokens: maxTokens ?? anthropicParams.max_tokens ?? outputLength ?? 1024,
|
|
569
|
+
...(funcTools.length > 0 && { tools: funcTools.map(funcToolToAnthropic) }),
|
|
570
|
+
...(anthropicParams.temperature !== undefined && {
|
|
571
|
+
temperature: anthropicParams.temperature,
|
|
572
|
+
}),
|
|
573
|
+
...(anthropicParams.top_p !== undefined && { top_p: anthropicParams.top_p }),
|
|
574
|
+
...(anthropicParams.top_k !== undefined && { top_k: anthropicParams.top_k }),
|
|
575
|
+
...(anthropicParams.stop_sequences !== undefined && {
|
|
576
|
+
stop_sequences: anthropicParams.stop_sequences,
|
|
577
|
+
}),
|
|
578
|
+
};
|
|
579
|
+
const createParams = {
|
|
580
|
+
...baseParams,
|
|
581
|
+
stream: false,
|
|
582
|
+
...(abortSignal ? { signal: abortSignal } : {}),
|
|
583
|
+
};
|
|
584
|
+
const response = await client.messages.create(createParams);
|
|
585
|
+
if (!response) {
|
|
586
|
+
throw new Error('No response from Anthropic API');
|
|
587
|
+
}
|
|
588
|
+
const returnedModel = typeof response.model === 'string' ? response.model : undefined;
|
|
589
|
+
const responseUsage = response.usage;
|
|
590
|
+
const cacheCreation = typeof responseUsage.cache_creation_input_tokens === 'number'
|
|
591
|
+
? responseUsage.cache_creation_input_tokens
|
|
592
|
+
: 0;
|
|
593
|
+
const cacheRead = typeof responseUsage.cache_read_input_tokens === 'number'
|
|
594
|
+
? responseUsage.cache_read_input_tokens
|
|
595
|
+
: 0;
|
|
596
|
+
const promptTokens = responseUsage.input_tokens + cacheCreation + cacheRead;
|
|
597
|
+
const completionTokens = responseUsage.output_tokens;
|
|
598
|
+
const usage = {
|
|
599
|
+
kind: 'available',
|
|
600
|
+
promptTokens,
|
|
601
|
+
completionTokens,
|
|
602
|
+
totalTokens: promptTokens + completionTokens,
|
|
603
|
+
};
|
|
604
|
+
return {
|
|
605
|
+
messages: anthropicToChatMessages(response, genseq),
|
|
606
|
+
usage,
|
|
607
|
+
llmGenModel: returnedModel,
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
exports.AnthropicGen = AnthropicGen;
|