@sinm/kai 1.9.0 → 1.9.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/dist-cli/kai-cli.js +1593 -532
- package/dist-electron/renderer/assets/{_baseUniq-wFb12gB-.js → _baseUniq-CsQsIo3h.js} +1 -1
- package/dist-electron/renderer/assets/_baseUniq-CsQsIo3h.js.gz +0 -0
- package/dist-electron/renderer/assets/{arc-Bjp2aBSU.js → arc-CnDy2qlp.js} +1 -1
- package/dist-electron/renderer/assets/arc-CnDy2qlp.js.gz +0 -0
- package/dist-electron/renderer/assets/{architectureDiagram-Q4EWVU46-AEAF6BMT.js → architectureDiagram-Q4EWVU46-7xdcupg1.js} +5 -5
- package/dist-electron/renderer/assets/architectureDiagram-Q4EWVU46-7xdcupg1.js.gz +0 -0
- package/dist-electron/renderer/assets/{blockDiagram-DXYQGD6D-CZGyJqzN.js → blockDiagram-DXYQGD6D-NHzIf6KM.js} +6 -6
- package/dist-electron/renderer/assets/blockDiagram-DXYQGD6D-NHzIf6KM.js.gz +0 -0
- package/dist-electron/renderer/assets/{c4Diagram-AHTNJAMY-QR6T5UK-.js → c4Diagram-AHTNJAMY-C805hJap.js} +2 -2
- package/dist-electron/renderer/assets/c4Diagram-AHTNJAMY-C805hJap.js.gz +0 -0
- package/dist-electron/renderer/assets/{channel-Bqk4dDiH.js → channel-yHIQhPj2.js} +1 -1
- package/dist-electron/renderer/assets/{chunk-4BX2VUAB-Ql_0mvKl.js → chunk-4BX2VUAB-BW86W7DE.js} +1 -1
- package/dist-electron/renderer/assets/{chunk-4TB4RGXK-DcpxCTnt.js → chunk-4TB4RGXK-CiAgH5vp.js} +5 -5
- package/dist-electron/renderer/assets/chunk-4TB4RGXK-CiAgH5vp.js.gz +0 -0
- package/dist-electron/renderer/assets/{chunk-55IACEB6-5i5ku6Mp.js → chunk-55IACEB6-CLYAwM0u.js} +1 -1
- package/dist-electron/renderer/assets/{chunk-EDXVE4YY-DWU8RPW7.js → chunk-EDXVE4YY-SvJyEgqT.js} +1 -1
- package/dist-electron/renderer/assets/chunk-EDXVE4YY-SvJyEgqT.js.gz +0 -0
- package/dist-electron/renderer/assets/{chunk-FMBD7UC4-CGgyRi9w.js → chunk-FMBD7UC4-CTX3SpFe.js} +1 -1
- package/dist-electron/renderer/assets/{chunk-OYMX7WX6-DsuO_QrB.js → chunk-OYMX7WX6-yuicy5fD.js} +3 -3
- package/dist-electron/renderer/assets/chunk-OYMX7WX6-yuicy5fD.js.gz +0 -0
- package/dist-electron/renderer/assets/{chunk-QZHKN3VN-Bbii2TV9.js → chunk-QZHKN3VN-8uwLkZ2k.js} +1 -1
- package/dist-electron/renderer/assets/{chunk-YZCP3GAM-DBLeyzP3.js → chunk-YZCP3GAM-BOYtvFmP.js} +1 -1
- package/dist-electron/renderer/assets/chunk-YZCP3GAM-BOYtvFmP.js.gz +0 -0
- package/dist-electron/renderer/assets/{classDiagram-6PBFFD2Q-CTppFDM-.js → classDiagram-6PBFFD2Q-DdqJHrBR.js} +6 -6
- package/dist-electron/renderer/assets/{classDiagram-v2-HSJHXN6E-CTppFDM-.js → classDiagram-v2-HSJHXN6E-DdqJHrBR.js} +6 -6
- package/dist-electron/renderer/assets/{clone-DJcYmsl6.js → clone-CohPIibk.js} +1 -1
- package/dist-electron/renderer/assets/{cose-bilkent-S5V4N54A-lOBC_Swy.js → cose-bilkent-S5V4N54A-B1jjJbx2.js} +1 -1
- package/dist-electron/renderer/assets/cose-bilkent-S5V4N54A-B1jjJbx2.js.gz +0 -0
- package/dist-electron/renderer/assets/{dagre-KV5264BT-CFc-IlN0.js → dagre-KV5264BT-Cr1UGppV.js} +6 -6
- package/dist-electron/renderer/assets/dagre-KV5264BT-Cr1UGppV.js.gz +0 -0
- package/dist-electron/renderer/assets/{diagram-5BDNPKRD-CMjGq3Qd.js → diagram-5BDNPKRD-OQB6O17M.js} +6 -6
- package/dist-electron/renderer/assets/diagram-5BDNPKRD-OQB6O17M.js.gz +0 -0
- package/dist-electron/renderer/assets/{diagram-G4DWMVQ6-BZ_RCuPz.js → diagram-G4DWMVQ6-B992OGq3.js} +6 -6
- package/dist-electron/renderer/assets/diagram-G4DWMVQ6-B992OGq3.js.gz +0 -0
- package/dist-electron/renderer/assets/{diagram-MMDJMWI5-CAbPKB-M.js → diagram-MMDJMWI5-sfDZyGEc.js} +5 -5
- package/dist-electron/renderer/assets/diagram-MMDJMWI5-sfDZyGEc.js.gz +0 -0
- package/dist-electron/renderer/assets/{diagram-TYMM5635-CUDsp3Va.js → diagram-TYMM5635-SAOHwHvV.js} +5 -5
- package/dist-electron/renderer/assets/diagram-TYMM5635-SAOHwHvV.js.gz +0 -0
- package/dist-electron/renderer/assets/{erDiagram-SMLLAGMA-DoaAVQ3k.js → erDiagram-SMLLAGMA-B3lOLLG4.js} +4 -4
- package/dist-electron/renderer/assets/erDiagram-SMLLAGMA-B3lOLLG4.js.gz +0 -0
- package/dist-electron/renderer/assets/{flowDiagram-DWJPFMVM-BPPswghk.js → flowDiagram-DWJPFMVM-DM8NWY2I.js} +6 -6
- package/dist-electron/renderer/assets/flowDiagram-DWJPFMVM-DM8NWY2I.js.gz +0 -0
- package/dist-electron/renderer/assets/{ganttDiagram-T4ZO3ILL-D9dDRsnt.js → ganttDiagram-T4ZO3ILL-Ck9cM-4F.js} +2 -2
- package/dist-electron/renderer/assets/ganttDiagram-T4ZO3ILL-Ck9cM-4F.js.gz +0 -0
- package/dist-electron/renderer/assets/{gitGraphDiagram-UUTBAWPF-BqSxB4JC.js → gitGraphDiagram-UUTBAWPF-BbTlLKCx.js} +6 -6
- package/dist-electron/renderer/assets/gitGraphDiagram-UUTBAWPF-BbTlLKCx.js.gz +0 -0
- package/dist-electron/renderer/assets/{graph-Cdcjro9E.js → graph-SD4HIKJw.js} +2 -2
- package/dist-electron/renderer/assets/graph-SD4HIKJw.js.gz +0 -0
- package/dist-electron/renderer/assets/{index-DR-b90MW.js → index-CHaHfSLU.js} +3004 -1996
- package/dist-electron/renderer/assets/index-CHaHfSLU.js.gz +0 -0
- package/dist-electron/renderer/assets/{index-DIbFt7rO.css → index-CP1VBw7a.css} +1545 -1057
- package/dist-electron/renderer/assets/index-CP1VBw7a.css.gz +0 -0
- package/dist-electron/renderer/assets/{infoDiagram-42DDH7IO-BNgkgl2w.js → infoDiagram-42DDH7IO-DyxtiwFL.js} +4 -4
- package/dist-electron/renderer/assets/{ishikawaDiagram-UXIWVN3A-B2smtRtE.js → ishikawaDiagram-UXIWVN3A-BUrLWa0T.js} +1 -1
- package/dist-electron/renderer/assets/ishikawaDiagram-UXIWVN3A-BUrLWa0T.js.gz +0 -0
- package/dist-electron/renderer/assets/{journeyDiagram-VCZTEJTY-5i0hgzSw.js → journeyDiagram-VCZTEJTY-BMmtCdj3.js} +4 -4
- package/dist-electron/renderer/assets/journeyDiagram-VCZTEJTY-BMmtCdj3.js.gz +0 -0
- package/dist-electron/renderer/assets/{kanban-definition-6JOO6SKY-DZ82Qc3W.js → kanban-definition-6JOO6SKY-OQBC48Se.js} +2 -2
- package/dist-electron/renderer/assets/kanban-definition-6JOO6SKY-OQBC48Se.js.gz +0 -0
- package/dist-electron/renderer/assets/{layout-DCDaRhDD.js → layout-D2Rz390M.js} +4 -4
- package/dist-electron/renderer/assets/layout-D2Rz390M.js.gz +0 -0
- package/dist-electron/renderer/assets/{linear-BhTANRPL.js → linear-CQh0Mysb.js} +1 -1
- package/dist-electron/renderer/assets/linear-CQh0Mysb.js.gz +0 -0
- package/dist-electron/renderer/assets/{min-fI6oHIzD.js → min-DlS-oIeB.js} +2 -2
- package/dist-electron/renderer/assets/min-DlS-oIeB.js.gz +0 -0
- package/dist-electron/renderer/assets/{mindmap-definition-QFDTVHPH-CFwqVKXp.js → mindmap-definition-QFDTVHPH-aTTTq6Nc.js} +3 -3
- package/dist-electron/renderer/assets/mindmap-definition-QFDTVHPH-aTTTq6Nc.js.gz +0 -0
- package/dist-electron/renderer/assets/{pieDiagram-DEJITSTG-B9qNWsik.js → pieDiagram-DEJITSTG-n1e04sg0.js} +6 -6
- package/dist-electron/renderer/assets/pieDiagram-DEJITSTG-n1e04sg0.js.gz +0 -0
- package/dist-electron/renderer/assets/{quadrantDiagram-34T5L4WZ-BH52I9Mz.js → quadrantDiagram-34T5L4WZ-C-xW2Cqp.js} +2 -2
- package/dist-electron/renderer/assets/quadrantDiagram-34T5L4WZ-C-xW2Cqp.js.gz +0 -0
- package/dist-electron/renderer/assets/{requirementDiagram-MS252O5E-zdr-UweE.js → requirementDiagram-MS252O5E-pnNGwrTw.js} +3 -3
- package/dist-electron/renderer/assets/requirementDiagram-MS252O5E-pnNGwrTw.js.gz +0 -0
- package/dist-electron/renderer/assets/{sankeyDiagram-XADWPNL6-fOSi4otN.js → sankeyDiagram-XADWPNL6-CbT_Xb_y.js} +1 -1
- package/dist-electron/renderer/assets/{sankeyDiagram-XADWPNL6-fOSi4otN.js.gz → sankeyDiagram-XADWPNL6-CbT_Xb_y.js.gz} +0 -0
- package/dist-electron/renderer/assets/{sequenceDiagram-FGHM5R23-BD9MRuC5.js → sequenceDiagram-FGHM5R23-a-9UfTJq.js} +3 -3
- package/dist-electron/renderer/assets/sequenceDiagram-FGHM5R23-a-9UfTJq.js.gz +0 -0
- package/dist-electron/renderer/assets/{stateDiagram-FHFEXIEX-CMQH2Bdw.js → stateDiagram-FHFEXIEX-LL3JhZd4.js} +8 -8
- package/dist-electron/renderer/assets/stateDiagram-FHFEXIEX-LL3JhZd4.js.gz +0 -0
- package/dist-electron/renderer/assets/{stateDiagram-v2-QKLJ7IA2-B4Kz8yNI.js → stateDiagram-v2-QKLJ7IA2-BQfhbm-p.js} +4 -4
- package/dist-electron/renderer/assets/{timeline-definition-GMOUNBTQ-eOylFnoH.js → timeline-definition-GMOUNBTQ-DeBW6Or5.js} +2 -2
- package/dist-electron/renderer/assets/timeline-definition-GMOUNBTQ-DeBW6Or5.js.gz +0 -0
- package/dist-electron/renderer/assets/{vennDiagram-DHZGUBPP-CYDW0VBV.js → vennDiagram-DHZGUBPP-DEq9JF1i.js} +1 -1
- package/dist-electron/renderer/assets/vennDiagram-DHZGUBPP-DEq9JF1i.js.gz +0 -0
- package/dist-electron/renderer/assets/{wardley-RL74JXVD-CYRSMbSd.js → wardley-RL74JXVD-ChJWklYY.js} +3 -3
- package/dist-electron/renderer/assets/wardley-RL74JXVD-ChJWklYY.js.gz +0 -0
- package/dist-electron/renderer/assets/{wardleyDiagram-NUSXRM2D-jjE8DGWF.js → wardleyDiagram-NUSXRM2D-CIROAFHI.js} +5 -5
- package/dist-electron/renderer/assets/wardleyDiagram-NUSXRM2D-CIROAFHI.js.gz +0 -0
- package/dist-electron/renderer/assets/{xychartDiagram-5P7HB3ND-BJCCYED3.js → xychartDiagram-5P7HB3ND-BedH4Z65.js} +2 -2
- package/dist-electron/renderer/assets/xychartDiagram-5P7HB3ND-BedH4Z65.js.gz +0 -0
- package/dist-electron/renderer/index.html +2 -2
- package/package.json +1 -1
- package/dist-electron/renderer/assets/_baseUniq-wFb12gB-.js.gz +0 -0
- package/dist-electron/renderer/assets/arc-Bjp2aBSU.js.gz +0 -0
- package/dist-electron/renderer/assets/architectureDiagram-Q4EWVU46-AEAF6BMT.js.gz +0 -0
- package/dist-electron/renderer/assets/blockDiagram-DXYQGD6D-CZGyJqzN.js.gz +0 -0
- package/dist-electron/renderer/assets/c4Diagram-AHTNJAMY-QR6T5UK-.js.gz +0 -0
- package/dist-electron/renderer/assets/chunk-4TB4RGXK-DcpxCTnt.js.gz +0 -0
- package/dist-electron/renderer/assets/chunk-EDXVE4YY-DWU8RPW7.js.gz +0 -0
- package/dist-electron/renderer/assets/chunk-OYMX7WX6-DsuO_QrB.js.gz +0 -0
- package/dist-electron/renderer/assets/chunk-YZCP3GAM-DBLeyzP3.js.gz +0 -0
- package/dist-electron/renderer/assets/cose-bilkent-S5V4N54A-lOBC_Swy.js.gz +0 -0
- package/dist-electron/renderer/assets/dagre-KV5264BT-CFc-IlN0.js.gz +0 -0
- package/dist-electron/renderer/assets/diagram-5BDNPKRD-CMjGq3Qd.js.gz +0 -0
- package/dist-electron/renderer/assets/diagram-G4DWMVQ6-BZ_RCuPz.js.gz +0 -0
- package/dist-electron/renderer/assets/diagram-MMDJMWI5-CAbPKB-M.js.gz +0 -0
- package/dist-electron/renderer/assets/diagram-TYMM5635-CUDsp3Va.js.gz +0 -0
- package/dist-electron/renderer/assets/erDiagram-SMLLAGMA-DoaAVQ3k.js.gz +0 -0
- package/dist-electron/renderer/assets/flowDiagram-DWJPFMVM-BPPswghk.js.gz +0 -0
- package/dist-electron/renderer/assets/ganttDiagram-T4ZO3ILL-D9dDRsnt.js.gz +0 -0
- package/dist-electron/renderer/assets/gitGraphDiagram-UUTBAWPF-BqSxB4JC.js.gz +0 -0
- package/dist-electron/renderer/assets/graph-Cdcjro9E.js.gz +0 -0
- package/dist-electron/renderer/assets/index-DIbFt7rO.css.gz +0 -0
- package/dist-electron/renderer/assets/index-DR-b90MW.js.gz +0 -0
- package/dist-electron/renderer/assets/ishikawaDiagram-UXIWVN3A-B2smtRtE.js.gz +0 -0
- package/dist-electron/renderer/assets/journeyDiagram-VCZTEJTY-5i0hgzSw.js.gz +0 -0
- package/dist-electron/renderer/assets/kanban-definition-6JOO6SKY-DZ82Qc3W.js.gz +0 -0
- package/dist-electron/renderer/assets/layout-DCDaRhDD.js.gz +0 -0
- package/dist-electron/renderer/assets/linear-BhTANRPL.js.gz +0 -0
- package/dist-electron/renderer/assets/min-fI6oHIzD.js.gz +0 -0
- package/dist-electron/renderer/assets/mindmap-definition-QFDTVHPH-CFwqVKXp.js.gz +0 -0
- package/dist-electron/renderer/assets/pieDiagram-DEJITSTG-B9qNWsik.js.gz +0 -0
- package/dist-electron/renderer/assets/quadrantDiagram-34T5L4WZ-BH52I9Mz.js.gz +0 -0
- package/dist-electron/renderer/assets/requirementDiagram-MS252O5E-zdr-UweE.js.gz +0 -0
- package/dist-electron/renderer/assets/sequenceDiagram-FGHM5R23-BD9MRuC5.js.gz +0 -0
- package/dist-electron/renderer/assets/stateDiagram-FHFEXIEX-CMQH2Bdw.js.gz +0 -0
- package/dist-electron/renderer/assets/timeline-definition-GMOUNBTQ-eOylFnoH.js.gz +0 -0
- package/dist-electron/renderer/assets/vennDiagram-DHZGUBPP-CYDW0VBV.js.gz +0 -0
- package/dist-electron/renderer/assets/wardley-RL74JXVD-CYRSMbSd.js.gz +0 -0
- package/dist-electron/renderer/assets/wardleyDiagram-NUSXRM2D-jjE8DGWF.js.gz +0 -0
- package/dist-electron/renderer/assets/xychartDiagram-5P7HB3ND-BJCCYED3.js.gz +0 -0
package/dist-cli/kai-cli.js
CHANGED
|
@@ -34,7 +34,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
34
34
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
35
35
|
|
|
36
36
|
// src/shared/ipc-events.ts
|
|
37
|
-
var IPC_SEND_USER_MESSAGE, IPC_STOP_RUN, IPC_CREATE_NEW_SESSION, IPC_COMPACT_CONVERSATION, IPC_CANCEL_QUEUED_MESSAGES, IPC_REQUEST_CONVERSATION_SNAPSHOT, IPC_CONVERSATION_EVENT, IPC_GET_SETTINGS, IPC_SAVE_SETTINGS, IPC_FETCH_MODELS, IPC_GET_MCP_SERVERS, IPC_SAVE_MCP_SERVERS, IPC_TEST_MCP_SERVER, IPC_GET_SKILLS, IPC_GET_SKILL, IPC_TOGGLE_SKILL, IPC_CREATE_AGENT, IPC_GET_AGENT, IPC_GET_AGENT_CONFIG, IPC_LIST_AGENTS, IPC_UPDATE_AGENT, IPC_DELETE_AGENT, IPC_OPTIMIZE_AGENT_DESCRIPTION, IPC_GET_AGENT_CHANNELS, IPC_UPDATE_AGENT_CHANNELS, IPC_SWITCH_CHANNEL, IPC_CREATE_CONVERSATION, IPC_GET_CONVERSATION, IPC_LIST_CONVERSATIONS, IPC_GET_CONVERSATION_AGENTS, IPC_UPDATE_CONVERSATION, IPC_DELETE_CONVERSATION, IPC_CREATE_GROUP, IPC_GET_GROUP, IPC_UPDATE_GROUP, IPC_DELETE_GROUP, IPC_GET_GROUP_MEMBERS, IPC_GET_TEAM_MEMORY, IPC_SAVE_GROUP_FILE, IPC_GET_GROUP_SETTINGS, IPC_GET_GROUP_MEMORY, IPC_LIST_GROUP_THREADS, IPC_GET_GROUP_THREAD, IPC_CREATE_GROUP_THREAD, IPC_UPDATE_GROUP_THREAD, IPC_DELETE_GROUP_THREAD, IPC_ARCHIVE_GROUP_THREAD, IPC_GET_MESSAGES, IPC_GET_MESSAGE, IPC_CREATE_LLM_CHANNEL, IPC_GET_LLM_CHANNEL, IPC_LIST_LLM_CHANNELS, IPC_UPDATE_LLM_CHANNEL, IPC_DELETE_LLM_CHANNEL, IPC_SET_DEFAULT_LLM_CHANNEL, IPC_GET_WORKSPACE_FILE, IPC_UPDATE_WORKSPACE_FILE, IPC_LIST_WORKSPACE_FILES, IPC_OPEN_WORKSPACE_DIR, IPC_OPEN_CHAT_DATA_DIR, IPC_GET_SEARCH_ENGINES, IPC_ADD_CUSTOM_ENGINE, IPC_UPDATE_CUSTOM_ENGINE, IPC_DELETE_CUSTOM_ENGINE, IPC_SET_DEFAULT_ENGINE, IPC_CREATE_SCHEDULED_TASK, IPC_GET_SCHEDULED_TASK, IPC_LIST_SCHEDULED_TASKS, IPC_UPDATE_SCHEDULED_TASK, IPC_DELETE_SCHEDULED_TASK, IPC_TOGGLE_SCHEDULED_TASK, IPC_LIST_TASK_EXECUTIONS, IPC_TASK_EXECUTION_EVENT, IPC_TRIGGER_MEMORY_UPDATE, IPC_GET_NIGHTLY_MEMORY_CONFIG, IPC_UPDATE_NIGHTLY_MEMORY_CONFIG, IPC_RUN_NIGHTLY_MEMORY_NOW, IPC_LIST_NIGHTLY_MEMORY_EXECUTIONS, IPC_OPEN_EXTERNAL_URL, IPC_OPEN_LOCAL_PATH, IPC_READ_FILE_CONTENT, IPC_SHOW_LOCAL_ITEM_IN_FOLDER, IPC_UPLOAD_ATTACHMENT, IPC_OPEN_ATTACHMENT, IPC_MEMORY_UPDATE_PROGRESS, IPC_HEALTH_GET_ALL, IPC_HEALTH_GET, IPC_HEALTH_UPDATE, IPC_REMOTE_ACCESS_START, IPC_REMOTE_ACCESS_STOP, IPC_REMOTE_ACCESS_ROTATE, IPC_REMOTE_ACCESS_STATUS, IPC_GET_APP_INFO, IPC_GET_RELEASE_NOTES, IPC_UPDATE_CHECK, IPC_UPDATE_DOWNLOAD, IPC_UPDATE_INSTALL, IPC_UPDATE_STATUS, IPC_UPDATE_STATUS_EVENT, IPC_UPDATE_AVAILABLE_EVENT, IPC_UPDATE_ERROR_EVENT, IPC_GET_PINNED, IPC_TOGGLE_PIN, IPC_CHANNEL_LIST, IPC_CHANNEL_BIND, IPC_CHANNEL_UPDATE_TARGET, IPC_CHANNEL_UNBIND, IPC_CHANNEL_TEST, IPC_CHANNEL_RECONNECT, IPC_CHANNEL_STATUS, IPC_CHANNEL_QRCODE, IPC_CHANNEL_QRCODE_POLL, IPC_CHANNEL_WECHAT_PERSONAL_QRCODE, IPC_CHANNEL_WECHAT_PERSONAL_QRCODE_POLL, IPC_TELEMETRY_TRACK, IPC_TELEMETRY_FEEDBACK, IPC_TELEMETRY_SET_ENABLED, IPC_TELEMETRY_IS_ENABLED;
|
|
37
|
+
var IPC_SEND_USER_MESSAGE, IPC_STOP_RUN, IPC_CREATE_NEW_SESSION, IPC_COMPACT_CONVERSATION, IPC_CANCEL_QUEUED_MESSAGES, IPC_REQUEST_CONVERSATION_SNAPSHOT, IPC_CONVERSATION_EVENT, IPC_GET_SETTINGS, IPC_SAVE_SETTINGS, IPC_FETCH_MODELS, IPC_GET_MCP_SERVERS, IPC_SAVE_MCP_SERVERS, IPC_TEST_MCP_SERVER, IPC_GET_SKILLS, IPC_GET_SKILL, IPC_TOGGLE_SKILL, IPC_CREATE_AGENT, IPC_GET_AGENT, IPC_GET_AGENT_CONFIG, IPC_LIST_AGENTS, IPC_UPDATE_AGENT, IPC_DELETE_AGENT, IPC_SET_AGENT_AVATAR, IPC_REMOVE_AGENT_AVATAR, IPC_OPTIMIZE_AGENT_DESCRIPTION, IPC_GET_AGENT_CHANNELS, IPC_UPDATE_AGENT_CHANNELS, IPC_SWITCH_CHANNEL, IPC_CREATE_CONVERSATION, IPC_GET_CONVERSATION, IPC_LIST_CONVERSATIONS, IPC_GET_CONVERSATION_AGENTS, IPC_UPDATE_CONVERSATION, IPC_DELETE_CONVERSATION, IPC_CREATE_GROUP, IPC_GET_GROUP, IPC_UPDATE_GROUP, IPC_DELETE_GROUP, IPC_SET_GROUP_AVATAR, IPC_REMOVE_GROUP_AVATAR, IPC_GET_GROUP_MEMBERS, IPC_GET_TEAM_MEMORY, IPC_SAVE_GROUP_FILE, IPC_GET_GROUP_SETTINGS, IPC_GET_GROUP_MEMORY, IPC_LIST_GROUP_THREADS, IPC_GET_GROUP_THREAD, IPC_CREATE_GROUP_THREAD, IPC_UPDATE_GROUP_THREAD, IPC_DELETE_GROUP_THREAD, IPC_ARCHIVE_GROUP_THREAD, IPC_GET_MESSAGES, IPC_GET_MESSAGE, IPC_CREATE_LLM_CHANNEL, IPC_GET_LLM_CHANNEL, IPC_LIST_LLM_CHANNELS, IPC_UPDATE_LLM_CHANNEL, IPC_DELETE_LLM_CHANNEL, IPC_SET_DEFAULT_LLM_CHANNEL, IPC_GET_WORKSPACE_FILE, IPC_UPDATE_WORKSPACE_FILE, IPC_LIST_WORKSPACE_FILES, IPC_OPEN_WORKSPACE_DIR, IPC_OPEN_CHAT_DATA_DIR, IPC_GET_SEARCH_ENGINES, IPC_ADD_CUSTOM_ENGINE, IPC_UPDATE_CUSTOM_ENGINE, IPC_DELETE_CUSTOM_ENGINE, IPC_SET_DEFAULT_ENGINE, IPC_CREATE_SCHEDULED_TASK, IPC_GET_SCHEDULED_TASK, IPC_LIST_SCHEDULED_TASKS, IPC_UPDATE_SCHEDULED_TASK, IPC_DELETE_SCHEDULED_TASK, IPC_TOGGLE_SCHEDULED_TASK, IPC_LIST_TASK_EXECUTIONS, IPC_TASK_EXECUTION_EVENT, IPC_TRIGGER_MEMORY_UPDATE, IPC_GET_NIGHTLY_MEMORY_CONFIG, IPC_UPDATE_NIGHTLY_MEMORY_CONFIG, IPC_RUN_NIGHTLY_MEMORY_NOW, IPC_LIST_NIGHTLY_MEMORY_EXECUTIONS, IPC_OPEN_EXTERNAL_URL, IPC_OPEN_LOCAL_PATH, IPC_READ_FILE_CONTENT, IPC_SHOW_LOCAL_ITEM_IN_FOLDER, IPC_COPY_IMAGE_TO_CLIPBOARD, IPC_UPLOAD_ATTACHMENT, IPC_OPEN_ATTACHMENT, IPC_MEMORY_UPDATE_PROGRESS, IPC_HEALTH_GET_ALL, IPC_HEALTH_GET, IPC_HEALTH_UPDATE, IPC_REMOTE_ACCESS_START, IPC_REMOTE_ACCESS_STOP, IPC_REMOTE_ACCESS_ROTATE, IPC_REMOTE_ACCESS_STATUS, IPC_GET_APP_INFO, IPC_GET_RELEASE_NOTES, IPC_UPDATE_CHECK, IPC_UPDATE_DOWNLOAD, IPC_UPDATE_INSTALL, IPC_UPDATE_STATUS, IPC_UPDATE_STATUS_EVENT, IPC_UPDATE_AVAILABLE_EVENT, IPC_UPDATE_ERROR_EVENT, IPC_GET_PINNED, IPC_TOGGLE_PIN, IPC_CHANNEL_LIST, IPC_CHANNEL_BIND, IPC_CHANNEL_UPDATE_TARGET, IPC_CHANNEL_UNBIND, IPC_CHANNEL_TEST, IPC_CHANNEL_RECONNECT, IPC_CHANNEL_STATUS, IPC_CHANNEL_QRCODE, IPC_CHANNEL_QRCODE_POLL, IPC_CHANNEL_WECHAT_PERSONAL_QRCODE, IPC_CHANNEL_WECHAT_PERSONAL_QRCODE_POLL, IPC_TELEMETRY_TRACK, IPC_TELEMETRY_FEEDBACK, IPC_TELEMETRY_SET_ENABLED, IPC_TELEMETRY_IS_ENABLED;
|
|
38
38
|
var init_ipc_events = __esm({
|
|
39
39
|
"src/shared/ipc-events.ts"() {
|
|
40
40
|
"use strict";
|
|
@@ -60,6 +60,8 @@ var init_ipc_events = __esm({
|
|
|
60
60
|
IPC_LIST_AGENTS = "LIST_AGENTS";
|
|
61
61
|
IPC_UPDATE_AGENT = "UPDATE_AGENT";
|
|
62
62
|
IPC_DELETE_AGENT = "DELETE_AGENT";
|
|
63
|
+
IPC_SET_AGENT_AVATAR = "SET_AGENT_AVATAR";
|
|
64
|
+
IPC_REMOVE_AGENT_AVATAR = "REMOVE_AGENT_AVATAR";
|
|
63
65
|
IPC_OPTIMIZE_AGENT_DESCRIPTION = "OPTIMIZE_AGENT_DESCRIPTION";
|
|
64
66
|
IPC_GET_AGENT_CHANNELS = "GET_AGENT_CHANNELS";
|
|
65
67
|
IPC_UPDATE_AGENT_CHANNELS = "UPDATE_AGENT_CHANNELS";
|
|
@@ -74,6 +76,8 @@ var init_ipc_events = __esm({
|
|
|
74
76
|
IPC_GET_GROUP = "GET_GROUP";
|
|
75
77
|
IPC_UPDATE_GROUP = "UPDATE_GROUP";
|
|
76
78
|
IPC_DELETE_GROUP = "DELETE_GROUP";
|
|
79
|
+
IPC_SET_GROUP_AVATAR = "SET_GROUP_AVATAR";
|
|
80
|
+
IPC_REMOVE_GROUP_AVATAR = "REMOVE_GROUP_AVATAR";
|
|
77
81
|
IPC_GET_GROUP_MEMBERS = "GET_GROUP_MEMBERS";
|
|
78
82
|
IPC_GET_TEAM_MEMORY = "GET_TEAM_MEMORY";
|
|
79
83
|
IPC_SAVE_GROUP_FILE = "SAVE_GROUP_FILE";
|
|
@@ -120,6 +124,7 @@ var init_ipc_events = __esm({
|
|
|
120
124
|
IPC_OPEN_LOCAL_PATH = "OPEN_LOCAL_PATH";
|
|
121
125
|
IPC_READ_FILE_CONTENT = "READ_FILE_CONTENT";
|
|
122
126
|
IPC_SHOW_LOCAL_ITEM_IN_FOLDER = "SHOW_LOCAL_ITEM_IN_FOLDER";
|
|
127
|
+
IPC_COPY_IMAGE_TO_CLIPBOARD = "COPY_IMAGE_TO_CLIPBOARD";
|
|
123
128
|
IPC_UPLOAD_ATTACHMENT = "UPLOAD_ATTACHMENT";
|
|
124
129
|
IPC_OPEN_ATTACHMENT = "OPEN_ATTACHMENT";
|
|
125
130
|
IPC_MEMORY_UPDATE_PROGRESS = "MEMORY_UPDATE_PROGRESS";
|
|
@@ -219,7 +224,7 @@ var require_lodash = __commonJS({
|
|
|
219
224
|
var HOT_COUNT = 800, HOT_SPAN = 16;
|
|
220
225
|
var LAZY_FILTER_FLAG = 1, LAZY_MAP_FLAG = 2, LAZY_WHILE_FLAG = 3;
|
|
221
226
|
var INFINITY = 1 / 0, MAX_SAFE_INTEGER = 9007199254740991, MAX_INTEGER = 17976931348623157e292, NAN = 0 / 0;
|
|
222
|
-
var
|
|
227
|
+
var MAX_ARRAY_LENGTH2 = 4294967295, MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH2 - 1, HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH2 >>> 1;
|
|
223
228
|
var wrapFlags = [
|
|
224
229
|
["ary", WRAP_ARY_FLAG],
|
|
225
230
|
["bind", WRAP_BIND_FLAG],
|
|
@@ -1015,7 +1020,7 @@ var require_lodash = __commonJS({
|
|
|
1015
1020
|
this.__dir__ = 1;
|
|
1016
1021
|
this.__filtered__ = false;
|
|
1017
1022
|
this.__iteratees__ = [];
|
|
1018
|
-
this.__takeCount__ =
|
|
1023
|
+
this.__takeCount__ = MAX_ARRAY_LENGTH2;
|
|
1019
1024
|
this.__views__ = [];
|
|
1020
1025
|
}
|
|
1021
1026
|
function lazyClone() {
|
|
@@ -3518,7 +3523,7 @@ var require_lodash = __commonJS({
|
|
|
3518
3523
|
}
|
|
3519
3524
|
return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined2, comparator) : [];
|
|
3520
3525
|
});
|
|
3521
|
-
function
|
|
3526
|
+
function join21(array3, separator) {
|
|
3522
3527
|
return array3 == null ? "" : nativeJoin.call(array3, separator);
|
|
3523
3528
|
}
|
|
3524
3529
|
function last2(array3) {
|
|
@@ -4116,7 +4121,7 @@ var require_lodash = __commonJS({
|
|
|
4116
4121
|
var defer = baseRest(function(func, args2) {
|
|
4117
4122
|
return baseDelay(func, 1, args2);
|
|
4118
4123
|
});
|
|
4119
|
-
var
|
|
4124
|
+
var delay4 = baseRest(function(func, wait, args2) {
|
|
4120
4125
|
return baseDelay(func, toNumber(wait) || 0, args2);
|
|
4121
4126
|
});
|
|
4122
4127
|
function flip(func) {
|
|
@@ -4426,7 +4431,7 @@ var require_lodash = __commonJS({
|
|
|
4426
4431
|
return result2 === result2 ? remainder ? result2 - remainder : result2 : 0;
|
|
4427
4432
|
}
|
|
4428
4433
|
function toLength(value) {
|
|
4429
|
-
return value ? baseClamp(toInteger(value), 0,
|
|
4434
|
+
return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH2) : 0;
|
|
4430
4435
|
}
|
|
4431
4436
|
function toNumber(value) {
|
|
4432
4437
|
if (typeof value == "number") {
|
|
@@ -4831,7 +4836,7 @@ var require_lodash = __commonJS({
|
|
|
4831
4836
|
if (limit && typeof limit != "number" && isIterateeCall(string4, separator, limit)) {
|
|
4832
4837
|
separator = limit = undefined2;
|
|
4833
4838
|
}
|
|
4834
|
-
limit = limit === undefined2 ?
|
|
4839
|
+
limit = limit === undefined2 ? MAX_ARRAY_LENGTH2 : limit >>> 0;
|
|
4835
4840
|
if (!limit) {
|
|
4836
4841
|
return [];
|
|
4837
4842
|
}
|
|
@@ -4946,7 +4951,7 @@ var require_lodash = __commonJS({
|
|
|
4946
4951
|
var strSymbols = stringToArray(string4), start = charsStartIndex(strSymbols, stringToArray(chars));
|
|
4947
4952
|
return castSlice(strSymbols, start).join("");
|
|
4948
4953
|
}
|
|
4949
|
-
function
|
|
4954
|
+
function truncate2(string4, options2) {
|
|
4950
4955
|
var length = DEFAULT_TRUNC_LENGTH, omission = DEFAULT_TRUNC_OMISSION;
|
|
4951
4956
|
if (isObject2(options2)) {
|
|
4952
4957
|
var separator = "separator" in options2 ? options2.separator : separator;
|
|
@@ -5150,9 +5155,9 @@ var require_lodash = __commonJS({
|
|
|
5150
5155
|
if (n < 1 || n > MAX_SAFE_INTEGER) {
|
|
5151
5156
|
return [];
|
|
5152
5157
|
}
|
|
5153
|
-
var index2 =
|
|
5158
|
+
var index2 = MAX_ARRAY_LENGTH2, length = nativeMin(n, MAX_ARRAY_LENGTH2);
|
|
5154
5159
|
iteratee2 = getIteratee(iteratee2);
|
|
5155
|
-
n -=
|
|
5160
|
+
n -= MAX_ARRAY_LENGTH2;
|
|
5156
5161
|
var result2 = baseTimes(length, iteratee2);
|
|
5157
5162
|
while (++index2 < n) {
|
|
5158
5163
|
iteratee2(index2);
|
|
@@ -5235,7 +5240,7 @@ var require_lodash = __commonJS({
|
|
|
5235
5240
|
lodash.defaults = defaults2;
|
|
5236
5241
|
lodash.defaultsDeep = defaultsDeep;
|
|
5237
5242
|
lodash.defer = defer;
|
|
5238
|
-
lodash.delay =
|
|
5243
|
+
lodash.delay = delay4;
|
|
5239
5244
|
lodash.difference = difference;
|
|
5240
5245
|
lodash.differenceBy = differenceBy;
|
|
5241
5246
|
lodash.differenceWith = differenceWith;
|
|
@@ -5442,7 +5447,7 @@ var require_lodash = __commonJS({
|
|
|
5442
5447
|
lodash.isUndefined = isUndefined;
|
|
5443
5448
|
lodash.isWeakMap = isWeakMap;
|
|
5444
5449
|
lodash.isWeakSet = isWeakSet;
|
|
5445
|
-
lodash.join =
|
|
5450
|
+
lodash.join = join21;
|
|
5446
5451
|
lodash.kebabCase = kebabCase;
|
|
5447
5452
|
lodash.last = last2;
|
|
5448
5453
|
lodash.lastIndexOf = lastIndexOf;
|
|
@@ -5506,7 +5511,7 @@ var require_lodash = __commonJS({
|
|
|
5506
5511
|
lodash.trim = trim;
|
|
5507
5512
|
lodash.trimEnd = trimEnd;
|
|
5508
5513
|
lodash.trimStart = trimStart;
|
|
5509
|
-
lodash.truncate =
|
|
5514
|
+
lodash.truncate = truncate2;
|
|
5510
5515
|
lodash.unescape = unescape2;
|
|
5511
5516
|
lodash.uniqueId = uniqueId;
|
|
5512
5517
|
lodash.upperCase = upperCase;
|
|
@@ -5535,7 +5540,7 @@ var require_lodash = __commonJS({
|
|
|
5535
5540
|
result2.__takeCount__ = nativeMin(n, result2.__takeCount__);
|
|
5536
5541
|
} else {
|
|
5537
5542
|
result2.__views__.push({
|
|
5538
|
-
"size": nativeMin(n,
|
|
5543
|
+
"size": nativeMin(n, MAX_ARRAY_LENGTH2),
|
|
5539
5544
|
"type": methodName + (result2.__dir__ < 0 ? "Right" : "")
|
|
5540
5545
|
});
|
|
5541
5546
|
}
|
|
@@ -5610,7 +5615,7 @@ var require_lodash = __commonJS({
|
|
|
5610
5615
|
return this.reverse().takeWhile(predicate).reverse();
|
|
5611
5616
|
};
|
|
5612
5617
|
LazyWrapper.prototype.toArray = function() {
|
|
5613
|
-
return this.take(
|
|
5618
|
+
return this.take(MAX_ARRAY_LENGTH2);
|
|
5614
5619
|
};
|
|
5615
5620
|
baseForOwn(LazyWrapper.prototype, function(func, methodName) {
|
|
5616
5621
|
var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName), isTaker = /^(?:head|last)$/.test(methodName), lodashFunc = lodash[isTaker ? "take" + (methodName == "last" ? "Right" : "") : methodName], retUnwrapped = isTaker || /^find/.test(methodName);
|
|
@@ -31570,11 +31575,11 @@ var require_core = __commonJS({
|
|
|
31570
31575
|
Ajv2.ValidationError = validation_error_1.default;
|
|
31571
31576
|
Ajv2.MissingRefError = ref_error_1.default;
|
|
31572
31577
|
exports2.default = Ajv2;
|
|
31573
|
-
function checkOptions(checkOpts, options2, msg,
|
|
31578
|
+
function checkOptions(checkOpts, options2, msg, log23 = "error") {
|
|
31574
31579
|
for (const key in checkOpts) {
|
|
31575
31580
|
const opt = key;
|
|
31576
31581
|
if (opt in options2)
|
|
31577
|
-
this.logger[
|
|
31582
|
+
this.logger[log23](`${msg}: option ${key}. ${checkOpts[opt]}`);
|
|
31578
31583
|
}
|
|
31579
31584
|
}
|
|
31580
31585
|
function getSchEnv(keyRef) {
|
|
@@ -34881,15 +34886,15 @@ var require_windows = __commonJS({
|
|
|
34881
34886
|
}
|
|
34882
34887
|
return false;
|
|
34883
34888
|
}
|
|
34884
|
-
function checkStat(
|
|
34885
|
-
if (!
|
|
34889
|
+
function checkStat(stat5, path10, options2) {
|
|
34890
|
+
if (!stat5.isSymbolicLink() && !stat5.isFile()) {
|
|
34886
34891
|
return false;
|
|
34887
34892
|
}
|
|
34888
34893
|
return checkPathExt(path10, options2);
|
|
34889
34894
|
}
|
|
34890
34895
|
function isexe(path10, options2, cb) {
|
|
34891
|
-
fs6.stat(path10, function(er,
|
|
34892
|
-
cb(er, er ? false : checkStat(
|
|
34896
|
+
fs6.stat(path10, function(er, stat5) {
|
|
34897
|
+
cb(er, er ? false : checkStat(stat5, path10, options2));
|
|
34893
34898
|
});
|
|
34894
34899
|
}
|
|
34895
34900
|
function sync(path10, options2) {
|
|
@@ -34905,20 +34910,20 @@ var require_mode = __commonJS({
|
|
|
34905
34910
|
isexe.sync = sync;
|
|
34906
34911
|
var fs6 = require("fs");
|
|
34907
34912
|
function isexe(path10, options2, cb) {
|
|
34908
|
-
fs6.stat(path10, function(er,
|
|
34909
|
-
cb(er, er ? false : checkStat(
|
|
34913
|
+
fs6.stat(path10, function(er, stat5) {
|
|
34914
|
+
cb(er, er ? false : checkStat(stat5, options2));
|
|
34910
34915
|
});
|
|
34911
34916
|
}
|
|
34912
34917
|
function sync(path10, options2) {
|
|
34913
34918
|
return checkStat(fs6.statSync(path10), options2);
|
|
34914
34919
|
}
|
|
34915
|
-
function checkStat(
|
|
34916
|
-
return
|
|
34920
|
+
function checkStat(stat5, options2) {
|
|
34921
|
+
return stat5.isFile() && checkMode(stat5, options2);
|
|
34917
34922
|
}
|
|
34918
|
-
function checkMode(
|
|
34919
|
-
var mod =
|
|
34920
|
-
var uid =
|
|
34921
|
-
var gid =
|
|
34923
|
+
function checkMode(stat5, options2) {
|
|
34924
|
+
var mod = stat5.mode;
|
|
34925
|
+
var uid = stat5.uid;
|
|
34926
|
+
var gid = stat5.gid;
|
|
34922
34927
|
var myUid = options2.uid !== void 0 ? options2.uid : process.getuid && process.getuid();
|
|
34923
34928
|
var myGid = options2.gid !== void 0 ? options2.gid : process.getgid && process.getgid();
|
|
34924
34929
|
var u = parseInt("100", 8);
|
|
@@ -36735,13 +36740,13 @@ var init_streamableHttp = __esm({
|
|
|
36735
36740
|
this.onerror?.(new Error(`Maximum reconnection attempts (${maxRetries}) exceeded.`));
|
|
36736
36741
|
return;
|
|
36737
36742
|
}
|
|
36738
|
-
const
|
|
36743
|
+
const delay4 = this._getNextReconnectionDelay(attemptCount);
|
|
36739
36744
|
this._reconnectionTimeout = setTimeout(() => {
|
|
36740
36745
|
this._startOrAuthSse(options2).catch((error48) => {
|
|
36741
36746
|
this.onerror?.(new Error(`Failed to reconnect SSE stream: ${error48 instanceof Error ? error48.message : String(error48)}`));
|
|
36742
36747
|
this._scheduleReconnection(options2, attemptCount + 1);
|
|
36743
36748
|
});
|
|
36744
|
-
},
|
|
36749
|
+
}, delay4);
|
|
36745
36750
|
}
|
|
36746
36751
|
_handleSseStream(stream, options2, isReconnectable) {
|
|
36747
36752
|
if (!stream) {
|
|
@@ -40066,43 +40071,337 @@ var init_client3 = __esm({
|
|
|
40066
40071
|
}
|
|
40067
40072
|
});
|
|
40068
40073
|
|
|
40074
|
+
// src/shared/logging/structured-logger.ts
|
|
40075
|
+
function createStructuredLogger(options2) {
|
|
40076
|
+
return new DefaultStructuredLogger(
|
|
40077
|
+
normalizeScope(options2.scope),
|
|
40078
|
+
options2.context ?? {},
|
|
40079
|
+
options2.sinks ?? [new ConsoleLogSink()],
|
|
40080
|
+
options2.minLevel ?? resolveDefaultLevel()
|
|
40081
|
+
);
|
|
40082
|
+
}
|
|
40083
|
+
function normalizeLogError(error48) {
|
|
40084
|
+
if (error48 instanceof Error) {
|
|
40085
|
+
const code = typeof error48.code === "string" ? error48.code : void 0;
|
|
40086
|
+
return {
|
|
40087
|
+
name: error48.name,
|
|
40088
|
+
message: sanitizeErrorMessage(error48.message),
|
|
40089
|
+
...code ? { code } : {},
|
|
40090
|
+
...error48.stack ? { stack: sanitizeErrorStack(error48.stack) } : {},
|
|
40091
|
+
fingerprint: fingerprintError(error48.name, code, error48.message)
|
|
40092
|
+
};
|
|
40093
|
+
}
|
|
40094
|
+
if (typeof error48 === "object" && error48 !== null) {
|
|
40095
|
+
const obj = error48;
|
|
40096
|
+
const name21 = typeof obj.name === "string" ? obj.name : void 0;
|
|
40097
|
+
const code = typeof obj.code === "string" ? obj.code : void 0;
|
|
40098
|
+
const message2 = typeof obj.message === "string" ? obj.message : safeString(error48);
|
|
40099
|
+
const stack = typeof obj.stack === "string" ? sanitizeErrorStack(obj.stack) : void 0;
|
|
40100
|
+
return {
|
|
40101
|
+
...name21 ? { name: name21 } : {},
|
|
40102
|
+
...code ? { code } : {},
|
|
40103
|
+
message: sanitizeErrorMessage(message2),
|
|
40104
|
+
...stack ? { stack } : {},
|
|
40105
|
+
fingerprint: fingerprintError(name21, code, message2)
|
|
40106
|
+
};
|
|
40107
|
+
}
|
|
40108
|
+
const message = safeString(error48);
|
|
40109
|
+
return {
|
|
40110
|
+
message: sanitizeErrorMessage(message),
|
|
40111
|
+
fingerprint: fingerprintError(void 0, void 0, message)
|
|
40112
|
+
};
|
|
40113
|
+
}
|
|
40114
|
+
function writeLogEventToSinks(event, sinks2) {
|
|
40115
|
+
const safeEvent = sanitizeLogEvent(event);
|
|
40116
|
+
for (const sink of sinks2) {
|
|
40117
|
+
try {
|
|
40118
|
+
sink.write(safeEvent);
|
|
40119
|
+
} catch {
|
|
40120
|
+
}
|
|
40121
|
+
}
|
|
40122
|
+
}
|
|
40123
|
+
function sanitizeLogEvent(event) {
|
|
40124
|
+
const sanitized = {
|
|
40125
|
+
...event,
|
|
40126
|
+
scope: normalizeScope(event.scope),
|
|
40127
|
+
event: normalizeEventName(event.event)
|
|
40128
|
+
};
|
|
40129
|
+
if (event.message) sanitized.message = truncate(event.message, MAX_STRING_LENGTH);
|
|
40130
|
+
if (event.context) sanitized.context = sanitizeContext(event.context);
|
|
40131
|
+
if (event.data) sanitized.data = sanitizeValue(event.data, 0);
|
|
40132
|
+
if (event.error) sanitized.error = normalizeLogError(event.error);
|
|
40133
|
+
return sanitized;
|
|
40134
|
+
}
|
|
40135
|
+
function compactConsolePayload(event) {
|
|
40136
|
+
const payload = {};
|
|
40137
|
+
if (event.context) payload.context = event.context;
|
|
40138
|
+
if (event.message) payload.message = event.message;
|
|
40139
|
+
if (event.data) payload.data = event.data;
|
|
40140
|
+
if (event.error) payload.error = event.error;
|
|
40141
|
+
return payload;
|
|
40142
|
+
}
|
|
40143
|
+
function shouldLog(level, minLevel) {
|
|
40144
|
+
return levelRank(level) >= levelRank(minLevel);
|
|
40145
|
+
}
|
|
40146
|
+
function levelRank(level) {
|
|
40147
|
+
switch (level) {
|
|
40148
|
+
case "debug":
|
|
40149
|
+
return 10;
|
|
40150
|
+
case "info":
|
|
40151
|
+
return 20;
|
|
40152
|
+
case "warn":
|
|
40153
|
+
return 30;
|
|
40154
|
+
case "error":
|
|
40155
|
+
return 40;
|
|
40156
|
+
case "fatal":
|
|
40157
|
+
return 50;
|
|
40158
|
+
}
|
|
40159
|
+
}
|
|
40160
|
+
function resolveDefaultLevel() {
|
|
40161
|
+
return process.env.NODE_ENV === "development" || process.env.KAI_DEBUG ? "debug" : "info";
|
|
40162
|
+
}
|
|
40163
|
+
function sanitizeContext(context2) {
|
|
40164
|
+
const out = {};
|
|
40165
|
+
for (const [key, value] of Object.entries(context2)) {
|
|
40166
|
+
if (typeof value === "string" && value.trim()) out[key] = truncate(value, 200);
|
|
40167
|
+
}
|
|
40168
|
+
return out;
|
|
40169
|
+
}
|
|
40170
|
+
function sanitizeValue(value, depth) {
|
|
40171
|
+
if (depth > MAX_DEPTH) return "[MaxDepth]";
|
|
40172
|
+
if (value instanceof Error) return normalizeLogError(value);
|
|
40173
|
+
if (typeof value === "string") return redactString(truncate(value, MAX_STRING_LENGTH));
|
|
40174
|
+
if (typeof value === "number" || typeof value === "boolean" || value === null) return value;
|
|
40175
|
+
if (typeof value === "undefined") return void 0;
|
|
40176
|
+
if (typeof value === "bigint") return value.toString();
|
|
40177
|
+
if (typeof value === "function") return `[Function ${value.name || "anonymous"}]`;
|
|
40178
|
+
if (typeof value === "symbol") return String(value);
|
|
40179
|
+
if (Array.isArray(value)) {
|
|
40180
|
+
return value.slice(0, MAX_ARRAY_LENGTH).map((item) => sanitizeValue(item, depth + 1));
|
|
40181
|
+
}
|
|
40182
|
+
if (typeof value === "object") {
|
|
40183
|
+
const result = {};
|
|
40184
|
+
let count = 0;
|
|
40185
|
+
for (const [key, child] of Object.entries(value)) {
|
|
40186
|
+
if (count >= MAX_OBJECT_KEYS) {
|
|
40187
|
+
result.__truncatedKeys = true;
|
|
40188
|
+
break;
|
|
40189
|
+
}
|
|
40190
|
+
if (SENSITIVE_KEY_PATTERN.test(key)) {
|
|
40191
|
+
result[key] = "[REDACTED]";
|
|
40192
|
+
} else {
|
|
40193
|
+
const sanitized = sanitizeValue(child, depth + 1);
|
|
40194
|
+
if (sanitized !== void 0) result[key] = sanitized;
|
|
40195
|
+
}
|
|
40196
|
+
count++;
|
|
40197
|
+
}
|
|
40198
|
+
return result;
|
|
40199
|
+
}
|
|
40200
|
+
return redactString(truncate(String(value), MAX_STRING_LENGTH));
|
|
40201
|
+
}
|
|
40202
|
+
function safeString(value) {
|
|
40203
|
+
try {
|
|
40204
|
+
return typeof value === "string" ? value : JSON.stringify(sanitizeValue(value, 0));
|
|
40205
|
+
} catch {
|
|
40206
|
+
return String(value);
|
|
40207
|
+
}
|
|
40208
|
+
}
|
|
40209
|
+
function sanitizeErrorMessage(message) {
|
|
40210
|
+
return redactString(truncate(message, 500));
|
|
40211
|
+
}
|
|
40212
|
+
function sanitizeErrorStack(stack) {
|
|
40213
|
+
return redactString(truncate(stack, 4e3));
|
|
40214
|
+
}
|
|
40215
|
+
function redactString(value) {
|
|
40216
|
+
return value.replace(/(sk-[A-Za-z0-9_-]{12,})/g, "[REDACTED_API_KEY]").replace(/(Bearer\s+)[A-Za-z0-9._~+/=-]{12,}/gi, "$1[REDACTED]").replace(/(api[_-]?key\s*[:=]\s*)[^\s,;&]+/gi, "$1[REDACTED]").replace(/(token\s*[:=]\s*)[^\s,;&]+/gi, "$1[REDACTED]");
|
|
40217
|
+
}
|
|
40218
|
+
function truncate(value, max) {
|
|
40219
|
+
return value.length > max ? `${value.slice(0, max)}\u2026` : value;
|
|
40220
|
+
}
|
|
40221
|
+
function normalizeScope(scope) {
|
|
40222
|
+
return scope.trim().replace(/[^a-zA-Z0-9_.-]/g, ".").replace(/\.+/g, ".").slice(0, 120) || "app";
|
|
40223
|
+
}
|
|
40224
|
+
function normalizeEventName(event) {
|
|
40225
|
+
return event.trim().replace(/[^a-zA-Z0-9_.:-]/g, ".").replace(/\.+/g, ".").slice(0, 160) || "log.message";
|
|
40226
|
+
}
|
|
40227
|
+
function fingerprintError(name21, code, message) {
|
|
40228
|
+
const base = `${name21 ?? "Error"}:${code ?? "none"}:${message.slice(0, 160)}`;
|
|
40229
|
+
let hash2 = 0;
|
|
40230
|
+
for (let i = 0; i < base.length; i++) {
|
|
40231
|
+
hash2 = (hash2 << 5) - hash2 + base.charCodeAt(i) | 0;
|
|
40232
|
+
}
|
|
40233
|
+
return Math.abs(hash2).toString(36);
|
|
40234
|
+
}
|
|
40235
|
+
var SENSITIVE_KEY_PATTERN, MAX_STRING_LENGTH, MAX_ARRAY_LENGTH, MAX_OBJECT_KEYS, MAX_DEPTH, DefaultStructuredLogger, ConsoleLogSink;
|
|
40236
|
+
var init_structured_logger = __esm({
|
|
40237
|
+
"src/shared/logging/structured-logger.ts"() {
|
|
40238
|
+
"use strict";
|
|
40239
|
+
SENSITIVE_KEY_PATTERN = /(api[-_]?key|token|secret|password|authorization|cookie|set-cookie|access[-_]?token|refresh[-_]?token)/i;
|
|
40240
|
+
MAX_STRING_LENGTH = 2e3;
|
|
40241
|
+
MAX_ARRAY_LENGTH = 20;
|
|
40242
|
+
MAX_OBJECT_KEYS = 50;
|
|
40243
|
+
MAX_DEPTH = 4;
|
|
40244
|
+
DefaultStructuredLogger = class _DefaultStructuredLogger {
|
|
40245
|
+
constructor(scope, context2, sinks2, minLevel) {
|
|
40246
|
+
this.scope = scope;
|
|
40247
|
+
this.context = context2;
|
|
40248
|
+
this.sinks = sinks2;
|
|
40249
|
+
this.minLevel = minLevel;
|
|
40250
|
+
}
|
|
40251
|
+
scope;
|
|
40252
|
+
context;
|
|
40253
|
+
sinks;
|
|
40254
|
+
minLevel;
|
|
40255
|
+
child(context2) {
|
|
40256
|
+
const { scope, ...childContext } = context2;
|
|
40257
|
+
return new _DefaultStructuredLogger(
|
|
40258
|
+
scope ? normalizeScope(scope) : this.scope,
|
|
40259
|
+
{ ...this.context, ...childContext },
|
|
40260
|
+
this.sinks,
|
|
40261
|
+
this.minLevel
|
|
40262
|
+
);
|
|
40263
|
+
}
|
|
40264
|
+
debug(event, data2) {
|
|
40265
|
+
this.write("debug", event, data2);
|
|
40266
|
+
}
|
|
40267
|
+
info(event, data2) {
|
|
40268
|
+
this.write("info", event, data2);
|
|
40269
|
+
}
|
|
40270
|
+
warn(event, data2) {
|
|
40271
|
+
this.write("warn", event, data2);
|
|
40272
|
+
}
|
|
40273
|
+
error(event, data2) {
|
|
40274
|
+
this.write("error", event, data2);
|
|
40275
|
+
}
|
|
40276
|
+
fatal(event, data2) {
|
|
40277
|
+
this.write("fatal", event, data2);
|
|
40278
|
+
}
|
|
40279
|
+
write(level, event, data2) {
|
|
40280
|
+
if (!shouldLog(level, this.minLevel)) return;
|
|
40281
|
+
const { error: error48, ...rest } = data2 ?? {};
|
|
40282
|
+
const logEvent = {
|
|
40283
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
40284
|
+
level,
|
|
40285
|
+
event,
|
|
40286
|
+
scope: this.scope,
|
|
40287
|
+
...Object.keys(this.context).length > 0 ? { context: this.context } : {},
|
|
40288
|
+
...Object.keys(rest).length > 0 ? { data: rest } : {},
|
|
40289
|
+
...error48 !== void 0 ? { error: normalizeLogError(error48) } : {}
|
|
40290
|
+
};
|
|
40291
|
+
writeLogEventToSinks(logEvent, this.sinks);
|
|
40292
|
+
}
|
|
40293
|
+
};
|
|
40294
|
+
ConsoleLogSink = class {
|
|
40295
|
+
write(event) {
|
|
40296
|
+
const prefix = `[${event.scope}] ${event.event}`;
|
|
40297
|
+
const payload = compactConsolePayload(event);
|
|
40298
|
+
if (event.level === "error" || event.level === "fatal") {
|
|
40299
|
+
console.error(prefix, payload);
|
|
40300
|
+
} else if (event.level === "warn") {
|
|
40301
|
+
console.warn(prefix, payload);
|
|
40302
|
+
} else if (event.level === "info") {
|
|
40303
|
+
console.info(prefix, payload);
|
|
40304
|
+
} else {
|
|
40305
|
+
console.log(prefix, payload);
|
|
40306
|
+
}
|
|
40307
|
+
}
|
|
40308
|
+
};
|
|
40309
|
+
}
|
|
40310
|
+
});
|
|
40311
|
+
|
|
40312
|
+
// src/shared/logging/index.ts
|
|
40313
|
+
var init_logging = __esm({
|
|
40314
|
+
"src/shared/logging/index.ts"() {
|
|
40315
|
+
"use strict";
|
|
40316
|
+
init_structured_logger();
|
|
40317
|
+
}
|
|
40318
|
+
});
|
|
40319
|
+
|
|
40069
40320
|
// src/shared/utils/logger.ts
|
|
40070
40321
|
function createLogger(prefix) {
|
|
40322
|
+
const scope = legacyScope(prefix);
|
|
40323
|
+
const logger40 = createStructuredLogger({
|
|
40324
|
+
scope,
|
|
40325
|
+
sinks,
|
|
40326
|
+
minLevel: currentLevel <= LOG_LEVELS.noise ? "debug" : "info"
|
|
40327
|
+
});
|
|
40071
40328
|
return {
|
|
40072
40329
|
noise: (...args2) => {
|
|
40073
40330
|
if (currentLevel <= LOG_LEVELS.noise) {
|
|
40074
|
-
|
|
40331
|
+
writeLegacy(logger40, "debug", "legacy.noise", args2);
|
|
40075
40332
|
}
|
|
40076
40333
|
},
|
|
40077
40334
|
debug: (...args2) => {
|
|
40078
40335
|
if (currentLevel <= LOG_LEVELS.debug) {
|
|
40079
|
-
|
|
40336
|
+
writeLegacy(logger40, "debug", "legacy.debug", args2);
|
|
40080
40337
|
}
|
|
40081
40338
|
},
|
|
40082
40339
|
info: (...args2) => {
|
|
40083
|
-
|
|
40340
|
+
writeLegacy(logger40, "info", "legacy.info", args2);
|
|
40084
40341
|
},
|
|
40085
40342
|
warn: (...args2) => {
|
|
40086
|
-
|
|
40343
|
+
writeLegacy(logger40, "warn", "legacy.warn", args2);
|
|
40087
40344
|
},
|
|
40088
40345
|
error: (...args2) => {
|
|
40089
|
-
|
|
40346
|
+
writeLegacy(logger40, "error", "legacy.error", args2);
|
|
40090
40347
|
}
|
|
40091
40348
|
};
|
|
40092
40349
|
}
|
|
40093
|
-
|
|
40350
|
+
function writeLegacy(logger40, level, event, args2) {
|
|
40351
|
+
const { message, data: data2, error: error48 } = normalizeLegacyArgs(args2);
|
|
40352
|
+
const payload = {
|
|
40353
|
+
...message ? { message } : {},
|
|
40354
|
+
...data2.length > 0 ? { args: data2 } : {},
|
|
40355
|
+
...error48 ? { error: error48 } : {}
|
|
40356
|
+
};
|
|
40357
|
+
if (level === "debug") logger40.debug(event, payload);
|
|
40358
|
+
else if (level === "info") logger40.info(event, payload);
|
|
40359
|
+
else if (level === "warn") logger40.warn(event, payload);
|
|
40360
|
+
else if (level === "error") logger40.error(event, payload);
|
|
40361
|
+
else logger40.fatal(event, payload);
|
|
40362
|
+
}
|
|
40363
|
+
function normalizeLegacyArgs(args2) {
|
|
40364
|
+
const [first2, ...rest] = args2;
|
|
40365
|
+
const message = typeof first2 === "string" ? first2 : void 0;
|
|
40366
|
+
const values = message ? rest : args2;
|
|
40367
|
+
const errorIndex = values.findIndex((value) => value instanceof Error);
|
|
40368
|
+
const error48 = errorIndex >= 0 ? values[errorIndex] : void 0;
|
|
40369
|
+
const data2 = errorIndex >= 0 ? values.filter((_4, index2) => index2 !== errorIndex) : values;
|
|
40370
|
+
return { message, data: data2, error: error48 };
|
|
40371
|
+
}
|
|
40372
|
+
function createDefaultSinks() {
|
|
40373
|
+
const defaults2 = [new ConsoleLogSink()];
|
|
40374
|
+
return defaults2;
|
|
40375
|
+
}
|
|
40376
|
+
function resolveLegacyLogLevel() {
|
|
40377
|
+
const env2 = typeof process !== "undefined" ? process.env : void 0;
|
|
40378
|
+
return env2?.NODE_ENV === "development" || env2?.KAI_DEBUG ? LOG_LEVELS.noise : LOG_LEVELS.info;
|
|
40379
|
+
}
|
|
40380
|
+
function legacyScope(prefix) {
|
|
40381
|
+
return prefix.trim().replace(/([a-z0-9])([A-Z])/g, "$1.$2").replace(/[^a-zA-Z0-9_.-]/g, ".").replace(/\.+/g, ".").toLowerCase().slice(0, 120) || "legacy";
|
|
40382
|
+
}
|
|
40383
|
+
var LOG_LEVELS, currentLevel, globalLogState, sinks, structuredLogger, logger;
|
|
40094
40384
|
var init_logger = __esm({
|
|
40095
40385
|
"src/shared/utils/logger.ts"() {
|
|
40096
40386
|
"use strict";
|
|
40387
|
+
init_logging();
|
|
40097
40388
|
LOG_LEVELS = {
|
|
40098
40389
|
noise: 0,
|
|
40099
40390
|
debug: 1,
|
|
40100
|
-
info: 2
|
|
40101
|
-
|
|
40102
|
-
|
|
40103
|
-
|
|
40104
|
-
|
|
40105
|
-
|
|
40391
|
+
info: 2,
|
|
40392
|
+
warn: 3,
|
|
40393
|
+
error: 4,
|
|
40394
|
+
fatal: 5
|
|
40395
|
+
};
|
|
40396
|
+
currentLevel = resolveLegacyLogLevel();
|
|
40397
|
+
globalLogState = globalThis;
|
|
40398
|
+
sinks = globalLogState.__KAI_LOG_SINKS__ ?? createDefaultSinks();
|
|
40399
|
+
globalLogState.__KAI_LOG_SINKS__ = sinks;
|
|
40400
|
+
structuredLogger = createStructuredLogger({
|
|
40401
|
+
scope: "global",
|
|
40402
|
+
sinks,
|
|
40403
|
+
minLevel: currentLevel <= LOG_LEVELS.noise ? "debug" : "info"
|
|
40404
|
+
});
|
|
40106
40405
|
logger = createLogger("global");
|
|
40107
40406
|
}
|
|
40108
40407
|
});
|
|
@@ -56280,7 +56579,7 @@ var require_node = __commonJS({
|
|
|
56280
56579
|
var tty = require("tty");
|
|
56281
56580
|
var util2 = require("util");
|
|
56282
56581
|
exports2.init = init;
|
|
56283
|
-
exports2.log =
|
|
56582
|
+
exports2.log = log23;
|
|
56284
56583
|
exports2.formatArgs = formatArgs;
|
|
56285
56584
|
exports2.save = save;
|
|
56286
56585
|
exports2.load = load2;
|
|
@@ -56415,7 +56714,7 @@ var require_node = __commonJS({
|
|
|
56415
56714
|
}
|
|
56416
56715
|
return (/* @__PURE__ */ new Date()).toISOString() + " ";
|
|
56417
56716
|
}
|
|
56418
|
-
function
|
|
56717
|
+
function log23(...args2) {
|
|
56419
56718
|
return process.stderr.write(util2.formatWithOptions(exports2.inspectOpts, ...args2) + "\n");
|
|
56420
56719
|
}
|
|
56421
56720
|
function save(namespaces) {
|
|
@@ -72158,9 +72457,9 @@ var require_query_generator = __commonJS({
|
|
|
72158
72457
|
}
|
|
72159
72458
|
return `json_unquote(json_extract(${quotedColumn},${pathStr}))`;
|
|
72160
72459
|
case "postgres":
|
|
72161
|
-
const
|
|
72460
|
+
const join21 = isJson ? "#>" : "#>>";
|
|
72162
72461
|
pathStr = this.escape(`{${paths.join(",")}}`);
|
|
72163
|
-
return `(${quotedColumn}${
|
|
72462
|
+
return `(${quotedColumn}${join21}${pathStr})`;
|
|
72164
72463
|
default:
|
|
72165
72464
|
throw new Error(`Unsupported ${this.dialect} for JSON operations`);
|
|
72166
72465
|
}
|
|
@@ -72848,7 +73147,7 @@ https://github.com/sequelize/sequelize/discussions/15694`);
|
|
|
72848
73147
|
const isBelongsTo = topAssociation.associationType === "BelongsTo";
|
|
72849
73148
|
const sourceField = isBelongsTo ? topAssociation.identifierField : topAssociation.sourceKeyField || topParent.model.primaryKeyField;
|
|
72850
73149
|
const targetField = isBelongsTo ? topAssociation.sourceKeyField || topInclude.model.primaryKeyField : topAssociation.identifierField;
|
|
72851
|
-
const
|
|
73150
|
+
const join21 = [
|
|
72852
73151
|
`${this.quoteIdentifier(topInclude.as)}.${this.quoteIdentifier(targetField)}`,
|
|
72853
73152
|
`${this.quoteTable(topParent.as || topParent.model.name)}.${this.quoteIdentifier(sourceField)}`
|
|
72854
73153
|
].join(" = ");
|
|
@@ -72859,7 +73158,7 @@ https://github.com/sequelize/sequelize/discussions/15694`);
|
|
|
72859
73158
|
where: {
|
|
72860
73159
|
[Op2.and]: [
|
|
72861
73160
|
topInclude.where,
|
|
72862
|
-
{ [Op2.join]: this.sequelize.literal(
|
|
73161
|
+
{ [Op2.join]: this.sequelize.literal(join21) }
|
|
72863
73162
|
]
|
|
72864
73163
|
},
|
|
72865
73164
|
limit: 1,
|
|
@@ -95700,12 +95999,12 @@ var require_form_data = __commonJS({
|
|
|
95700
95999
|
if (value.end != void 0 && value.end != Infinity && value.start != void 0) {
|
|
95701
96000
|
callback(null, value.end + 1 - (value.start ? value.start : 0));
|
|
95702
96001
|
} else {
|
|
95703
|
-
fs6.stat(value.path, function(err,
|
|
96002
|
+
fs6.stat(value.path, function(err, stat5) {
|
|
95704
96003
|
if (err) {
|
|
95705
96004
|
callback(err);
|
|
95706
96005
|
return;
|
|
95707
96006
|
}
|
|
95708
|
-
var fileSize =
|
|
96007
|
+
var fileSize = stat5.size - (value.start ? value.start : 0);
|
|
95709
96008
|
callback(null, fileSize);
|
|
95710
96009
|
});
|
|
95711
96010
|
}
|
|
@@ -104289,15 +104588,15 @@ var require_index_cjs = __commonJS({
|
|
|
104289
104588
|
return;
|
|
104290
104589
|
}
|
|
104291
104590
|
this.authFailureAttempts++;
|
|
104292
|
-
const
|
|
104293
|
-
this.logger.info(`Auth failed, reconnecting in ${
|
|
104591
|
+
const delay4 = Math.min(this.reconnectBaseDelay * Math.pow(2, this.authFailureAttempts - 1), this.reconnectMaxDelay);
|
|
104592
|
+
this.logger.info(`Auth failed, reconnecting in ${delay4}ms (auth attempt ${this.authFailureAttempts}/${this.maxAuthFailureAttempts})...`);
|
|
104294
104593
|
this.onReconnecting?.(this.authFailureAttempts);
|
|
104295
104594
|
this.reconnectTimer = setTimeout(() => {
|
|
104296
104595
|
this.reconnectTimer = null;
|
|
104297
104596
|
if (this.isManualClose)
|
|
104298
104597
|
return;
|
|
104299
104598
|
this.connect();
|
|
104300
|
-
},
|
|
104599
|
+
}, delay4);
|
|
104301
104600
|
} else {
|
|
104302
104601
|
if (this.maxReconnectAttempts !== -1 && this.reconnectAttempts >= this.maxReconnectAttempts) {
|
|
104303
104602
|
this.logger.error(`Max reconnect attempts reached (${this.maxReconnectAttempts}), giving up`);
|
|
@@ -104305,15 +104604,15 @@ var require_index_cjs = __commonJS({
|
|
|
104305
104604
|
return;
|
|
104306
104605
|
}
|
|
104307
104606
|
this.reconnectAttempts++;
|
|
104308
|
-
const
|
|
104309
|
-
this.logger.info(`Connection lost, reconnecting in ${
|
|
104607
|
+
const delay4 = Math.min(this.reconnectBaseDelay * Math.pow(2, this.reconnectAttempts - 1), this.reconnectMaxDelay);
|
|
104608
|
+
this.logger.info(`Connection lost, reconnecting in ${delay4}ms (attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts})...`);
|
|
104310
104609
|
this.onReconnecting?.(this.reconnectAttempts);
|
|
104311
104610
|
this.reconnectTimer = setTimeout(() => {
|
|
104312
104611
|
this.reconnectTimer = null;
|
|
104313
104612
|
if (this.isManualClose)
|
|
104314
104613
|
return;
|
|
104315
104614
|
this.connect();
|
|
104316
|
-
},
|
|
104615
|
+
}, delay4);
|
|
104317
104616
|
}
|
|
104318
104617
|
}
|
|
104319
104618
|
/**
|
|
@@ -104900,9 +105199,9 @@ var require_index_cjs = __commonJS({
|
|
|
104900
105199
|
} catch (err) {
|
|
104901
105200
|
lastError = err;
|
|
104902
105201
|
if (attempt < MAX_CHUNK_RETRIES) {
|
|
104903
|
-
const
|
|
104904
|
-
this.logger.warn(`Chunk ${chunkIndex} upload failed (attempt ${attempt + 1}/${MAX_CHUNK_RETRIES + 1}), retrying in ${
|
|
104905
|
-
await new Promise((r) => setTimeout(r,
|
|
105202
|
+
const delay4 = 500 * (attempt + 1);
|
|
105203
|
+
this.logger.warn(`Chunk ${chunkIndex} upload failed (attempt ${attempt + 1}/${MAX_CHUNK_RETRIES + 1}), retrying in ${delay4}ms... error: ${err instanceof Error ? err.message : JSON.stringify(err)}`);
|
|
105204
|
+
await new Promise((r) => setTimeout(r, delay4));
|
|
104906
105205
|
}
|
|
104907
105206
|
}
|
|
104908
105207
|
}
|
|
@@ -106736,19 +107035,19 @@ var require_token_io = __commonJS({
|
|
|
106736
107035
|
getUserDataDir: () => getUserDataDir
|
|
106737
107036
|
});
|
|
106738
107037
|
module2.exports = __toCommonJS2(token_io_exports);
|
|
106739
|
-
var
|
|
107038
|
+
var import_path31 = __toESM2(require("path"));
|
|
106740
107039
|
var import_fs22 = __toESM2(require("fs"));
|
|
106741
107040
|
var import_os4 = __toESM2(require("os"));
|
|
106742
107041
|
var import_token_error = require_token_error();
|
|
106743
107042
|
function findRootDir() {
|
|
106744
107043
|
try {
|
|
106745
107044
|
let dir = process.cwd();
|
|
106746
|
-
while (dir !==
|
|
106747
|
-
const pkgPath =
|
|
107045
|
+
while (dir !== import_path31.default.dirname(dir)) {
|
|
107046
|
+
const pkgPath = import_path31.default.join(dir, ".vercel");
|
|
106748
107047
|
if (import_fs22.default.existsSync(pkgPath)) {
|
|
106749
107048
|
return dir;
|
|
106750
107049
|
}
|
|
106751
|
-
dir =
|
|
107050
|
+
dir = import_path31.default.dirname(dir);
|
|
106752
107051
|
}
|
|
106753
107052
|
} catch (e) {
|
|
106754
107053
|
throw new import_token_error.VercelOidcTokenError(
|
|
@@ -106763,9 +107062,9 @@ var require_token_io = __commonJS({
|
|
|
106763
107062
|
}
|
|
106764
107063
|
switch (import_os4.default.platform()) {
|
|
106765
107064
|
case "darwin":
|
|
106766
|
-
return
|
|
107065
|
+
return import_path31.default.join(import_os4.default.homedir(), "Library/Application Support");
|
|
106767
107066
|
case "linux":
|
|
106768
|
-
return
|
|
107067
|
+
return import_path31.default.join(import_os4.default.homedir(), ".local/share");
|
|
106769
107068
|
case "win32":
|
|
106770
107069
|
if (process.env.LOCALAPPDATA) {
|
|
106771
107070
|
return process.env.LOCALAPPDATA;
|
|
@@ -116300,12 +116599,12 @@ function simulateReadableStream({
|
|
|
116300
116599
|
_internal
|
|
116301
116600
|
}) {
|
|
116302
116601
|
var _a212;
|
|
116303
|
-
const
|
|
116602
|
+
const delay22 = (_a212 = _internal == null ? void 0 : _internal.delay) != null ? _a212 : delay;
|
|
116304
116603
|
let index2 = 0;
|
|
116305
116604
|
return new ReadableStream({
|
|
116306
116605
|
async pull(controller) {
|
|
116307
116606
|
if (index2 < chunks.length) {
|
|
116308
|
-
await
|
|
116607
|
+
await delay22(index2 === 0 ? initialDelayInMs : chunkDelayInMs);
|
|
116309
116608
|
controller.enqueue(chunks[index2++]);
|
|
116310
116609
|
} else {
|
|
116311
116610
|
controller.close();
|
|
@@ -116521,7 +116820,7 @@ function pruneMessages({
|
|
|
116521
116820
|
function smoothStream({
|
|
116522
116821
|
delayInMs = 10,
|
|
116523
116822
|
chunking = "word",
|
|
116524
|
-
_internal: { delay:
|
|
116823
|
+
_internal: { delay: delay22 = delay } = {}
|
|
116525
116824
|
} = {}) {
|
|
116526
116825
|
let detectChunk;
|
|
116527
116826
|
if (chunking != null && typeof chunking === "object" && "segment" in chunking && typeof chunking.segment === "function") {
|
|
@@ -116602,7 +116901,7 @@ function smoothStream({
|
|
|
116602
116901
|
while ((match = detectChunk(buffer)) != null) {
|
|
116603
116902
|
controller.enqueue({ type, text: match, id });
|
|
116604
116903
|
buffer = buffer.slice(match.length);
|
|
116605
|
-
await
|
|
116904
|
+
await delay22(delayInMs);
|
|
116606
116905
|
}
|
|
116607
116906
|
}
|
|
116608
116907
|
});
|
|
@@ -124030,7 +124329,7 @@ var init_message_summarizer = __esm({
|
|
|
124030
124329
|
SUMMARIZER_MAX_TOOL_RESULT_CHARS = 2e3;
|
|
124031
124330
|
SUMMARIZER_MAX_TOOL_CALL_ARGS_CHARS_WRITE = 1500;
|
|
124032
124331
|
SUMMARIZER_MAX_TOOL_CALL_ARGS_CHARS_DEFAULT = 500;
|
|
124033
|
-
WRITE_TOOL_NAMES = /* @__PURE__ */ new Set(["write", "edit", "createFile"]);
|
|
124332
|
+
WRITE_TOOL_NAMES = /* @__PURE__ */ new Set(["writeFile", "editFile", "write", "edit", "createFile"]);
|
|
124034
124333
|
SUMMARIZER_SYSTEM_PROMPT = [
|
|
124035
124334
|
"You are a continuation summarizer for an AI agent's working session.",
|
|
124036
124335
|
"Your summary will replace the original conversation history \u2014 the agent can only see your summary to continue the work.",
|
|
@@ -124575,8 +124874,8 @@ function getMaxImageDimension() {
|
|
|
124575
124874
|
return configured && configured > 0 ? configured : DEFAULT_MAX_IMAGE_DIMENSION;
|
|
124576
124875
|
}
|
|
124577
124876
|
async function resizeImageBuffer(buffer, maxDimension) {
|
|
124578
|
-
const
|
|
124579
|
-
const image =
|
|
124877
|
+
const sharp2 = (await import("sharp")).default;
|
|
124878
|
+
const image = sharp2(buffer);
|
|
124580
124879
|
const metadata = await image.metadata();
|
|
124581
124880
|
const width = metadata.width || 0;
|
|
124582
124881
|
const height = metadata.height || 0;
|
|
@@ -124589,7 +124888,7 @@ async function resizeImageBuffer(buffer, maxDimension) {
|
|
|
124589
124888
|
};
|
|
124590
124889
|
}
|
|
124591
124890
|
const resizedBuffer = await image.resize(maxDimension, maxDimension, { fit: "inside", withoutEnlargement: true }).toBuffer();
|
|
124592
|
-
const resizedMetadata = await
|
|
124891
|
+
const resizedMetadata = await sharp2(resizedBuffer).metadata();
|
|
124593
124892
|
return {
|
|
124594
124893
|
buffer: resizedBuffer,
|
|
124595
124894
|
mediaType: `image/${resizedMetadata.format || metadata.format || "png"}`,
|
|
@@ -124846,21 +125145,30 @@ var FILE_PATH_TOOLS;
|
|
|
124846
125145
|
var init_tool_args = __esm({
|
|
124847
125146
|
"src/core/tools/shared/tool-args.ts"() {
|
|
124848
125147
|
"use strict";
|
|
124849
|
-
FILE_PATH_TOOLS = /* @__PURE__ */ new Set(["read", "write", "edit", "patch"]);
|
|
125148
|
+
FILE_PATH_TOOLS = /* @__PURE__ */ new Set(["readFile", "writeFile", "editFile", "applyPatch", "read", "write", "edit", "patch"]);
|
|
124850
125149
|
}
|
|
124851
125150
|
});
|
|
124852
125151
|
|
|
124853
125152
|
// src/core/tools/shared/display.ts
|
|
124854
|
-
function
|
|
125153
|
+
function getWorkdirArg(args2) {
|
|
125154
|
+
if (!args2 || typeof args2 !== "object") return null;
|
|
125155
|
+
const workdir = args2.workdir;
|
|
125156
|
+
return typeof workdir === "string" && workdir.length > 0 ? workdir : null;
|
|
125157
|
+
}
|
|
125158
|
+
function resolveFilePath(filePath, scope) {
|
|
124855
125159
|
if ((0, import_path14.isAbsolute)(filePath)) return filePath;
|
|
124856
|
-
const baseDir = agentId ? getAgentWorkspaceDir(agentId) : process.cwd();
|
|
125160
|
+
const baseDir = scope?.groupId ? getGroupDir(scope.groupId) : scope?.agentId ? getAgentWorkspaceDir(scope.agentId) : process.cwd();
|
|
124857
125161
|
return (0, import_path14.resolve)(baseDir, filePath);
|
|
124858
125162
|
}
|
|
124859
|
-
function normalizeToolArgsForDisplay(toolName, args2, agentId) {
|
|
125163
|
+
function normalizeToolArgsForDisplay(toolName, args2, agentId, groupId) {
|
|
124860
125164
|
if (!isFilePathTool(toolName)) return args2;
|
|
124861
125165
|
const path10 = getToolPathArg(args2);
|
|
124862
125166
|
if (!path10) return args2;
|
|
124863
|
-
|
|
125167
|
+
const workdir = getWorkdirArg(args2);
|
|
125168
|
+
if (workdir) {
|
|
125169
|
+
return replaceToolPathArg(args2, (0, import_path14.isAbsolute)(path10) ? path10 : (0, import_path14.resolve)(workdir, path10));
|
|
125170
|
+
}
|
|
125171
|
+
return replaceToolPathArg(args2, resolveFilePath(path10, { agentId, groupId }));
|
|
124864
125172
|
}
|
|
124865
125173
|
var import_path14;
|
|
124866
125174
|
var init_display = __esm({
|
|
@@ -124868,6 +125176,7 @@ var init_display = __esm({
|
|
|
124868
125176
|
"use strict";
|
|
124869
125177
|
import_path14 = require("path");
|
|
124870
125178
|
init_workspace();
|
|
125179
|
+
init_group_file_store();
|
|
124871
125180
|
init_tool_args();
|
|
124872
125181
|
}
|
|
124873
125182
|
});
|
|
@@ -124948,7 +125257,7 @@ function buildSystemInfo(agentId) {
|
|
|
124948
125257
|
`- \u4E3B\u673A\u540D\uFF1A${(0, import_os2.hostname)()}`,
|
|
124949
125258
|
`- \u7528\u6237\u540D\uFF1A${(0, import_os2.userInfo)().username}`,
|
|
124950
125259
|
`- \u9ED8\u8BA4Shell\uFF1A${process.env.SHELL || "/bin/sh"}`,
|
|
124951
|
-
`- Agent\u5DE5\u4F5C\u76EE\u5F55\uFF1A${getAgentWorkspaceDir(agentId)}`,
|
|
125260
|
+
`- Agent\u9ED8\u8BA4\u5DE5\u4F5C\u76EE\u5F55\uFF1A${getAgentWorkspaceDir(agentId)}`,
|
|
124952
125261
|
`- \u9644\u4EF6\u76EE\u5F55\uFF1A${config.getAttachmentsPath()}`
|
|
124953
125262
|
];
|
|
124954
125263
|
return `${sysInfoLines.join("\n")}
|
|
@@ -125008,10 +125317,7 @@ var init_PromptBuilder = __esm({
|
|
|
125008
125317
|
if (workspaceContent) {
|
|
125009
125318
|
sections.push(workspaceContent);
|
|
125010
125319
|
}
|
|
125011
|
-
sections.push(
|
|
125012
|
-
buildSystemInfo(this.agent.id),
|
|
125013
|
-
SYSTEM_RUNTIME_INSTRUCTIONS
|
|
125014
|
-
);
|
|
125320
|
+
sections.push(buildSystemInfo(this.agent.id), SYSTEM_RUNTIME_INSTRUCTIONS);
|
|
125015
125321
|
if (this.additionalInstructions) {
|
|
125016
125322
|
sections.push(this.additionalInstructions);
|
|
125017
125323
|
}
|
|
@@ -125037,7 +125343,7 @@ function buildGroupWorkspaceInstructions(groupDir) {
|
|
|
125037
125343
|
- \`memory/YYYY-MM-DD.md\` \u2014 \u6BCF\u65E5\u8BA8\u8BBA\u8BB0\u5F55
|
|
125038
125344
|
- \`docs/\` \u2014 \u5171\u4EAB\u6587\u6863
|
|
125039
125345
|
|
|
125040
|
-
\u4F7F\u7528 \`
|
|
125346
|
+
\u4F7F\u7528 \`readFile\`\u3001\`writeFile\`\u3001\`editFile\`\u3001\`applyPatch\` \u67E5\u770B\u6216\u4FEE\u6539\u8FD9\u4E9B\u6587\u4EF6\u3002\u8C03\u7528\u65F6 \`workdir\` \u4F7F\u7528\u7FA4\u76EE\u5F55\uFF0C\`path\` \u4F7F\u7528\u76F8\u5BF9\u7FA4\u76EE\u5F55\u7684\u8DEF\u5F84\u3002
|
|
125041
125347
|
|
|
125042
125348
|
\u53D7\u4FDD\u62A4\u6587\u4EF6\uFF08\u7981\u6B62\u4FEE\u6539\uFF09\uFF1A
|
|
125043
125349
|
- \`GROUP_SETTINGS.md\`
|
|
@@ -125178,7 +125484,67 @@ var init_prompts = __esm({
|
|
|
125178
125484
|
}
|
|
125179
125485
|
});
|
|
125180
125486
|
|
|
125487
|
+
// src/shared/crash-breadcrumb-port.ts
|
|
125488
|
+
function recordAppCrashBreadcrumb(event, data2, level = "info") {
|
|
125489
|
+
try {
|
|
125490
|
+
recorder?.(event, data2, level);
|
|
125491
|
+
} catch {
|
|
125492
|
+
}
|
|
125493
|
+
}
|
|
125494
|
+
var recorder;
|
|
125495
|
+
var init_crash_breadcrumb_port = __esm({
|
|
125496
|
+
"src/shared/crash-breadcrumb-port.ts"() {
|
|
125497
|
+
"use strict";
|
|
125498
|
+
}
|
|
125499
|
+
});
|
|
125500
|
+
|
|
125181
125501
|
// src/core/agent/kernel/AgentExecutor.ts
|
|
125502
|
+
function isGlm51Thinking(ctx) {
|
|
125503
|
+
return ctx.model.toLowerCase().includes("glm-5.1") && Boolean(ctx.reasoningEffort && ctx.reasoningEffort !== "off");
|
|
125504
|
+
}
|
|
125505
|
+
function buildLlmRequestSettings(ctx) {
|
|
125506
|
+
const omitSampling = isGlm51Thinking(ctx);
|
|
125507
|
+
return {
|
|
125508
|
+
temperature: omitSampling ? void 0 : ctx.temperature,
|
|
125509
|
+
topP: omitSampling ? void 0 : ctx.topP,
|
|
125510
|
+
maxOutputTokens: resolveMaxOutputTokens(
|
|
125511
|
+
ctx.maxTokens,
|
|
125512
|
+
modelCapability.getMaxOutputTokens(ctx.model)
|
|
125513
|
+
),
|
|
125514
|
+
providerOptions: buildProviderOptions(ctx.apiType, ctx.reasoningEffort),
|
|
125515
|
+
filtered: {
|
|
125516
|
+
temperature: omitSampling && ctx.temperature !== void 0,
|
|
125517
|
+
topP: omitSampling && ctx.topP !== void 0,
|
|
125518
|
+
reasoningMetadata: omitSampling
|
|
125519
|
+
}
|
|
125520
|
+
};
|
|
125521
|
+
}
|
|
125522
|
+
function stripUnsupportedReasoningMetadataForModel(messages, ctx) {
|
|
125523
|
+
if (!isGlm51Thinking(ctx)) return messages;
|
|
125524
|
+
let changed = false;
|
|
125525
|
+
const sanitized = messages.map((message) => {
|
|
125526
|
+
if (!Array.isArray(message.content)) return message;
|
|
125527
|
+
let contentChanged = false;
|
|
125528
|
+
const content = message.content.map((part) => {
|
|
125529
|
+
if (part.type !== "reasoning") return part;
|
|
125530
|
+
const record2 = part;
|
|
125531
|
+
if (!("providerOptions" in record2) && !("providerMetadata" in record2) && !("experimental_providerMetadata" in record2)) {
|
|
125532
|
+
return part;
|
|
125533
|
+
}
|
|
125534
|
+
const {
|
|
125535
|
+
providerOptions: _providerOptions,
|
|
125536
|
+
providerMetadata: _providerMetadata,
|
|
125537
|
+
experimental_providerMetadata: _experimentalProviderMetadata,
|
|
125538
|
+
...rest
|
|
125539
|
+
} = record2;
|
|
125540
|
+
contentChanged = true;
|
|
125541
|
+
changed = true;
|
|
125542
|
+
return rest;
|
|
125543
|
+
});
|
|
125544
|
+
return contentChanged ? { ...message, content } : message;
|
|
125545
|
+
});
|
|
125546
|
+
return changed ? sanitized : messages;
|
|
125547
|
+
}
|
|
125182
125548
|
function buildProviderOptions(apiType, reasoningEffort) {
|
|
125183
125549
|
if (!reasoningEffort || reasoningEffort === "off") return void 0;
|
|
125184
125550
|
const budgetMap = {
|
|
@@ -125232,7 +125598,18 @@ function isReasoningOnlyAssistantMessage(message) {
|
|
|
125232
125598
|
}
|
|
125233
125599
|
return hasReasoning;
|
|
125234
125600
|
}
|
|
125235
|
-
|
|
125601
|
+
function getMissingToolFields(toolName, parsed) {
|
|
125602
|
+
const policy = TOOL_REPAIR_POLICIES[toolName];
|
|
125603
|
+
if (!policy || !parsed || typeof parsed !== "object") return [];
|
|
125604
|
+
const args2 = parsed;
|
|
125605
|
+
return policy.fields.filter((field) => {
|
|
125606
|
+
if (toolName === "applyPatch" && field === "patch") {
|
|
125607
|
+
return (typeof args2.patch !== "string" || args2.patch.length === 0) && (typeof args2.input !== "string" || args2.input.length === 0);
|
|
125608
|
+
}
|
|
125609
|
+
return typeof args2[field] !== "string" || args2[field].length === 0;
|
|
125610
|
+
});
|
|
125611
|
+
}
|
|
125612
|
+
var logger17, FallbackExhaustedError, TOOL_REPAIR_POLICIES, AgentExecutor, StreamContentState, TextStreamState, ReasoningStreamState;
|
|
125236
125613
|
var init_AgentExecutor = __esm({
|
|
125237
125614
|
"src/core/agent/kernel/AgentExecutor.ts"() {
|
|
125238
125615
|
"use strict";
|
|
@@ -125251,6 +125628,7 @@ var init_AgentExecutor = __esm({
|
|
|
125251
125628
|
init_execution();
|
|
125252
125629
|
init_execution_deps();
|
|
125253
125630
|
init_prompts();
|
|
125631
|
+
init_crash_breadcrumb_port();
|
|
125254
125632
|
logger17 = createLogger("AgentExecutor");
|
|
125255
125633
|
FallbackExhaustedError = class extends Error {
|
|
125256
125634
|
constructor(attempts) {
|
|
@@ -125262,6 +125640,24 @@ var init_AgentExecutor = __esm({
|
|
|
125262
125640
|
}
|
|
125263
125641
|
attempts;
|
|
125264
125642
|
};
|
|
125643
|
+
TOOL_REPAIR_POLICIES = {
|
|
125644
|
+
readFile: {
|
|
125645
|
+
fields: ["workdir", "path"],
|
|
125646
|
+
guidance: '\u8BF7\u91CD\u65B0\u8C03\u7528\u5DE5\u5177\uFF0C\u52A1\u5FC5\u5148\u8F93\u51FA "workdir" \u5B57\u6BB5\uFF0C\u518D\u8F93\u51FA "path" \u5B57\u6BB5\u3002'
|
|
125647
|
+
},
|
|
125648
|
+
writeFile: {
|
|
125649
|
+
fields: ["workdir", "path", "content"],
|
|
125650
|
+
guidance: '\u8BF7\u91CD\u65B0\u8C03\u7528\u5DE5\u5177\uFF0C\u52A1\u5FC5\u5148\u8F93\u51FA "workdir" \u5B57\u6BB5\uFF0C\u518D\u8F93\u51FA "path" \u5B57\u6BB5\uFF0C\u6700\u540E\u8F93\u51FA "content" \u5927\u6587\u672C\u5B57\u6BB5\u3002'
|
|
125651
|
+
},
|
|
125652
|
+
editFile: {
|
|
125653
|
+
fields: ["workdir", "path", "oldString", "newString"],
|
|
125654
|
+
guidance: '\u8BF7\u91CD\u65B0\u8C03\u7528\u5DE5\u5177\uFF0C\u52A1\u5FC5\u5148\u8F93\u51FA "workdir" \u5B57\u6BB5\uFF0C\u518D\u8F93\u51FA "path" \u5B57\u6BB5\uFF0C\u6700\u540E\u8F93\u51FA "oldString"/"newString" \u5927\u6587\u672C\u5B57\u6BB5\u3002'
|
|
125655
|
+
},
|
|
125656
|
+
applyPatch: {
|
|
125657
|
+
fields: ["workdir", "patch"],
|
|
125658
|
+
guidance: '\u8BF7\u91CD\u65B0\u8C03\u7528\u5DE5\u5177\uFF0C\u52A1\u5FC5\u5148\u8F93\u51FA "workdir" \u5B57\u6BB5\uFF0C\u6700\u540E\u8F93\u51FA "patch" \u5927\u6587\u672C\u5B57\u6BB5\u3002'
|
|
125659
|
+
}
|
|
125660
|
+
};
|
|
125265
125661
|
AgentExecutor = class _AgentExecutor {
|
|
125266
125662
|
streamCallback;
|
|
125267
125663
|
lastCompactedMessages = [];
|
|
@@ -125283,6 +125679,7 @@ var init_AgentExecutor = __esm({
|
|
|
125283
125679
|
tools;
|
|
125284
125680
|
deps;
|
|
125285
125681
|
runtime;
|
|
125682
|
+
groupId;
|
|
125286
125683
|
customStopWhen;
|
|
125287
125684
|
_ctx;
|
|
125288
125685
|
/** 上下文压缩重试计数(独立于瞬时错误重试) */
|
|
@@ -125302,6 +125699,7 @@ var init_AgentExecutor = __esm({
|
|
|
125302
125699
|
this.tools = options2.tools;
|
|
125303
125700
|
this.deps = resolveAgentExecutionDeps(options2.deps);
|
|
125304
125701
|
this.runtime = options2.runtime ?? createExecutionRuntime();
|
|
125702
|
+
this.groupId = options2.groupId;
|
|
125305
125703
|
this.contextId = options2.contextId;
|
|
125306
125704
|
this.saveContext = options2.saveContext;
|
|
125307
125705
|
this.saveSeq = options2.saveSeqMessages;
|
|
@@ -125505,6 +125903,15 @@ var init_AgentExecutor = __esm({
|
|
|
125505
125903
|
`Fallback: ${ctx.channelId}:${ctx.model} \u2192 ${targetChannel.id}:${fallbackModel}`
|
|
125506
125904
|
);
|
|
125507
125905
|
messages = this.getMessagesForRetry(messages);
|
|
125906
|
+
this.runInfoCallback?.({
|
|
125907
|
+
model: fallbackModel,
|
|
125908
|
+
fallback: true,
|
|
125909
|
+
fallbackTransition: {
|
|
125910
|
+
fromModel: ctx.model,
|
|
125911
|
+
toModel: fallbackModel,
|
|
125912
|
+
reason: this.classifyFallbackReason(error48)
|
|
125913
|
+
}
|
|
125914
|
+
});
|
|
125508
125915
|
this.switchContext(targetChannel, fallbackModel);
|
|
125509
125916
|
this.contextWindowOverride = void 0;
|
|
125510
125917
|
this.compressionRetryCount = 0;
|
|
@@ -125560,6 +125967,19 @@ var init_AgentExecutor = __esm({
|
|
|
125560
125967
|
if (/terminated/.test(msg)) return true;
|
|
125561
125968
|
return false;
|
|
125562
125969
|
}
|
|
125970
|
+
/**
|
|
125971
|
+
* 前端只需要稳定、可翻译的原因枚举;原始 provider 错误留在日志里。
|
|
125972
|
+
*/
|
|
125973
|
+
classifyFallbackReason(error48) {
|
|
125974
|
+
const msg = error48 instanceof Error ? error48.message?.toLowerCase() ?? "" : String(error48).toLowerCase();
|
|
125975
|
+
if (/\b(rate\s*limit|too\s+many\s+requests|429)\b/.test(msg)) return "rate_limit";
|
|
125976
|
+
if (/\b(timeout|timed\s*out|etimedout|deadline)\b/.test(msg)) return "timeout";
|
|
125977
|
+
if (/context|token|maximum|too\s+long|length/.test(msg)) return "context_overflow";
|
|
125978
|
+
if (/api|provider|server|5\d\d|overloaded|unavailable|connection|econnreset|terminated/.test(msg)) {
|
|
125979
|
+
return "api_error";
|
|
125980
|
+
}
|
|
125981
|
+
return "unknown";
|
|
125982
|
+
}
|
|
125563
125983
|
/**
|
|
125564
125984
|
* 查找下一个可用的 fallback 条目
|
|
125565
125985
|
* 排除:已尝试的、锁定的
|
|
@@ -125589,6 +126009,7 @@ var init_AgentExecutor = __esm({
|
|
|
125589
126009
|
let latency = 0;
|
|
125590
126010
|
this.runInfoCallback?.({ model: ctx.model, fallback: this.triedKeys.size > 0 });
|
|
125591
126011
|
messages = this.projectMessagesForProvider(messages, ctx.apiType);
|
|
126012
|
+
messages = stripUnsupportedReasoningMetadataForModel(messages, ctx);
|
|
125592
126013
|
messages = await multimodalTransformer.transform(messages, ctx.model);
|
|
125593
126014
|
const model = this.deps.languageModelFactory.createLanguageModel(
|
|
125594
126015
|
{
|
|
@@ -125605,6 +126026,25 @@ var init_AgentExecutor = __esm({
|
|
|
125605
126026
|
if (!lastStep) return true;
|
|
125606
126027
|
return (lastStep.toolCalls || []).length === 0;
|
|
125607
126028
|
};
|
|
126029
|
+
const requestSettings = buildLlmRequestSettings(ctx);
|
|
126030
|
+
const streamId = genId(ID_TYPE.MSG);
|
|
126031
|
+
const breadcrumbBase = {
|
|
126032
|
+
streamId,
|
|
126033
|
+
contextId: this.contextId,
|
|
126034
|
+
threadId: this.groupId ? this.contextId : void 0,
|
|
126035
|
+
agentId: ctx.agentId,
|
|
126036
|
+
channelId: ctx.channelId,
|
|
126037
|
+
provider: ctx.apiType,
|
|
126038
|
+
model: ctx.model,
|
|
126039
|
+
groupId: this.groupId
|
|
126040
|
+
};
|
|
126041
|
+
recordAppCrashBreadcrumb("llm.stream.start", {
|
|
126042
|
+
...breadcrumbBase,
|
|
126043
|
+
messageCount: messages.length,
|
|
126044
|
+
hasTools: Object.keys(this.tools).length > 0,
|
|
126045
|
+
reasoningEffort: ctx.reasoningEffort,
|
|
126046
|
+
filtered: requestSettings.filtered
|
|
126047
|
+
});
|
|
125608
126048
|
const agent = new ToolLoopAgent({
|
|
125609
126049
|
...this.settings,
|
|
125610
126050
|
model,
|
|
@@ -125613,15 +126053,16 @@ var init_AgentExecutor = __esm({
|
|
|
125613
126053
|
try {
|
|
125614
126054
|
const repaired = jsonrepair(toolCall.input);
|
|
125615
126055
|
const parsed = JSON.parse(repaired);
|
|
125616
|
-
|
|
125617
|
-
|
|
126056
|
+
const missingFields = getMissingToolFields(toolCall.toolName, parsed);
|
|
126057
|
+
if (missingFields.length > 0) {
|
|
126058
|
+
const policy = TOOL_REPAIR_POLICIES[toolCall.toolName];
|
|
126059
|
+
throw new Error(`\u7F3A\u5C11 ${missingFields.join("/")} \u5B57\u6BB5\u3002${policy.guidance}`);
|
|
125618
126060
|
}
|
|
125619
126061
|
return { ...toolCall, input: repaired };
|
|
125620
126062
|
} catch (err) {
|
|
125621
|
-
|
|
125622
|
-
|
|
125623
|
-
|
|
125624
|
-
);
|
|
126063
|
+
const policy = TOOL_REPAIR_POLICIES[toolCall.toolName];
|
|
126064
|
+
if (policy) {
|
|
126065
|
+
throw new Error(`JSON \u89E3\u6790\u5931\u8D25\u3002${policy.guidance}`);
|
|
125625
126066
|
}
|
|
125626
126067
|
throw new Error(`${toolCall.toolName}:\u53C2\u6570\u89E3\u6790\u51FA\u9519\uFF0C\u8BF7\u7B80\u5316\u8F93\u51FA\u6216\u4F7F\u7528\u5176\u4ED6\u5DE5\u5177\u518D\u8BD5`);
|
|
125627
126068
|
}
|
|
@@ -125630,13 +126071,10 @@ var init_AgentExecutor = __esm({
|
|
|
125630
126071
|
},
|
|
125631
126072
|
stopWhen: this.customStopWhen || defaultStopWhen,
|
|
125632
126073
|
tools: this.tools,
|
|
125633
|
-
temperature:
|
|
125634
|
-
topP:
|
|
125635
|
-
maxOutputTokens:
|
|
125636
|
-
|
|
125637
|
-
modelCapability.getMaxOutputTokens(ctx.model)
|
|
125638
|
-
),
|
|
125639
|
-
providerOptions: buildProviderOptions(ctx.apiType, ctx.reasoningEffort)
|
|
126074
|
+
temperature: requestSettings.temperature,
|
|
126075
|
+
topP: requestSettings.topP,
|
|
126076
|
+
maxOutputTokens: requestSettings.maxOutputTokens,
|
|
126077
|
+
providerOptions: requestSettings.providerOptions
|
|
125640
126078
|
});
|
|
125641
126079
|
try {
|
|
125642
126080
|
const result = await agent.stream({
|
|
@@ -125647,6 +126085,12 @@ var init_AgentExecutor = __esm({
|
|
|
125647
126085
|
const steps = await result.steps;
|
|
125648
126086
|
const response = await result.response;
|
|
125649
126087
|
const responseUsage = await result.totalUsage;
|
|
126088
|
+
recordAppCrashBreadcrumb("llm.stream.end", {
|
|
126089
|
+
...breadcrumbBase,
|
|
126090
|
+
latencyMs: Date.now() - startTime,
|
|
126091
|
+
stepCount: steps.length,
|
|
126092
|
+
usage: responseUsage
|
|
126093
|
+
});
|
|
125650
126094
|
const allMessages = this.lastCompactedMessages;
|
|
125651
126095
|
logger17.debug(
|
|
125652
126096
|
`executeInternal: lastCompactedMessages=${this.lastCompactedMessages.length}, response.messages=${response.messages.length}, allMessages=${allMessages.length}`
|
|
@@ -125675,6 +126119,11 @@ var init_AgentExecutor = __esm({
|
|
|
125675
126119
|
steps
|
|
125676
126120
|
};
|
|
125677
126121
|
} catch (error48) {
|
|
126122
|
+
recordAppCrashBreadcrumb("llm.stream.error", {
|
|
126123
|
+
...breadcrumbBase,
|
|
126124
|
+
latencyMs: Date.now() - startTime,
|
|
126125
|
+
error: error48
|
|
126126
|
+
}, "error");
|
|
125678
126127
|
if (error48 instanceof DOMException && error48.name === "AbortError" || abortSignal?.aborted) {
|
|
125679
126128
|
throw error48;
|
|
125680
126129
|
}
|
|
@@ -125993,7 +126442,7 @@ var init_AgentExecutor = __esm({
|
|
|
125993
126442
|
toolCall: {
|
|
125994
126443
|
id: chunk.toolCallId,
|
|
125995
126444
|
name: chunk.toolName,
|
|
125996
|
-
args: normalizeToolArgsForDisplay(chunk.toolName, chunk.input ?? {}, this.agent.id),
|
|
126445
|
+
args: normalizeToolArgsForDisplay(chunk.toolName, chunk.input ?? {}, this.agent.id, this.groupId),
|
|
125997
126446
|
status: "pending",
|
|
125998
126447
|
startedAt: meta3?.startedAt ?? Date.now()
|
|
125999
126448
|
}
|
|
@@ -126031,7 +126480,8 @@ var init_AgentExecutor = __esm({
|
|
|
126031
126480
|
args: normalizeToolArgsForDisplay(
|
|
126032
126481
|
chunk.toolName,
|
|
126033
126482
|
chunk.input ?? void 0,
|
|
126034
|
-
this.agent.id
|
|
126483
|
+
this.agent.id,
|
|
126484
|
+
this.groupId
|
|
126035
126485
|
),
|
|
126036
126486
|
status: "success",
|
|
126037
126487
|
result: (() => {
|
|
@@ -126069,7 +126519,8 @@ var init_AgentExecutor = __esm({
|
|
|
126069
126519
|
args: normalizeToolArgsForDisplay(
|
|
126070
126520
|
chunk.toolName,
|
|
126071
126521
|
chunk.input ?? void 0,
|
|
126072
|
-
this.agent.id
|
|
126522
|
+
this.agent.id,
|
|
126523
|
+
this.groupId
|
|
126073
126524
|
),
|
|
126074
126525
|
status: "error",
|
|
126075
126526
|
error: String(chunk.error),
|
|
@@ -130193,7 +130644,9 @@ function mergeUsage(...usages) {
|
|
|
130193
130644
|
return {
|
|
130194
130645
|
inputTokens: validUsages.reduce((sum, u) => sum + (u.inputTokens || 0), 0),
|
|
130195
130646
|
outputTokens: validUsages.reduce((sum, u) => sum + (u.outputTokens || 0), 0),
|
|
130196
|
-
totalTokens: validUsages.reduce((sum, u) => sum + (u.totalTokens || 0), 0)
|
|
130647
|
+
totalTokens: validUsages.reduce((sum, u) => sum + (u.totalTokens || 0), 0),
|
|
130648
|
+
cachedInputTokens: validUsages.reduce((sum, u) => sum + (u.cachedInputTokens || 0), 0),
|
|
130649
|
+
reasoningTokens: validUsages.reduce((sum, u) => sum + (u.reasoningTokens || 0), 0)
|
|
130197
130650
|
};
|
|
130198
130651
|
}
|
|
130199
130652
|
var init_message = __esm({
|
|
@@ -130585,6 +131038,9 @@ var init_PlanCoordinator = __esm({
|
|
|
130585
131038
|
const result = await this.deps.taskOrchestrator.runPlanStepInternal(abortSignal, retryTodoIds);
|
|
130586
131039
|
return this.buildCheckpoint(plan, result, checkpointIndex);
|
|
130587
131040
|
}
|
|
131041
|
+
buildProgressSnapshot() {
|
|
131042
|
+
return this.buildTodoProgress(this.requirePlan().todos);
|
|
131043
|
+
}
|
|
130588
131044
|
buildCheckpoint(plan, step, checkpointIndex) {
|
|
130589
131045
|
const todoProgress = this.buildTodoProgress(plan.todos);
|
|
130590
131046
|
const failure = this.findFailure(step.results, plan.todos);
|
|
@@ -130969,7 +131425,8 @@ var init_TaskOrchestrator = __esm({
|
|
|
130969
131425
|
tools: allTools,
|
|
130970
131426
|
stopWhen: createTaskStopWhen(),
|
|
130971
131427
|
deps: this.agentDeps,
|
|
130972
|
-
runtime
|
|
131428
|
+
runtime,
|
|
131429
|
+
groupId: this.deps.thread.groupId
|
|
130973
131430
|
});
|
|
130974
131431
|
return [taskExecutor, input];
|
|
130975
131432
|
}
|
|
@@ -131132,7 +131589,9 @@ var init_TaskOrchestrator = __esm({
|
|
|
131132
131589
|
};
|
|
131133
131590
|
},
|
|
131134
131591
|
broadcast: async (options2) => {
|
|
131135
|
-
return this.executeBroadcast(options2.question, options2.targetAgentIds, abortSignal
|
|
131592
|
+
return this.executeBroadcast(options2.question, options2.targetAgentIds, abortSignal, {
|
|
131593
|
+
contextMessages: this.deps.getInheritedMessages()
|
|
131594
|
+
});
|
|
131136
131595
|
},
|
|
131137
131596
|
listTasks: async () => {
|
|
131138
131597
|
return {
|
|
@@ -131328,12 +131787,13 @@ var init_TaskOrchestrator = __esm({
|
|
|
131328
131787
|
*
|
|
131329
131788
|
* @returns 各 Agent 的回答内容(供调用方 — 通常是 LLM — 汇总使用)
|
|
131330
131789
|
*/
|
|
131331
|
-
async executeBroadcast(question, targetAgentIds, abortSignal) {
|
|
131790
|
+
async executeBroadcast(question, targetAgentIds, abortSignal, options2 = {}) {
|
|
131332
131791
|
const uniqueTargetAgentIds = Array.from(new Set(targetAgentIds));
|
|
131333
131792
|
const { pass, reason } = this.deps.context.canBroadcast(uniqueTargetAgentIds.length);
|
|
131334
131793
|
if (!pass) {
|
|
131335
131794
|
return {
|
|
131336
|
-
responses: [{ agentId: "", agentName: "", content: `\u5E7F\u64AD\u5931\u8D25\uFF1A${reason}
|
|
131795
|
+
responses: [{ agentId: "", agentName: "", content: `\u5E7F\u64AD\u5931\u8D25\uFF1A${reason}`, status: "failed", error: reason }],
|
|
131796
|
+
error: reason
|
|
131337
131797
|
};
|
|
131338
131798
|
}
|
|
131339
131799
|
const broadcastId = genId(ID_TYPE.BROADCAST);
|
|
@@ -131344,6 +131804,17 @@ var init_TaskOrchestrator = __esm({
|
|
|
131344
131804
|
const agent = await this.deps.thread.getGroup().findMember(agentId);
|
|
131345
131805
|
if (!agent) {
|
|
131346
131806
|
invalidIds.push(agentId);
|
|
131807
|
+
responses.push({
|
|
131808
|
+
agentId,
|
|
131809
|
+
agentName: agentId,
|
|
131810
|
+
status: "failed",
|
|
131811
|
+
blocks: [{
|
|
131812
|
+
type: "text",
|
|
131813
|
+
text: "\u76EE\u6807\u6210\u5458\u4E0D\u5B58\u5728\uFF0C\u5DF2\u8DF3\u8FC7\u8BE5\u76EE\u6807\uFF0C\u8BF7\u4ECE\u76EE\u6807\u5217\u8868\u4E2D\u79FB\u9664\u65E0\u6548 agentId \u540E\u518D\u8BD5\u3002",
|
|
131814
|
+
id: `broadcast-error-${agentId}`
|
|
131815
|
+
}],
|
|
131816
|
+
error: `Agent ${agentId} \u4E0D\u5728\u5F53\u524D\u7FA4\u804A\u6210\u5458\u4E2D\u3002\u5F53\u524D\u6210\u5458 ID\uFF1A${memberIds.join(", ")}\u3002`
|
|
131817
|
+
});
|
|
131347
131818
|
continue;
|
|
131348
131819
|
}
|
|
131349
131820
|
responses.push({
|
|
@@ -131354,15 +131825,6 @@ var init_TaskOrchestrator = __esm({
|
|
|
131354
131825
|
blocks: []
|
|
131355
131826
|
});
|
|
131356
131827
|
}
|
|
131357
|
-
if (invalidIds.length > 0) {
|
|
131358
|
-
return {
|
|
131359
|
-
responses: [{
|
|
131360
|
-
agentId: "",
|
|
131361
|
-
agentName: "",
|
|
131362
|
-
content: `\u5E7F\u64AD\u5931\u8D25\uFF1AAgent ${invalidIds.join(", ")} \u4E0D\u5728\u5F53\u524D\u7FA4\u804A\u6210\u5458\u4E2D\u3002\u5F53\u524D\u6210\u5458 ID\uFF1A${memberIds.join(", ")}\u3002\u8BF7\u68C0\u67E5 agentId \u662F\u5426\u6B63\u786E\u3002`
|
|
131363
|
-
}]
|
|
131364
|
-
};
|
|
131365
|
-
}
|
|
131366
131828
|
const emitBroadcastBlock = (status) => {
|
|
131367
131829
|
this.deps.onStream({
|
|
131368
131830
|
type: "broadcast",
|
|
@@ -131377,11 +131839,13 @@ var init_TaskOrchestrator = __esm({
|
|
|
131377
131839
|
});
|
|
131378
131840
|
};
|
|
131379
131841
|
emitBroadcastBlock("pending");
|
|
131380
|
-
const validResponses = new Map(
|
|
131842
|
+
const validResponses = new Map(
|
|
131843
|
+
responses.filter((response) => response.status !== "failed").map((response) => [response.agentId, response])
|
|
131844
|
+
);
|
|
131381
131845
|
const executors = uniqueTargetAgentIds.map(async (agentId) => {
|
|
131382
131846
|
const response = validResponses.get(agentId);
|
|
131383
131847
|
if (!response) {
|
|
131384
|
-
return { agentId, agentName: "", content: "\
|
|
131848
|
+
return { agentId, agentName: "", content: "\u76EE\u6807\u6210\u5458\u4E0D\u5B58\u5728\uFF0C\u5DF2\u8DF3\u8FC7\u8BE5\u76EE\u6807\u3002", status: "failed", error: "Agent \u4E0D\u5728\u5F53\u524D\u7FA4\u804A\u6210\u5458\u4E2D" };
|
|
131385
131849
|
}
|
|
131386
131850
|
response.status = "thinking";
|
|
131387
131851
|
emitBroadcastBlock("running");
|
|
@@ -131391,7 +131855,7 @@ var init_TaskOrchestrator = __esm({
|
|
|
131391
131855
|
response.status = "failed";
|
|
131392
131856
|
response.blocks = [{ type: "text", text: `Agent ${agentId} \u4E0D\u5728\u5F53\u524D\u7FA4\u804A\u6210\u5458\u4E2D`, id: `broadcast-error-${agentId}` }];
|
|
131393
131857
|
emitBroadcastBlock("running");
|
|
131394
|
-
return { agentId, agentName: response.agentName, content: "\u6267\u884C\u5931\u8D25\uFF1AAgent \u4E0D\u5728\u7FA4\u804A\u6210\u5458\u4E2D" };
|
|
131858
|
+
return { agentId, agentName: response.agentName, content: "\u6267\u884C\u5931\u8D25\uFF1AAgent \u4E0D\u5728\u5F53\u524D\u7FA4\u804A\u6210\u5458\u4E2D", status: "failed", error: "Agent \u4E0D\u5728\u5F53\u524D\u7FA4\u804A\u6210\u5458\u4E2D" };
|
|
131395
131859
|
}
|
|
131396
131860
|
const agentConfig = await agent.getConfig();
|
|
131397
131861
|
const runtime = this.deps.getRuntime?.() ?? createExecutionRuntime();
|
|
@@ -131405,11 +131869,12 @@ var init_TaskOrchestrator = __esm({
|
|
|
131405
131869
|
runtime
|
|
131406
131870
|
);
|
|
131407
131871
|
const skills = await this.deps.getSkills(agent);
|
|
131872
|
+
const contextMessages = this.deps.removeSystem(options2.contextMessages ?? []);
|
|
131408
131873
|
const broadcastPrompt = [
|
|
131409
131874
|
`\u4F60\u662F @${agent.name}\u3002${agent.description || ""}`,
|
|
131410
131875
|
"",
|
|
131411
131876
|
`# \u5E7F\u64AD\u95EE\u9898`,
|
|
131412
|
-
`\u4EE5\u4E0B\u662F\u6765\u81EA\u56E2\u961F\u7684\u5E7F\u64AD\u95EE\u9898\
|
|
131877
|
+
`\u4EE5\u4E0B\u662F\u6765\u81EA\u56E2\u961F\u7684\u5E7F\u64AD\u95EE\u9898\u3002\u8BF7\u5148\u7406\u89E3\u4E0A\u9762\u7684\u5F53\u524D\u8BA8\u8BBA\u4E0A\u4E0B\u6587\uFF0C\u518D\u57FA\u4E8E\u4F60\u7684\u4E13\u4E1A\u89D2\u8272\u548C\u89C6\u89D2\u72EC\u7ACB\u56DE\u7B54\u3002`,
|
|
131413
131878
|
"",
|
|
131414
131879
|
`## \u95EE\u9898`,
|
|
131415
131880
|
question
|
|
@@ -131424,6 +131889,7 @@ var init_TaskOrchestrator = __esm({
|
|
|
131424
131889
|
mode: "broadcast"
|
|
131425
131890
|
})
|
|
131426
131891
|
},
|
|
131892
|
+
...contextMessages,
|
|
131427
131893
|
{
|
|
131428
131894
|
role: "user",
|
|
131429
131895
|
content: broadcastPrompt
|
|
@@ -131439,7 +131905,8 @@ var init_TaskOrchestrator = __esm({
|
|
|
131439
131905
|
tools,
|
|
131440
131906
|
stopWhen: createTaskStopWhen(),
|
|
131441
131907
|
deps: this.agentDeps,
|
|
131442
|
-
runtime
|
|
131908
|
+
runtime,
|
|
131909
|
+
groupId: this.deps.thread.groupId
|
|
131443
131910
|
});
|
|
131444
131911
|
executor.onStream((block) => {
|
|
131445
131912
|
const existingIdx = response.blocks.findIndex(
|
|
@@ -131464,23 +131931,29 @@ var init_TaskOrchestrator = __esm({
|
|
|
131464
131931
|
(msg) => msg.role === "assistant"
|
|
131465
131932
|
);
|
|
131466
131933
|
const content = extractAssistantText(lastAssistant?.content) || "\uFF08\u65E0\u6587\u672C\u56DE\u590D\uFF09";
|
|
131467
|
-
return { agentId, agentName: agent.name, content };
|
|
131934
|
+
return { agentId, agentName: agent.name, content, status: "done" };
|
|
131468
131935
|
} catch (err) {
|
|
131469
131936
|
response.status = "failed";
|
|
131937
|
+
const errorText = `\u6267\u884C\u5931\u8D25\uFF1A${err instanceof Error ? err.message : String(err)}`;
|
|
131470
131938
|
response.blocks = [
|
|
131471
131939
|
{
|
|
131472
131940
|
type: "text",
|
|
131473
|
-
text:
|
|
131941
|
+
text: errorText,
|
|
131474
131942
|
id: `broadcast-error-${agentId}`
|
|
131475
131943
|
}
|
|
131476
131944
|
];
|
|
131945
|
+
response.error = errorText;
|
|
131477
131946
|
emitBroadcastBlock("running");
|
|
131478
|
-
return { agentId, agentName: response.agentName, content: "\u6267\u884C\u5931\u8D25" };
|
|
131947
|
+
return { agentId, agentName: response.agentName, content: "\u6267\u884C\u5931\u8D25", status: "failed", error: errorText };
|
|
131479
131948
|
}
|
|
131480
131949
|
});
|
|
131481
131950
|
const results = await Promise.all(executors);
|
|
131482
131951
|
emitBroadcastBlock("done");
|
|
131483
|
-
|
|
131952
|
+
const failedCount = results.filter((result) => result.status === "failed").length;
|
|
131953
|
+
return {
|
|
131954
|
+
responses: results,
|
|
131955
|
+
...failedCount === results.length && results.length > 0 ? { error: "\u5E7F\u64AD\u5168\u90E8\u5931\u8D25" } : {}
|
|
131956
|
+
};
|
|
131484
131957
|
}
|
|
131485
131958
|
};
|
|
131486
131959
|
}
|
|
@@ -131936,7 +132409,8 @@ var init_SwarmExecutor = __esm({
|
|
|
131936
132409
|
const { responses } = await this.taskOrchestrator.executeBroadcast(
|
|
131937
132410
|
question,
|
|
131938
132411
|
targetIds,
|
|
131939
|
-
abortSignal
|
|
132412
|
+
abortSignal,
|
|
132413
|
+
{ contextMessages: resultMessages }
|
|
131940
132414
|
);
|
|
131941
132415
|
const broadcastResultMessage = {
|
|
131942
132416
|
role: "assistant",
|
|
@@ -132170,7 +132644,8 @@ var init_SwarmExecutor = __esm({
|
|
|
132170
132644
|
tools: { ...tools, ...swarmTools },
|
|
132171
132645
|
stopWhen: createSwarmStopWhen(),
|
|
132172
132646
|
deps: this.agentDeps,
|
|
132173
|
-
runtime
|
|
132647
|
+
runtime,
|
|
132648
|
+
groupId: this.thread.groupId
|
|
132174
132649
|
});
|
|
132175
132650
|
if (options2?.suppressStream) {
|
|
132176
132651
|
executor.onStream((block) => options2?.onBlock?.(block));
|
|
@@ -132207,10 +132682,8 @@ var init_SwarmExecutor = __esm({
|
|
|
132207
132682
|
* 监督者模式执行流程
|
|
132208
132683
|
*
|
|
132209
132684
|
* 1. 阶段 1: Planning — supervisor 调用 plan 工具制定计划(不执行任务)
|
|
132210
|
-
* 2. 阶段 2
|
|
132211
|
-
*
|
|
132212
|
-
* - supervisor 执行任务或调用 evaluate_result 评审
|
|
132213
|
-
* - achieved=true → 结束;否则继续下一轮
|
|
132685
|
+
* 2. 阶段 2: Runtime 自动调度 ready todos 并等待本批收口
|
|
132686
|
+
* 3. 阶段 3: Supervisor 只在 checkpoint 调用 verdict 做语义裁决
|
|
132214
132687
|
*/
|
|
132215
132688
|
async executeSupervised(messages, supervisor, abortSignal) {
|
|
132216
132689
|
let totalUsage;
|
|
@@ -132462,7 +132935,8 @@ var init_SwarmExecutor = __esm({
|
|
|
132462
132935
|
tools: { ...tools, ...swarmTools },
|
|
132463
132936
|
stopWhen,
|
|
132464
132937
|
deps: this.agentDeps,
|
|
132465
|
-
runtime
|
|
132938
|
+
runtime,
|
|
132939
|
+
groupId: this.thread.groupId
|
|
132466
132940
|
});
|
|
132467
132941
|
if (this.streamCallback) {
|
|
132468
132942
|
executor.onStream(this.streamCallback);
|
|
@@ -133441,8 +133915,139 @@ var init_error_classifier = __esm({
|
|
|
133441
133915
|
}
|
|
133442
133916
|
});
|
|
133443
133917
|
|
|
133918
|
+
// src/core/message/queue/StreamingPersistScheduler.ts
|
|
133919
|
+
var log15, DEFAULT_PERSIST_INTERVAL_MS, StreamingPersistScheduler;
|
|
133920
|
+
var init_StreamingPersistScheduler = __esm({
|
|
133921
|
+
"src/core/message/queue/StreamingPersistScheduler.ts"() {
|
|
133922
|
+
"use strict";
|
|
133923
|
+
init_logger();
|
|
133924
|
+
log15 = createLogger("StreamingPersistScheduler");
|
|
133925
|
+
DEFAULT_PERSIST_INTERVAL_MS = 500;
|
|
133926
|
+
StreamingPersistScheduler = class {
|
|
133927
|
+
constructor(options2) {
|
|
133928
|
+
this.options = options2;
|
|
133929
|
+
}
|
|
133930
|
+
options;
|
|
133931
|
+
skeletonPersisted = false;
|
|
133932
|
+
skeletonPromise = null;
|
|
133933
|
+
inflightUpdate = null;
|
|
133934
|
+
dirty = false;
|
|
133935
|
+
timer = null;
|
|
133936
|
+
flushed = false;
|
|
133937
|
+
flushPromise = null;
|
|
133938
|
+
notify() {
|
|
133939
|
+
if (this.flushed) return;
|
|
133940
|
+
if (!this.skeletonPersisted && !this.skeletonPromise) {
|
|
133941
|
+
this.startSkeletonInsert();
|
|
133942
|
+
return;
|
|
133943
|
+
}
|
|
133944
|
+
this.dirty = true;
|
|
133945
|
+
if (this.skeletonPersisted) {
|
|
133946
|
+
this.scheduleUpdate();
|
|
133947
|
+
}
|
|
133948
|
+
}
|
|
133949
|
+
flush() {
|
|
133950
|
+
if (!this.flushPromise) {
|
|
133951
|
+
this.flushPromise = this.doFlush();
|
|
133952
|
+
}
|
|
133953
|
+
return this.flushPromise;
|
|
133954
|
+
}
|
|
133955
|
+
async doFlush() {
|
|
133956
|
+
this.flushed = true;
|
|
133957
|
+
this.clearTimer();
|
|
133958
|
+
await this.skeletonPromise;
|
|
133959
|
+
await this.inflightUpdate;
|
|
133960
|
+
if (this.dirty && this.skeletonPersisted) {
|
|
133961
|
+
this.dirty = false;
|
|
133962
|
+
await this.runFinalUpdate();
|
|
133963
|
+
}
|
|
133964
|
+
}
|
|
133965
|
+
get hasPersistedSkeleton() {
|
|
133966
|
+
return this.skeletonPersisted;
|
|
133967
|
+
}
|
|
133968
|
+
cancel() {
|
|
133969
|
+
this.flushed = true;
|
|
133970
|
+
this.flushPromise ??= Promise.resolve();
|
|
133971
|
+
this.clearTimer();
|
|
133972
|
+
}
|
|
133973
|
+
startSkeletonInsert() {
|
|
133974
|
+
const snapshot = this.cloneBlocks();
|
|
133975
|
+
const promise2 = this.options.insertSkeleton(snapshot).then(() => {
|
|
133976
|
+
this.skeletonPersisted = true;
|
|
133977
|
+
log15.noise(`streaming skeleton persisted, aiMessageId=${this.options.messageId}`);
|
|
133978
|
+
}).catch((error48) => {
|
|
133979
|
+
log15.warn(`streaming skeleton insert failed, aiMessageId=${this.options.messageId}`, error48);
|
|
133980
|
+
}).finally(() => {
|
|
133981
|
+
this.skeletonPromise = null;
|
|
133982
|
+
if (this.dirty && this.skeletonPersisted && !this.flushed) {
|
|
133983
|
+
this.scheduleUpdate();
|
|
133984
|
+
}
|
|
133985
|
+
});
|
|
133986
|
+
this.skeletonPromise = promise2;
|
|
133987
|
+
this.track(promise2, `streaming-skeleton:${this.options.messageId}`);
|
|
133988
|
+
}
|
|
133989
|
+
scheduleUpdate() {
|
|
133990
|
+
if (this.flushed || this.timer || this.inflightUpdate) return;
|
|
133991
|
+
this.timer = setTimeout(() => {
|
|
133992
|
+
this.timer = null;
|
|
133993
|
+
this.startUpdate();
|
|
133994
|
+
}, this.options.persistIntervalMs ?? DEFAULT_PERSIST_INTERVAL_MS);
|
|
133995
|
+
}
|
|
133996
|
+
startUpdate() {
|
|
133997
|
+
if (this.flushed || !this.skeletonPersisted || !this.dirty || this.inflightUpdate) return;
|
|
133998
|
+
const snapshot = this.cloneBlocks();
|
|
133999
|
+
if (snapshot.length === 0) return;
|
|
134000
|
+
this.dirty = false;
|
|
134001
|
+
const promise2 = this.options.updateBlocks(snapshot).catch((error48) => {
|
|
134002
|
+
this.dirty = true;
|
|
134003
|
+
log15.noise(`streaming update failed, aiMessageId=${this.options.messageId}`, error48);
|
|
134004
|
+
}).finally(() => {
|
|
134005
|
+
this.inflightUpdate = null;
|
|
134006
|
+
if (this.dirty && !this.flushed) {
|
|
134007
|
+
this.scheduleUpdate();
|
|
134008
|
+
}
|
|
134009
|
+
});
|
|
134010
|
+
this.inflightUpdate = promise2;
|
|
134011
|
+
this.track(promise2, `streaming-update:${this.options.messageId}`);
|
|
134012
|
+
}
|
|
134013
|
+
async runFinalUpdate() {
|
|
134014
|
+
const snapshot = this.cloneBlocks();
|
|
134015
|
+
if (snapshot.length === 0) return;
|
|
134016
|
+
const promise2 = this.options.updateBlocks(snapshot);
|
|
134017
|
+
this.track(promise2, `streaming-final-update:${this.options.messageId}`);
|
|
134018
|
+
try {
|
|
134019
|
+
await promise2;
|
|
134020
|
+
} catch (error48) {
|
|
134021
|
+
log15.warn(`streaming final flush failed, aiMessageId=${this.options.messageId}`, error48);
|
|
134022
|
+
}
|
|
134023
|
+
}
|
|
134024
|
+
cloneBlocks() {
|
|
134025
|
+
return structuredClone(this.options.getBlocks());
|
|
134026
|
+
}
|
|
134027
|
+
clearTimer() {
|
|
134028
|
+
if (!this.timer) return;
|
|
134029
|
+
clearTimeout(this.timer);
|
|
134030
|
+
this.timer = null;
|
|
134031
|
+
}
|
|
134032
|
+
track(promise2, label) {
|
|
134033
|
+
this.options.pendingDbWrites?.track(promise2, label);
|
|
134034
|
+
}
|
|
134035
|
+
};
|
|
134036
|
+
}
|
|
134037
|
+
});
|
|
134038
|
+
|
|
133444
134039
|
// src/core/message/queue/MessageProcessor.ts
|
|
133445
|
-
|
|
134040
|
+
function normalizeUsage(usage) {
|
|
134041
|
+
const normalized = {};
|
|
134042
|
+
for (const key of TOKEN_USAGE_KEYS) {
|
|
134043
|
+
const value = usage[key];
|
|
134044
|
+
if (typeof value === "number") {
|
|
134045
|
+
normalized[key] = value;
|
|
134046
|
+
}
|
|
134047
|
+
}
|
|
134048
|
+
return Object.keys(normalized).length > 0 ? normalized : void 0;
|
|
134049
|
+
}
|
|
134050
|
+
var log16, TOKEN_USAGE_KEYS, MAX_RETRIES, RETRY_DELAY_BASE, MessageProcessor;
|
|
133446
134051
|
var init_MessageProcessor = __esm({
|
|
133447
134052
|
"src/core/message/queue/MessageProcessor.ts"() {
|
|
133448
134053
|
"use strict";
|
|
@@ -133454,16 +134059,26 @@ var init_MessageProcessor = __esm({
|
|
|
133454
134059
|
init_logger();
|
|
133455
134060
|
init_error_classifier();
|
|
133456
134061
|
init_message_deps();
|
|
133457
|
-
|
|
134062
|
+
init_StreamingPersistScheduler();
|
|
134063
|
+
log16 = createLogger("MessageProcessor");
|
|
134064
|
+
TOKEN_USAGE_KEYS = [
|
|
134065
|
+
"inputTokens",
|
|
134066
|
+
"outputTokens",
|
|
134067
|
+
"totalTokens",
|
|
134068
|
+
"cachedInputTokens",
|
|
134069
|
+
"reasoningTokens"
|
|
134070
|
+
];
|
|
133458
134071
|
MAX_RETRIES = 3;
|
|
133459
134072
|
RETRY_DELAY_BASE = 1e3;
|
|
133460
134073
|
MessageProcessor = class {
|
|
133461
|
-
constructor(callbacks, messageQueue2) {
|
|
134074
|
+
constructor(callbacks, messageQueue2, pendingDbWrites) {
|
|
133462
134075
|
this.callbacks = callbacks;
|
|
133463
134076
|
this.messageQueue = messageQueue2;
|
|
134077
|
+
this.pendingDbWrites = pendingDbWrites;
|
|
133464
134078
|
}
|
|
133465
134079
|
callbacks;
|
|
133466
134080
|
messageQueue;
|
|
134081
|
+
pendingDbWrites;
|
|
133467
134082
|
/**
|
|
133468
134083
|
* 处理消息。
|
|
133469
134084
|
*
|
|
@@ -133481,10 +134096,12 @@ var init_MessageProcessor = __esm({
|
|
|
133481
134096
|
agentId = conversationId;
|
|
133482
134097
|
}
|
|
133483
134098
|
if (!agentId) {
|
|
133484
|
-
|
|
134099
|
+
log16.error(`no agentId found for conversation ${conversationId}`);
|
|
133485
134100
|
return { success: false };
|
|
133486
134101
|
}
|
|
133487
134102
|
const aiMessageId = aiMessageIdOverride || genId(ID_TYPE.MSG);
|
|
134103
|
+
const createdAt = Date.now();
|
|
134104
|
+
const startTime = Date.now();
|
|
133488
134105
|
const ctx = {
|
|
133489
134106
|
conversationId,
|
|
133490
134107
|
thread,
|
|
@@ -133492,20 +134109,38 @@ var init_MessageProcessor = __esm({
|
|
|
133492
134109
|
metadata,
|
|
133493
134110
|
agentId,
|
|
133494
134111
|
runId: genId(ID_TYPE.RUN),
|
|
133495
|
-
aiMessageId
|
|
133496
|
-
createdAt
|
|
133497
|
-
startTime
|
|
134112
|
+
aiMessageId,
|
|
134113
|
+
createdAt,
|
|
134114
|
+
startTime,
|
|
133498
134115
|
streamingBlocks: [],
|
|
133499
134116
|
retryCount,
|
|
133500
134117
|
model: void 0,
|
|
133501
134118
|
fallback: void 0,
|
|
133502
134119
|
streamingUsage: {},
|
|
133503
|
-
|
|
133504
|
-
|
|
134120
|
+
persistScheduler: new StreamingPersistScheduler({
|
|
134121
|
+
messageId: aiMessageId,
|
|
134122
|
+
getBlocks: () => ctx.streamingBlocks,
|
|
134123
|
+
insertSkeleton: async (blocks) => {
|
|
134124
|
+
await messageRepository2.insertWithId(
|
|
134125
|
+
{
|
|
134126
|
+
conversationId,
|
|
134127
|
+
senderId: agentId,
|
|
134128
|
+
senderRole: "agent",
|
|
134129
|
+
blocks
|
|
134130
|
+
},
|
|
134131
|
+
{ id: aiMessageId, createdAt, updatedAt: Date.now() }
|
|
134132
|
+
);
|
|
134133
|
+
},
|
|
134134
|
+
updateBlocks: (blocks) => messageRepository2.update(aiMessageId, {
|
|
134135
|
+
blocks,
|
|
134136
|
+
updatedAt: Date.now()
|
|
134137
|
+
}),
|
|
134138
|
+
pendingDbWrites: this.pendingDbWrites
|
|
134139
|
+
}),
|
|
133505
134140
|
isThread
|
|
133506
134141
|
};
|
|
133507
134142
|
this.messageQueue?.registerRunId(ctx.runId, conversationId);
|
|
133508
|
-
|
|
134143
|
+
log16.noise(`runId=${ctx.runId}, agentId=${agentId}, isThread=${isThread}`);
|
|
133509
134144
|
try {
|
|
133510
134145
|
return await this.executeAgent(ctx);
|
|
133511
134146
|
} catch (err) {
|
|
@@ -133538,7 +134173,7 @@ var init_MessageProcessor = __esm({
|
|
|
133538
134173
|
if (isThread) {
|
|
133539
134174
|
const mgr = await this.callbacks.getThreadManager(conversationId);
|
|
133540
134175
|
if (!mgr) {
|
|
133541
|
-
|
|
134176
|
+
log16.error(`thread manager not found, threadId=${conversationId}`);
|
|
133542
134177
|
this.callbacks.unregisterAbortController(conversationId);
|
|
133543
134178
|
return { success: false };
|
|
133544
134179
|
}
|
|
@@ -133563,18 +134198,20 @@ var init_MessageProcessor = __esm({
|
|
|
133563
134198
|
streamingBlocks.push(block);
|
|
133564
134199
|
}
|
|
133565
134200
|
messageCache.set(aiMessageId, conversationId, streamingBlocks);
|
|
133566
|
-
|
|
134201
|
+
ctx.persistScheduler.notify();
|
|
133567
134202
|
});
|
|
133568
134203
|
chat.onRunInfo((info) => {
|
|
133569
134204
|
ctx.model = info.model;
|
|
133570
134205
|
ctx.fallback = info.fallback;
|
|
134206
|
+
ctx.fallbackTransition = info.fallbackTransition ?? ctx.fallbackTransition;
|
|
133571
134207
|
eventBus.emit({
|
|
133572
134208
|
type: "run.progress",
|
|
133573
134209
|
conversationId,
|
|
133574
134210
|
runId,
|
|
133575
134211
|
messageId: aiMessageId,
|
|
133576
134212
|
model: info.model,
|
|
133577
|
-
fallback: info.fallback
|
|
134213
|
+
fallback: info.fallback,
|
|
134214
|
+
fallbackTransition: info.fallbackTransition
|
|
133578
134215
|
});
|
|
133579
134216
|
});
|
|
133580
134217
|
chat.onUsageUpdate((usage2) => {
|
|
@@ -133583,13 +134220,6 @@ var init_MessageProcessor = __esm({
|
|
|
133583
134220
|
const PROGRESS_INTERVAL_MS = 3e3;
|
|
133584
134221
|
ctx.progressTimer = setInterval(() => {
|
|
133585
134222
|
if (abortController.signal.aborted) return;
|
|
133586
|
-
const u = ctx.streamingUsage;
|
|
133587
|
-
const hasUsage = (u.inputTokens ?? 0) > 0 || (u.outputTokens ?? 0) > 0;
|
|
133588
|
-
const usage2 = hasUsage ? {
|
|
133589
|
-
inputTokens: u.inputTokens ?? void 0,
|
|
133590
|
-
outputTokens: u.outputTokens ?? void 0,
|
|
133591
|
-
totalTokens: u.totalTokens ?? void 0
|
|
133592
|
-
} : void 0;
|
|
133593
134223
|
eventBus.emit({
|
|
133594
134224
|
type: "run.progress",
|
|
133595
134225
|
conversationId,
|
|
@@ -133597,21 +134227,23 @@ var init_MessageProcessor = __esm({
|
|
|
133597
134227
|
messageId: aiMessageId,
|
|
133598
134228
|
model: ctx.model,
|
|
133599
134229
|
fallback: ctx.fallback,
|
|
133600
|
-
|
|
134230
|
+
fallbackTransition: ctx.fallbackTransition,
|
|
134231
|
+
usage: normalizeUsage(ctx.streamingUsage)
|
|
133601
134232
|
});
|
|
133602
134233
|
}, PROGRESS_INTERVAL_MS);
|
|
133603
|
-
|
|
134234
|
+
log16.noise(`calling chat.reply, conversationId=${conversationId}`);
|
|
133604
134235
|
const { usage, model, fallback, finalAgentId } = await chat.reply(message, abortController.signal, metadata);
|
|
133605
134236
|
if (finalAgentId) {
|
|
133606
134237
|
ctx.agentId = finalAgentId;
|
|
133607
134238
|
}
|
|
133608
134239
|
const durationMs = Date.now() - startTime;
|
|
133609
|
-
|
|
134240
|
+
log16.noise(`chat.reply completed, conversationId=${conversationId}, usage=`, usage, "model=", model, "fallback=", fallback, "durationMs=", durationMs);
|
|
133610
134241
|
if (ctx.progressTimer) {
|
|
133611
134242
|
clearInterval(ctx.progressTimer);
|
|
133612
134243
|
ctx.progressTimer = void 0;
|
|
133613
134244
|
}
|
|
133614
|
-
|
|
134245
|
+
await ctx.persistScheduler.flush();
|
|
134246
|
+
if (ctx.persistScheduler.hasPersistedSkeleton) {
|
|
133615
134247
|
await messageRepository2.update(aiMessageId, {
|
|
133616
134248
|
blocks: streamingBlocks,
|
|
133617
134249
|
senderId: ctx.agentId,
|
|
@@ -133649,7 +134281,7 @@ var init_MessageProcessor = __esm({
|
|
|
133649
134281
|
model,
|
|
133650
134282
|
fallback
|
|
133651
134283
|
});
|
|
133652
|
-
|
|
134284
|
+
log16.noise(`run.completed, conversationId=${conversationId}, runId=${runId}`);
|
|
133653
134285
|
this.callbacks.unregisterAbortController(conversationId);
|
|
133654
134286
|
return { success: true };
|
|
133655
134287
|
}
|
|
@@ -133662,7 +134294,7 @@ var init_MessageProcessor = __esm({
|
|
|
133662
134294
|
clearInterval(ctx.progressTimer);
|
|
133663
134295
|
ctx.progressTimer = void 0;
|
|
133664
134296
|
}
|
|
133665
|
-
|
|
134297
|
+
log16.error(`error occurred, conversationId=${conversationId}, runId=${runId}, error=`, err);
|
|
133666
134298
|
this.callbacks.unregisterAbortController(conversationId);
|
|
133667
134299
|
try {
|
|
133668
134300
|
if (err instanceof DOMException ? err.name === "AbortError" : err instanceof Error && err.name === "AbortError") {
|
|
@@ -133679,9 +134311,9 @@ var init_MessageProcessor = __esm({
|
|
|
133679
134311
|
}
|
|
133680
134312
|
if (isRetryableError(err) && retryCount < MAX_RETRIES) {
|
|
133681
134313
|
const attempt = retryCount + 1;
|
|
133682
|
-
const
|
|
133683
|
-
|
|
133684
|
-
`[Retry] conversationId=${conversationId}, runId=${runId}, messageId=${aiMessageId}, attempt=${attempt}/${MAX_RETRIES}, delay=${
|
|
134314
|
+
const delay4 = RETRY_DELAY_BASE * Math.pow(2, retryCount);
|
|
134315
|
+
log16.warn(
|
|
134316
|
+
`[Retry] conversationId=${conversationId}, runId=${runId}, messageId=${aiMessageId}, attempt=${attempt}/${MAX_RETRIES}, delay=${delay4}ms, error=${getErrorMessage3(err)}`
|
|
133685
134317
|
);
|
|
133686
134318
|
eventBus.emit({
|
|
133687
134319
|
type: "run.retrying",
|
|
@@ -133690,12 +134322,12 @@ var init_MessageProcessor = __esm({
|
|
|
133690
134322
|
messageId: aiMessageId,
|
|
133691
134323
|
attempt,
|
|
133692
134324
|
maxAttempts: MAX_RETRIES,
|
|
133693
|
-
delay:
|
|
134325
|
+
delay: delay4
|
|
133694
134326
|
});
|
|
133695
134327
|
return {
|
|
133696
134328
|
success: false,
|
|
133697
134329
|
shouldRetry: true,
|
|
133698
|
-
retryDelay:
|
|
134330
|
+
retryDelay: delay4,
|
|
133699
134331
|
aiMessageId
|
|
133700
134332
|
};
|
|
133701
134333
|
}
|
|
@@ -133719,53 +134351,17 @@ var init_MessageProcessor = __esm({
|
|
|
133719
134351
|
messageCache.delete(aiMessageId);
|
|
133720
134352
|
}
|
|
133721
134353
|
}
|
|
133722
|
-
/**
|
|
133723
|
-
* 流式持久化:第一个 block 时 insert 骨架,之后每 2 个 block update 一次。
|
|
133724
|
-
* 防止中途崩溃导致消息丢失。
|
|
133725
|
-
*/
|
|
133726
|
-
persistStreamingBlock(ctx) {
|
|
133727
|
-
const { streamingBlocks, streamingPersisted, aiMessageId, conversationId, agentId, createdAt } = ctx;
|
|
133728
|
-
const { messageRepository: messageRepository2 } = resolveMessageDeps();
|
|
133729
|
-
if (!streamingPersisted) {
|
|
133730
|
-
ctx.streamingPersisted = true;
|
|
133731
|
-
ctx.blockCountSincePersist = 0;
|
|
133732
|
-
messageRepository2.insertWithId(
|
|
133733
|
-
{
|
|
133734
|
-
conversationId,
|
|
133735
|
-
senderId: agentId,
|
|
133736
|
-
senderRole: "agent",
|
|
133737
|
-
blocks: streamingBlocks
|
|
133738
|
-
},
|
|
133739
|
-
{ id: aiMessageId, createdAt, updatedAt: Date.now() }
|
|
133740
|
-
).then(() => {
|
|
133741
|
-
log15.noise(`streaming skeleton persisted, aiMessageId=${aiMessageId}`);
|
|
133742
|
-
}).catch((err) => {
|
|
133743
|
-
log15.warn(`streaming skeleton insert failed, aiMessageId=${aiMessageId}`, err);
|
|
133744
|
-
});
|
|
133745
|
-
return;
|
|
133746
|
-
}
|
|
133747
|
-
ctx.blockCountSincePersist++;
|
|
133748
|
-
if (ctx.blockCountSincePersist >= 2) {
|
|
133749
|
-
ctx.blockCountSincePersist = 0;
|
|
133750
|
-
if (streamingBlocks.length === 0) return;
|
|
133751
|
-
messageRepository2.update(aiMessageId, {
|
|
133752
|
-
blocks: streamingBlocks,
|
|
133753
|
-
updatedAt: Date.now()
|
|
133754
|
-
}).catch((err) => {
|
|
133755
|
-
log15.noise(`streaming update failed, aiMessageId=${aiMessageId}`, err);
|
|
133756
|
-
});
|
|
133757
|
-
}
|
|
133758
|
-
}
|
|
133759
134354
|
/**
|
|
133760
134355
|
* 持久化错误消息到数据库
|
|
133761
134356
|
*/
|
|
133762
134357
|
async persistErrorMessage(ctx, error48) {
|
|
133763
|
-
const { conversationId, aiMessageId, createdAt, startTime, streamingBlocks, agentId,
|
|
134358
|
+
const { conversationId, aiMessageId, createdAt, startTime, streamingBlocks, agentId, model, fallback, metadata, streamingUsage } = ctx;
|
|
133764
134359
|
const durationMs = Date.now() - startTime;
|
|
133765
134360
|
const { messageRepository: messageRepository2 } = resolveMessageDeps();
|
|
133766
134361
|
const usage = Object.keys(streamingUsage).length > 0 ? streamingUsage : void 0;
|
|
133767
134362
|
try {
|
|
133768
|
-
|
|
134363
|
+
await ctx.persistScheduler.flush();
|
|
134364
|
+
if (ctx.persistScheduler.hasPersistedSkeleton) {
|
|
133769
134365
|
await messageRepository2.update(aiMessageId, {
|
|
133770
134366
|
blocks: streamingBlocks,
|
|
133771
134367
|
...error48 ? { error: error48 } : {},
|
|
@@ -133794,8 +134390,50 @@ var init_MessageProcessor = __esm({
|
|
|
133794
134390
|
);
|
|
133795
134391
|
}
|
|
133796
134392
|
} catch (persistErr) {
|
|
133797
|
-
|
|
134393
|
+
log16.error(`failed to persist error message, aiMessageId=${aiMessageId}`, persistErr);
|
|
134394
|
+
}
|
|
134395
|
+
}
|
|
134396
|
+
};
|
|
134397
|
+
}
|
|
134398
|
+
});
|
|
134399
|
+
|
|
134400
|
+
// src/core/message/queue/PendingDbWrites.ts
|
|
134401
|
+
function delay2(ms) {
|
|
134402
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
134403
|
+
}
|
|
134404
|
+
var log17, PendingDbWrites;
|
|
134405
|
+
var init_PendingDbWrites = __esm({
|
|
134406
|
+
"src/core/message/queue/PendingDbWrites.ts"() {
|
|
134407
|
+
"use strict";
|
|
134408
|
+
init_logger();
|
|
134409
|
+
log17 = createLogger("PendingDbWrites");
|
|
134410
|
+
PendingDbWrites = class {
|
|
134411
|
+
pending = /* @__PURE__ */ new Set();
|
|
134412
|
+
track(promise2, label) {
|
|
134413
|
+
const tracked = promise2.then(() => void 0).catch((error48) => {
|
|
134414
|
+
log17.warn(`pending DB write failed: ${label}`, error48);
|
|
134415
|
+
}).finally(() => {
|
|
134416
|
+
this.pending.delete(tracked);
|
|
134417
|
+
});
|
|
134418
|
+
this.pending.add(tracked);
|
|
134419
|
+
}
|
|
134420
|
+
snapshot() {
|
|
134421
|
+
return { pending: this.pending.size };
|
|
134422
|
+
}
|
|
134423
|
+
async drain(timeoutMs) {
|
|
134424
|
+
if (this.pending.size === 0) return "drained";
|
|
134425
|
+
const deadline = Date.now() + timeoutMs;
|
|
134426
|
+
while (this.pending.size > 0) {
|
|
134427
|
+
const remaining = deadline - Date.now();
|
|
134428
|
+
if (remaining <= 0) return "timeout";
|
|
134429
|
+
const batch = [...this.pending];
|
|
134430
|
+
const result = await Promise.race([
|
|
134431
|
+
Promise.allSettled(batch).then(() => "settled"),
|
|
134432
|
+
delay2(remaining).then(() => "timeout")
|
|
134433
|
+
]);
|
|
134434
|
+
if (result === "timeout") return "timeout";
|
|
133798
134435
|
}
|
|
134436
|
+
return "drained";
|
|
133799
134437
|
}
|
|
133800
134438
|
};
|
|
133801
134439
|
}
|
|
@@ -133817,7 +134455,10 @@ var init_time = __esm({
|
|
|
133817
134455
|
function stripSystemTag(content) {
|
|
133818
134456
|
return content.replace(/\n<current_time>[^<]*<\/current_time>/g, "");
|
|
133819
134457
|
}
|
|
133820
|
-
|
|
134458
|
+
function delay3(ms) {
|
|
134459
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
134460
|
+
}
|
|
134461
|
+
var log18, MessageQueue, messageQueue;
|
|
133821
134462
|
var init_MessageQueue = __esm({
|
|
133822
134463
|
"src/core/message/queue/MessageQueue.ts"() {
|
|
133823
134464
|
"use strict";
|
|
@@ -133825,9 +134466,10 @@ var init_MessageQueue = __esm({
|
|
|
133825
134466
|
init_message_deps();
|
|
133826
134467
|
init_ThreadManagerPool();
|
|
133827
134468
|
init_MessageProcessor();
|
|
134469
|
+
init_PendingDbWrites();
|
|
133828
134470
|
init_logger();
|
|
133829
134471
|
init_time();
|
|
133830
|
-
|
|
134472
|
+
log18 = createLogger("MessageQueue");
|
|
133831
134473
|
MessageQueue = class {
|
|
133832
134474
|
constructor(threadManagerProvider) {
|
|
133833
134475
|
this.threadManagerProvider = threadManagerProvider;
|
|
@@ -133848,7 +134490,7 @@ var init_MessageQueue = __esm({
|
|
|
133848
134490
|
this.abortMap.delete(conversationId);
|
|
133849
134491
|
},
|
|
133850
134492
|
getThreadManager: (threadId) => this.threadManagerProvider.getManager(threadId)
|
|
133851
|
-
}, this);
|
|
134493
|
+
}, this, this.pendingDbWrites);
|
|
133852
134494
|
}
|
|
133853
134495
|
threadManagerProvider;
|
|
133854
134496
|
queueMap = /* @__PURE__ */ new Map();
|
|
@@ -133861,8 +134503,14 @@ var init_MessageQueue = __esm({
|
|
|
133861
134503
|
isDestroyed = false;
|
|
133862
134504
|
processingSet = /* @__PURE__ */ new Set();
|
|
133863
134505
|
// 通道 ID(单聊=agentId,群线程=threadId)。同线程串行,不同线程可并行
|
|
134506
|
+
processingPromises = /* @__PURE__ */ new Set();
|
|
134507
|
+
pendingDbWrites = new PendingDbWrites();
|
|
133864
134508
|
processor;
|
|
133865
134509
|
push(conversationId, message, metadata, queueContext) {
|
|
134510
|
+
if (this.isDestroyed) {
|
|
134511
|
+
log18.warn(`push ignored after destroy, conversationId=${conversationId}`);
|
|
134512
|
+
return;
|
|
134513
|
+
}
|
|
133866
134514
|
const prev2 = this.queueMap.get(conversationId) || [];
|
|
133867
134515
|
this.queueMap.set(conversationId, [...prev2, {
|
|
133868
134516
|
message,
|
|
@@ -133871,9 +134519,9 @@ var init_MessageQueue = __esm({
|
|
|
133871
134519
|
originalContent: queueContext?.originalContent ?? "",
|
|
133872
134520
|
hasAttachments: queueContext?.hasAttachments ?? false
|
|
133873
134521
|
}]);
|
|
133874
|
-
|
|
134522
|
+
log18.noise(`push: conversationId=${conversationId}, queueLength=${prev2.length + 1}`);
|
|
133875
134523
|
this.emitQueueUpdated(conversationId);
|
|
133876
|
-
this.
|
|
134524
|
+
this.startConsume(conversationId);
|
|
133877
134525
|
}
|
|
133878
134526
|
getQueuedMessages(conversationId) {
|
|
133879
134527
|
return this.queueMap.get(conversationId) || [];
|
|
@@ -133882,7 +134530,7 @@ var init_MessageQueue = __esm({
|
|
|
133882
134530
|
return this.processingSet.has(conversationId);
|
|
133883
134531
|
}
|
|
133884
134532
|
stop(conversationId) {
|
|
133885
|
-
|
|
134533
|
+
log18.noise(`stop: conversationId=${conversationId}`);
|
|
133886
134534
|
this.abortMap.get(conversationId)?.abort();
|
|
133887
134535
|
}
|
|
133888
134536
|
/**
|
|
@@ -133894,7 +134542,7 @@ var init_MessageQueue = __esm({
|
|
|
133894
134542
|
if (!items || items.length === 0) return [];
|
|
133895
134543
|
const cancelled = items.splice(0);
|
|
133896
134544
|
this.queueMap.set(conversationId, []);
|
|
133897
|
-
|
|
134545
|
+
log18.noise(`cancelQueuedMessages: conversationId=${conversationId}, cancelled=${cancelled.length}`);
|
|
133898
134546
|
this.emitQueueUpdated(conversationId);
|
|
133899
134547
|
return cancelled;
|
|
133900
134548
|
}
|
|
@@ -133902,7 +134550,7 @@ var init_MessageQueue = __esm({
|
|
|
133902
134550
|
return this.runIdMap.get(runId);
|
|
133903
134551
|
}
|
|
133904
134552
|
registerRunId(runId, conversationId) {
|
|
133905
|
-
|
|
134553
|
+
log18.noise(`registerRunId: runId=${runId}, conversationId=${conversationId}`);
|
|
133906
134554
|
this.runIdMap.set(runId, conversationId);
|
|
133907
134555
|
this.conversationRunIdMap.set(conversationId, runId);
|
|
133908
134556
|
}
|
|
@@ -133917,7 +134565,7 @@ var init_MessageQueue = __esm({
|
|
|
133917
134565
|
emitQueueUpdated(conversationId) {
|
|
133918
134566
|
const pending = this.queueMap.get(conversationId)?.length || 0;
|
|
133919
134567
|
const running = this.processingSet.has(conversationId);
|
|
133920
|
-
|
|
134568
|
+
log18.noise(
|
|
133921
134569
|
`emitQueueUpdated: conversationId=${conversationId}, pending=${pending}, running=${running}, processingSet=${this.processingSet.size}`
|
|
133922
134570
|
);
|
|
133923
134571
|
eventBus.emit({
|
|
@@ -133926,21 +134574,30 @@ var init_MessageQueue = __esm({
|
|
|
133926
134574
|
queue: { pending, running }
|
|
133927
134575
|
});
|
|
133928
134576
|
}
|
|
134577
|
+
startConsume(conversationId, retryCount = 0) {
|
|
134578
|
+
if (this.isDestroyed) return;
|
|
134579
|
+
const promise2 = this.consume(conversationId, retryCount).catch((error48) => {
|
|
134580
|
+
log18.error(`consume failed, conversationId=${conversationId}`, error48);
|
|
134581
|
+
}).finally(() => {
|
|
134582
|
+
this.processingPromises.delete(promise2);
|
|
134583
|
+
});
|
|
134584
|
+
this.processingPromises.add(promise2);
|
|
134585
|
+
}
|
|
133929
134586
|
async consume(conversationId, retryCount = 0) {
|
|
133930
134587
|
if (this.isDestroyed) return;
|
|
133931
134588
|
if (this.processingSet.has(conversationId)) {
|
|
133932
|
-
|
|
134589
|
+
log18.noise(`consume: already processing, conversationId=${conversationId}`);
|
|
133933
134590
|
return;
|
|
133934
134591
|
}
|
|
133935
134592
|
const queue = this.queueMap.get(conversationId);
|
|
133936
134593
|
if (!queue || queue.length === 0) {
|
|
133937
|
-
|
|
134594
|
+
log18.noise(`consume: no message in queue, conversationId=${conversationId}`);
|
|
133938
134595
|
return;
|
|
133939
134596
|
}
|
|
133940
134597
|
const items = queue.splice(0);
|
|
133941
134598
|
const hasAttachments = items.some((item) => item.hasAttachments);
|
|
133942
134599
|
this.processingSet.add(conversationId);
|
|
133943
|
-
|
|
134600
|
+
log18.noise(`consume: start processing, conversationId=${conversationId}, merged=${items.length}, hasAttachments=${hasAttachments}`);
|
|
133944
134601
|
this.emitQueueUpdated(conversationId);
|
|
133945
134602
|
let shouldContinue = false;
|
|
133946
134603
|
let willRetry = false;
|
|
@@ -133954,7 +134611,7 @@ var init_MessageQueue = __esm({
|
|
|
133954
134611
|
if (skippedIds.length > 0) {
|
|
133955
134612
|
await resolveMessageDeps().messageRepository.delete(skippedIds);
|
|
133956
134613
|
eventBus.emit({ type: "messages.revoked", conversationId, messageIds: skippedIds });
|
|
133957
|
-
|
|
134614
|
+
log18.noise(`consume: cleaned up ${skippedIds.length} skipped DB messages (attachment conflict)`);
|
|
133958
134615
|
}
|
|
133959
134616
|
const result = await this.processor.processMessage(
|
|
133960
134617
|
conversationId,
|
|
@@ -133970,9 +134627,10 @@ var init_MessageQueue = __esm({
|
|
|
133970
134627
|
this.queueMap.set(conversationId, [current, ...this.queueMap.get(conversationId) || []]);
|
|
133971
134628
|
const nextRetryCount = retryCount + 1;
|
|
133972
134629
|
const timerId = setTimeout(() => {
|
|
134630
|
+
if (this.isDestroyed) return;
|
|
133973
134631
|
this.timers.delete(conversationId);
|
|
133974
134632
|
this.processingSet.delete(conversationId);
|
|
133975
|
-
this.
|
|
134633
|
+
this.startConsume(conversationId, nextRetryCount);
|
|
133976
134634
|
}, result.retryDelay);
|
|
133977
134635
|
this.timers.set(conversationId, timerId);
|
|
133978
134636
|
willRetry = true;
|
|
@@ -134011,15 +134669,16 @@ ${stripped}`;
|
|
|
134011
134669
|
this.queueMap.set(conversationId, [...items, ...this.queueMap.get(conversationId) || []]);
|
|
134012
134670
|
const nextRetryCount = retryCount + 1;
|
|
134013
134671
|
const timerId = setTimeout(() => {
|
|
134672
|
+
if (this.isDestroyed) return;
|
|
134014
134673
|
this.timers.delete(conversationId);
|
|
134015
134674
|
this.processingSet.delete(conversationId);
|
|
134016
|
-
this.
|
|
134675
|
+
this.startConsume(conversationId, nextRetryCount);
|
|
134017
134676
|
}, result.retryDelay);
|
|
134018
134677
|
this.timers.set(conversationId, timerId);
|
|
134019
134678
|
willRetry = true;
|
|
134020
134679
|
return;
|
|
134021
134680
|
}
|
|
134022
|
-
|
|
134681
|
+
log18.noise(`consume: completed, conversationId=${conversationId}`);
|
|
134023
134682
|
const mergedIds = items.slice(0, -1).map((item) => item.dbMessageId).filter((id) => Boolean(id));
|
|
134024
134683
|
if (mergedIds.length > 0) {
|
|
134025
134684
|
await resolveMessageDeps().messageRepository.delete(mergedIds);
|
|
@@ -134028,7 +134687,7 @@ ${stripped}`;
|
|
|
134028
134687
|
conversationId,
|
|
134029
134688
|
messageIds: mergedIds
|
|
134030
134689
|
});
|
|
134031
|
-
|
|
134690
|
+
log18.noise(`consume: cleaned up ${mergedIds.length} merged DB messages`);
|
|
134032
134691
|
}
|
|
134033
134692
|
shouldContinue = (this.queueMap.get(conversationId)?.length ?? 0) > 0;
|
|
134034
134693
|
}
|
|
@@ -134039,11 +134698,37 @@ ${stripped}`;
|
|
|
134039
134698
|
}
|
|
134040
134699
|
}
|
|
134041
134700
|
if (shouldContinue) {
|
|
134042
|
-
|
|
134043
|
-
|
|
134701
|
+
log18.noise(`consume: continuing with next message, conversationId=${conversationId}`);
|
|
134702
|
+
this.startConsume(conversationId);
|
|
134703
|
+
}
|
|
134704
|
+
}
|
|
134705
|
+
async shutdown(options2 = {}) {
|
|
134706
|
+
const timeoutMs = options2.timeoutMs ?? 3e3;
|
|
134707
|
+
const deadline = Date.now() + timeoutMs;
|
|
134708
|
+
this.isDestroyed = true;
|
|
134709
|
+
for (const timer of this.timers.values()) {
|
|
134710
|
+
clearTimeout(timer);
|
|
134711
|
+
}
|
|
134712
|
+
this.timers.clear();
|
|
134713
|
+
for (const controller of this.abortMap.values()) {
|
|
134714
|
+
controller.abort();
|
|
134715
|
+
}
|
|
134716
|
+
const processingResult = await this.drainProcessing(deadline);
|
|
134717
|
+
if (processingResult === "timeout") {
|
|
134718
|
+
log18.warn(`shutdown timed out waiting for active processing, remaining=${this.processingPromises.size}`);
|
|
134719
|
+
}
|
|
134720
|
+
const dbWritesResult = await this.pendingDbWrites.drain(Math.max(0, deadline - Date.now()));
|
|
134721
|
+
if (dbWritesResult === "timeout") {
|
|
134722
|
+
log18.warn(`shutdown timed out waiting for pending DB writes, remaining=${this.pendingDbWrites.snapshot().pending}`);
|
|
134723
|
+
}
|
|
134724
|
+
this.abortMap.clear();
|
|
134725
|
+
this.processingSet.clear();
|
|
134726
|
+
for (const conversationId of this.queueMap.keys()) {
|
|
134727
|
+
this.emitQueueUpdated(conversationId);
|
|
134044
134728
|
}
|
|
134045
134729
|
}
|
|
134046
134730
|
destroy() {
|
|
134731
|
+
if (this.isDestroyed) return;
|
|
134047
134732
|
this.isDestroyed = true;
|
|
134048
134733
|
for (const timer of this.timers.values()) {
|
|
134049
134734
|
clearTimeout(timer);
|
|
@@ -134055,6 +134740,23 @@ ${stripped}`;
|
|
|
134055
134740
|
this.abortMap.clear();
|
|
134056
134741
|
this.processingSet.clear();
|
|
134057
134742
|
}
|
|
134743
|
+
getPendingDbWritesCount() {
|
|
134744
|
+
return this.pendingDbWrites.snapshot().pending;
|
|
134745
|
+
}
|
|
134746
|
+
async drainProcessing(deadline) {
|
|
134747
|
+
if (this.processingPromises.size === 0) return "drained";
|
|
134748
|
+
while (this.processingPromises.size > 0) {
|
|
134749
|
+
const remaining = deadline - Date.now();
|
|
134750
|
+
if (remaining <= 0) return "timeout";
|
|
134751
|
+
const batch = [...this.processingPromises];
|
|
134752
|
+
const result = await Promise.race([
|
|
134753
|
+
Promise.allSettled(batch).then(() => "settled"),
|
|
134754
|
+
delay3(remaining).then(() => "timeout")
|
|
134755
|
+
]);
|
|
134756
|
+
if (result === "timeout") return "timeout";
|
|
134757
|
+
}
|
|
134758
|
+
return "drained";
|
|
134759
|
+
}
|
|
134058
134760
|
};
|
|
134059
134761
|
messageQueue = new MessageQueue(threadManagerPool);
|
|
134060
134762
|
}
|
|
@@ -134077,7 +134779,7 @@ var init_message2 = __esm({
|
|
|
134077
134779
|
});
|
|
134078
134780
|
|
|
134079
134781
|
// src/core/message/MessagePublisher.ts
|
|
134080
|
-
var
|
|
134782
|
+
var log19, MessagePublisherImpl, messagePublisher;
|
|
134081
134783
|
var init_MessagePublisher = __esm({
|
|
134082
134784
|
"src/core/message/MessagePublisher.ts"() {
|
|
134083
134785
|
"use strict";
|
|
@@ -134087,7 +134789,7 @@ var init_MessagePublisher = __esm({
|
|
|
134087
134789
|
init_message_deps();
|
|
134088
134790
|
init_logger();
|
|
134089
134791
|
init_time();
|
|
134090
|
-
|
|
134792
|
+
log19 = createLogger("MessagePublisher");
|
|
134091
134793
|
MessagePublisherImpl = class {
|
|
134092
134794
|
/**
|
|
134093
134795
|
* 发送用户消息
|
|
@@ -134122,7 +134824,7 @@ var init_MessagePublisher = __esm({
|
|
|
134122
134824
|
}
|
|
134123
134825
|
);
|
|
134124
134826
|
}
|
|
134125
|
-
|
|
134827
|
+
log19.noise(`published user message, id=${message.id}, conversationId=${conversationId}`);
|
|
134126
134828
|
return message;
|
|
134127
134829
|
}
|
|
134128
134830
|
/**
|
|
@@ -134144,7 +134846,7 @@ var init_MessagePublisher = __esm({
|
|
|
134144
134846
|
});
|
|
134145
134847
|
await sessionContextStore.saveAgentContext(conversationId, []);
|
|
134146
134848
|
this.emitAccepted(message);
|
|
134147
|
-
|
|
134849
|
+
log19.noise(`reset context (single), conversationId=${conversationId}`);
|
|
134148
134850
|
return conversationId;
|
|
134149
134851
|
}
|
|
134150
134852
|
/**
|
|
@@ -134172,7 +134874,7 @@ var init_MessagePublisher = __esm({
|
|
|
134172
134874
|
// 保持 QueueItem 不变量
|
|
134173
134875
|
);
|
|
134174
134876
|
}
|
|
134175
|
-
|
|
134877
|
+
log19.noise(`published system message, id=${message.id}, conversationId=${conversationId}`);
|
|
134176
134878
|
return message;
|
|
134177
134879
|
}
|
|
134178
134880
|
/**
|
|
@@ -134275,7 +134977,7 @@ var require_logger2 = __commonJS({
|
|
|
134275
134977
|
};
|
|
134276
134978
|
var GREEN = "\x1B[32m";
|
|
134277
134979
|
var RESET = "\x1B[0m";
|
|
134278
|
-
function
|
|
134980
|
+
function log23(level, message, extra) {
|
|
134279
134981
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
134280
134982
|
const color = levelColors[level] ?? "";
|
|
134281
134983
|
const prefix = `[${timestamp}] [PID: ${process.pid}] ${GREEN}[NODE-CRON]${GREEN} ${color}[${level}]${RESET}`;
|
|
@@ -134298,23 +135000,23 @@ var require_logger2 = __commonJS({
|
|
|
134298
135000
|
}
|
|
134299
135001
|
var logger40 = {
|
|
134300
135002
|
info(message) {
|
|
134301
|
-
|
|
135003
|
+
log23("INFO", message);
|
|
134302
135004
|
},
|
|
134303
135005
|
warn(message) {
|
|
134304
|
-
|
|
135006
|
+
log23("WARN", message);
|
|
134305
135007
|
},
|
|
134306
135008
|
error(message, err) {
|
|
134307
135009
|
if (message instanceof Error) {
|
|
134308
|
-
|
|
135010
|
+
log23("ERROR", message.message, message);
|
|
134309
135011
|
} else {
|
|
134310
|
-
|
|
135012
|
+
log23("ERROR", message, err);
|
|
134311
135013
|
}
|
|
134312
135014
|
},
|
|
134313
135015
|
debug(message, err) {
|
|
134314
135016
|
if (message instanceof Error) {
|
|
134315
|
-
|
|
135017
|
+
log23("DEBUG", message.message, message);
|
|
134316
135018
|
} else {
|
|
134317
|
-
|
|
135019
|
+
log23("DEBUG", message, err);
|
|
134318
135020
|
}
|
|
134319
135021
|
}
|
|
134320
135022
|
};
|
|
@@ -134562,11 +135264,11 @@ var require_runner = __commonJS({
|
|
|
134562
135264
|
const maxDelay = 864e5;
|
|
134563
135265
|
const nextRun = timeMatcher.getNextMatch(currentDate);
|
|
134564
135266
|
const now2 = /* @__PURE__ */ new Date();
|
|
134565
|
-
const
|
|
134566
|
-
if (
|
|
135267
|
+
const delay4 = nextRun.getTime() - now2.getTime();
|
|
135268
|
+
if (delay4 > maxDelay) {
|
|
134567
135269
|
return maxDelay;
|
|
134568
135270
|
}
|
|
134569
|
-
return Math.max(0,
|
|
135271
|
+
return Math.max(0, delay4);
|
|
134570
135272
|
}
|
|
134571
135273
|
function nowWithoutMs() {
|
|
134572
135274
|
const date5 = /* @__PURE__ */ new Date();
|
|
@@ -135992,7 +136694,7 @@ var init_MemoryUpdateExecutor = __esm({
|
|
|
135992
136694
|
for (const block of toolBlocks) {
|
|
135993
136695
|
const toolCall = block.toolCall;
|
|
135994
136696
|
if (toolCall.status !== "success") continue;
|
|
135995
|
-
if (
|
|
136697
|
+
if (!["writeFile", "editFile", "write", "edit"].includes(toolCall.name)) continue;
|
|
135996
136698
|
const output = this.readToolOutput(toolCall.result);
|
|
135997
136699
|
if (!output?.success || typeof output.path !== "string") continue;
|
|
135998
136700
|
const relativePath = this.toRelativeWorkspacePath(workspaceDir, output.path);
|
|
@@ -140001,23 +140703,23 @@ function getKaiRoot() {
|
|
|
140001
140703
|
return config.getAppDataPath();
|
|
140002
140704
|
}
|
|
140003
140705
|
function getDbPath() {
|
|
140004
|
-
return (0,
|
|
140706
|
+
return (0, import_path20.join)(config.getAppDataPath(), "kai.db");
|
|
140005
140707
|
}
|
|
140006
140708
|
function getThreadsRoot(groupId) {
|
|
140007
|
-
return (0,
|
|
140709
|
+
return (0, import_path20.join)(getGroupDir(groupId), "threads");
|
|
140008
140710
|
}
|
|
140009
140711
|
function getThreadMetaPath(groupId, threadId) {
|
|
140010
|
-
return (0,
|
|
140712
|
+
return (0, import_path20.join)(getThreadsRoot(groupId), threadId, "meta.json");
|
|
140011
140713
|
}
|
|
140012
140714
|
async function atomicWriteJson5(filePath, data2) {
|
|
140013
|
-
await (0,
|
|
140715
|
+
await (0, import_promises21.mkdir)((0, import_path20.dirname)(filePath), { recursive: true });
|
|
140014
140716
|
const tmp = `${filePath}.tmp`;
|
|
140015
|
-
await (0,
|
|
140717
|
+
await (0, import_promises21.writeFile)(tmp, `${JSON.stringify(data2, null, 2)}
|
|
140016
140718
|
`, "utf-8");
|
|
140017
|
-
await (0,
|
|
140719
|
+
await (0, import_promises21.rename)(tmp, filePath);
|
|
140018
140720
|
}
|
|
140019
140721
|
async function isMigrationNeeded() {
|
|
140020
|
-
const groupsRoot = (0,
|
|
140722
|
+
const groupsRoot = (0, import_path20.join)(getKaiRoot(), "groups");
|
|
140021
140723
|
if ((0, import_fs13.existsSync)(groupsRoot)) {
|
|
140022
140724
|
try {
|
|
140023
140725
|
const { readdir: readdir9 } = await import("fs/promises");
|
|
@@ -140025,7 +140727,7 @@ async function isMigrationNeeded() {
|
|
|
140025
140727
|
const dirs = entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
140026
140728
|
if (dirs.length > 0) {
|
|
140027
140729
|
const allMigrated = dirs.every(
|
|
140028
|
-
(g) => (0, import_fs13.existsSync)((0,
|
|
140730
|
+
(g) => (0, import_fs13.existsSync)((0, import_path20.join)(getGroupDir(g), "threads"))
|
|
140029
140731
|
);
|
|
140030
140732
|
if (allMigrated) return false;
|
|
140031
140733
|
}
|
|
@@ -140070,7 +140772,7 @@ async function migrateGroupsToThreads() {
|
|
|
140070
140772
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
140071
140773
|
const backupPath = `${dbPath}.bak.${timestamp}`;
|
|
140072
140774
|
logger33.debug(`Backing up database to ${backupPath}`);
|
|
140073
|
-
await (0,
|
|
140775
|
+
await (0, import_promises21.copyFile)(dbPath, backupPath);
|
|
140074
140776
|
try {
|
|
140075
140777
|
logger33.debug("Rebuilding messages table (removing FK)");
|
|
140076
140778
|
await sequelize.transaction(async (t) => {
|
|
@@ -140202,13 +140904,13 @@ async function migrateGroupsToThreads() {
|
|
|
140202
140904
|
for (const conv of groupConversations) {
|
|
140203
140905
|
const row = conv;
|
|
140204
140906
|
const groupId = row.target_id;
|
|
140205
|
-
const threadsDir = (0,
|
|
140907
|
+
const threadsDir = (0, import_path20.join)(getGroupDir(groupId), "threads");
|
|
140206
140908
|
if (!(0, import_fs13.existsSync)(threadsDir)) continue;
|
|
140207
140909
|
try {
|
|
140208
140910
|
const { readdir: readdirAsync } = await import("fs/promises");
|
|
140209
140911
|
const threadDirs = (await readdirAsync(threadsDir, { withFileTypes: true })).filter((e) => e.isDirectory());
|
|
140210
140912
|
const hasMeta = threadDirs.some(
|
|
140211
|
-
(td) => (0, import_fs13.existsSync)((0,
|
|
140913
|
+
(td) => (0, import_fs13.existsSync)((0, import_path20.join)(threadsDir, td.name, "meta.json"))
|
|
140212
140914
|
);
|
|
140213
140915
|
if (hasMeta) groupsWithThread++;
|
|
140214
140916
|
} catch {
|
|
@@ -140244,7 +140946,7 @@ async function migrateGroupsToThreads() {
|
|
|
140244
140946
|
if ((0, import_fs13.existsSync)(backupPath)) {
|
|
140245
140947
|
logger33.debug("Restoring database from backup...");
|
|
140246
140948
|
try {
|
|
140247
|
-
await (0,
|
|
140949
|
+
await (0, import_promises21.copyFile)(backupPath, dbPath);
|
|
140248
140950
|
logger33.debug("Database restored from backup");
|
|
140249
140951
|
} catch (restoreError) {
|
|
140250
140952
|
logger33.error(
|
|
@@ -140259,7 +140961,7 @@ async function migrateGroupsToThreads() {
|
|
|
140259
140961
|
async function rollbackThreads() {
|
|
140260
140962
|
const sequelize = getSequelize();
|
|
140261
140963
|
const dbPath = getDbPath();
|
|
140262
|
-
const groupsRoot = (0,
|
|
140964
|
+
const groupsRoot = (0, import_path20.join)(getKaiRoot(), "groups");
|
|
140263
140965
|
if (!(0, import_fs13.existsSync)(groupsRoot)) {
|
|
140264
140966
|
logger33.debug("No groups directory, nothing to rollback.");
|
|
140265
140967
|
return;
|
|
@@ -140267,7 +140969,7 @@ async function rollbackThreads() {
|
|
|
140267
140969
|
const { readdir: readdir9 } = await import("fs/promises");
|
|
140268
140970
|
const dirs = (await readdir9(groupsRoot, { withFileTypes: true })).filter((e) => e.isDirectory()).map((e) => e.name);
|
|
140269
140971
|
const hasThreads = dirs.some(
|
|
140270
|
-
(g) => (0, import_fs13.existsSync)((0,
|
|
140972
|
+
(g) => (0, import_fs13.existsSync)((0, import_path20.join)(getGroupDir(g), "threads"))
|
|
140271
140973
|
);
|
|
140272
140974
|
if (!hasThreads) {
|
|
140273
140975
|
logger33.debug("No threads directories found, nothing to rollback.");
|
|
@@ -140282,12 +140984,12 @@ async function rollbackThreads() {
|
|
|
140282
140984
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
140283
140985
|
const backupPath = `${dbPath}.bak.rollback.${timestamp}`;
|
|
140284
140986
|
logger33.debug(`Backing up database to ${backupPath}`);
|
|
140285
|
-
await (0,
|
|
140987
|
+
await (0, import_promises21.copyFile)(dbPath, backupPath);
|
|
140286
140988
|
try {
|
|
140287
140989
|
logger33.debug("Restoring group conversations from thread files");
|
|
140288
140990
|
let restored = 0;
|
|
140289
140991
|
for (const groupId of dirs) {
|
|
140290
|
-
const threadsDir = (0,
|
|
140992
|
+
const threadsDir = (0, import_path20.join)(getGroupDir(groupId), "threads");
|
|
140291
140993
|
if (!(0, import_fs13.existsSync)(threadsDir)) continue;
|
|
140292
140994
|
let threadDirs;
|
|
140293
140995
|
try {
|
|
@@ -140298,7 +141000,7 @@ async function rollbackThreads() {
|
|
|
140298
141000
|
for (const threadId of threadDirs) {
|
|
140299
141001
|
const metaPath = getThreadMetaPath(groupId, threadId);
|
|
140300
141002
|
if (!(0, import_fs13.existsSync)(metaPath)) continue;
|
|
140301
|
-
const raw = await (0,
|
|
141003
|
+
const raw = await (0, import_promises21.readFile)(metaPath, "utf-8");
|
|
140302
141004
|
const meta3 = JSON.parse(raw);
|
|
140303
141005
|
if (!meta3.isDefault) {
|
|
140304
141006
|
const orphanCount = await sequelize.query(
|
|
@@ -140425,9 +141127,9 @@ async function rollbackThreads() {
|
|
|
140425
141127
|
logger33.debug("Messages table rebuilt with FK restored");
|
|
140426
141128
|
logger33.debug("Removing threads directories");
|
|
140427
141129
|
for (const groupId of dirs) {
|
|
140428
|
-
const threadsDir = (0,
|
|
141130
|
+
const threadsDir = (0, import_path20.join)(getGroupDir(groupId), "threads");
|
|
140429
141131
|
if ((0, import_fs13.existsSync)(threadsDir)) {
|
|
140430
|
-
await (0,
|
|
141132
|
+
await (0, import_promises21.rm)(threadsDir, { recursive: true, force: true });
|
|
140431
141133
|
}
|
|
140432
141134
|
}
|
|
140433
141135
|
const finalRows = await sequelize.query(
|
|
@@ -140448,7 +141150,7 @@ async function rollbackThreads() {
|
|
|
140448
141150
|
if ((0, import_fs13.existsSync)(backupPath)) {
|
|
140449
141151
|
logger33.debug("Restoring database from backup...");
|
|
140450
141152
|
try {
|
|
140451
|
-
await (0,
|
|
141153
|
+
await (0, import_promises21.copyFile)(backupPath, dbPath);
|
|
140452
141154
|
logger33.debug("Database restored from backup");
|
|
140453
141155
|
} catch (restoreError) {
|
|
140454
141156
|
logger33.error(
|
|
@@ -140460,13 +141162,13 @@ async function rollbackThreads() {
|
|
|
140460
141162
|
throw error48;
|
|
140461
141163
|
}
|
|
140462
141164
|
}
|
|
140463
|
-
var
|
|
141165
|
+
var import_path20, import_fs13, import_promises21, logger33;
|
|
140464
141166
|
var init_threads_migration = __esm({
|
|
140465
141167
|
"src/adapters/db/migration/threads-migration.ts"() {
|
|
140466
141168
|
"use strict";
|
|
140467
|
-
|
|
141169
|
+
import_path20 = require("path");
|
|
140468
141170
|
import_fs13 = require("fs");
|
|
140469
|
-
|
|
141171
|
+
import_promises21 = require("fs/promises");
|
|
140470
141172
|
init_lib();
|
|
140471
141173
|
init_sequelize();
|
|
140472
141174
|
init_config();
|
|
@@ -140484,13 +141186,13 @@ __export(cron_sqlite_migration_exports, {
|
|
|
140484
141186
|
migrateCronSqliteToFileStore: () => migrateCronSqliteToFileStore
|
|
140485
141187
|
});
|
|
140486
141188
|
function getDataCronDir2() {
|
|
140487
|
-
return (0,
|
|
141189
|
+
return (0, import_path21.join)(config.getAppDataPath(), "data", CRON_DIR2);
|
|
140488
141190
|
}
|
|
140489
141191
|
function getAgentsDir2() {
|
|
140490
|
-
return (0,
|
|
141192
|
+
return (0, import_path21.join)(config.getAppDataPath(), "agents");
|
|
140491
141193
|
}
|
|
140492
141194
|
function getGroupsDir2() {
|
|
140493
|
-
return (0,
|
|
141195
|
+
return (0, import_path21.join)(config.getAppDataPath(), "groups");
|
|
140494
141196
|
}
|
|
140495
141197
|
function parseDatetime(value) {
|
|
140496
141198
|
if (!value) return 0;
|
|
@@ -140508,17 +141210,17 @@ function parseScriptArgs(raw) {
|
|
|
140508
141210
|
}
|
|
140509
141211
|
async function writeJsonAtomic(filePath, data2) {
|
|
140510
141212
|
const dir = filePath.substring(0, filePath.lastIndexOf("/"));
|
|
140511
|
-
await (0,
|
|
141213
|
+
await (0, import_promises22.mkdir)(dir, { recursive: true });
|
|
140512
141214
|
const tmp = `${filePath}.tmp`;
|
|
140513
|
-
await (0,
|
|
140514
|
-
await (0,
|
|
141215
|
+
await (0, import_promises22.writeFile)(tmp, JSON.stringify(data2, null, 2), "utf-8");
|
|
141216
|
+
await (0, import_promises22.rename)(tmp, filePath);
|
|
140515
141217
|
}
|
|
140516
141218
|
function getTaskDir2(task) {
|
|
140517
141219
|
if (task.type === "agent" && task.agentId) {
|
|
140518
|
-
return (0,
|
|
141220
|
+
return (0, import_path21.join)(getAgentsDir2(), task.agentId, CRON_DIR2);
|
|
140519
141221
|
}
|
|
140520
141222
|
if (task.type === "group" && task.groupId) {
|
|
140521
|
-
return (0,
|
|
141223
|
+
return (0, import_path21.join)(getGroupsDir2(), task.groupId, CRON_DIR2);
|
|
140522
141224
|
}
|
|
140523
141225
|
return getDataCronDir2();
|
|
140524
141226
|
}
|
|
@@ -140555,7 +141257,7 @@ async function migrateTasks(sequelize) {
|
|
|
140555
141257
|
continue;
|
|
140556
141258
|
}
|
|
140557
141259
|
const dir = getTaskDir2(task);
|
|
140558
|
-
const filePath = (0,
|
|
141260
|
+
const filePath = (0, import_path21.join)(dir, `${task.id}.json`);
|
|
140559
141261
|
if ((0, import_fs14.existsSync)(filePath)) {
|
|
140560
141262
|
logger34.debug(`Task ${task.id} already exists in filesystem, skipping`);
|
|
140561
141263
|
continue;
|
|
@@ -140588,9 +141290,9 @@ async function migrateExecutions(sequelize) {
|
|
|
140588
141290
|
for (const [taskId, execs] of byTask) {
|
|
140589
141291
|
try {
|
|
140590
141292
|
const taskDir = await findTaskBaseDir(taskId);
|
|
140591
|
-
const execDir = (0,
|
|
141293
|
+
const execDir = (0, import_path21.join)(taskDir, taskId);
|
|
140592
141294
|
for (const row of execs) {
|
|
140593
|
-
const filePath = (0,
|
|
141295
|
+
const filePath = (0, import_path21.join)(execDir, `${row.id}.json`);
|
|
140594
141296
|
if ((0, import_fs14.existsSync)(filePath)) continue;
|
|
140595
141297
|
const execution = {
|
|
140596
141298
|
id: row.id,
|
|
@@ -140683,15 +141385,15 @@ function rowToTask(row, conversationMap) {
|
|
|
140683
141385
|
};
|
|
140684
141386
|
}
|
|
140685
141387
|
async function findTaskBaseDir(taskId) {
|
|
140686
|
-
const directGlobalPath = (0,
|
|
141388
|
+
const directGlobalPath = (0, import_path21.join)(getDataCronDir2(), `${taskId}.json`);
|
|
140687
141389
|
if ((0, import_fs14.existsSync)(directGlobalPath)) return getDataCronDir2();
|
|
140688
141390
|
const agentsDir = getAgentsDir2();
|
|
140689
141391
|
if ((0, import_fs14.existsSync)(agentsDir)) {
|
|
140690
141392
|
try {
|
|
140691
|
-
const owners = await (0,
|
|
141393
|
+
const owners = await (0, import_promises22.readdir)(agentsDir);
|
|
140692
141394
|
for (const ownerId of owners) {
|
|
140693
|
-
const cronDir = (0,
|
|
140694
|
-
const filePath = (0,
|
|
141395
|
+
const cronDir = (0, import_path21.join)(agentsDir, ownerId, CRON_DIR2);
|
|
141396
|
+
const filePath = (0, import_path21.join)(cronDir, `${taskId}.json`);
|
|
140695
141397
|
if ((0, import_fs14.existsSync)(filePath)) return cronDir;
|
|
140696
141398
|
}
|
|
140697
141399
|
} catch {
|
|
@@ -140700,10 +141402,10 @@ async function findTaskBaseDir(taskId) {
|
|
|
140700
141402
|
const groupsDir = getGroupsDir2();
|
|
140701
141403
|
if ((0, import_fs14.existsSync)(groupsDir)) {
|
|
140702
141404
|
try {
|
|
140703
|
-
const owners = await (0,
|
|
141405
|
+
const owners = await (0, import_promises22.readdir)(groupsDir);
|
|
140704
141406
|
for (const ownerId of owners) {
|
|
140705
|
-
const cronDir = (0,
|
|
140706
|
-
const filePath = (0,
|
|
141407
|
+
const cronDir = (0, import_path21.join)(groupsDir, ownerId, CRON_DIR2);
|
|
141408
|
+
const filePath = (0, import_path21.join)(cronDir, `${taskId}.json`);
|
|
140707
141409
|
if ((0, import_fs14.existsSync)(filePath)) return cronDir;
|
|
140708
141410
|
}
|
|
140709
141411
|
} catch {
|
|
@@ -140737,13 +141439,13 @@ async function migrateCronSqliteToFileStore() {
|
|
|
140737
141439
|
logger34.debug(`Migrated ${tasksMigrated} tasks and ${execsMigrated} executions to filesystem`);
|
|
140738
141440
|
await dropLegacyTables(sequelize);
|
|
140739
141441
|
}
|
|
140740
|
-
var
|
|
141442
|
+
var import_path21, import_promises22, import_fs14, logger34, CRON_DIR2;
|
|
140741
141443
|
var init_cron_sqlite_migration = __esm({
|
|
140742
141444
|
"src/adapters/db/migration/cron-sqlite-migration.ts"() {
|
|
140743
141445
|
"use strict";
|
|
140744
141446
|
init_lib();
|
|
140745
|
-
|
|
140746
|
-
|
|
141447
|
+
import_path21 = require("path");
|
|
141448
|
+
import_promises22 = require("fs/promises");
|
|
140747
141449
|
import_fs14 = require("fs");
|
|
140748
141450
|
init_config();
|
|
140749
141451
|
init_logger();
|
|
@@ -144409,24 +145111,24 @@ var require_dbcs_codec = __commonJS({
|
|
|
144409
145111
|
return this.encodeTable[high];
|
|
144410
145112
|
};
|
|
144411
145113
|
DBCSCodec.prototype._setEncodeChar = function(uCode, dbcsCode) {
|
|
144412
|
-
var
|
|
145114
|
+
var bucket2 = this._getEncodeBucket(uCode);
|
|
144413
145115
|
var low = uCode & 255;
|
|
144414
|
-
if (
|
|
144415
|
-
this.encodeTableSeq[SEQ_START -
|
|
144416
|
-
else if (
|
|
144417
|
-
|
|
145116
|
+
if (bucket2[low] <= SEQ_START)
|
|
145117
|
+
this.encodeTableSeq[SEQ_START - bucket2[low]][DEF_CHAR] = dbcsCode;
|
|
145118
|
+
else if (bucket2[low] == UNASSIGNED)
|
|
145119
|
+
bucket2[low] = dbcsCode;
|
|
144418
145120
|
};
|
|
144419
145121
|
DBCSCodec.prototype._setEncodeSequence = function(seq, dbcsCode) {
|
|
144420
145122
|
var uCode = seq[0];
|
|
144421
|
-
var
|
|
145123
|
+
var bucket2 = this._getEncodeBucket(uCode);
|
|
144422
145124
|
var low = uCode & 255;
|
|
144423
145125
|
var node;
|
|
144424
|
-
if (
|
|
144425
|
-
node = this.encodeTableSeq[SEQ_START -
|
|
145126
|
+
if (bucket2[low] <= SEQ_START) {
|
|
145127
|
+
node = this.encodeTableSeq[SEQ_START - bucket2[low]];
|
|
144426
145128
|
} else {
|
|
144427
145129
|
node = {};
|
|
144428
|
-
if (
|
|
144429
|
-
|
|
145130
|
+
if (bucket2[low] !== UNASSIGNED) node[DEF_CHAR] = bucket2[low];
|
|
145131
|
+
bucket2[low] = SEQ_START - this.encodeTableSeq.length;
|
|
144430
145132
|
this.encodeTableSeq.push(node);
|
|
144431
145133
|
}
|
|
144432
145134
|
for (var j = 1; j < seq.length - 1; j++) {
|
|
@@ -146915,9 +147617,9 @@ var require_timers = __commonJS({
|
|
|
146915
147617
|
* before the specified function or code is executed.
|
|
146916
147618
|
* @param {*} arg
|
|
146917
147619
|
*/
|
|
146918
|
-
constructor(callback,
|
|
147620
|
+
constructor(callback, delay4, arg) {
|
|
146919
147621
|
this._onTimeout = callback;
|
|
146920
|
-
this._idleTimeout =
|
|
147622
|
+
this._idleTimeout = delay4;
|
|
146921
147623
|
this._timerArg = arg;
|
|
146922
147624
|
this.refresh();
|
|
146923
147625
|
}
|
|
@@ -146962,8 +147664,8 @@ var require_timers = __commonJS({
|
|
|
146962
147664
|
* when the timer expires.
|
|
146963
147665
|
* @returns {NodeJS.Timeout|FastTimer}
|
|
146964
147666
|
*/
|
|
146965
|
-
setTimeout(callback,
|
|
146966
|
-
return
|
|
147667
|
+
setTimeout(callback, delay4, arg) {
|
|
147668
|
+
return delay4 <= RESOLUTION_MS ? setTimeout(callback, delay4, arg) : new FastTimer(callback, delay4, arg);
|
|
146967
147669
|
},
|
|
146968
147670
|
/**
|
|
146969
147671
|
* The clearTimeout method cancels an instantiated Timer previously created
|
|
@@ -146989,8 +147691,8 @@ var require_timers = __commonJS({
|
|
|
146989
147691
|
* when the timer expires.
|
|
146990
147692
|
* @returns {FastTimer}
|
|
146991
147693
|
*/
|
|
146992
|
-
setFastTimeout(callback,
|
|
146993
|
-
return new FastTimer(callback,
|
|
147694
|
+
setFastTimeout(callback, delay4, arg) {
|
|
147695
|
+
return new FastTimer(callback, delay4, arg);
|
|
146994
147696
|
},
|
|
146995
147697
|
/**
|
|
146996
147698
|
* The clearTimeout method cancels an instantiated FastTimer previously
|
|
@@ -147016,8 +147718,8 @@ var require_timers = __commonJS({
|
|
|
147016
147718
|
* @deprecated
|
|
147017
147719
|
* @param {number} [delay=0] The delay in milliseconds to add to the now value.
|
|
147018
147720
|
*/
|
|
147019
|
-
tick(
|
|
147020
|
-
fastNow +=
|
|
147721
|
+
tick(delay4 = 0) {
|
|
147722
|
+
fastNow += delay4 - RESOLUTION_MS + 1;
|
|
147021
147723
|
onTick();
|
|
147022
147724
|
onTick();
|
|
147023
147725
|
},
|
|
@@ -153410,21 +154112,21 @@ var require_client_h1 = __commonJS({
|
|
|
153410
154112
|
this.connection = "";
|
|
153411
154113
|
this.maxResponseSize = client[kMaxResponseSize];
|
|
153412
154114
|
}
|
|
153413
|
-
setTimeout(
|
|
153414
|
-
if (
|
|
154115
|
+
setTimeout(delay4, type) {
|
|
154116
|
+
if (delay4 !== this.timeoutValue || type & USE_FAST_TIMER ^ this.timeoutType & USE_FAST_TIMER) {
|
|
153415
154117
|
if (this.timeout) {
|
|
153416
154118
|
timers.clearTimeout(this.timeout);
|
|
153417
154119
|
this.timeout = null;
|
|
153418
154120
|
}
|
|
153419
|
-
if (
|
|
154121
|
+
if (delay4) {
|
|
153420
154122
|
if (type & USE_FAST_TIMER) {
|
|
153421
|
-
this.timeout = timers.setFastTimeout(onParserTimeout,
|
|
154123
|
+
this.timeout = timers.setFastTimeout(onParserTimeout, delay4, new WeakRef(this));
|
|
153422
154124
|
} else {
|
|
153423
|
-
this.timeout = setTimeout(onParserTimeout,
|
|
154125
|
+
this.timeout = setTimeout(onParserTimeout, delay4, new WeakRef(this));
|
|
153424
154126
|
this.timeout?.unref();
|
|
153425
154127
|
}
|
|
153426
154128
|
}
|
|
153427
|
-
this.timeoutValue =
|
|
154129
|
+
this.timeoutValue = delay4;
|
|
153428
154130
|
} else if (this.timeout) {
|
|
153429
154131
|
if (this.timeout.refresh) {
|
|
153430
154132
|
this.timeout.refresh();
|
|
@@ -159290,7 +159992,7 @@ var require_mock_utils = __commonJS({
|
|
|
159290
159992
|
if (mockDispatch2.data.callback) {
|
|
159291
159993
|
mockDispatch2.data = { ...mockDispatch2.data, ...mockDispatch2.data.callback(opts) };
|
|
159292
159994
|
}
|
|
159293
|
-
const { data: { statusCode, data: data2, headers, trailers, error: error48 }, delay:
|
|
159995
|
+
const { data: { statusCode, data: data2, headers, trailers, error: error48 }, delay: delay4, persist } = mockDispatch2;
|
|
159294
159996
|
const { timesInvoked, times } = mockDispatch2;
|
|
159295
159997
|
mockDispatch2.consumed = !persist && timesInvoked >= times;
|
|
159296
159998
|
mockDispatch2.pending = timesInvoked < times;
|
|
@@ -159313,11 +160015,11 @@ var require_mock_utils = __commonJS({
|
|
|
159313
160015
|
handler.onError(err);
|
|
159314
160016
|
}
|
|
159315
160017
|
handler.onConnect?.(abort, null);
|
|
159316
|
-
if (typeof
|
|
160018
|
+
if (typeof delay4 === "number" && delay4 > 0) {
|
|
159317
160019
|
timer = setTimeout(() => {
|
|
159318
160020
|
timer = null;
|
|
159319
160021
|
handleReply(this[kDispatches]);
|
|
159320
|
-
},
|
|
160022
|
+
}, delay4);
|
|
159321
160023
|
} else {
|
|
159322
160024
|
handleReply(this[kDispatches]);
|
|
159323
160025
|
}
|
|
@@ -159687,13 +160389,13 @@ var require_mock_call_history = __commonJS({
|
|
|
159687
160389
|
function makeFilterCalls(parameterName) {
|
|
159688
160390
|
return (parameterValue) => {
|
|
159689
160391
|
if (typeof parameterValue === "string" || parameterValue == null) {
|
|
159690
|
-
return this.logs.filter((
|
|
159691
|
-
return
|
|
160392
|
+
return this.logs.filter((log23) => {
|
|
160393
|
+
return log23[parameterName] === parameterValue;
|
|
159692
160394
|
});
|
|
159693
160395
|
}
|
|
159694
160396
|
if (parameterValue instanceof RegExp) {
|
|
159695
|
-
return this.logs.filter((
|
|
159696
|
-
return parameterValue.test(
|
|
160397
|
+
return this.logs.filter((log23) => {
|
|
160398
|
+
return parameterValue.test(log23[parameterName]);
|
|
159697
160399
|
});
|
|
159698
160400
|
}
|
|
159699
160401
|
throw new InvalidArgumentError3(`${parameterName} parameter should be one of string, regexp, undefined or null`);
|
|
@@ -159788,8 +160490,8 @@ var require_mock_call_history = __commonJS({
|
|
|
159788
160490
|
return this.logs.filter(criteria);
|
|
159789
160491
|
}
|
|
159790
160492
|
if (criteria instanceof RegExp) {
|
|
159791
|
-
return this.logs.filter((
|
|
159792
|
-
return criteria.test(
|
|
160493
|
+
return this.logs.filter((log23) => {
|
|
160494
|
+
return criteria.test(log23.toString());
|
|
159793
160495
|
});
|
|
159794
160496
|
}
|
|
159795
160497
|
if (typeof criteria === "object" && criteria !== null) {
|
|
@@ -159839,13 +160541,13 @@ var require_mock_call_history = __commonJS({
|
|
|
159839
160541
|
this.logs = [];
|
|
159840
160542
|
}
|
|
159841
160543
|
[kMockCallHistoryAddLog](requestInit) {
|
|
159842
|
-
const
|
|
159843
|
-
this.logs.push(
|
|
159844
|
-
return
|
|
160544
|
+
const log23 = new MockCallHistoryLog(requestInit);
|
|
160545
|
+
this.logs.push(log23);
|
|
160546
|
+
return log23;
|
|
159845
160547
|
}
|
|
159846
160548
|
*[Symbol.iterator]() {
|
|
159847
|
-
for (const
|
|
159848
|
-
yield
|
|
160549
|
+
for (const log23 of this.calls()) {
|
|
160550
|
+
yield log23;
|
|
159849
160551
|
}
|
|
159850
160552
|
}
|
|
159851
160553
|
};
|
|
@@ -160230,7 +160932,7 @@ var require_snapshot_utils = __commonJS({
|
|
|
160230
160932
|
var require_snapshot_recorder = __commonJS({
|
|
160231
160933
|
"node_modules/undici/lib/mock/snapshot-recorder.js"(exports2, module2) {
|
|
160232
160934
|
"use strict";
|
|
160233
|
-
var { writeFile: writeFile15, readFile: readFile18, mkdir:
|
|
160935
|
+
var { writeFile: writeFile15, readFile: readFile18, mkdir: mkdir15 } = require("node:fs/promises");
|
|
160234
160936
|
var { dirname: dirname9, resolve: resolve9 } = require("node:path");
|
|
160235
160937
|
var { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = require("node:timers");
|
|
160236
160938
|
var { InvalidArgumentError: InvalidArgumentError3, UndiciError } = require_errors3();
|
|
@@ -160462,7 +161164,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
160462
161164
|
throw new InvalidArgumentError3("Snapshot path is required");
|
|
160463
161165
|
}
|
|
160464
161166
|
const resolvedPath = resolve9(path10);
|
|
160465
|
-
await
|
|
161167
|
+
await mkdir15(dirname9(resolvedPath), { recursive: true });
|
|
160466
161168
|
const data2 = Array.from(this.#snapshots.entries()).map(([hash2, snapshot]) => ({
|
|
160467
161169
|
hash: hash2,
|
|
160468
161170
|
snapshot
|
|
@@ -189145,14 +189847,14 @@ var require_turndown_cjs = __commonJS({
|
|
|
189145
189847
|
} else if (node.nodeType === 1) {
|
|
189146
189848
|
replacement = replacementForNode.call(self2, node);
|
|
189147
189849
|
}
|
|
189148
|
-
return
|
|
189850
|
+
return join21(output, replacement);
|
|
189149
189851
|
}, "");
|
|
189150
189852
|
}
|
|
189151
189853
|
function postProcess(output) {
|
|
189152
189854
|
var self2 = this;
|
|
189153
189855
|
this.rules.forEach(function(rule) {
|
|
189154
189856
|
if (typeof rule.append === "function") {
|
|
189155
|
-
output =
|
|
189857
|
+
output = join21(output, rule.append(self2.options));
|
|
189156
189858
|
}
|
|
189157
189859
|
});
|
|
189158
189860
|
return output.replace(/^[\t\r\n]+/, "").replace(/[\t\r\n\s]+$/, "");
|
|
@@ -189164,7 +189866,7 @@ var require_turndown_cjs = __commonJS({
|
|
|
189164
189866
|
if (whitespace2.leading || whitespace2.trailing) content = content.trim();
|
|
189165
189867
|
return whitespace2.leading + rule.replacement(content, node, this.options) + whitespace2.trailing;
|
|
189166
189868
|
}
|
|
189167
|
-
function
|
|
189869
|
+
function join21(output, replacement) {
|
|
189168
189870
|
var s1 = trimTrailingNewlines(output);
|
|
189169
189871
|
var s2 = trimLeadingNewlines(replacement);
|
|
189170
189872
|
var nls = Math.max(output.length - s1.length, replacement.length - s2.length);
|
|
@@ -189263,9 +189965,9 @@ var McpManager = class {
|
|
|
189263
189965
|
if (attempt === maxRetries - 1) {
|
|
189264
189966
|
break;
|
|
189265
189967
|
}
|
|
189266
|
-
const
|
|
189267
|
-
logger2.debug(`Tool ${name21} failed (attempt ${attempt + 1}/${maxRetries}), retrying in ${
|
|
189268
|
-
await new Promise((resolve9) => setTimeout(resolve9,
|
|
189968
|
+
const delay4 = Math.pow(2, attempt) * 100;
|
|
189969
|
+
logger2.debug(`Tool ${name21} failed (attempt ${attempt + 1}/${maxRetries}), retrying in ${delay4}ms...`);
|
|
189970
|
+
await new Promise((resolve9) => setTimeout(resolve9, delay4));
|
|
189269
189971
|
}
|
|
189270
189972
|
}
|
|
189271
189973
|
throw lastError || new Error(`Tool ${name21} execution failed after ${maxRetries} attempts`);
|
|
@@ -189618,8 +190320,8 @@ var SessionCleaner = class {
|
|
|
189618
190320
|
for (const dir of dirs) {
|
|
189619
190321
|
const fullPath = import_path6.default.join(sessionsDir, dir);
|
|
189620
190322
|
try {
|
|
189621
|
-
const
|
|
189622
|
-
if (
|
|
190323
|
+
const stat5 = await import_promises4.default.stat(fullPath);
|
|
190324
|
+
if (stat5.isDirectory() && stat5.mtimeMs < cutoffTime) {
|
|
189623
190325
|
await import_promises4.default.rm(fullPath, { recursive: true, force: true });
|
|
189624
190326
|
cleaned++;
|
|
189625
190327
|
logger7.debug("Removed old session:", dir);
|
|
@@ -189893,11 +190595,11 @@ var WeComBotClient = class {
|
|
|
189893
190595
|
scheduleReconnect() {
|
|
189894
190596
|
if (this.reconnectTimer || this.disposed || this.intentionalDisconnect) return;
|
|
189895
190597
|
this.reconnectAttempts += 1;
|
|
189896
|
-
const
|
|
190598
|
+
const delay4 = Math.min(
|
|
189897
190599
|
INITIAL_RECONNECT_DELAY_MS * 2 ** (this.reconnectAttempts - 1),
|
|
189898
190600
|
MAX_RECONNECT_DELAY_MS
|
|
189899
190601
|
);
|
|
189900
|
-
log2.info(`schedule reconnect in ${
|
|
190602
|
+
log2.info(`schedule reconnect in ${delay4}ms, attempt=${this.reconnectAttempts}`);
|
|
189901
190603
|
this.setState("reconnecting");
|
|
189902
190604
|
this.reconnectTimer = setTimeout(() => {
|
|
189903
190605
|
this.reconnectTimer = null;
|
|
@@ -189907,7 +190609,7 @@ var WeComBotClient = class {
|
|
|
189907
190609
|
this.scheduleReconnect();
|
|
189908
190610
|
}
|
|
189909
190611
|
});
|
|
189910
|
-
},
|
|
190612
|
+
}, delay4);
|
|
189911
190613
|
}
|
|
189912
190614
|
clearReconnectTimer() {
|
|
189913
190615
|
if (!this.reconnectTimer) return;
|
|
@@ -191620,7 +192322,7 @@ function checkSendFilePolicy(resolvedPath) {
|
|
|
191620
192322
|
// src/adapters/channel/shared/ChannelManager.ts
|
|
191621
192323
|
var import_promises13 = require("node:fs/promises");
|
|
191622
192324
|
init_config();
|
|
191623
|
-
var
|
|
192325
|
+
var log20 = createLogger("ChannelManager");
|
|
191624
192326
|
var ChannelManager = class {
|
|
191625
192327
|
adapters = /* @__PURE__ */ new Map();
|
|
191626
192328
|
configStore;
|
|
@@ -191656,7 +192358,7 @@ var ChannelManager = class {
|
|
|
191656
192358
|
this.adapters.set(config3.connectionId, adapter2);
|
|
191657
192359
|
this.subscribeAdapter(config3.connectionId, adapter2);
|
|
191658
192360
|
await adapter2.connect();
|
|
191659
|
-
|
|
192361
|
+
log20.info(`registered channel: ${config3.connectionId}`);
|
|
191660
192362
|
}
|
|
191661
192363
|
/** 更新已注册接入的绑定目标 */
|
|
191662
192364
|
async updateTarget(connectionId, target) {
|
|
@@ -191669,7 +192371,7 @@ var ChannelManager = class {
|
|
|
191669
192371
|
this.adapters.set(connectionId, adapter2);
|
|
191670
192372
|
this.subscribeAdapter(connectionId, adapter2);
|
|
191671
192373
|
await adapter2.connect();
|
|
191672
|
-
|
|
192374
|
+
log20.info(`updated target for channel: ${connectionId}`);
|
|
191673
192375
|
}
|
|
191674
192376
|
/** 连接已注册的接入 */
|
|
191675
192377
|
async connect(connectionId) {
|
|
@@ -191704,7 +192406,7 @@ var ChannelManager = class {
|
|
|
191704
192406
|
await this.secretStore.delete(config3.secretRef);
|
|
191705
192407
|
await this.configStore.delete(connectionId);
|
|
191706
192408
|
}
|
|
191707
|
-
|
|
192409
|
+
log20.info(`unregistered channel: ${connectionId}`);
|
|
191708
192410
|
}
|
|
191709
192411
|
/** 发送消息到外部 */
|
|
191710
192412
|
async send(reply) {
|
|
@@ -191767,11 +192469,11 @@ var ChannelManager = class {
|
|
|
191767
192469
|
this.subscribeAdapter(config3.connectionId, adapter2);
|
|
191768
192470
|
await adapter2.connect();
|
|
191769
192471
|
} catch (error48) {
|
|
191770
|
-
|
|
192472
|
+
log20.error(`failed to init channel ${config3.connectionId}:`, error48);
|
|
191771
192473
|
}
|
|
191772
192474
|
}
|
|
191773
192475
|
this.initialized = true;
|
|
191774
|
-
|
|
192476
|
+
log20.info(`channel manager initialized, adapters=${this.adapters.size}`);
|
|
191775
192477
|
}
|
|
191776
192478
|
/** 清理所有资源(app quit 时调用) */
|
|
191777
192479
|
async dispose() {
|
|
@@ -191783,9 +192485,9 @@ var ChannelManager = class {
|
|
|
191783
192485
|
if (adapter2?.stream) {
|
|
191784
192486
|
try {
|
|
191785
192487
|
await adapter2.stream.finish(pending.streamFrame, pending.streamId, "\u26A0\uFE0F \u7CFB\u7EDF\u5173\u95ED");
|
|
191786
|
-
|
|
192488
|
+
log20.info(`stream finished (dispose): runId=${runId}`);
|
|
191787
192489
|
} catch (err) {
|
|
191788
|
-
|
|
192490
|
+
log20.warn(`stream finish failed during dispose: runId=${runId}`, err);
|
|
191789
192491
|
}
|
|
191790
192492
|
}
|
|
191791
192493
|
}
|
|
@@ -191794,7 +192496,7 @@ var ChannelManager = class {
|
|
|
191794
192496
|
try {
|
|
191795
192497
|
await adapter2.disconnect();
|
|
191796
192498
|
} catch (error48) {
|
|
191797
|
-
|
|
192499
|
+
log20.warn(`disconnect failed: ${connectionId}`, error48);
|
|
191798
192500
|
}
|
|
191799
192501
|
adapter2.dispose();
|
|
191800
192502
|
}
|
|
@@ -191868,7 +192570,7 @@ var ChannelManager = class {
|
|
|
191868
192570
|
switch (event.type) {
|
|
191869
192571
|
case "message.received":
|
|
191870
192572
|
if (this.dedupe.isProcessed(event.message.channelType, event.message.connectionId, event.message.id)) {
|
|
191871
|
-
|
|
192573
|
+
log20.info(`skip duplicated inbound message: ${event.message.id}`);
|
|
191872
192574
|
return;
|
|
191873
192575
|
}
|
|
191874
192576
|
if (this.aggregator.enabled) {
|
|
@@ -191878,10 +192580,10 @@ var ChannelManager = class {
|
|
|
191878
192580
|
}
|
|
191879
192581
|
return;
|
|
191880
192582
|
case "status.changed":
|
|
191881
|
-
|
|
192583
|
+
log20.info(`channel status changed: ${connectionId} -> ${event.status.state}`);
|
|
191882
192584
|
return;
|
|
191883
192585
|
case "error":
|
|
191884
|
-
|
|
192586
|
+
log20.warn(`channel error: ${connectionId} ${event.error.code} ${event.error.message}`);
|
|
191885
192587
|
return;
|
|
191886
192588
|
default: {
|
|
191887
192589
|
const exhaustive = event;
|
|
@@ -191897,12 +192599,12 @@ var ChannelManager = class {
|
|
|
191897
192599
|
}
|
|
191898
192600
|
async routeInboundMessage(message) {
|
|
191899
192601
|
if (this.dedupe.isProcessed(message.channelType, message.connectionId, message.id)) {
|
|
191900
|
-
|
|
192602
|
+
log20.info(`skip duplicated inbound message: ${message.id}`);
|
|
191901
192603
|
return;
|
|
191902
192604
|
}
|
|
191903
192605
|
const config3 = await this.configStore.get(message.connectionId);
|
|
191904
192606
|
if (!config3) {
|
|
191905
|
-
|
|
192607
|
+
log20.warn(`channel config not found for inbound message: ${message.connectionId}`);
|
|
191906
192608
|
return;
|
|
191907
192609
|
}
|
|
191908
192610
|
try {
|
|
@@ -191913,7 +192615,7 @@ var ChannelManager = class {
|
|
|
191913
192615
|
}
|
|
191914
192616
|
this.dedupe.markProcessed(message.channelType, message.connectionId, message.id);
|
|
191915
192617
|
} catch (error48) {
|
|
191916
|
-
|
|
192618
|
+
log20.error(`failed to route inbound message ${message.id}:`, error48);
|
|
191917
192619
|
}
|
|
191918
192620
|
}
|
|
191919
192621
|
async deliverToAgent(config3, message) {
|
|
@@ -192035,9 +192737,9 @@ var ChannelManager = class {
|
|
|
192035
192737
|
if (adapter2.sendTyping) {
|
|
192036
192738
|
try {
|
|
192037
192739
|
await adapter2.sendTyping(pending.chatId, pending.chatType);
|
|
192038
|
-
|
|
192740
|
+
log20.noise(`typing sent: runId=${runId}, chatId=${pending.chatId}`);
|
|
192039
192741
|
} catch (err) {
|
|
192040
|
-
|
|
192742
|
+
log20.noise(`typing send failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
192041
192743
|
}
|
|
192042
192744
|
}
|
|
192043
192745
|
return;
|
|
@@ -192045,10 +192747,10 @@ var ChannelManager = class {
|
|
|
192045
192747
|
try {
|
|
192046
192748
|
await adapter2.stream.start(pending.streamFrame, pending.streamId);
|
|
192047
192749
|
pending.streamStarted = true;
|
|
192048
|
-
|
|
192750
|
+
log20.noise(`stream started: runId=${runId}, streamId=${pending.streamId}`);
|
|
192049
192751
|
} catch (err) {
|
|
192050
192752
|
pending.streamStarted = false;
|
|
192051
|
-
|
|
192753
|
+
log20.warn(`stream start failed, will fallback to send on completed: ${err instanceof Error ? err.message : String(err)}`);
|
|
192052
192754
|
}
|
|
192053
192755
|
}
|
|
192054
192756
|
/** message.block.updated → 刷新流式内容 */
|
|
@@ -192063,14 +192765,14 @@ var ChannelManager = class {
|
|
|
192063
192765
|
try {
|
|
192064
192766
|
await adapter2.stream.update(pending.streamFrame, pending.streamId, block.text);
|
|
192065
192767
|
} catch (err) {
|
|
192066
|
-
|
|
192768
|
+
log20.noise(`stream update failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
192067
192769
|
}
|
|
192068
192770
|
}
|
|
192069
192771
|
/** run.completed → 结束流式回复(或降级为一次性 send) */
|
|
192070
192772
|
async handleRunCompleted(conversationId, runId, messageId) {
|
|
192071
192773
|
const pending = this.pendingReplies.get(runId);
|
|
192072
192774
|
if (!pending) {
|
|
192073
|
-
|
|
192775
|
+
log20.warn(`handleRunCompleted: no pending reply for runId=${runId}, conversationId=${conversationId}`);
|
|
192074
192776
|
return;
|
|
192075
192777
|
}
|
|
192076
192778
|
this.pendingReplies.delete(runId);
|
|
@@ -192078,20 +192780,20 @@ var ChannelManager = class {
|
|
|
192078
192780
|
try {
|
|
192079
192781
|
const assistantMsg = await messageRepository.findById(messageId);
|
|
192080
192782
|
if (!assistantMsg || assistantMsg.senderRole !== "agent") {
|
|
192081
|
-
|
|
192783
|
+
log20.warn(`no assistant reply found for channel outbound: ${conversationId}, messageId=${messageId}`);
|
|
192082
192784
|
return;
|
|
192083
192785
|
}
|
|
192084
192786
|
await this.sendFilesFromBlocks(pending, assistantMsg.blocks);
|
|
192085
192787
|
const text4 = assistantMsg.blocks.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
192086
192788
|
if (!text4) {
|
|
192087
|
-
|
|
192789
|
+
log20.info(`assistant reply has no text, skip text outbound: ${conversationId}`);
|
|
192088
192790
|
return;
|
|
192089
192791
|
}
|
|
192090
192792
|
if (pending.streamStarted) {
|
|
192091
192793
|
const adapter2 = this.adapters.get(pending.connectionId);
|
|
192092
192794
|
if (adapter2?.stream) {
|
|
192093
192795
|
await adapter2.stream.finish(pending.streamFrame, pending.streamId, text4);
|
|
192094
|
-
|
|
192796
|
+
log20.info(`stream finished: conversationId=${conversationId}`);
|
|
192095
192797
|
return;
|
|
192096
192798
|
}
|
|
192097
192799
|
}
|
|
@@ -192103,12 +192805,12 @@ var ChannelManager = class {
|
|
|
192103
192805
|
};
|
|
192104
192806
|
const result = await this.send(reply);
|
|
192105
192807
|
if (result.ok) {
|
|
192106
|
-
|
|
192808
|
+
log20.info(`channel reply sent: conversationId=${conversationId}`);
|
|
192107
192809
|
} else {
|
|
192108
|
-
|
|
192810
|
+
log20.error(`channel reply failed: ${result.code} ${result.message}`);
|
|
192109
192811
|
}
|
|
192110
192812
|
} catch (error48) {
|
|
192111
|
-
|
|
192813
|
+
log20.error(`channel reply error:`, error48);
|
|
192112
192814
|
}
|
|
192113
192815
|
}
|
|
192114
192816
|
/** 清理 run 失败/停止时的残留上下文(含流式会话收尾) */
|
|
@@ -192119,9 +192821,9 @@ var ChannelManager = class {
|
|
|
192119
192821
|
if (adapter2?.stream) {
|
|
192120
192822
|
try {
|
|
192121
192823
|
await adapter2.stream.finish(pending.streamFrame, pending.streamId, "\u26A0\uFE0F \u56DE\u590D\u51FA\u9519");
|
|
192122
|
-
|
|
192824
|
+
log20.info(`stream finished (run cleanup): conversationId=${conversationId}, runId=${runId}`);
|
|
192123
192825
|
} catch (err) {
|
|
192124
|
-
|
|
192826
|
+
log20.warn(`stream finish failed during cleanup: ${err instanceof Error ? err.message : String(err)}`);
|
|
192125
192827
|
}
|
|
192126
192828
|
}
|
|
192127
192829
|
}
|
|
@@ -192132,28 +192834,28 @@ var ChannelManager = class {
|
|
|
192132
192834
|
async sendFilesFromBlocks(pending, blocks) {
|
|
192133
192835
|
const adapter2 = this.adapters.get(pending.connectionId);
|
|
192134
192836
|
if (!adapter2) {
|
|
192135
|
-
|
|
192837
|
+
log20.error(`sendFilesFromBlocks: adapter not found for connectionId=${pending.connectionId}`);
|
|
192136
192838
|
return;
|
|
192137
192839
|
}
|
|
192138
192840
|
const failures = [];
|
|
192139
192841
|
let total = 0;
|
|
192140
|
-
|
|
192842
|
+
log20.info(`sendFilesFromBlocks: scanning ${blocks.length} blocks, channelType=${pending.channelType}`);
|
|
192141
192843
|
for (const block of blocks) {
|
|
192142
192844
|
if (block.type === "tool") {
|
|
192143
192845
|
const toolCall = block.toolCall;
|
|
192144
192846
|
if (toolCall.name !== "sendFile" || toolCall.status !== "success") continue;
|
|
192145
192847
|
const filePath = this.extractSendFilePath(toolCall.args);
|
|
192146
|
-
|
|
192848
|
+
log20.info(`sendFilesFromBlocks: found sendFile toolCall, filePath=${filePath}, args=${JSON.stringify(toolCall.args)}`);
|
|
192147
192849
|
if (!filePath) continue;
|
|
192148
192850
|
total++;
|
|
192149
192851
|
try {
|
|
192150
192852
|
await this.assertSendableFilePath(filePath);
|
|
192151
192853
|
await adapter2.sendFile(pending.chatId, filePath, pending.chatType);
|
|
192152
|
-
|
|
192854
|
+
log20.info(`channel file sent: ${pending.channelType} -> ${filePath}`);
|
|
192153
192855
|
} catch (err) {
|
|
192154
192856
|
const msg = err instanceof Error ? err.message : String(err);
|
|
192155
192857
|
failures.push(`${filePath}: ${msg}`);
|
|
192156
|
-
|
|
192858
|
+
log20.error(`channel file send failed: ${pending.channelType} -> ${msg}`);
|
|
192157
192859
|
}
|
|
192158
192860
|
continue;
|
|
192159
192861
|
}
|
|
@@ -192166,17 +192868,17 @@ var ChannelManager = class {
|
|
|
192166
192868
|
const absolutePath = await attachmentStorage.getAttachmentPath(att.path);
|
|
192167
192869
|
await this.assertSendableFilePath(absolutePath);
|
|
192168
192870
|
await adapter2.sendFile(pending.chatId, absolutePath, pending.chatType);
|
|
192169
|
-
|
|
192871
|
+
log20.info(`channel image sent: ${pending.channelType} -> ${absolutePath}`);
|
|
192170
192872
|
} catch (err) {
|
|
192171
192873
|
const msg = err instanceof Error ? err.message : String(err);
|
|
192172
192874
|
failures.push(`${att.path}: ${msg}`);
|
|
192173
|
-
|
|
192875
|
+
log20.error(`channel image send failed: ${pending.channelType} -> ${msg}`);
|
|
192174
192876
|
}
|
|
192175
192877
|
}
|
|
192176
192878
|
}
|
|
192177
192879
|
}
|
|
192178
192880
|
if (failures.length > 0) {
|
|
192179
|
-
|
|
192881
|
+
log20.error(`sendFiles: ${failures.length}/${total} files failed: ${failures.join("; ")}`);
|
|
192180
192882
|
}
|
|
192181
192883
|
}
|
|
192182
192884
|
extractSendFilePath(args2) {
|
|
@@ -211498,6 +212200,7 @@ var DESKTOP_ONLY_CHANNELS = /* @__PURE__ */ new Set([
|
|
|
211498
212200
|
IPC_OPEN_EXTERNAL_URL,
|
|
211499
212201
|
IPC_OPEN_LOCAL_PATH,
|
|
211500
212202
|
IPC_SHOW_LOCAL_ITEM_IN_FOLDER,
|
|
212203
|
+
IPC_COPY_IMAGE_TO_CLIPBOARD,
|
|
211501
212204
|
IPC_OPEN_ATTACHMENT
|
|
211502
212205
|
]);
|
|
211503
212206
|
var RpcRouter = class {
|
|
@@ -211553,12 +212256,83 @@ function registerRpc(channel, handler) {
|
|
|
211553
212256
|
|
|
211554
212257
|
// src/electron/main/telemetry/MainTelemetryService.ts
|
|
211555
212258
|
init_logger();
|
|
212259
|
+
|
|
212260
|
+
// src/electron/main/telemetry/TelemetryPolicy.ts
|
|
212261
|
+
var DEFAULT_UPLOAD_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
212262
|
+
"app.started",
|
|
212263
|
+
"conversation.created",
|
|
212264
|
+
"conversation.deleted",
|
|
212265
|
+
"session.created",
|
|
212266
|
+
"session.deleted",
|
|
212267
|
+
"message.sent",
|
|
212268
|
+
"message.stopped",
|
|
212269
|
+
"group.thread.created",
|
|
212270
|
+
"update.check",
|
|
212271
|
+
"update.available",
|
|
212272
|
+
"feedback.sent",
|
|
212273
|
+
"run_completed",
|
|
212274
|
+
"llm_call_finished",
|
|
212275
|
+
"crash.summary",
|
|
212276
|
+
"memory.alert"
|
|
212277
|
+
]);
|
|
212278
|
+
var BLOCKED_PROPERTY_PATTERN = /(prompt|content|messageText|response|stack|path|file|directory|command|stdout|stderr|url|query|apikey|api_key|secret|password|authorization|cookie)/i;
|
|
212279
|
+
var MAX_PROPERTIES = 50;
|
|
212280
|
+
var MAX_STRING_LENGTH2 = 200;
|
|
212281
|
+
var DefaultTelemetryPolicy = class {
|
|
212282
|
+
constructor(allowlist = DEFAULT_UPLOAD_ALLOWLIST) {
|
|
212283
|
+
this.allowlist = allowlist;
|
|
212284
|
+
}
|
|
212285
|
+
allowlist;
|
|
212286
|
+
shouldUploadEventName(name21) {
|
|
212287
|
+
return this.allowlist.has(name21);
|
|
212288
|
+
}
|
|
212289
|
+
sanitizeProperties(name21, properties) {
|
|
212290
|
+
if (!properties) return void 0;
|
|
212291
|
+
const out = {};
|
|
212292
|
+
let count = 0;
|
|
212293
|
+
for (const [rawKey, value] of Object.entries(properties)) {
|
|
212294
|
+
if (count >= MAX_PROPERTIES) break;
|
|
212295
|
+
const key = rawKey.trim();
|
|
212296
|
+
if (!key || key.length > 100 || BLOCKED_PROPERTY_PATTERN.test(key)) continue;
|
|
212297
|
+
if (typeof value === "string") {
|
|
212298
|
+
out[key] = normalizeStringProperty(key, value);
|
|
212299
|
+
count++;
|
|
212300
|
+
} else if (typeof value === "number" && Number.isFinite(value)) {
|
|
212301
|
+
out[key] = bucketNumberIfNeeded(key, value);
|
|
212302
|
+
count++;
|
|
212303
|
+
} else if (typeof value === "boolean") {
|
|
212304
|
+
out[key] = value;
|
|
212305
|
+
count++;
|
|
212306
|
+
}
|
|
212307
|
+
}
|
|
212308
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
212309
|
+
}
|
|
212310
|
+
};
|
|
212311
|
+
var defaultTelemetryPolicy = new DefaultTelemetryPolicy();
|
|
212312
|
+
function normalizeStringProperty(key, value) {
|
|
212313
|
+
return value.slice(0, MAX_STRING_LENGTH2);
|
|
212314
|
+
}
|
|
212315
|
+
function bucketNumberIfNeeded(key, value) {
|
|
212316
|
+
if (/duration|latency|elapsed/i.test(key)) return bucket(value, [1e3, 3e3, 1e4, 3e4, 6e4], "ms");
|
|
212317
|
+
if (/token/i.test(key)) return bucket(value, [1e3, 4e3, 16e3, 64e3, 128e3], "tokens");
|
|
212318
|
+
if (/length|size|bytes|count/i.test(key)) return bucket(value, [1, 10, 100, 1e3, 1e4], "count");
|
|
212319
|
+
if (/rss|heap|memory/i.test(key)) return bucket(value, [256, 512, 1024, 1536, 2200, 4096], "mb");
|
|
212320
|
+
return value;
|
|
212321
|
+
}
|
|
212322
|
+
function bucket(value, limits, suffix) {
|
|
212323
|
+
for (const limit of limits) {
|
|
212324
|
+
if (value <= limit) return `<=${limit}${suffix}`;
|
|
212325
|
+
}
|
|
212326
|
+
return `>${limits[limits.length - 1]}${suffix}`;
|
|
212327
|
+
}
|
|
212328
|
+
|
|
212329
|
+
// src/electron/main/telemetry/MainTelemetryService.ts
|
|
211556
212330
|
var logger22 = createLogger("telemetry");
|
|
211557
212331
|
function sanitizeEventName(value) {
|
|
211558
212332
|
if (typeof value !== "string") return "";
|
|
211559
212333
|
return value.trim().slice(0, 200);
|
|
211560
212334
|
}
|
|
211561
|
-
function sanitizeProperties(input) {
|
|
212335
|
+
function sanitizeProperties(name21, input) {
|
|
211562
212336
|
if (!input || typeof input !== "object" || Array.isArray(input)) return void 0;
|
|
211563
212337
|
const out = {};
|
|
211564
212338
|
let count = 0;
|
|
@@ -211577,7 +212351,7 @@ function sanitizeProperties(input) {
|
|
|
211577
212351
|
count++;
|
|
211578
212352
|
}
|
|
211579
212353
|
}
|
|
211580
|
-
return Object.keys(out).length > 0 ? out : void 0;
|
|
212354
|
+
return defaultTelemetryPolicy.sanitizeProperties(name21, Object.keys(out).length > 0 ? out : void 0);
|
|
211581
212355
|
}
|
|
211582
212356
|
function sanitizeFeedback(input) {
|
|
211583
212357
|
if (!input || typeof input !== "object") return null;
|
|
@@ -211611,7 +212385,8 @@ var MainTelemetryService = class {
|
|
|
211611
212385
|
}
|
|
211612
212386
|
track(name21, properties) {
|
|
211613
212387
|
try {
|
|
211614
|
-
|
|
212388
|
+
if (!defaultTelemetryPolicy.shouldUploadEventName(name21)) return;
|
|
212389
|
+
this.client.track(name21, defaultTelemetryPolicy.sanitizeProperties(name21, properties));
|
|
211615
212390
|
} catch (err) {
|
|
211616
212391
|
logger22.debug("telemetry track ignored", err);
|
|
211617
212392
|
}
|
|
@@ -211669,7 +212444,7 @@ var MainTelemetryService = class {
|
|
|
211669
212444
|
registerRpc(IPC_TELEMETRY_TRACK, (name21, properties) => {
|
|
211670
212445
|
const safeName = sanitizeEventName(name21);
|
|
211671
212446
|
if (!safeName) return;
|
|
211672
|
-
this.track(safeName, sanitizeProperties(properties));
|
|
212447
|
+
this.track(safeName, sanitizeProperties(safeName, properties));
|
|
211673
212448
|
});
|
|
211674
212449
|
registerRpc(IPC_TELEMETRY_FEEDBACK, async (feedback) => {
|
|
211675
212450
|
const safe = sanitizeFeedback(feedback);
|
|
@@ -211781,7 +212556,8 @@ function withLlmLanguageTelemetry(model, context2) {
|
|
|
211781
212556
|
ok: true,
|
|
211782
212557
|
streaming: false,
|
|
211783
212558
|
durationMs: Date.now() - startedAt,
|
|
211784
|
-
finishReason: result.finishReason?.unified
|
|
212559
|
+
finishReason: result.finishReason?.unified,
|
|
212560
|
+
...summarizeUsage(result.usage)
|
|
211785
212561
|
});
|
|
211786
212562
|
return result;
|
|
211787
212563
|
} catch (error48) {
|
|
@@ -211913,6 +212689,11 @@ function sanitizeLlmTelemetry(event) {
|
|
|
211913
212689
|
addBoolean(properties, "hasFiles", event.hasFiles);
|
|
211914
212690
|
addBoolean(properties, "hasTools", event.hasTools);
|
|
211915
212691
|
addString(properties, "finishReason", event.finishReason);
|
|
212692
|
+
addNumber(properties, "inputTokens", event.inputTokens);
|
|
212693
|
+
addNumber(properties, "outputTokens", event.outputTokens);
|
|
212694
|
+
addNumber(properties, "totalTokens", event.totalTokens);
|
|
212695
|
+
addNumber(properties, "cachedInputTokens", event.cachedInputTokens);
|
|
212696
|
+
addNumber(properties, "reasoningTokens", event.reasoningTokens);
|
|
211916
212697
|
return properties;
|
|
211917
212698
|
}
|
|
211918
212699
|
function summarizeLanguageInput(params) {
|
|
@@ -211955,12 +212736,14 @@ function summarizeImageInput(params) {
|
|
|
211955
212736
|
function instrumentStream(stream, context2, input, startedAt) {
|
|
211956
212737
|
let captured = false;
|
|
211957
212738
|
let finishReason;
|
|
212739
|
+
let usage;
|
|
211958
212740
|
const captureOnce = (event) => {
|
|
211959
212741
|
if (captured) return;
|
|
211960
212742
|
captured = true;
|
|
211961
212743
|
captureLlmCallFinished({
|
|
211962
212744
|
...context2,
|
|
211963
212745
|
...input,
|
|
212746
|
+
...usage,
|
|
211964
212747
|
...event,
|
|
211965
212748
|
streaming: true,
|
|
211966
212749
|
durationMs: Date.now() - startedAt
|
|
@@ -211970,6 +212753,7 @@ function instrumentStream(stream, context2, input, startedAt) {
|
|
|
211970
212753
|
transform(chunk, controller) {
|
|
211971
212754
|
if (isStreamFinishChunk(chunk)) {
|
|
211972
212755
|
finishReason = chunk.finishReason?.unified;
|
|
212756
|
+
usage = summarizeUsage(chunk.usage);
|
|
211973
212757
|
} else if (isStreamErrorChunk(chunk)) {
|
|
211974
212758
|
captureOnce({ ok: false, ...classifyLlmError(chunk.error) });
|
|
211975
212759
|
}
|
|
@@ -211986,6 +212770,28 @@ function isStreamFinishChunk(chunk) {
|
|
|
211986
212770
|
function isStreamErrorChunk(chunk) {
|
|
211987
212771
|
return !!chunk && typeof chunk === "object" && chunk.type === "error";
|
|
211988
212772
|
}
|
|
212773
|
+
function summarizeUsage(usage) {
|
|
212774
|
+
if (!usage || typeof usage !== "object") return void 0;
|
|
212775
|
+
const record2 = usage;
|
|
212776
|
+
const inputTokens = getFiniteNumber(record2.inputTokens);
|
|
212777
|
+
const outputTokens = getFiniteNumber(record2.outputTokens);
|
|
212778
|
+
const totalTokens = getFiniteNumber(record2.totalTokens) ?? (typeof inputTokens === "number" || typeof outputTokens === "number" ? (inputTokens ?? 0) + (outputTokens ?? 0) : void 0);
|
|
212779
|
+
const cachedInputTokens = getFiniteNumber(record2.cachedInputTokens);
|
|
212780
|
+
const reasoningTokens = getFiniteNumber(record2.reasoningTokens);
|
|
212781
|
+
if (inputTokens === void 0 && outputTokens === void 0 && totalTokens === void 0 && cachedInputTokens === void 0 && reasoningTokens === void 0) {
|
|
212782
|
+
return void 0;
|
|
212783
|
+
}
|
|
212784
|
+
const summarizedUsage = {};
|
|
212785
|
+
setUsageField(summarizedUsage, "inputTokens", inputTokens);
|
|
212786
|
+
setUsageField(summarizedUsage, "outputTokens", outputTokens);
|
|
212787
|
+
setUsageField(summarizedUsage, "totalTokens", totalTokens);
|
|
212788
|
+
setUsageField(summarizedUsage, "cachedInputTokens", cachedInputTokens);
|
|
212789
|
+
setUsageField(summarizedUsage, "reasoningTokens", reasoningTokens);
|
|
212790
|
+
return summarizedUsage;
|
|
212791
|
+
}
|
|
212792
|
+
function getFiniteNumber(value) {
|
|
212793
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
212794
|
+
}
|
|
211989
212795
|
function isLanguageModelV3(model) {
|
|
211990
212796
|
return typeof model === "object" && model !== null && model.specificationVersion === "v3";
|
|
211991
212797
|
}
|
|
@@ -212036,6 +212842,11 @@ function addNumber(properties, key, value) {
|
|
|
212036
212842
|
function addBoolean(properties, key, value) {
|
|
212037
212843
|
if (typeof value === "boolean") properties[key] = value;
|
|
212038
212844
|
}
|
|
212845
|
+
function setUsageField(usage, key, value) {
|
|
212846
|
+
if (typeof value === "number") {
|
|
212847
|
+
usage[key] = value;
|
|
212848
|
+
}
|
|
212849
|
+
}
|
|
212039
212850
|
function hasOwnInputImages(value) {
|
|
212040
212851
|
if (!value || typeof value !== "object") return false;
|
|
212041
212852
|
return Object.keys(value).some((key) => key.toLowerCase().includes("image"));
|
|
@@ -212217,6 +213028,7 @@ var AutoUpdaterManager = class {
|
|
|
212217
213028
|
}
|
|
212218
213029
|
/** 用户每日首次发送消息后静默检查(延迟 3s) */
|
|
212219
213030
|
triggerDailyAutoCheck() {
|
|
213031
|
+
if (process.env.KAI_RUNTIME === "cli") return;
|
|
212220
213032
|
const { app } = getElectron();
|
|
212221
213033
|
if (!app.isPackaged) return;
|
|
212222
213034
|
const enabled = config.get("autoCheckForUpdates");
|
|
@@ -212326,7 +213138,7 @@ async function resolveIdType(id) {
|
|
|
212326
213138
|
}
|
|
212327
213139
|
return { type: "single", conversationId: id };
|
|
212328
213140
|
}
|
|
212329
|
-
async function resolveTargetAgent(threadId, groupId, mentionDirective) {
|
|
213141
|
+
async function resolveTargetAgent(threadId, groupId, mentionDirective, supervisorId) {
|
|
212330
213142
|
if (!groupId) {
|
|
212331
213143
|
const targetAgentId2 = mentionDirective.kind === "single" ? mentionDirective.agentId : threadId;
|
|
212332
213144
|
if (!targetAgentId2) {
|
|
@@ -212334,6 +213146,10 @@ async function resolveTargetAgent(threadId, groupId, mentionDirective) {
|
|
|
212334
213146
|
}
|
|
212335
213147
|
return targetAgentId2;
|
|
212336
213148
|
}
|
|
213149
|
+
if (supervisorId) {
|
|
213150
|
+
await threadService.updateSpeaker(threadId, supervisorId);
|
|
213151
|
+
return supervisorId;
|
|
213152
|
+
}
|
|
212337
213153
|
if (mentionDirective.kind === "broadcast") {
|
|
212338
213154
|
const thread2 = await threadFileStore.findById(threadId);
|
|
212339
213155
|
if (thread2?.speakerId) return thread2.speakerId;
|
|
@@ -212423,7 +213239,12 @@ async function handleSendUserMessage(request) {
|
|
|
212423
213239
|
throw new Error("Conversation is being compacted, please wait");
|
|
212424
213240
|
}
|
|
212425
213241
|
const blocks = buildUserBlocks(content, attachments);
|
|
212426
|
-
const targetAgentId = await resolveTargetAgent(
|
|
213242
|
+
const targetAgentId = await resolveTargetAgent(
|
|
213243
|
+
conversationId,
|
|
213244
|
+
groupId,
|
|
213245
|
+
mentionDirective,
|
|
213246
|
+
normalizedMetadata?.supervisorId
|
|
213247
|
+
);
|
|
212427
213248
|
try {
|
|
212428
213249
|
const message = await messagePublisher.publishUserMessage(conversationId, blocks, {
|
|
212429
213250
|
metadata: normalizedMetadata,
|
|
@@ -212542,7 +213363,7 @@ function registerChatHandlers() {
|
|
|
212542
213363
|
}
|
|
212543
213364
|
|
|
212544
213365
|
// src/electron/main/handlers/conversation-handlers.ts
|
|
212545
|
-
var
|
|
213366
|
+
var import_promises15 = require("fs/promises");
|
|
212546
213367
|
init_conversation_event_bus();
|
|
212547
213368
|
init_message2();
|
|
212548
213369
|
init_agent_file_store();
|
|
@@ -212557,6 +213378,40 @@ init_thread_file_store();
|
|
|
212557
213378
|
init_agent_file_store();
|
|
212558
213379
|
init_ThreadManagerPool();
|
|
212559
213380
|
init_logger();
|
|
213381
|
+
|
|
213382
|
+
// src/electron/main/handlers/avatar-storage.ts
|
|
213383
|
+
var import_promises14 = require("fs/promises");
|
|
213384
|
+
var import_path18 = require("path");
|
|
213385
|
+
var import_sharp = __toESM(require("sharp"));
|
|
213386
|
+
var AVATAR_DIR = "avatars";
|
|
213387
|
+
var AVATAR_FILE = "avatar.png";
|
|
213388
|
+
var AVATAR_RELATIVE_PATH = `${AVATAR_DIR}/${AVATAR_FILE}`;
|
|
213389
|
+
var MAX_AVATAR_SOURCE_BYTES = 10 * 1024 * 1024;
|
|
213390
|
+
var AVATAR_SIZE = 256;
|
|
213391
|
+
async function writeOwnerAvatar(ownerDir, sourcePath) {
|
|
213392
|
+
const source = sourcePath.trim();
|
|
213393
|
+
if (!source) throw new Error("AVATAR_SOURCE_REQUIRED");
|
|
213394
|
+
const sourceStats = await (0, import_promises14.stat)(source).catch(() => null);
|
|
213395
|
+
if (!sourceStats?.isFile()) throw new Error("AVATAR_SOURCE_NOT_FILE");
|
|
213396
|
+
if (sourceStats.size > MAX_AVATAR_SOURCE_BYTES) throw new Error("AVATAR_IMAGE_TOO_LARGE");
|
|
213397
|
+
const avatarDir = (0, import_path18.join)(ownerDir, AVATAR_DIR);
|
|
213398
|
+
const avatarPath = (0, import_path18.join)(avatarDir, AVATAR_FILE);
|
|
213399
|
+
await (0, import_promises14.mkdir)(avatarDir, { recursive: true });
|
|
213400
|
+
try {
|
|
213401
|
+
await (0, import_sharp.default)(source, { failOn: "error" }).rotate().resize(AVATAR_SIZE, AVATAR_SIZE, { fit: "cover", position: "centre" }).png().toFile(avatarPath);
|
|
213402
|
+
} catch (error48) {
|
|
213403
|
+
if (error48 instanceof Error && /Input file contains unsupported image format|corrupt|invalid/i.test(error48.message)) {
|
|
213404
|
+
throw new Error("AVATAR_IMAGE_UNREADABLE");
|
|
213405
|
+
}
|
|
213406
|
+
throw new Error("AVATAR_SAVE_FAILED");
|
|
213407
|
+
}
|
|
213408
|
+
return AVATAR_RELATIVE_PATH;
|
|
213409
|
+
}
|
|
213410
|
+
async function removeOwnerAvatar(ownerDir) {
|
|
213411
|
+
await (0, import_promises14.rm)((0, import_path18.join)(ownerDir, AVATAR_DIR), { force: true, recursive: true }).catch(() => void 0);
|
|
213412
|
+
}
|
|
213413
|
+
|
|
213414
|
+
// src/electron/main/handlers/conversation-handlers.ts
|
|
212560
213415
|
var logger25 = createLogger("conversation-handlers");
|
|
212561
213416
|
var filterVisibleMessages = (messages) => messages.filter((message) => !message.compressionMetadata?.isSummary);
|
|
212562
213417
|
async function removeAgentFromAllGroups(agentId) {
|
|
@@ -212592,6 +213447,7 @@ async function resolveConversationView(id) {
|
|
|
212592
213447
|
title: group.name,
|
|
212593
213448
|
type: "group",
|
|
212594
213449
|
groupId: group.id,
|
|
213450
|
+
avatar: group.avatar,
|
|
212595
213451
|
createdAt: thread.createdAt,
|
|
212596
213452
|
updatedAt: thread.updatedAt,
|
|
212597
213453
|
messageCount: 0
|
|
@@ -212678,6 +213534,7 @@ async function handleListConversations() {
|
|
|
212678
213534
|
title: group.name,
|
|
212679
213535
|
type: "group",
|
|
212680
213536
|
groupId: group.id,
|
|
213537
|
+
avatar: group.avatar,
|
|
212681
213538
|
createdAt: defaultThreadWithMsg.createdAt,
|
|
212682
213539
|
updatedAt: defaultThreadWithMsg.updatedAt,
|
|
212683
213540
|
messageCount: 0,
|
|
@@ -212739,6 +213596,17 @@ async function handleUpdateGroup(id, updates) {
|
|
|
212739
213596
|
await emitConversationSnapshot(defaultThread.id);
|
|
212740
213597
|
}
|
|
212741
213598
|
}
|
|
213599
|
+
async function handleSetGroupAvatar(groupId, sourcePath) {
|
|
213600
|
+
if (!await groupFileStore.exists(groupId)) throw new Error("GROUP_NOT_FOUND");
|
|
213601
|
+
const avatar = await writeOwnerAvatar(getGroupDir(groupId), sourcePath);
|
|
213602
|
+
await handleUpdateGroup(groupId, { avatar });
|
|
213603
|
+
return { avatar };
|
|
213604
|
+
}
|
|
213605
|
+
async function handleRemoveGroupAvatar(groupId) {
|
|
213606
|
+
if (!await groupFileStore.exists(groupId)) throw new Error("GROUP_NOT_FOUND");
|
|
213607
|
+
await removeOwnerAvatar(getGroupDir(groupId));
|
|
213608
|
+
await handleUpdateGroup(groupId, { avatar: null });
|
|
213609
|
+
}
|
|
212742
213610
|
async function handleDeleteGroup(id) {
|
|
212743
213611
|
threadManagerPool.removeManagersByGroup(id);
|
|
212744
213612
|
const threads = await threadFileStore.listByGroupId(id);
|
|
@@ -212807,7 +213675,7 @@ async function handleOpenAttachment(relativePath) {
|
|
|
212807
213675
|
await shell2.openPath(absolutePath);
|
|
212808
213676
|
}
|
|
212809
213677
|
async function openDir(dir) {
|
|
212810
|
-
await (0,
|
|
213678
|
+
await (0, import_promises15.mkdir)(dir, { recursive: true });
|
|
212811
213679
|
const { shell: shell2 } = require("electron");
|
|
212812
213680
|
const error48 = await shell2.openPath(dir);
|
|
212813
213681
|
if (error48) throw new Error(error48);
|
|
@@ -212836,6 +213704,8 @@ function registerConversationHandlers() {
|
|
|
212836
213704
|
registerRpc(IPC_GET_GROUP, handleGetGroup);
|
|
212837
213705
|
registerRpc(IPC_UPDATE_GROUP, handleUpdateGroup);
|
|
212838
213706
|
registerRpc(IPC_DELETE_GROUP, handleDeleteGroup);
|
|
213707
|
+
registerRpc(IPC_SET_GROUP_AVATAR, handleSetGroupAvatar);
|
|
213708
|
+
registerRpc(IPC_REMOVE_GROUP_AVATAR, handleRemoveGroupAvatar);
|
|
212839
213709
|
registerRpc(IPC_GET_GROUP_MEMBERS, handleGetGroupMembers);
|
|
212840
213710
|
registerRpc(IPC_LIST_GROUP_THREADS, handleListGroupThreads);
|
|
212841
213711
|
registerRpc(IPC_GET_GROUP_THREAD, handleGetGroupThread);
|
|
@@ -213032,6 +213902,19 @@ async function handleDeleteAgent(id) {
|
|
|
213032
213902
|
);
|
|
213033
213903
|
await agentFileStore.delete(id);
|
|
213034
213904
|
}
|
|
213905
|
+
async function handleSetAgentAvatar(agentId, sourcePath) {
|
|
213906
|
+
const agent = await loadAgent(agentId, true);
|
|
213907
|
+
if (!agent) throw new Error("AGENT_NOT_FOUND");
|
|
213908
|
+
const avatar = await writeOwnerAvatar(getAgentRootDir(agentId), sourcePath);
|
|
213909
|
+
await agentFileStore.writeMeta({ ...agent, avatar, updatedAt: Date.now() });
|
|
213910
|
+
return { avatar };
|
|
213911
|
+
}
|
|
213912
|
+
async function handleRemoveAgentAvatar(agentId) {
|
|
213913
|
+
const agent = await loadAgent(agentId, true);
|
|
213914
|
+
if (!agent) throw new Error("AGENT_NOT_FOUND");
|
|
213915
|
+
await removeOwnerAvatar(getAgentRootDir(agentId));
|
|
213916
|
+
await agentFileStore.writeMeta({ ...agent, avatar: void 0, updatedAt: Date.now() });
|
|
213917
|
+
}
|
|
213035
213918
|
async function handleGetWorkspaceFile(agentId, filename) {
|
|
213036
213919
|
return getWorkspaceFile(agentId, filename);
|
|
213037
213920
|
}
|
|
@@ -213179,6 +214062,8 @@ function registerAgentHandlers() {
|
|
|
213179
214062
|
registerRpc(IPC_LIST_AGENTS, handleListAgents);
|
|
213180
214063
|
registerRpc(IPC_UPDATE_AGENT, handleUpdateAgent);
|
|
213181
214064
|
registerRpc(IPC_DELETE_AGENT, handleDeleteAgent);
|
|
214065
|
+
registerRpc(IPC_SET_AGENT_AVATAR, handleSetAgentAvatar);
|
|
214066
|
+
registerRpc(IPC_REMOVE_AGENT_AVATAR, handleRemoveAgentAvatar);
|
|
213182
214067
|
registerRpc(IPC_GET_WORKSPACE_FILE, handleGetWorkspaceFile);
|
|
213183
214068
|
registerRpc(IPC_UPDATE_WORKSPACE_FILE, handleUpdateWorkspaceFile);
|
|
213184
214069
|
registerRpc(IPC_LIST_WORKSPACE_FILES, handleListWorkspaceFiles);
|
|
@@ -213628,13 +214513,17 @@ function registerSearchHandlers() {
|
|
|
213628
214513
|
}
|
|
213629
214514
|
|
|
213630
214515
|
// src/electron/main/handlers/url-handlers.ts
|
|
213631
|
-
var
|
|
214516
|
+
var import_promises16 = __toESM(require("node:fs/promises"));
|
|
213632
214517
|
var import_node_path4 = __toESM(require("node:path"));
|
|
213633
214518
|
init_ipc_events();
|
|
213634
214519
|
init_config();
|
|
213635
214520
|
init_workspace();
|
|
214521
|
+
init_agent_file_store();
|
|
214522
|
+
init_group_file_store();
|
|
213636
214523
|
var SAFE_PROTOCOLS = ["http:", "https:"];
|
|
213637
214524
|
var INVALID_PATH_CHARS = /[\0\r\n`$<>|;&]/;
|
|
214525
|
+
var WINDOWS_DRIVE_ABSOLUTE_PATH = /^[A-Za-z]:[\\/]/;
|
|
214526
|
+
var WINDOWS_UNC_ABSOLUTE_PATH = /^\\\\[^\\/]+[\\/][^\\/]+/;
|
|
213638
214527
|
function isUrlSafe(urlString) {
|
|
213639
214528
|
try {
|
|
213640
214529
|
const url2 = new URL(urlString);
|
|
@@ -213647,6 +214536,9 @@ function isSubPath(parentDir, targetPath) {
|
|
|
213647
214536
|
const relative4 = import_node_path4.default.relative(parentDir, targetPath);
|
|
213648
214537
|
return relative4 === "" || !relative4.startsWith("..") && !import_node_path4.default.isAbsolute(relative4);
|
|
213649
214538
|
}
|
|
214539
|
+
function isAvatarPath(parts) {
|
|
214540
|
+
return parts.length === 2 && parts[0] === "avatars" && parts[1] === "avatar.png";
|
|
214541
|
+
}
|
|
213650
214542
|
function resolveKaiLocalPath(urlString) {
|
|
213651
214543
|
let pathname;
|
|
213652
214544
|
try {
|
|
@@ -213683,6 +214575,18 @@ function resolveKaiLocalPath(urlString) {
|
|
|
213683
214575
|
}
|
|
213684
214576
|
return resolvedPath;
|
|
213685
214577
|
}
|
|
214578
|
+
if (pathname.startsWith("/agent/") || pathname.startsWith("/group/")) {
|
|
214579
|
+
const [kind, ownerId, ...relativeParts] = pathname.slice(1).split("/");
|
|
214580
|
+
if (!ownerId || !isAvatarPath(relativeParts)) {
|
|
214581
|
+
throw new Error("ERROR_INVALID_LOCAL_PATH");
|
|
214582
|
+
}
|
|
214583
|
+
const ownerDir = kind === "agent" ? getAgentRootDir(ownerId) : getGroupDir(ownerId);
|
|
214584
|
+
const resolvedPath = import_node_path4.default.resolve(ownerDir, relativeParts.join("/"));
|
|
214585
|
+
if (!isSubPath(ownerDir, resolvedPath)) {
|
|
214586
|
+
throw new Error("ERROR_INVALID_LOCAL_PATH");
|
|
214587
|
+
}
|
|
214588
|
+
return resolvedPath;
|
|
214589
|
+
}
|
|
213686
214590
|
throw new Error("ERROR_INVALID_LOCAL_PATH");
|
|
213687
214591
|
}
|
|
213688
214592
|
function resolveLocalPath(inputPath) {
|
|
@@ -213697,12 +214601,14 @@ function resolveLocalPath(inputPath) {
|
|
|
213697
214601
|
resolvedPath = import_node_path4.default.join(homeDir, trimmedPath.slice(2));
|
|
213698
214602
|
} else if (trimmedPath.startsWith("./")) {
|
|
213699
214603
|
resolvedPath = import_node_path4.default.resolve(process.cwd(), trimmedPath);
|
|
214604
|
+
} else if (WINDOWS_DRIVE_ABSOLUTE_PATH.test(trimmedPath) || WINDOWS_UNC_ABSOLUTE_PATH.test(trimmedPath)) {
|
|
214605
|
+
resolvedPath = import_node_path4.default.win32.normalize(trimmedPath);
|
|
213700
214606
|
} else if (trimmedPath.startsWith("/")) {
|
|
213701
214607
|
resolvedPath = import_node_path4.default.normalize(trimmedPath);
|
|
213702
214608
|
} else {
|
|
213703
214609
|
throw new Error("ERROR_INVALID_LOCAL_PATH");
|
|
213704
214610
|
}
|
|
213705
|
-
if (!import_node_path4.default.isAbsolute(resolvedPath)) {
|
|
214611
|
+
if (!import_node_path4.default.isAbsolute(resolvedPath) && !import_node_path4.default.win32.isAbsolute(resolvedPath)) {
|
|
213706
214612
|
throw new Error("ERROR_INVALID_LOCAL_PATH");
|
|
213707
214613
|
}
|
|
213708
214614
|
return resolvedPath;
|
|
@@ -213714,7 +214620,7 @@ async function handleOpenExternalUrl(url2) {
|
|
|
213714
214620
|
}
|
|
213715
214621
|
async function handleOpenLocalPath(inputPath) {
|
|
213716
214622
|
const resolvedPath = resolveLocalPath(inputPath);
|
|
213717
|
-
const stats = await
|
|
214623
|
+
const stats = await import_promises16.default.stat(resolvedPath).catch(() => null);
|
|
213718
214624
|
if (!stats?.isFile()) {
|
|
213719
214625
|
throw new Error("ERROR_LOCAL_PATH_NOT_FILE");
|
|
213720
214626
|
}
|
|
@@ -213724,7 +214630,7 @@ async function handleOpenLocalPath(inputPath) {
|
|
|
213724
214630
|
}
|
|
213725
214631
|
async function handleReadFileContent(inputPath) {
|
|
213726
214632
|
const resolvedPath = resolveLocalPath(inputPath);
|
|
213727
|
-
const stats = await
|
|
214633
|
+
const stats = await import_promises16.default.stat(resolvedPath).catch(() => null);
|
|
213728
214634
|
if (!stats?.isFile()) {
|
|
213729
214635
|
throw new Error("ERROR_LOCAL_PATH_NOT_FILE");
|
|
213730
214636
|
}
|
|
@@ -213738,7 +214644,7 @@ async function handleReadFileContent(inputPath) {
|
|
|
213738
214644
|
mimeType
|
|
213739
214645
|
};
|
|
213740
214646
|
}
|
|
213741
|
-
const buffer = await
|
|
214647
|
+
const buffer = await import_promises16.default.readFile(resolvedPath);
|
|
213742
214648
|
const isText2 = !isBufferBinary(buffer);
|
|
213743
214649
|
const content = isText2 ? buffer.toString("utf-8") : "";
|
|
213744
214650
|
return {
|
|
@@ -213753,11 +214659,29 @@ async function handleShowLocalItemInFolder(localUrlOrPath) {
|
|
|
213753
214659
|
const { shell: shell2 } = require("electron");
|
|
213754
214660
|
shell2.showItemInFolder(resolvedPath);
|
|
213755
214661
|
}
|
|
214662
|
+
async function handleCopyImageToClipboard(localUrlOrPath) {
|
|
214663
|
+
const resolvedPath = localUrlOrPath.startsWith("kai://local/") ? resolveKaiLocalPath(localUrlOrPath) : resolveLocalPath(localUrlOrPath);
|
|
214664
|
+
const stats = await import_promises16.default.stat(resolvedPath).catch(() => null);
|
|
214665
|
+
if (!stats?.isFile()) {
|
|
214666
|
+
throw new Error("ERROR_LOCAL_PATH_NOT_FILE");
|
|
214667
|
+
}
|
|
214668
|
+
const mimeType = getMimeType2(import_node_path4.default.extname(resolvedPath).toLowerCase());
|
|
214669
|
+
if (!mimeType.startsWith("image/")) {
|
|
214670
|
+
throw new Error("ERROR_LOCAL_PATH_NOT_IMAGE");
|
|
214671
|
+
}
|
|
214672
|
+
const { clipboard, nativeImage } = require("electron");
|
|
214673
|
+
const image = nativeImage.createFromPath(resolvedPath);
|
|
214674
|
+
if (image.isEmpty()) {
|
|
214675
|
+
throw new Error("ERROR_IMAGE_CLIPBOARD_UNSUPPORTED");
|
|
214676
|
+
}
|
|
214677
|
+
clipboard.writeImage(image);
|
|
214678
|
+
}
|
|
213756
214679
|
function registerUrlHandlers() {
|
|
213757
214680
|
registerRpc(IPC_OPEN_EXTERNAL_URL, handleOpenExternalUrl);
|
|
213758
214681
|
registerRpc(IPC_OPEN_LOCAL_PATH, handleOpenLocalPath);
|
|
213759
214682
|
registerRpc(IPC_READ_FILE_CONTENT, handleReadFileContent);
|
|
213760
214683
|
registerRpc(IPC_SHOW_LOCAL_ITEM_IN_FOLDER, handleShowLocalItemInFolder);
|
|
214684
|
+
registerRpc(IPC_COPY_IMAGE_TO_CLIPBOARD, handleCopyImageToClipboard);
|
|
213761
214685
|
}
|
|
213762
214686
|
function getMimeType2(ext) {
|
|
213763
214687
|
const map3 = {
|
|
@@ -214248,7 +215172,7 @@ function setupHealthIPC() {
|
|
|
214248
215172
|
|
|
214249
215173
|
// src/electron/main/handlers/app-info-handlers.ts
|
|
214250
215174
|
init_ipc_events();
|
|
214251
|
-
var
|
|
215175
|
+
var import_promises17 = __toESM(require("node:fs/promises"));
|
|
214252
215176
|
var import_node_path5 = __toESM(require("node:path"));
|
|
214253
215177
|
function getReleaseNotesPath() {
|
|
214254
215178
|
const { app } = require("electron");
|
|
@@ -214267,7 +215191,7 @@ async function handleGetAppInfo() {
|
|
|
214267
215191
|
}
|
|
214268
215192
|
async function handleGetReleaseNotes() {
|
|
214269
215193
|
try {
|
|
214270
|
-
return await
|
|
215194
|
+
return await import_promises17.default.readFile(getReleaseNotesPath(), "utf-8");
|
|
214271
215195
|
} catch {
|
|
214272
215196
|
return "";
|
|
214273
215197
|
}
|
|
@@ -214285,12 +215209,12 @@ init_config();
|
|
|
214285
215209
|
|
|
214286
215210
|
// src/adapters/transport/http-server.ts
|
|
214287
215211
|
var import_node_http = __toESM(require("node:http"));
|
|
214288
|
-
var
|
|
215212
|
+
var import_promises18 = __toESM(require("node:fs/promises"));
|
|
214289
215213
|
var import_node_path6 = __toESM(require("node:path"));
|
|
214290
215214
|
var import_node_os2 = __toESM(require("node:os"));
|
|
214291
215215
|
var import_node_zlib = __toESM(require("node:zlib"));
|
|
214292
215216
|
var import_node_fs = require("node:fs");
|
|
214293
|
-
var
|
|
215217
|
+
var import_promises19 = require("node:stream/promises");
|
|
214294
215218
|
|
|
214295
215219
|
// node_modules/ws/wrapper.mjs
|
|
214296
215220
|
var import_stream5 = __toESM(require_stream(), 1);
|
|
@@ -214444,8 +215368,17 @@ var WsConnectionManager = class {
|
|
|
214444
215368
|
// src/adapters/transport/http-server.ts
|
|
214445
215369
|
init_workspace();
|
|
214446
215370
|
init_config();
|
|
215371
|
+
init_agent_file_store();
|
|
215372
|
+
init_group_file_store();
|
|
214447
215373
|
var DEFAULT_PORT = 9527;
|
|
214448
215374
|
var MAX_JSON_BODY_SIZE = 5 * 1024 * 1024;
|
|
215375
|
+
function isSubPath2(parent2, child) {
|
|
215376
|
+
const rel = import_node_path6.default.relative(parent2, child);
|
|
215377
|
+
return rel === "" || !!rel && !rel.startsWith("..") && !import_node_path6.default.isAbsolute(rel);
|
|
215378
|
+
}
|
|
215379
|
+
function isAvatarPath2(parts) {
|
|
215380
|
+
return parts.length === 2 && parts[0] === "avatars" && parts[1] === "avatar.png";
|
|
215381
|
+
}
|
|
214449
215382
|
var MAX_UPLOAD_SIZE = ATTACHMENT.MAX_SIZE;
|
|
214450
215383
|
var RENDERER_DIST_DIR = (() => {
|
|
214451
215384
|
const electronPath = import_node_path6.default.resolve(__dirname, "../renderer");
|
|
@@ -214490,8 +215423,8 @@ function getCacheControl2(filePath) {
|
|
|
214490
215423
|
}
|
|
214491
215424
|
async function fileExists(filePath) {
|
|
214492
215425
|
try {
|
|
214493
|
-
const
|
|
214494
|
-
return
|
|
215426
|
+
const stat5 = await import_promises18.default.stat(filePath);
|
|
215427
|
+
return stat5.isFile();
|
|
214495
215428
|
} catch {
|
|
214496
215429
|
return false;
|
|
214497
215430
|
}
|
|
@@ -214520,7 +215453,7 @@ async function sendStaticAsset(filePath, response, requestHeaders) {
|
|
|
214520
215453
|
}
|
|
214521
215454
|
response.writeHead(200, headers);
|
|
214522
215455
|
try {
|
|
214523
|
-
await (0,
|
|
215456
|
+
await (0, import_promises19.pipeline)((0, import_node_fs.createReadStream)(actualPath), response);
|
|
214524
215457
|
} catch (error48) {
|
|
214525
215458
|
if (!response.headersSent) {
|
|
214526
215459
|
response.writeHead(500);
|
|
@@ -214541,8 +215474,8 @@ async function serveStaticFile(urlPath, response, requestHeaders) {
|
|
|
214541
215474
|
return;
|
|
214542
215475
|
}
|
|
214543
215476
|
try {
|
|
214544
|
-
const
|
|
214545
|
-
const filePath =
|
|
215477
|
+
const stat5 = await import_promises18.default.stat(resolvedPath);
|
|
215478
|
+
const filePath = stat5.isDirectory() ? import_node_path6.default.join(resolvedPath, "index.html") : resolvedPath;
|
|
214546
215479
|
if (!await fileExists(filePath)) throw new Error("Not a file");
|
|
214547
215480
|
await sendStaticAsset(filePath, response, requestHeaders);
|
|
214548
215481
|
} catch {
|
|
@@ -214661,7 +215594,7 @@ var HttpTransportServer = class {
|
|
|
214661
215594
|
}
|
|
214662
215595
|
/**
|
|
214663
215596
|
* 提供本地文件访问(与 kai:// protocol handler 同构)
|
|
214664
|
-
* 路径格式:/full/absolute/path、/workspace/{agentId}/relative/path、/attachment/{relativePath}
|
|
215597
|
+
* 路径格式:/full/absolute/path、/workspace/{agentId}/relative/path、/attachment/{relativePath}、/agent/{agentId}/avatars/avatar.png、/group/{groupId}/avatars/avatar.png
|
|
214665
215598
|
*/
|
|
214666
215599
|
async serveLocalFile(pathname, response, isDownload = false) {
|
|
214667
215600
|
let decodedPathname;
|
|
@@ -214685,7 +215618,21 @@ var HttpTransportServer = class {
|
|
|
214685
215618
|
const relativePath = decodedPathname.slice(12);
|
|
214686
215619
|
const attachmentsDir = config.getAttachmentsPath();
|
|
214687
215620
|
resolvedPath = import_node_path6.default.resolve(attachmentsDir, relativePath);
|
|
214688
|
-
if (!
|
|
215621
|
+
if (!isSubPath2(attachmentsDir, resolvedPath)) {
|
|
215622
|
+
response.writeHead(403);
|
|
215623
|
+
response.end("Forbidden");
|
|
215624
|
+
return;
|
|
215625
|
+
}
|
|
215626
|
+
} else if (decodedPathname.startsWith("/agent/") || decodedPathname.startsWith("/group/")) {
|
|
215627
|
+
const [kind, ownerId, ...relativeParts] = decodedPathname.slice(1).split("/");
|
|
215628
|
+
if (!ownerId || !isAvatarPath2(relativeParts)) {
|
|
215629
|
+
response.writeHead(400);
|
|
215630
|
+
response.end("Bad Request");
|
|
215631
|
+
return;
|
|
215632
|
+
}
|
|
215633
|
+
const ownerDir = kind === "agent" ? getAgentRootDir(ownerId) : getGroupDir(ownerId);
|
|
215634
|
+
resolvedPath = import_node_path6.default.resolve(ownerDir, relativeParts.join("/"));
|
|
215635
|
+
if (!isSubPath2(ownerDir, resolvedPath)) {
|
|
214689
215636
|
response.writeHead(403);
|
|
214690
215637
|
response.end("Forbidden");
|
|
214691
215638
|
return;
|
|
@@ -214702,7 +215649,7 @@ var HttpTransportServer = class {
|
|
|
214702
215649
|
const imagePath = parts.slice(1).join("/");
|
|
214703
215650
|
const workspaceDir = getAgentWorkspaceDir(agentId);
|
|
214704
215651
|
resolvedPath = import_node_path6.default.resolve(workspaceDir, imagePath);
|
|
214705
|
-
if (!
|
|
215652
|
+
if (!isSubPath2(workspaceDir, resolvedPath)) {
|
|
214706
215653
|
response.writeHead(403);
|
|
214707
215654
|
response.end("Forbidden");
|
|
214708
215655
|
return;
|
|
@@ -214713,10 +215660,13 @@ var HttpTransportServer = class {
|
|
|
214713
215660
|
return;
|
|
214714
215661
|
}
|
|
214715
215662
|
try {
|
|
214716
|
-
await
|
|
215663
|
+
await import_promises18.default.stat(resolvedPath);
|
|
214717
215664
|
const ext = import_node_path6.default.extname(resolvedPath).toLowerCase();
|
|
214718
215665
|
const mimeType = getMimeType(ext);
|
|
214719
215666
|
const headers = { "Content-Type": mimeType };
|
|
215667
|
+
if (decodedPathname.startsWith("/agent/") || decodedPathname.startsWith("/group/")) {
|
|
215668
|
+
headers["Cache-Control"] = "no-store";
|
|
215669
|
+
}
|
|
214720
215670
|
if (isDownload) {
|
|
214721
215671
|
const filename = import_node_path6.default.basename(resolvedPath);
|
|
214722
215672
|
const asciiSafe = filename.replace(/[^\x20-\x7E]/g, "");
|
|
@@ -215150,14 +216100,14 @@ function registerUpdateHandlers() {
|
|
|
215150
216100
|
}
|
|
215151
216101
|
|
|
215152
216102
|
// src/adapters/storage/PinnedStore.ts
|
|
215153
|
-
var
|
|
215154
|
-
var
|
|
216103
|
+
var import_path19 = require("path");
|
|
216104
|
+
var import_promises20 = require("fs/promises");
|
|
215155
216105
|
var import_fs12 = require("fs");
|
|
215156
216106
|
init_config();
|
|
215157
216107
|
var FILE_NAME = "pinned.json";
|
|
215158
216108
|
var SCHEMA_VERSION4 = 1;
|
|
215159
216109
|
function getPinnedPath() {
|
|
215160
|
-
return (0,
|
|
216110
|
+
return (0, import_path19.join)(config.getAppDataPath(), "config", FILE_NAME);
|
|
215161
216111
|
}
|
|
215162
216112
|
function createDefaultPinnedFile() {
|
|
215163
216113
|
return { version: SCHEMA_VERSION4, agents: {}, groups: {} };
|
|
@@ -215192,17 +216142,17 @@ function clonePinnedFile(data2) {
|
|
|
215192
216142
|
};
|
|
215193
216143
|
}
|
|
215194
216144
|
async function atomicWriteJson4(path10, data2) {
|
|
215195
|
-
const dir = (0,
|
|
215196
|
-
await (0,
|
|
216145
|
+
const dir = (0, import_path19.dirname)(path10);
|
|
216146
|
+
await (0, import_promises20.mkdir)(dir, { recursive: true });
|
|
215197
216147
|
const tmp = `${path10}.tmp`;
|
|
215198
|
-
await (0,
|
|
216148
|
+
await (0, import_promises20.writeFile)(tmp, `${JSON.stringify(data2, null, 2)}
|
|
215199
216149
|
`, "utf-8");
|
|
215200
|
-
await (0,
|
|
216150
|
+
await (0, import_promises20.rename)(tmp, path10);
|
|
215201
216151
|
}
|
|
215202
216152
|
async function readJsonFile5(path10) {
|
|
215203
216153
|
if (!(0, import_fs12.existsSync)(path10)) return null;
|
|
215204
216154
|
try {
|
|
215205
|
-
const raw = await (0,
|
|
216155
|
+
const raw = await (0, import_promises20.readFile)(path10, "utf-8");
|
|
215206
216156
|
return JSON.parse(raw);
|
|
215207
216157
|
} catch {
|
|
215208
216158
|
return null;
|
|
@@ -215226,14 +216176,14 @@ var PinnedStore = class {
|
|
|
215226
216176
|
}
|
|
215227
216177
|
async pin(type, id) {
|
|
215228
216178
|
const data2 = await this.load();
|
|
215229
|
-
const
|
|
215230
|
-
|
|
216179
|
+
const bucket2 = type === "agent" ? data2.agents : data2.groups;
|
|
216180
|
+
bucket2[id] = Date.now();
|
|
215231
216181
|
await this.flush();
|
|
215232
216182
|
}
|
|
215233
216183
|
async unpin(type, id) {
|
|
215234
216184
|
const data2 = await this.load();
|
|
215235
|
-
const
|
|
215236
|
-
delete
|
|
216185
|
+
const bucket2 = type === "agent" ? data2.agents : data2.groups;
|
|
216186
|
+
delete bucket2[id];
|
|
215237
216187
|
await this.flush();
|
|
215238
216188
|
}
|
|
215239
216189
|
};
|
|
@@ -215261,7 +216211,7 @@ var import_node_https = __toESM(require("node:https"));
|
|
|
215261
216211
|
init_id2();
|
|
215262
216212
|
init_ipc_events();
|
|
215263
216213
|
init_logger();
|
|
215264
|
-
var
|
|
216214
|
+
var log21 = createLogger("ChannelHandlers");
|
|
215265
216215
|
var VALID_CHANNEL_TYPES = ["wecom-bot", "wechat-personal"];
|
|
215266
216216
|
function httpsGetJson(url2, timeoutMs = 1e4) {
|
|
215267
216217
|
return new Promise((resolve9, reject) => {
|
|
@@ -215464,9 +216414,9 @@ function registerHandlers() {
|
|
|
215464
216414
|
}
|
|
215465
216415
|
|
|
215466
216416
|
// src/adapters/db/migration/kai-migration.ts
|
|
215467
|
-
var
|
|
216417
|
+
var import_path22 = require("path");
|
|
215468
216418
|
var import_fs15 = require("fs");
|
|
215469
|
-
var
|
|
216419
|
+
var import_promises23 = require("fs/promises");
|
|
215470
216420
|
var import_lt2 = __toESM(require_lt());
|
|
215471
216421
|
init_lib();
|
|
215472
216422
|
init_agent_file_store();
|
|
@@ -215493,7 +216443,7 @@ function getKaiRootDir() {
|
|
|
215493
216443
|
return config.getAppDataPath();
|
|
215494
216444
|
}
|
|
215495
216445
|
function getKaiConfigPath() {
|
|
215496
|
-
return (0,
|
|
216446
|
+
return (0, import_path22.join)(getKaiRootDir(), KAI_CONFIG_FILE);
|
|
215497
216447
|
}
|
|
215498
216448
|
function ensureKaiRootDir() {
|
|
215499
216449
|
const root2 = getKaiRootDir();
|
|
@@ -215518,9 +216468,9 @@ async function writeKaiDataFile(version3) {
|
|
|
215518
216468
|
ensureKaiRootDir();
|
|
215519
216469
|
const path10 = getKaiConfigPath();
|
|
215520
216470
|
const tmp = `${path10}.tmp`;
|
|
215521
|
-
await (0,
|
|
216471
|
+
await (0, import_promises23.writeFile)(tmp, `${JSON.stringify({ version: version3 }, null, 2)}
|
|
215522
216472
|
`, "utf-8");
|
|
215523
|
-
await (0,
|
|
216473
|
+
await (0, import_promises23.rename)(tmp, path10);
|
|
215524
216474
|
}
|
|
215525
216475
|
function currentVersion() {
|
|
215526
216476
|
return readKaiDataFile()?.version ?? "0.0.0";
|
|
@@ -215697,16 +216647,16 @@ async function migrateConversationIds() {
|
|
|
215697
216647
|
});
|
|
215698
216648
|
await sequelize.query("PRAGMA foreign_keys = ON");
|
|
215699
216649
|
}
|
|
215700
|
-
const conversationsDir = (0,
|
|
216650
|
+
const conversationsDir = (0, import_path22.resolve)(config.getAppDataPath(), "conversations");
|
|
215701
216651
|
if ((0, import_fs15.existsSync)(conversationsDir)) {
|
|
215702
216652
|
try {
|
|
215703
216653
|
const entries = (0, import_fs15.readdirSync)(conversationsDir, { withFileTypes: true });
|
|
215704
216654
|
for (const entry of entries) {
|
|
215705
216655
|
if (!entry.isDirectory()) continue;
|
|
215706
|
-
const oldDir = (0,
|
|
216656
|
+
const oldDir = (0, import_path22.join)(conversationsDir, entry.name);
|
|
215707
216657
|
const targetId = idMap.get(entry.name);
|
|
215708
216658
|
if (targetId) {
|
|
215709
|
-
const newDir = (0,
|
|
216659
|
+
const newDir = (0, import_path22.join)(conversationsDir, targetId);
|
|
215710
216660
|
if (!(0, import_fs15.existsSync)(newDir)) {
|
|
215711
216661
|
(0, import_fs15.renameSync)(oldDir, newDir);
|
|
215712
216662
|
logger35.debug(`Renamed dir ${entry.name} \u2192 ${targetId}`);
|
|
@@ -215956,7 +216906,7 @@ init_normalize_tool_schema();
|
|
|
215956
216906
|
var import_child_process3 = require("child_process");
|
|
215957
216907
|
init_dist6();
|
|
215958
216908
|
init_zod();
|
|
215959
|
-
var
|
|
216909
|
+
var import_path23 = require("path");
|
|
215960
216910
|
init_workspace();
|
|
215961
216911
|
|
|
215962
216912
|
// node_modules/shell-env/index.js
|
|
@@ -216073,10 +217023,10 @@ function getUserShellEnv() {
|
|
|
216073
217023
|
// src/adapters/tools/tool-names.ts
|
|
216074
217024
|
var BUILT_IN_TOOL_NAMES = Object.freeze({
|
|
216075
217025
|
SHELL: "shell",
|
|
216076
|
-
READ: "
|
|
216077
|
-
WRITE: "
|
|
216078
|
-
EDIT: "
|
|
216079
|
-
PATCH: "
|
|
217026
|
+
READ: "readFile",
|
|
217027
|
+
WRITE: "writeFile",
|
|
217028
|
+
EDIT: "editFile",
|
|
217029
|
+
PATCH: "applyPatch",
|
|
216080
217030
|
WEB_FETCH: "webFetch",
|
|
216081
217031
|
WEB_SEARCH: "webSearch"
|
|
216082
217032
|
});
|
|
@@ -216111,7 +217061,7 @@ function createShellTool(agentId) {
|
|
|
216111
217061
|
};
|
|
216112
217062
|
if (workdir) {
|
|
216113
217063
|
const baseDir = agentId ? getAgentWorkspaceDir(agentId) : process.cwd();
|
|
216114
|
-
options2.cwd = (0,
|
|
217064
|
+
options2.cwd = (0, import_path23.isAbsolute)(workdir) ? workdir : (0, import_path23.resolve)(baseDir, workdir);
|
|
216115
217065
|
} else if (agentId) {
|
|
216116
217066
|
options2.cwd = getAgentWorkspaceDir(agentId);
|
|
216117
217067
|
}
|
|
@@ -216236,11 +217186,11 @@ function spawnWithAbort(shell2, command, options2, timeoutMs, abortSignal) {
|
|
|
216236
217186
|
// src/adapters/tools/filesystem/read-file.ts
|
|
216237
217187
|
init_dist6();
|
|
216238
217188
|
init_zod();
|
|
216239
|
-
var
|
|
217189
|
+
var import_promises24 = require("fs/promises");
|
|
216240
217190
|
var import_fs16 = require("fs");
|
|
216241
217191
|
|
|
216242
217192
|
// src/adapters/tools/filesystem/resolve-file-path.ts
|
|
216243
|
-
var
|
|
217193
|
+
var import_path24 = require("path");
|
|
216244
217194
|
init_workspace();
|
|
216245
217195
|
init_group_file_store();
|
|
216246
217196
|
var GROUP_PROTECTED_JSON_FILES = /* @__PURE__ */ new Set([
|
|
@@ -216249,38 +217199,38 @@ var GROUP_PROTECTED_JSON_FILES = /* @__PURE__ */ new Set([
|
|
|
216249
217199
|
"members.json"
|
|
216250
217200
|
]);
|
|
216251
217201
|
function containsPathTraversal(p) {
|
|
216252
|
-
return (0,
|
|
217202
|
+
return (0, import_path24.normalize)(p).split(/[/\\]+/).some((part) => part === "..");
|
|
216253
217203
|
}
|
|
216254
217204
|
function isWithinBase(resolvedPath, baseDir) {
|
|
216255
|
-
const rel = (0,
|
|
216256
|
-
return !rel.startsWith("..") && !(0,
|
|
217205
|
+
const rel = (0, import_path24.relative)(baseDir, resolvedPath);
|
|
217206
|
+
return !rel.startsWith("..") && !(0, import_path24.isAbsolute)(rel);
|
|
216257
217207
|
}
|
|
216258
217208
|
function isGroupProtectedFile(resolvedPath, groupDir) {
|
|
216259
|
-
|
|
217209
|
+
if (!isWithinBase((0, import_path24.normalize)(resolvedPath), (0, import_path24.normalize)(groupDir))) {
|
|
217210
|
+
return false;
|
|
217211
|
+
}
|
|
217212
|
+
const name21 = (0, import_path24.basename)(resolvedPath);
|
|
216260
217213
|
return name21.endsWith(".json") && GROUP_PROTECTED_JSON_FILES.has(name21);
|
|
216261
217214
|
}
|
|
216262
|
-
function
|
|
216263
|
-
|
|
216264
|
-
|
|
216265
|
-
|
|
216266
|
-
|
|
216267
|
-
|
|
217215
|
+
function resolveToolFilePath(workdir, filePath) {
|
|
217216
|
+
if (!workdir || !(0, import_path24.isAbsolute)(workdir)) {
|
|
217217
|
+
throw new Error("workdir is required and must be an absolute path");
|
|
217218
|
+
}
|
|
217219
|
+
if (!filePath) {
|
|
217220
|
+
throw new Error("path is required and must be relative to workdir");
|
|
217221
|
+
}
|
|
217222
|
+
if ((0, import_path24.isAbsolute)(filePath)) {
|
|
217223
|
+
throw new Error("path must be relative to workdir, not absolute");
|
|
216268
217224
|
}
|
|
216269
217225
|
if (containsPathTraversal(filePath)) {
|
|
216270
217226
|
throw new Error(`Path traversal not allowed: ${filePath}`);
|
|
216271
217227
|
}
|
|
216272
|
-
|
|
216273
|
-
|
|
216274
|
-
|
|
216275
|
-
|
|
216276
|
-
if (!isWithinBase(resolved, groupDir)) {
|
|
216277
|
-
throw new Error(`Path escapes group directory: ${filePath}`);
|
|
216278
|
-
}
|
|
216279
|
-
return resolved;
|
|
217228
|
+
const normalizedWorkdir = (0, import_path24.normalize)(workdir);
|
|
217229
|
+
const resolvedPath = (0, import_path24.resolve)(normalizedWorkdir, filePath);
|
|
217230
|
+
if (!isWithinBase(resolvedPath, normalizedWorkdir)) {
|
|
217231
|
+
throw new Error(`Path escapes workdir: ${filePath}`);
|
|
216280
217232
|
}
|
|
216281
|
-
|
|
216282
|
-
const baseDir = agentId ? getAgentWorkspaceDir(agentId) : process.cwd();
|
|
216283
|
-
return (0, import_path23.resolve)(baseDir, filePath);
|
|
217233
|
+
return resolvedPath;
|
|
216284
217234
|
}
|
|
216285
217235
|
|
|
216286
217236
|
// src/adapters/tools/filesystem/read-file.ts
|
|
@@ -216337,28 +217287,29 @@ var BINARY_EXTENSIONS2 = /* @__PURE__ */ new Set([
|
|
|
216337
217287
|
".pyc",
|
|
216338
217288
|
".wasm"
|
|
216339
217289
|
]);
|
|
216340
|
-
function createReadFileTool(
|
|
217290
|
+
function createReadFileTool(_scope = {}, tracker) {
|
|
216341
217291
|
return {
|
|
216342
|
-
|
|
216343
|
-
description: "Read file content from the local filesystem.\n- Returns content with line numbers.\n- If the path is a directory, lists its contents.\n- For large files, use `offset` and `limit` to read in chunks.",
|
|
217292
|
+
readFile: tool({
|
|
217293
|
+
description: "Read file content from the local filesystem.\n- `workdir` is REQUIRED and must be an absolute path.\n- `path` must be relative to `workdir`; absolute paths and `..` are rejected.\n- Returns content with line numbers.\n- If the path is a directory, lists its contents.\n- For large files, use `offset` and `limit` to read in chunks.",
|
|
216344
217294
|
inputSchema: zodSchema(
|
|
216345
217295
|
external_exports3.object({
|
|
216346
|
-
|
|
217296
|
+
workdir: external_exports3.string().describe("REQUIRED FIRST FIELD. Absolute root directory for this file operation."),
|
|
217297
|
+
path: external_exports3.string().describe("The file or directory path, relative to workdir. Do not use absolute paths or .."),
|
|
216347
217298
|
offset: external_exports3.number().optional().describe("Line number to start reading from (1-indexed, default: 1)"),
|
|
216348
217299
|
limit: external_exports3.number().optional().describe("Maximum number of lines to read (default: 2000)")
|
|
216349
217300
|
})
|
|
216350
217301
|
),
|
|
216351
|
-
execute: async ({ path: filePath, offset = 1, limit = DEFAULT_LIMIT }, { abortSignal }) => {
|
|
217302
|
+
execute: async ({ workdir, path: filePath, offset = 1, limit = DEFAULT_LIMIT }, { abortSignal }) => {
|
|
216352
217303
|
if (abortSignal?.aborted) throw new DOMException("The operation was aborted", "AbortError");
|
|
216353
217304
|
try {
|
|
216354
|
-
const resolvedPath =
|
|
217305
|
+
const resolvedPath = resolveToolFilePath(workdir, filePath);
|
|
216355
217306
|
if (!(0, import_fs16.existsSync)(resolvedPath)) {
|
|
216356
217307
|
return { error: `Path does not exist: ${filePath}`, content: "" };
|
|
216357
217308
|
}
|
|
216358
|
-
const fileStat = await (0,
|
|
217309
|
+
const fileStat = await (0, import_promises24.stat)(resolvedPath);
|
|
216359
217310
|
if (fileStat.isDirectory()) {
|
|
216360
217311
|
tracker?.markKnown(resolvedPath);
|
|
216361
|
-
const entries = await (0,
|
|
217312
|
+
const entries = await (0, import_promises24.readdir)(resolvedPath, { withFileTypes: true });
|
|
216362
217313
|
const lines = entries.sort((a, b) => {
|
|
216363
217314
|
if (a.isDirectory() && !b.isDirectory()) return -1;
|
|
216364
217315
|
if (!a.isDirectory() && b.isDirectory()) return 1;
|
|
@@ -216381,7 +217332,7 @@ function createReadFileTool(scope = {}, tracker) {
|
|
|
216381
217332
|
content: ""
|
|
216382
217333
|
};
|
|
216383
217334
|
}
|
|
216384
|
-
const content = await (0,
|
|
217335
|
+
const content = await (0, import_promises24.readFile)(resolvedPath, "utf-8");
|
|
216385
217336
|
const allLines = content.split("\n");
|
|
216386
217337
|
if (allLines.length > 0 && allLines[allLines.length - 1] === "") {
|
|
216387
217338
|
allLines.pop();
|
|
@@ -216415,8 +217366,8 @@ function createReadFileTool(scope = {}, tracker) {
|
|
|
216415
217366
|
// src/adapters/tools/filesystem/write-file.ts
|
|
216416
217367
|
init_dist6();
|
|
216417
217368
|
init_zod();
|
|
216418
|
-
var
|
|
216419
|
-
var
|
|
217369
|
+
var import_promises25 = require("fs/promises");
|
|
217370
|
+
var import_path25 = require("path");
|
|
216420
217371
|
var import_fs17 = require("fs");
|
|
216421
217372
|
init_group_file_store();
|
|
216422
217373
|
|
|
@@ -217189,18 +218140,20 @@ function createUnifiedFileDiff(displayPath, previousContent, nextContent) {
|
|
|
217189
218140
|
// src/adapters/tools/filesystem/write-file.ts
|
|
217190
218141
|
function createWriteFileTool(scope = {}, tracker) {
|
|
217191
218142
|
return {
|
|
217192
|
-
|
|
217193
|
-
description: "Write content to a file on the local filesystem. Creates parent directories if they do not exist.
|
|
218143
|
+
writeFile: tool({
|
|
218144
|
+
description: "Write content to a file on the local filesystem. Creates parent directories if they do not exist. `workdir` is REQUIRED and must be an absolute path. `path` must be relative to `workdir`; absolute paths and `..` are rejected. mode defaults to `overwrite`; use `append` only for append-only files such as logs or memory notes. IMPORTANT: For editing specific parts of an existing file, prefer `editFile` \u2014 it is more token-efficient and less error-prone than rewriting the entire file.",
|
|
217194
218145
|
inputSchema: zodSchema(
|
|
217195
218146
|
external_exports3.object({
|
|
217196
|
-
|
|
217197
|
-
|
|
218147
|
+
workdir: external_exports3.string().describe("REQUIRED FIRST FIELD. Absolute root directory for this file operation."),
|
|
218148
|
+
path: external_exports3.string().describe("The file path, relative to workdir. Do not use absolute paths or .."),
|
|
218149
|
+
content: external_exports3.string().describe("The content to write to the file"),
|
|
218150
|
+
mode: external_exports3.enum(["overwrite", "append"]).optional().describe("Write mode. Defaults to overwrite. Use append only for append-only text files.")
|
|
217198
218151
|
})
|
|
217199
218152
|
),
|
|
217200
|
-
execute: async ({ path: filePath, content }, { abortSignal }) => {
|
|
218153
|
+
execute: async ({ workdir, path: filePath, content, mode = "overwrite" }, { abortSignal }) => {
|
|
217201
218154
|
if (abortSignal?.aborted) throw new DOMException("The operation was aborted", "AbortError");
|
|
217202
218155
|
try {
|
|
217203
|
-
const resolvedPath =
|
|
218156
|
+
const resolvedPath = resolveToolFilePath(workdir, filePath);
|
|
217204
218157
|
if (scope.groupId) {
|
|
217205
218158
|
const groupDir = getGroupDir(scope.groupId);
|
|
217206
218159
|
if (isGroupProtectedFile(resolvedPath, groupDir)) {
|
|
@@ -217211,27 +218164,35 @@ function createWriteFileTool(scope = {}, tracker) {
|
|
|
217211
218164
|
}
|
|
217212
218165
|
}
|
|
217213
218166
|
const isNewFile = !(0, import_fs17.existsSync)(resolvedPath);
|
|
217214
|
-
if (!isNewFile && tracker && !tracker.isKnown(resolvedPath)) {
|
|
218167
|
+
if (mode === "overwrite" && !isNewFile && tracker && !tracker.isKnown(resolvedPath)) {
|
|
217215
218168
|
return {
|
|
217216
218169
|
success: false,
|
|
217217
|
-
error: `Cannot
|
|
218170
|
+
error: `Cannot modify existing file without reading it first. Call readFile on "${filePath}" before using writeFile to overwrite it.`
|
|
217218
218171
|
};
|
|
217219
218172
|
}
|
|
217220
218173
|
let oldContent = "";
|
|
217221
218174
|
if (!isNewFile) {
|
|
217222
218175
|
try {
|
|
217223
|
-
oldContent = await (0,
|
|
218176
|
+
oldContent = await (0, import_promises25.readFile)(resolvedPath, "utf-8");
|
|
217224
218177
|
} catch {
|
|
217225
218178
|
}
|
|
217226
218179
|
}
|
|
217227
|
-
const
|
|
217228
|
-
|
|
217229
|
-
await (0,
|
|
217230
|
-
|
|
218180
|
+
const nextContent = mode === "append" ? oldContent + content : content;
|
|
218181
|
+
const diff = createUnifiedFileDiff(filePath, oldContent, nextContent);
|
|
218182
|
+
await (0, import_promises25.mkdir)((0, import_path25.dirname)(resolvedPath), { recursive: true });
|
|
218183
|
+
if (mode === "append") {
|
|
218184
|
+
await (0, import_promises25.appendFile)(resolvedPath, content, "utf-8");
|
|
218185
|
+
} else {
|
|
218186
|
+
await (0, import_promises25.writeFile)(resolvedPath, content, "utf-8");
|
|
218187
|
+
}
|
|
218188
|
+
if (isNewFile) {
|
|
218189
|
+
tracker?.markKnown(resolvedPath);
|
|
218190
|
+
}
|
|
217231
218191
|
return {
|
|
217232
218192
|
success: true,
|
|
217233
218193
|
path: resolvedPath,
|
|
217234
218194
|
bytesWritten: Buffer.byteLength(content, "utf-8"),
|
|
218195
|
+
mode,
|
|
217235
218196
|
isNewFile,
|
|
217236
218197
|
diff
|
|
217237
218198
|
};
|
|
@@ -217249,25 +218210,26 @@ function createWriteFileTool(scope = {}, tracker) {
|
|
|
217249
218210
|
// src/adapters/tools/filesystem/edit-file.ts
|
|
217250
218211
|
init_dist6();
|
|
217251
218212
|
init_zod();
|
|
217252
|
-
var
|
|
218213
|
+
var import_promises26 = require("fs/promises");
|
|
217253
218214
|
var import_fs18 = require("fs");
|
|
217254
218215
|
init_group_file_store();
|
|
217255
|
-
function createEditFileTool(scope = {}) {
|
|
218216
|
+
function createEditFileTool(scope = {}, tracker) {
|
|
217256
218217
|
return {
|
|
217257
|
-
|
|
217258
|
-
description: "Perform exact string replacement in a file. The oldString must match exactly (including whitespace and indentation). Fails if oldString is not found or found multiple times (unless replaceAll is true).",
|
|
218218
|
+
editFile: tool({
|
|
218219
|
+
description: "Perform exact string replacement in a file. The oldString must match exactly (including whitespace and indentation). Fails if oldString is not found or found multiple times (unless replaceAll is true). `workdir` is REQUIRED and must be an absolute path. `path` must be relative to `workdir`; absolute paths and `..` are rejected.",
|
|
217259
218220
|
inputSchema: zodSchema(
|
|
217260
218221
|
external_exports3.object({
|
|
217261
|
-
|
|
218222
|
+
workdir: external_exports3.string().describe("REQUIRED FIRST FIELD. Absolute root directory for this file operation."),
|
|
218223
|
+
path: external_exports3.string().describe("The file path, relative to workdir. Do not use absolute paths or .."),
|
|
217262
218224
|
oldString: external_exports3.string().describe("The exact text to be replaced"),
|
|
217263
218225
|
newString: external_exports3.string().describe("The text to replace it with"),
|
|
217264
218226
|
replaceAll: external_exports3.boolean().optional().describe("Replace all occurrences of oldString (default: false)")
|
|
217265
218227
|
})
|
|
217266
218228
|
),
|
|
217267
|
-
execute: async ({ path: filePath, oldString, newString, replaceAll = false }, { abortSignal }) => {
|
|
218229
|
+
execute: async ({ workdir, path: filePath, oldString, newString, replaceAll = false }, { abortSignal }) => {
|
|
217268
218230
|
if (abortSignal?.aborted) throw new DOMException("The operation was aborted", "AbortError");
|
|
217269
218231
|
try {
|
|
217270
|
-
const resolvedPath =
|
|
218232
|
+
const resolvedPath = resolveToolFilePath(workdir, filePath);
|
|
217271
218233
|
if (scope.groupId) {
|
|
217272
218234
|
const groupDir = getGroupDir(scope.groupId);
|
|
217273
218235
|
if (isGroupProtectedFile(resolvedPath, groupDir)) {
|
|
@@ -217280,7 +218242,11 @@ function createEditFileTool(scope = {}) {
|
|
|
217280
218242
|
if (!(0, import_fs18.existsSync)(resolvedPath)) {
|
|
217281
218243
|
return { success: false, error: `File does not exist: ${filePath}` };
|
|
217282
218244
|
}
|
|
217283
|
-
const
|
|
218245
|
+
const accessError = tracker?.assertKnownForMutation(resolvedPath, "edit", "editFile", filePath);
|
|
218246
|
+
if (accessError) {
|
|
218247
|
+
return { success: false, error: accessError };
|
|
218248
|
+
}
|
|
218249
|
+
const content = await (0, import_promises26.readFile)(resolvedPath, "utf-8");
|
|
217284
218250
|
const matchCount = content.split(oldString).length - 1;
|
|
217285
218251
|
if (matchCount === 0) {
|
|
217286
218252
|
return { success: false, error: "oldString not found in file" };
|
|
@@ -217293,7 +218259,8 @@ function createEditFileTool(scope = {}) {
|
|
|
217293
218259
|
}
|
|
217294
218260
|
const updatedContent = replaceAll ? content.split(oldString).join(newString) : content.replace(oldString, newString);
|
|
217295
218261
|
const diff = createUnifiedFileDiff(filePath, content, updatedContent);
|
|
217296
|
-
await (0,
|
|
218262
|
+
await (0, import_promises26.writeFile)(resolvedPath, updatedContent, "utf-8");
|
|
218263
|
+
tracker?.markKnown(resolvedPath);
|
|
217297
218264
|
return {
|
|
217298
218265
|
success: true,
|
|
217299
218266
|
path: resolvedPath,
|
|
@@ -217314,39 +218281,47 @@ function createEditFileTool(scope = {}) {
|
|
|
217314
218281
|
// src/adapters/tools/filesystem/apply-patch.ts
|
|
217315
218282
|
init_dist6();
|
|
217316
218283
|
init_zod();
|
|
217317
|
-
var
|
|
218284
|
+
var import_promises27 = require("fs/promises");
|
|
217318
218285
|
var import_fs19 = require("fs");
|
|
217319
|
-
var
|
|
218286
|
+
var import_path26 = require("path");
|
|
217320
218287
|
init_group_file_store();
|
|
217321
218288
|
function containsPathTraversal2(p) {
|
|
217322
|
-
return (0,
|
|
218289
|
+
return (0, import_path26.normalize)(p).split(/[/\\]+/).some((part) => part === "..");
|
|
217323
218290
|
}
|
|
217324
218291
|
function isWithinBase2(resolvedPath, baseDir) {
|
|
217325
|
-
const rel = (0,
|
|
217326
|
-
return !rel.startsWith("..") && !(0,
|
|
218292
|
+
const rel = (0, import_path26.relative)(baseDir, resolvedPath);
|
|
218293
|
+
return !rel.startsWith("..") && !(0, import_path26.isAbsolute)(rel);
|
|
217327
218294
|
}
|
|
217328
218295
|
function resolvePatchWorkdir(workdir) {
|
|
217329
218296
|
if (typeof workdir !== "string" || workdir.length === 0) {
|
|
217330
218297
|
throw new Error("patch workdir is required and must be an absolute path");
|
|
217331
218298
|
}
|
|
217332
|
-
if (!(0,
|
|
218299
|
+
if (!(0, import_path26.isAbsolute)(workdir)) {
|
|
217333
218300
|
throw new Error("patch workdir must be an absolute path");
|
|
217334
218301
|
}
|
|
217335
|
-
return (0,
|
|
218302
|
+
return (0, import_path26.normalize)(workdir);
|
|
217336
218303
|
}
|
|
217337
218304
|
function resolvePatchPath(filePath, workdir) {
|
|
217338
|
-
if ((0,
|
|
218305
|
+
if ((0, import_path26.isAbsolute)(filePath)) {
|
|
217339
218306
|
throw new Error(`Patch file paths must be relative to workdir; pass workdir instead of absolute paths: ${filePath}`);
|
|
217340
218307
|
}
|
|
217341
218308
|
if (containsPathTraversal2(filePath)) {
|
|
217342
218309
|
throw new Error(`Path traversal not allowed in patch file path: ${filePath}`);
|
|
217343
218310
|
}
|
|
217344
|
-
const resolved = (0,
|
|
218311
|
+
const resolved = (0, import_path26.resolve)(workdir, filePath);
|
|
217345
218312
|
if (!isWithinBase2(resolved, workdir)) {
|
|
217346
218313
|
throw new Error(`Patch file path escapes workdir: ${filePath}`);
|
|
217347
218314
|
}
|
|
217348
218315
|
return resolved;
|
|
217349
218316
|
}
|
|
218317
|
+
function getPatchMutationAccessError(filePatch, resolvedPath, displayPath, tracker) {
|
|
218318
|
+
if (filePatch.action === "add" && !(0, import_fs19.existsSync)(resolvedPath)) return null;
|
|
218319
|
+
if (filePatch.action !== "add" && !(0, import_fs19.existsSync)(resolvedPath)) return null;
|
|
218320
|
+
if (filePatch.action === "add") {
|
|
218321
|
+
return tracker.assertKnownForMutation(resolvedPath, "replace", "applyPatch", displayPath);
|
|
218322
|
+
}
|
|
218323
|
+
return tracker.assertKnownForMutation(resolvedPath, filePatch.action, "applyPatch", displayPath);
|
|
218324
|
+
}
|
|
217350
218325
|
function parsePatch2(input) {
|
|
217351
218326
|
const lines = input.split("\n");
|
|
217352
218327
|
const patches = [];
|
|
@@ -217437,19 +218412,26 @@ function applyHunks(content, filePath, hunks) {
|
|
|
217437
218412
|
}
|
|
217438
218413
|
return { result };
|
|
217439
218414
|
}
|
|
217440
|
-
function createApplyPatchTool(scope = {}) {
|
|
218415
|
+
function createApplyPatchTool(scope = {}, tracker) {
|
|
217441
218416
|
return {
|
|
217442
|
-
|
|
217443
|
-
description: 'Apply a multi-file patch using a structured diff format. This is ideal for multi-file or multi-location edits where calling `
|
|
218417
|
+
applyPatch: tool({
|
|
218418
|
+
description: 'Apply a multi-file patch using a structured diff format. This is ideal for multi-file or multi-location edits where calling `editFile` multiple times would be brittle.\n\nThe patch is a stripped-down, file-oriented diff format with no line numbers. It uses a high-level envelope:\n\n```\n*** Begin Patch\n[ one or more file operations ]\n*** End Patch\n```\n\nEach operation starts with one of three headers:\n- `*** Add File: <path>` \u2014 create a new file. Every following line must start with `+`.\n- `*** Delete File: <path>` \u2014 remove an existing file.\n- `*** Update File: <path>` \u2014 modify an existing file in place (optionally with a rename).\n\nFor Update operations, you may add `*** Move to: <new path>` on the next line to rename the file.\nThen include one or more "hunks", each introduced by `@@` (optionally followed by a context header).\n\nWithin a hunk, each line starts with:\n- ` ` (space) \u2014 context line (unchanged, used for matching)\n- `-` \u2014 line to remove\n- `+` \u2014 line to add\n\n**Important guidelines for Update hunks:**\n- Always include 3 lines of context before and after each change. Context lines help locate the correct position in the file.\n- If 3 lines of context is insufficient to uniquely identify the code, use `@@` with a class or function name to narrow down the location. Example: `@@ class UserService`\n- For deeply nested or repeated code, use multiple `@@` markers to jump to the right context. Example:\n ```\n @@ class UserService\n @@ async login():\n - return false\n + return await authenticate()\n ```\n- Use `*** End of File` to mark a pure insertion at the end of a file.\n- `workdir` is REQUIRED and must be an absolute path. It is the root directory where the patch is applied.\n- File paths inside the patch are relative to `workdir`, never absolute.\n- Do not use `..` in patch file paths; paths may not escape `workdir`.\n\nFull example combining multiple operations:\n```\n*** Begin Patch\n*** Add File: hello.txt\n+Hello world\n*** Update File: src/app.py\n*** Move to: src/main.py\n@@ def greet():\n- print("Hi")\n+ print("Hello, world!")\n*** Delete File: obsolete.txt\n*** End Patch\n```',
|
|
217444
218419
|
inputSchema: zodSchema(
|
|
217445
218420
|
external_exports3.object({
|
|
217446
218421
|
workdir: external_exports3.string().describe("REQUIRED FIRST FIELD. Absolute root directory where the patch is applied. Patch file paths are relative to this directory."),
|
|
217447
|
-
|
|
218422
|
+
patch: external_exports3.string().optional().describe(
|
|
217448
218423
|
"The patch content. Must start with *** Begin Patch and end with *** End Patch."
|
|
217449
218424
|
)
|
|
218425
|
+
}).passthrough().superRefine((args2, ctx) => {
|
|
218426
|
+
const legacyInput = args2.input;
|
|
218427
|
+
if (typeof args2.patch !== "string" && typeof legacyInput !== "string") {
|
|
218428
|
+
ctx.addIssue({ code: external_exports3.ZodIssueCode.custom, message: "patch is required" });
|
|
218429
|
+
}
|
|
217450
218430
|
})
|
|
217451
218431
|
),
|
|
217452
|
-
execute: async (
|
|
218432
|
+
execute: async (args2, { abortSignal }) => {
|
|
218433
|
+
const { workdir, patch } = args2;
|
|
218434
|
+
const input = args2.input;
|
|
217453
218435
|
if (abortSignal?.aborted) throw new DOMException("The operation was aborted", "AbortError");
|
|
217454
218436
|
let patchWorkdir;
|
|
217455
218437
|
try {
|
|
@@ -217457,7 +218439,11 @@ function createApplyPatchTool(scope = {}) {
|
|
|
217457
218439
|
} catch (error48) {
|
|
217458
218440
|
return { success: false, error: error48 instanceof Error ? error48.message : String(error48) };
|
|
217459
218441
|
}
|
|
217460
|
-
const
|
|
218442
|
+
const patchContent = patch ?? input;
|
|
218443
|
+
if (typeof patchContent !== "string") {
|
|
218444
|
+
return { success: false, error: "patch is required" };
|
|
218445
|
+
}
|
|
218446
|
+
const patches = parsePatch2(patchContent);
|
|
217461
218447
|
if (patches.length === 0) {
|
|
217462
218448
|
return { success: false, error: "No file operations found in patch" };
|
|
217463
218449
|
}
|
|
@@ -217487,6 +218473,18 @@ function createApplyPatchTool(scope = {}) {
|
|
|
217487
218473
|
continue;
|
|
217488
218474
|
}
|
|
217489
218475
|
}
|
|
218476
|
+
if (tracker) {
|
|
218477
|
+
const mutationError = getPatchMutationAccessError(filePatch, resolvedPath, filePatch.path, tracker);
|
|
218478
|
+
if (mutationError) {
|
|
218479
|
+
results.push({
|
|
218480
|
+
action: filePatch.action,
|
|
218481
|
+
path: filePatch.path,
|
|
218482
|
+
success: false,
|
|
218483
|
+
error: mutationError
|
|
218484
|
+
});
|
|
218485
|
+
continue;
|
|
218486
|
+
}
|
|
218487
|
+
}
|
|
217490
218488
|
try {
|
|
217491
218489
|
switch (filePatch.action) {
|
|
217492
218490
|
case "add": {
|
|
@@ -217500,8 +218498,9 @@ function createApplyPatchTool(scope = {}) {
|
|
|
217500
218498
|
continue;
|
|
217501
218499
|
}
|
|
217502
218500
|
const content = (filePatch.content || "").replace(/\n$/, "");
|
|
217503
|
-
await (0,
|
|
217504
|
-
await (0,
|
|
218501
|
+
await (0, import_promises27.mkdir)((0, import_path26.dirname)(resolvedPath), { recursive: true });
|
|
218502
|
+
await (0, import_promises27.writeFile)(resolvedPath, content, "utf-8");
|
|
218503
|
+
tracker?.markKnown(resolvedPath);
|
|
217505
218504
|
results.push({
|
|
217506
218505
|
action: "add",
|
|
217507
218506
|
path: filePatch.path,
|
|
@@ -217519,7 +218518,7 @@ function createApplyPatchTool(scope = {}) {
|
|
|
217519
218518
|
});
|
|
217520
218519
|
continue;
|
|
217521
218520
|
}
|
|
217522
|
-
const oldContent = await (0,
|
|
218521
|
+
const oldContent = await (0, import_promises27.readFile)(resolvedPath, "utf-8");
|
|
217523
218522
|
let newContent;
|
|
217524
218523
|
if (filePatch.hunks && filePatch.hunks.length > 0) {
|
|
217525
218524
|
const { result, error: error48 } = applyHunks(oldContent, filePatch.path, filePatch.hunks);
|
|
@@ -217538,9 +218537,46 @@ function createApplyPatchTool(scope = {}) {
|
|
|
217538
218537
|
}
|
|
217539
218538
|
if (filePatch.moveTo) {
|
|
217540
218539
|
const newResolvedPath = resolvePatchPath(filePatch.moveTo, patchWorkdir);
|
|
217541
|
-
|
|
217542
|
-
|
|
217543
|
-
|
|
218540
|
+
if (newResolvedPath === resolvedPath) {
|
|
218541
|
+
results.push({
|
|
218542
|
+
action: "rename",
|
|
218543
|
+
path: `${filePatch.path} \u2192 ${filePatch.moveTo}`,
|
|
218544
|
+
success: false,
|
|
218545
|
+
error: "Move target must differ from source path"
|
|
218546
|
+
});
|
|
218547
|
+
continue;
|
|
218548
|
+
}
|
|
218549
|
+
if (scope.groupId) {
|
|
218550
|
+
const groupDir = getGroupDir(scope.groupId);
|
|
218551
|
+
if (isGroupProtectedFile(newResolvedPath, groupDir)) {
|
|
218552
|
+
results.push({
|
|
218553
|
+
action: "rename",
|
|
218554
|
+
path: `${filePatch.path} \u2192 ${filePatch.moveTo}`,
|
|
218555
|
+
success: false,
|
|
218556
|
+
error: `Cannot modify protected file: ${filePatch.moveTo}`
|
|
218557
|
+
});
|
|
218558
|
+
continue;
|
|
218559
|
+
}
|
|
218560
|
+
}
|
|
218561
|
+
await (0, import_promises27.mkdir)((0, import_path26.dirname)(newResolvedPath), { recursive: true });
|
|
218562
|
+
const moveTargetError = tracker?.assertKnownForMutation(
|
|
218563
|
+
newResolvedPath,
|
|
218564
|
+
"overwrite rename target",
|
|
218565
|
+
"applyPatch",
|
|
218566
|
+
filePatch.moveTo
|
|
218567
|
+
);
|
|
218568
|
+
if ((0, import_fs19.existsSync)(newResolvedPath) && moveTargetError) {
|
|
218569
|
+
results.push({
|
|
218570
|
+
action: "rename",
|
|
218571
|
+
path: `${filePatch.path} \u2192 ${filePatch.moveTo}`,
|
|
218572
|
+
success: false,
|
|
218573
|
+
error: moveTargetError
|
|
218574
|
+
});
|
|
218575
|
+
continue;
|
|
218576
|
+
}
|
|
218577
|
+
await (0, import_promises27.writeFile)(newResolvedPath, newContent, "utf-8");
|
|
218578
|
+
await (0, import_promises27.unlink)(resolvedPath);
|
|
218579
|
+
tracker?.markKnown(newResolvedPath);
|
|
217544
218580
|
const diff = createUnifiedFileDiff(filePatch.path, oldContent, newContent);
|
|
217545
218581
|
results.push({
|
|
217546
218582
|
action: "rename",
|
|
@@ -217550,7 +218586,8 @@ function createApplyPatchTool(scope = {}) {
|
|
|
217550
218586
|
});
|
|
217551
218587
|
} else {
|
|
217552
218588
|
const diff = createUnifiedFileDiff(filePatch.path, oldContent, newContent);
|
|
217553
|
-
await (0,
|
|
218589
|
+
await (0, import_promises27.writeFile)(resolvedPath, newContent, "utf-8");
|
|
218590
|
+
tracker?.markKnown(resolvedPath);
|
|
217554
218591
|
results.push({
|
|
217555
218592
|
action: "update",
|
|
217556
218593
|
path: filePatch.path,
|
|
@@ -217570,7 +218607,7 @@ function createApplyPatchTool(scope = {}) {
|
|
|
217570
218607
|
});
|
|
217571
218608
|
continue;
|
|
217572
218609
|
}
|
|
217573
|
-
await (0,
|
|
218610
|
+
await (0, import_promises27.unlink)(resolvedPath);
|
|
217574
218611
|
results.push({
|
|
217575
218612
|
action: "delete",
|
|
217576
218613
|
path: filePatch.path,
|
|
@@ -232278,12 +233315,12 @@ function createWebSearchTool(executor) {
|
|
|
232278
233315
|
}
|
|
232279
233316
|
|
|
232280
233317
|
// src/electron/main/utils/icon.ts
|
|
232281
|
-
var
|
|
233318
|
+
var import_path27 = require("path");
|
|
232282
233319
|
function getIconPath() {
|
|
232283
233320
|
if (process.env.NODE_ENV === "development") {
|
|
232284
|
-
return (0,
|
|
233321
|
+
return (0, import_path27.join)(__dirname, "../../resources/icon.png");
|
|
232285
233322
|
}
|
|
232286
|
-
return (0,
|
|
233323
|
+
return (0, import_path27.join)(process.resourcesPath, "icon.png");
|
|
232287
233324
|
}
|
|
232288
233325
|
|
|
232289
233326
|
// src/adapters/tools/web/search/electron/search-with-window.ts
|
|
@@ -232727,16 +233764,16 @@ function createSchedulerTools(scope) {
|
|
|
232727
233764
|
// src/adapters/tools/image/analyze.ts
|
|
232728
233765
|
init_dist6();
|
|
232729
233766
|
init_zod();
|
|
232730
|
-
var
|
|
233767
|
+
var import_promises28 = require("fs/promises");
|
|
232731
233768
|
var import_fs20 = require("fs");
|
|
232732
|
-
var
|
|
233769
|
+
var import_path28 = require("path");
|
|
232733
233770
|
init_config();
|
|
232734
233771
|
init_multimodal();
|
|
232735
233772
|
init_logger();
|
|
232736
233773
|
var logger37 = createLogger("AnalyzeImageTool");
|
|
232737
233774
|
function resolveImagePath(imagePath) {
|
|
232738
|
-
if ((0,
|
|
232739
|
-
return (0,
|
|
233775
|
+
if ((0, import_path28.isAbsolute)(imagePath)) return imagePath;
|
|
233776
|
+
return (0, import_path28.resolve)(process.cwd(), imagePath);
|
|
232740
233777
|
}
|
|
232741
233778
|
function createModelFromCandidate(candidate) {
|
|
232742
233779
|
const channels = config.get("llmChannels") ?? [];
|
|
@@ -232787,8 +233824,8 @@ async function loadImageAsDataUrl(imagePathOrUrl, abortSignal) {
|
|
|
232787
233824
|
} else {
|
|
232788
233825
|
const absPath = resolveImagePath(imagePathOrUrl);
|
|
232789
233826
|
if (!(0, import_fs20.existsSync)(absPath)) throw new Error(`\u56FE\u7247\u6587\u4EF6\u4E0D\u5B58\u5728: ${absPath}`);
|
|
232790
|
-
buffer = await (0,
|
|
232791
|
-
mimeType = extToMime((0,
|
|
233827
|
+
buffer = await (0, import_promises28.readFile)(absPath);
|
|
233828
|
+
mimeType = extToMime((0, import_path28.extname)(absPath));
|
|
232792
233829
|
}
|
|
232793
233830
|
const maxDim = getMaxImageDimension();
|
|
232794
233831
|
const resized = await resizeImageBuffer(buffer, maxDim);
|
|
@@ -232855,9 +233892,9 @@ function createAnalyzeImageTool() {
|
|
|
232855
233892
|
// src/adapters/tools/image/generate.ts
|
|
232856
233893
|
init_dist6();
|
|
232857
233894
|
init_zod();
|
|
232858
|
-
var
|
|
233895
|
+
var import_promises29 = require("fs/promises");
|
|
232859
233896
|
var import_fs21 = require("fs");
|
|
232860
|
-
var
|
|
233897
|
+
var import_path29 = require("path");
|
|
232861
233898
|
init_config();
|
|
232862
233899
|
init_logger();
|
|
232863
233900
|
var logger38 = createLogger("GenerateImageTool");
|
|
@@ -232894,9 +233931,9 @@ async function loadImageBuffer(imagePathOrUrl, abortSignal) {
|
|
|
232894
233931
|
if (!response.ok) throw new Error(`\u83B7\u53D6\u56FE\u7247\u5931\u8D25: ${response.status} ${response.statusText}`);
|
|
232895
233932
|
return Buffer.from(await response.arrayBuffer());
|
|
232896
233933
|
}
|
|
232897
|
-
const absPath = (0,
|
|
233934
|
+
const absPath = (0, import_path29.isAbsolute)(imagePathOrUrl) ? imagePathOrUrl : (0, import_path29.resolve)(process.cwd(), imagePathOrUrl);
|
|
232898
233935
|
if (!(0, import_fs21.existsSync)(absPath)) throw new Error(`\u56FE\u7247\u6587\u4EF6\u4E0D\u5B58\u5728: ${absPath}`);
|
|
232899
|
-
return (0,
|
|
233936
|
+
return (0, import_promises29.readFile)(absPath);
|
|
232900
233937
|
}
|
|
232901
233938
|
function createGenerateImageTool() {
|
|
232902
233939
|
return {
|
|
@@ -233000,6 +234037,16 @@ var FileAccessTracker = class {
|
|
|
233000
234037
|
isKnown(resolvedPath) {
|
|
233001
234038
|
return this.knownPaths.has(resolvedPath);
|
|
233002
234039
|
}
|
|
234040
|
+
/**
|
|
234041
|
+
* Enforce the mutation policy for an existing path.
|
|
234042
|
+
*
|
|
234043
|
+
* New files are allowed by the tools themselves. Existing files must have been
|
|
234044
|
+
* read, or created by a previous write in this tool set, before any mutation.
|
|
234045
|
+
*/
|
|
234046
|
+
assertKnownForMutation(resolvedPath, action, toolName, filePath) {
|
|
234047
|
+
if (this.isKnown(resolvedPath)) return null;
|
|
234048
|
+
return `Cannot ${action} existing file without reading it first. Call readFile on "${filePath}" before using ${toolName}.`;
|
|
234049
|
+
}
|
|
233003
234050
|
/** 重置(新会话 / 新工具实例时调用) */
|
|
233004
234051
|
clear() {
|
|
233005
234052
|
this.knownPaths.clear();
|
|
@@ -233041,8 +234088,8 @@ function getBuiltInTools(context2 = {}) {
|
|
|
233041
234088
|
...createShellTool(agentId),
|
|
233042
234089
|
...createReadFileTool(scope, tracker),
|
|
233043
234090
|
...createWriteFileTool(scope, tracker),
|
|
233044
|
-
...createEditFileTool(scope),
|
|
233045
|
-
...createApplyPatchTool(scope),
|
|
234091
|
+
...createEditFileTool(scope, tracker),
|
|
234092
|
+
...createApplyPatchTool(scope, tracker),
|
|
233046
234093
|
...createWebFetchTool(),
|
|
233047
234094
|
...createWebSearchTool2(),
|
|
233048
234095
|
...createDatabaseTool()
|
|
@@ -233075,7 +234122,7 @@ init_zod();
|
|
|
233075
234122
|
var import_node_fs2 = require("node:fs");
|
|
233076
234123
|
var import_node_path7 = require("node:path");
|
|
233077
234124
|
init_logger();
|
|
233078
|
-
var
|
|
234125
|
+
var log22 = createLogger("SendFileTool");
|
|
233079
234126
|
function createSendFileTool(attachmentPort) {
|
|
233080
234127
|
return {
|
|
233081
234128
|
sendFile: tool({
|
|
@@ -233113,7 +234160,7 @@ function createSendFileTool(attachmentPort) {
|
|
|
233113
234160
|
const fileBuffer = (0, import_node_fs2.readFileSync)(filePath);
|
|
233114
234161
|
const metadata = await attachmentPort.saveAttachment(fileBuffer, filename, mimeType);
|
|
233115
234162
|
const type = isImageExtension(ext) ? "\u56FE\u7247" : "\u6587\u4EF6";
|
|
233116
|
-
|
|
234163
|
+
log22.info(`sendFile: ${filePath} \u2192 attachment ${metadata.id} (${type}, ${(fileStat.size / 1024).toFixed(1)}KB)`);
|
|
233117
234164
|
return {
|
|
233118
234165
|
text: `${type}\u5DF2\u53D1\u9001: ${filename}`,
|
|
233119
234166
|
attachment: {
|
|
@@ -233126,7 +234173,7 @@ function createSendFileTool(attachmentPort) {
|
|
|
233126
234173
|
};
|
|
233127
234174
|
} catch (error48) {
|
|
233128
234175
|
const message = error48 instanceof Error ? error48.message : String(error48);
|
|
233129
|
-
|
|
234176
|
+
log22.error("sendFile error:", message);
|
|
233130
234177
|
return `\u53D1\u9001\u6587\u4EF6\u5931\u8D25: ${message}`;
|
|
233131
234178
|
}
|
|
233132
234179
|
}
|
|
@@ -233328,8 +234375,8 @@ var ToolOutputArtifactStateSlot = defineExecutionSlot({
|
|
|
233328
234375
|
});
|
|
233329
234376
|
|
|
233330
234377
|
// src/adapters/tools/middleware/save-tool-output-artifact.ts
|
|
233331
|
-
var
|
|
233332
|
-
var
|
|
234378
|
+
var import_promises30 = require("fs/promises");
|
|
234379
|
+
var import_path30 = require("path");
|
|
233333
234380
|
init_workspace();
|
|
233334
234381
|
init_thread_file_store();
|
|
233335
234382
|
|
|
@@ -233520,7 +234567,7 @@ async function handleWebFetchResult(ctx, result) {
|
|
|
233520
234567
|
|
|
233521
234568
|
---
|
|
233522
234569
|
[\u5185\u5BB9\u8D85\u8FC7 ${WEB_MAX_CHARS} \u5B57\u7B26\uFF0C\u5DF2\u622A\u65AD\u3002\u5B8C\u6574\u5185\u5BB9\u5DF2\u4FDD\u5B58\u5230: ${artifact.absolutePath}]
|
|
233523
|
-
[\u53EF\u7528
|
|
234570
|
+
[\u53EF\u7528 readFile \u8BFB\u53D6\u5B8C\u6574\u5185\u5BB9]`;
|
|
233524
234571
|
recordArtifact(ctx, "content", artifact);
|
|
233525
234572
|
return {
|
|
233526
234573
|
kind: "success",
|
|
@@ -233570,7 +234617,7 @@ async function handleWebSearchResult(ctx, result) {
|
|
|
233570
234617
|
|
|
233571
234618
|
---
|
|
233572
234619
|
[\u5185\u5BB9\u8D85\u8FC7 ${WEB_MAX_CHARS} \u5B57\u7B26\uFF0C\u5DF2\u622A\u65AD\u3002\u5B8C\u6574\u5185\u5BB9\u5DF2\u4FDD\u5B58\u5230: ${artifact.absolutePath}]
|
|
233573
|
-
[\u53EF\u7528
|
|
234620
|
+
[\u53EF\u7528 readFile \u8BFB\u53D6\u5B8C\u6574\u5185\u5BB9]`;
|
|
233574
234621
|
recordArtifact(ctx, "content", artifact);
|
|
233575
234622
|
return {
|
|
233576
234623
|
kind: "success",
|
|
@@ -233601,11 +234648,11 @@ async function saveArtifact(ctx, filename, text4) {
|
|
|
233601
234648
|
const resultsRoot = resolveToolResultsRoot(ctx);
|
|
233602
234649
|
const now2 = ctx.runtime.now();
|
|
233603
234650
|
const today = now2.toISOString().split("T")[0];
|
|
233604
|
-
const dir = (0,
|
|
233605
|
-
await (0,
|
|
233606
|
-
const absolutePath = (0,
|
|
234651
|
+
const dir = (0, import_path30.join)(resultsRoot, today);
|
|
234652
|
+
await (0, import_promises30.mkdir)(dir, { recursive: true });
|
|
234653
|
+
const absolutePath = (0, import_path30.join)(dir, filename);
|
|
233607
234654
|
const content = limitArtifactBytes(text4);
|
|
233608
|
-
await (0,
|
|
234655
|
+
await (0, import_promises30.writeFile)(absolutePath, content, "utf-8");
|
|
233609
234656
|
return {
|
|
233610
234657
|
absolutePath,
|
|
233611
234658
|
relativePath: `tool_results/${today}/${filename}`,
|
|
@@ -233616,9 +234663,9 @@ async function saveArtifact(ctx, filename, text4) {
|
|
|
233616
234663
|
}
|
|
233617
234664
|
function resolveToolResultsRoot(ctx) {
|
|
233618
234665
|
if (ctx.groupId && ctx.threadId) {
|
|
233619
|
-
return (0,
|
|
234666
|
+
return (0, import_path30.join)(getThreadDir(ctx.groupId, ctx.threadId), "tool_results");
|
|
233620
234667
|
}
|
|
233621
|
-
return (0,
|
|
234668
|
+
return (0, import_path30.join)(getAgentWorkspaceDir(ctx.agentId), "tool_results");
|
|
233622
234669
|
}
|
|
233623
234670
|
function recordArtifact(ctx, stream, artifact) {
|
|
233624
234671
|
const state = ctx.runtime.runState.getOrCreate(ToolOutputArtifactStateSlot, () => ({ artifacts: [] }));
|
|
@@ -233672,6 +234719,16 @@ registry2.seal();
|
|
|
233672
234719
|
var toolExecutionRegistry = registry2;
|
|
233673
234720
|
|
|
233674
234721
|
// src/adapters/tools/agent-tool-provider.ts
|
|
234722
|
+
var LEGACY_TOOL_NAME_ALIASES = {
|
|
234723
|
+
read: "readFile",
|
|
234724
|
+
write: "writeFile",
|
|
234725
|
+
edit: "editFile",
|
|
234726
|
+
patch: "applyPatch"
|
|
234727
|
+
};
|
|
234728
|
+
function getDisabledToolNames(toolName) {
|
|
234729
|
+
const canonical = LEGACY_TOOL_NAME_ALIASES[toolName];
|
|
234730
|
+
return canonical ? [toolName, canonical] : [toolName];
|
|
234731
|
+
}
|
|
233675
234732
|
var DefaultAgentToolProvider = class {
|
|
233676
234733
|
async getTools(agent, conversationIdOrContext, runtime) {
|
|
233677
234734
|
const toolContext = normalizeToolProviderContext(conversationIdOrContext);
|
|
@@ -233686,7 +234743,9 @@ var DefaultAgentToolProvider = class {
|
|
|
233686
234743
|
const tools = { ...mcpTools, ...skillTool, ...builtInTools };
|
|
233687
234744
|
if (disabledTools?.length) {
|
|
233688
234745
|
for (const toolName of disabledTools) {
|
|
233689
|
-
|
|
234746
|
+
for (const disabledToolName of getDisabledToolNames(toolName)) {
|
|
234747
|
+
delete tools[disabledToolName];
|
|
234748
|
+
}
|
|
233690
234749
|
}
|
|
233691
234750
|
}
|
|
233692
234751
|
const wrappedTools = wrapToolsWithExecutionPipeline(tools, {
|
|
@@ -233794,6 +234853,7 @@ function bootstrapAgentExecutionDeps() {
|
|
|
233794
234853
|
|
|
233795
234854
|
// src/app/bootstrap.ts
|
|
233796
234855
|
init_logger();
|
|
234856
|
+
init_sequelize();
|
|
233797
234857
|
var logger39 = createLogger("bootstrap");
|
|
233798
234858
|
var unsubscribeConversationEvents = null;
|
|
233799
234859
|
async function bootstrapApplication() {
|
|
@@ -233848,6 +234908,7 @@ async function cleanup() {
|
|
|
233848
234908
|
threadManagerPool.stopCleanup();
|
|
233849
234909
|
await channelManager.dispose();
|
|
233850
234910
|
await mcpManager?.dispose();
|
|
234911
|
+
await closeSequelize();
|
|
233851
234912
|
}
|
|
233852
234913
|
|
|
233853
234914
|
// src/cli/index.ts
|