@xopcai/xopc 0.0.360 → 0.0.362
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/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-CnmHVy1D.js → activity-store-_2aJ4ozN.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CQTERenW.js → agent-avatar-dicebear-CSIn4ghK.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-DBNFaHYa.js +1 -0
- package/dist/gateway/static/root/assets/agent-plugin-dialog-DJkGbMVg.js +1 -0
- package/dist/gateway/static/root/assets/agents-CuQayYYr.js +66 -0
- package/dist/gateway/static/root/assets/{agents-admin-api-BtnYiq7O.js → agents-admin-api-Dl0V7UQq.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-V5QVeMvW.js → app-management-settings-panel-CSczq9QV.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-BDkRcoI6.js → appearance-settings-W0vc1J1Q.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-DzCyL89L.js → apps-page-esnvb3hh.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-DZCN9m71.js → archive-plugin-CBR91gHK.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-DOu1wMOV.js → automations-page-B9RdzKUS.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-U9TEZd_t.js +7 -0
- package/dist/gateway/static/root/assets/{binary-plugins-U63xxRgh.js → binary-plugins-C9KIjPph.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-K6is5GrS.js → block-editor-C0bammwh.js} +3 -3
- package/dist/gateway/static/root/assets/{browser-automation-inputs-MmkUGn9W.js → browser-automation-inputs-D2E0co_S.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-B8IiXEBs.js → browser-automations-page-8kqdhAOz.js} +2 -2
- package/dist/gateway/static/root/assets/browser-settings-page-Dl4idi13.js +3 -0
- package/dist/gateway/static/root/assets/{capabilities-BXG_5wIg.js → capabilities-Bfktn_7E.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-Bigu28Z6.js → capabilities-BmMMlNmY.js} +1 -1
- package/dist/gateway/static/root/assets/capabilities-page-3ImhKPBx.js +2 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-4VDEB_ob.js +8 -0
- package/dist/gateway/static/root/assets/{capability-header-actions-wh3Nr0qS.js → capability-header-actions-D1gxCGi8.js} +1 -1
- package/dist/gateway/static/root/assets/channels-Drbr2JR-.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-BU-X9nu1.js → chat-terminal-dock-CSkksCaa.js} +2 -2
- package/dist/gateway/static/root/assets/{computer-settings-page-MyXsSqFJ.js → computer-settings-page-BIXpOJAk.js} +1 -1
- package/dist/gateway/static/root/assets/{connector-service-page-DyxPM_MZ.js → connector-service-page-CTnlVEE1.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-BluT2l4d.js +2 -0
- package/dist/gateway/static/root/assets/{date-picker-WRFvi7Pu.js → date-picker-Bw-CydDe.js} +1 -1
- package/dist/gateway/static/root/assets/dependency-picker-CgHzhtAc.js +1 -0
- package/dist/gateway/static/root/assets/{desktop-pet-iaVa9vVM.js → desktop-pet-YahEnyfd.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-0RS3sP3Z.js → desktop-pet-settings-47Z4bqJr.js} +1 -1
- package/dist/gateway/static/root/assets/device-pairing-wizard-C3aPEEaM.js +1 -0
- package/dist/gateway/static/root/assets/{directory-picker-path-field-Btlldlt3.js → directory-picker-path-field-DH_ok92y.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-BImQT4PU.js → extension-debug-page-t1TiLQrR.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BmuLv-ET.js → extension-page-BeV-7G1h.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-provider-Dg7cRxDX.js → extension-provider-CFCxzqna.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-7Kr8UJK4.js → extension-settings-page-DCODJHOu.js} +1 -1
- package/dist/gateway/static/root/assets/{fallback-models-B0w1lumZ.js → fallback-models-CJzvASNV.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-EZxaKXdC.js → gateway-config-swr-B3LfyXpc.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-realtime-DBRa17u3.js → gateway-realtime-CWxXXAe_.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-realtime-store-DS4WzQyF.js +1 -0
- package/dist/gateway/static/root/assets/gateway-settings-Q5NFzAJ_.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-Wtxq_y2f.js → gateway-startup-retry-BzQP02wp.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-DndTkAw8.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-Bnl0CH4n.js → image-generation-api-BO-Xs__S.js} +1 -1
- package/dist/gateway/static/root/assets/{imports-page-BLOJY67-.js → imports-page-Bb6Gm30L.js} +1 -1
- package/dist/gateway/static/root/assets/index-Byk2QKIS.css +1 -0
- package/dist/gateway/static/root/assets/index-qOHWhsEK.js +106 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-Dlbsip2R.js → keyboard-shortcuts-settings-D2u6sk5l.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-nyWeTK0r.js → local-app-workbench-page-CHeMfXrB.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-CfEpFLs0.js → local-apps-page-BanU1SLr.js} +1 -1
- package/dist/gateway/static/root/assets/{local-session-drafts-CeHhcudO.js → local-session-drafts-DLZQBcZY.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-ChN_vjs2.js → locale-store-BbwWB0ra.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-A38cawkA.js → logs-page-CQdHKCL0.js} +2 -2
- package/dist/gateway/static/root/assets/management-settings-D0V5kCx0.js +1 -0
- package/dist/gateway/static/root/assets/{markdown-view-DKlJx4eo.js → markdown-view-DIBLXsPm.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-JWzrPQwt.js → media-plugins-XPzvDZPz.js} +1 -1
- package/dist/gateway/static/root/assets/{messages-CnM6Qfr7.js → messages-B4AhAW4B.js} +2 -2
- package/dist/gateway/static/root/assets/models-hub-cache-DN5MnhL8.js +1 -0
- package/dist/gateway/static/root/assets/{note-detail-panel-CUGVyo2V.js → note-detail-panel-CodeKI_W.js} +3 -3
- package/dist/gateway/static/root/assets/{notes-api-D8nvWMMC.js → notes-api-CLn4r03Z.js} +1 -1
- package/dist/gateway/static/root/assets/notes-page-liRQoHbF.js +8 -0
- package/dist/gateway/static/root/assets/{oauth-api-BXn1a9qx.js → oauth-api-D9zkd42J.js} +1 -1
- package/dist/gateway/static/root/assets/{page-context-capture-button-C72qIgBg.js → page-context-capture-button-DO6DB9pi.js} +1 -1
- package/dist/gateway/static/root/assets/personal-page-DdfdwOv5.js +1 -0
- package/dist/gateway/static/root/assets/{product-open-page-CT98FsVl.js → product-open-page-C9a3sm6Z.js} +1 -1
- package/dist/gateway/static/root/assets/{project-detail-page-BlqOVwKP.js → project-detail-page-BVe5R-Nj.js} +1 -1
- package/dist/gateway/static/root/assets/projects-page-D_rCwi7w.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-BM_81rLe.js → registry-api-BFxQTbXQ.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-B3imt2du.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-ry0jprz7.js → runtime-tools-settings-panel-C9WC8hJM.js} +1 -1
- package/dist/gateway/static/root/assets/{scenes-page-CV1GkOj6.js → scenes-page-DL95V1UP.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-C5zMrxgR.js → schema-form-CDgGmgrq.js} +1 -1
- package/dist/gateway/static/root/assets/{send-session-input-Dt0t5SoR.js → send-session-input-tkAQXGBG.js} +1 -1
- package/dist/gateway/static/root/assets/{session-api-UkGomZfv.js → session-api-9X7qep91.js} +1 -1
- package/dist/gateway/static/root/assets/{session-manager-DDR-gv_e.js → session-manager-Dy22bbJT.js} +2 -2
- package/dist/gateway/static/root/assets/sessions-page-CeeKIVsM.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-DuvJrDU2.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-C88fsfZF.js → settings-page-xmUGYSOG.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-DESlRgZS.js → setup-status-panel-CmjT9Q4P.js} +1 -1
- package/dist/gateway/static/root/assets/{share-link-dialog-BvSRHs1P.js → share-link-dialog-DeOe9qfQ.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-D5Gey-6E.js → share-preview-page-Ck27gozJ.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-api-DwqLga5H.js → shares-api-D-GuMkPu.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-DpvM2OyO.js +1 -0
- package/dist/gateway/static/root/assets/{skill-api-1hbX3qDC.js → skill-api-BpD02td8.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-reload-api-C1hzIawD.js → skill-reload-api-CezAwYxM.js} +1 -1
- package/dist/gateway/static/root/assets/skills-page-BCgbVI-P.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-DbNk-Jwq.js → system-settings-panel-UODcpzsP.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-BbqQnNes.js +2 -0
- package/dist/gateway/static/root/assets/{theme-store-DTYk7Gll.js → theme-store-6IK2Ik2J.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-H3FheXYH.js → tunnel-api-Eey2aZIz.js} +1 -1
- package/dist/gateway/static/root/assets/{usage-page-DGbqcsV6.js → usage-page-BrWj5mk3.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-R3hEHQQq.js → use-autosave-B-3BJbnn.js} +1 -1
- package/dist/gateway/static/root/assets/{use-composer-attachments-pzPAUV_o.js → use-composer-attachments-ByAHuR8v.js} +1 -1
- package/dist/gateway/static/root/assets/{use-file-preview-expanded-DNhXjL0W.js → use-file-preview-expanded-CXVwWJeP.js} +2 -2
- package/dist/gateway/static/root/assets/user-model-page-Cg-oM8nY.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-C-AF-IcO.js → voice-api-key-field-BtffIKZD.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-CxGsCDoW.js → voice-config-api-BMm9dSKX.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-DfyI9kVf.js → work-discovery-overlay-ByHhF_4r.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-De80GODZ.js → workflow-run-setup-panel-DfNn5VTy.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-B67D-7Wt.js +6 -0
- package/dist/gateway/static/root/assets/{workspace-api-Dwa8kHdY.js → workspace-api-TAD7LYsc.js} +2 -2
- package/dist/gateway/static/root/connector-icons/README.md +5 -2
- package/dist/gateway/static/root/connector-icons/SOURCES.md +15 -1
- package/dist/gateway/static/root/connector-icons/amap.ico +0 -0
- package/dist/gateway/static/root/connector-icons/antv-chart.png +0 -0
- package/dist/gateway/static/root/connector-icons/bailian.png +0 -0
- package/dist/gateway/static/root/connector-icons/dida365.png +0 -0
- package/dist/gateway/static/root/connector-icons/flomo.png +0 -0
- package/dist/gateway/static/root/connector-icons/gmail.svg +1 -3
- package/dist/gateway/static/root/connector-icons/jira.svg +3 -14
- package/dist/gateway/static/root/connector-icons/railway-12306.jpg +0 -0
- package/dist/gateway/static/root/connector-icons/railway-query.svg +1 -0
- package/dist/gateway/static/root/connector-icons/tencent-docs.ico +0 -0
- package/dist/gateway/static/root/connector-icons/yuque.png +0 -0
- package/dist/gateway/static/root/index.html +28 -29
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/task-result-delivery.js +2 -2
- package/dist/src/agent/agent-manager.js +3 -3
- package/dist/src/agent/background-review/run-background-review.js +1 -1
- package/dist/src/agent/embedded/run-for-session.js +70 -4
- package/dist/src/agent/external-tools/endpoint-provider.js +2 -2
- package/dist/src/agent/image/tool-model-config.js +1 -1
- package/dist/src/agent/inbound/attachment-pipeline.js +13 -0
- package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +1 -1
- package/dist/src/agent/memory/compaction-policy.d.ts +4 -0
- package/dist/src/agent/memory/compaction-policy.js +3 -0
- package/dist/src/agent/memory/idle-compaction-scheduler.d.ts +28 -0
- package/dist/src/agent/memory/idle-compaction-scheduler.js +127 -0
- package/dist/src/agent/service/process-direct-one-shot.js +1 -0
- package/dist/src/agent/service/process-direct-streaming.js +1 -0
- package/dist/src/agent/service.js +3 -2
- package/dist/src/agent/session/session-config-service.js +1 -1
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/index.js +1 -1
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +1 -1
- package/dist/src/agent/tasks/task-judge-service.js +1 -1
- package/dist/src/agent/tools/delegation-policy.js +1 -0
- package/dist/src/agent/tools/factory.js +16 -2
- package/dist/src/agent/tools/index.d.ts +1 -0
- package/dist/src/agent/tools/index.js +2 -1
- package/dist/src/agent/tools/media-read-tool.d.ts +5 -1
- package/dist/src/agent/tools/media-read-tool.js +44 -5
- package/dist/src/agent/tools/personal-read-tool.d.ts +3 -0
- package/dist/src/agent/tools/personal-read-tool.js +155 -0
- package/dist/src/agent/tools/personal-task-tool.js +1 -1
- package/dist/src/agent/tools/read.d.ts +3 -0
- package/dist/src/agent/tools/read.js +26 -8
- package/dist/src/agent/tools/session-search-tool.d.ts +1 -0
- package/dist/src/agent/tools/session-search-tool.js +39 -5
- package/dist/src/agent/tools/xopc-use-tool.js +2 -2
- package/dist/src/agent-catalog/capabilities.js +2 -2
- package/dist/src/auth/credentials.js +1 -1
- package/dist/src/auth/oauth-provider-lock.js +1 -1
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/automations/capabilities/drafts.js +1 -1
- package/dist/src/bootstrap/application-state.js +1 -1
- package/dist/src/browser/providers/browser-ext-install.js +1 -1
- package/dist/src/capabilities/runtime/dispatcher.js +1 -1
- package/dist/src/capabilities/runtime/product.js +1 -1
- package/dist/src/cli/commands/agent.js +1 -1
- package/dist/src/cli/commands/agents.js +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/onboard/model.js +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +1 -1
- package/dist/src/config/index.js +3 -3
- package/dist/src/config/loader.js +1 -1
- package/dist/src/config/models-json.js +1 -1
- package/dist/src/config/schema.d.ts +10 -0
- package/dist/src/config/schema.js +1 -1
- package/dist/src/connectors/china-catalog.js +572 -0
- package/dist/src/connectors/cli/authorization.js +3 -2
- package/dist/src/connectors/cli/installer.js +3 -1
- package/dist/src/extensions/agent-plugins/validation.js +1 -1
- package/dist/src/extensions/lockfile.js +1 -1
- package/dist/src/gateway/agents-admin.js +2 -2
- package/dist/src/gateway/hono/lib/config-payload.d.ts +10 -0
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +2 -2
- package/dist/src/gateway/hono/routes/connectors.js +1 -1
- package/dist/src/gateway/hono/routes/notes.js +2 -2
- package/dist/src/gateway/hono/routes/personal-agent.js +1 -1
- package/dist/src/gateway/hono/routes/projects.js +2 -2
- package/dist/src/gateway/hono/routes/session-input-handler.js +1 -1
- package/dist/src/gateway/hono/routes/sessions.js +1 -1
- package/dist/src/gateway/hono/routes/tasks.js +1 -1
- package/dist/src/gateway/hono/routes/voice.js +1 -1
- package/dist/src/gateway/image-generation-setup.js +2 -2
- package/dist/src/gateway/lock.js +1 -1
- package/dist/src/gateway/service/agent-runner.js +1 -0
- package/dist/src/gateway/service/session-command-service.js +1 -1
- package/dist/src/gateway/service/session-input-coordinator.d.ts +1 -0
- package/dist/src/gateway/service/session-input-coordinator.js +2 -0
- package/dist/src/gateway/service.js +1 -1
- package/dist/src/gateway/side-chat/manager.js +3 -2
- package/dist/src/gateway/xopc-cloud-capability-setup.js +1 -1
- package/dist/src/infra/update-restart.js +1 -1
- package/dist/src/local-apps/service.js +1 -1
- package/dist/src/media/store.js +5 -1
- package/dist/src/personal-agent/policy.d.ts +1 -1
- package/dist/src/personal-agent/policy.js +4 -0
- package/dist/src/personal-agent/request-service.js +1 -1
- package/dist/src/personal-agent/service.js +9 -7
- package/dist/src/providers/model-catalog-persistence.js +1 -1
- package/dist/src/session/store.d.ts +12 -1
- package/dist/src/session/store.js +33 -0
- package/dist/src/storage/sqlite/transcript-repository.d.ts +4 -1
- package/dist/src/storage/sqlite/transcript-repository.js +15 -1
- package/dist/src/tasks/capabilities/read.js +2 -2
- package/dist/src/tasks/task-main-update-decision-service.js +1 -1
- package/dist/src/tasks/task-result-delivery-repository.js +4 -5
- package/dist/src/tui/backends/embedded-backend.js +2 -2
- package/dist/src/user-context/config.d.ts +48 -0
- package/dist/src/user-context/config.js +23 -3
- package/dist/src/voice/realtime/persona-context.js +1 -1
- package/dist/src/voice/realtime/runtime.js +1 -1
- package/package.json +2 -2
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CPF0lunJ.js +0 -1
- package/dist/gateway/static/root/assets/agent-plugin-dialog-BjDaZlKy.js +0 -1
- package/dist/gateway/static/root/assets/agents-XopBILLB.js +0 -66
- package/dist/gateway/static/root/assets/automations-workspace-CiY_2otj.js +0 -7
- package/dist/gateway/static/root/assets/browser-settings-page-Cms2Bu3Q.js +0 -3
- package/dist/gateway/static/root/assets/capabilities-page-BAFRNHQv.js +0 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-Cws6od1d.js +0 -8
- package/dist/gateway/static/root/assets/channels-DxwismTc.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-C7-OC3MW.js +0 -2
- package/dist/gateway/static/root/assets/dependency-picker-CLun5Tst.js +0 -1
- package/dist/gateway/static/root/assets/device-pairing-wizard-DVAGb04L.js +0 -1
- package/dist/gateway/static/root/assets/gateway-realtime-store-7glMlD2l.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-DmPvmwYp.js +0 -1
- package/dist/gateway/static/root/assets/home-page-N0Mp-eTJ.js +0 -1
- package/dist/gateway/static/root/assets/index-B7AHDHSO.css +0 -1
- package/dist/gateway/static/root/assets/index-BXrBL_Hb.js +0 -106
- package/dist/gateway/static/root/assets/management-settings-Cse9K61x.js +0 -1
- package/dist/gateway/static/root/assets/model-display-name-DXhO9rcM.js +0 -1
- package/dist/gateway/static/root/assets/models-hub-cache-DnIOzcvn.js +0 -1
- package/dist/gateway/static/root/assets/notes-page-Dk89l5dC.js +0 -8
- package/dist/gateway/static/root/assets/personal-page-DCtduzh8.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-DVN2q_yR.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-BP5kUgIN.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-BXtGeOsR.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CvFVkELy.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-btoP07Fx.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-DYJbwwBT.js +0 -2
- package/dist/gateway/static/root/assets/task-detail-page-DoLKOJrE.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-7pW4Pazn.js +0 -2
- package/dist/gateway/static/root/assets/workflows-page-BuH3pC1C.js +0 -6
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { createLogger } from "../../utils/logger/index.js";
|
|
2
|
+
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
//#region src/agent/memory/idle-compaction-scheduler.ts
|
|
4
|
+
init_logger();
|
|
5
|
+
const log = createLogger("IdleCompaction");
|
|
6
|
+
/** Generation checks protect commits even when a provider ignores cancellation. */
|
|
7
|
+
var IdleCompactionScheduler = class {
|
|
8
|
+
states = /* @__PURE__ */ new Map();
|
|
9
|
+
running = false;
|
|
10
|
+
disposed = false;
|
|
11
|
+
metrics = {
|
|
12
|
+
committed: 0,
|
|
13
|
+
skipped: 0,
|
|
14
|
+
stale: 0,
|
|
15
|
+
cancelled: 0,
|
|
16
|
+
failed: 0
|
|
17
|
+
};
|
|
18
|
+
getMetrics() {
|
|
19
|
+
return { ...this.metrics };
|
|
20
|
+
}
|
|
21
|
+
interrupt(conversationId) {
|
|
22
|
+
const state = this.states.get(conversationId);
|
|
23
|
+
if (!state) return;
|
|
24
|
+
state.generation++;
|
|
25
|
+
if (state.timer) clearTimeout(state.timer);
|
|
26
|
+
state.timer = void 0;
|
|
27
|
+
state.job = void 0;
|
|
28
|
+
if (state.controller && !state.controller.signal.aborted) {
|
|
29
|
+
this.metrics.cancelled++;
|
|
30
|
+
state.controller.abort();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
beginTurn(conversationId) {
|
|
34
|
+
this.interrupt(conversationId);
|
|
35
|
+
const state = this.states.get(conversationId) ?? {
|
|
36
|
+
generation: 0,
|
|
37
|
+
active: 0,
|
|
38
|
+
eligibleAt: 0
|
|
39
|
+
};
|
|
40
|
+
state.active++;
|
|
41
|
+
this.states.set(conversationId, state);
|
|
42
|
+
return state.generation;
|
|
43
|
+
}
|
|
44
|
+
endTurn(conversationId, generation, job, options) {
|
|
45
|
+
const state = this.states.get(conversationId);
|
|
46
|
+
if (!state) return;
|
|
47
|
+
state.active = Math.max(0, state.active - 1);
|
|
48
|
+
if (this.disposed || state.active || state.generation !== generation || !job || !options) return;
|
|
49
|
+
state.job = job;
|
|
50
|
+
state.queuedAt = Date.now();
|
|
51
|
+
state.options = options;
|
|
52
|
+
const delay = Math.max(options.idleMs, state.eligibleAt - Date.now());
|
|
53
|
+
state.timer = setTimeout(() => {
|
|
54
|
+
state.timer = void 0;
|
|
55
|
+
this.drain();
|
|
56
|
+
}, delay);
|
|
57
|
+
state.timer.unref?.();
|
|
58
|
+
}
|
|
59
|
+
cancelAll() {
|
|
60
|
+
for (const id of this.states.keys()) this.interrupt(id);
|
|
61
|
+
}
|
|
62
|
+
dispose() {
|
|
63
|
+
this.disposed = true;
|
|
64
|
+
this.cancelAll();
|
|
65
|
+
for (const state of this.states.values()) if (state.deadline) clearTimeout(state.deadline);
|
|
66
|
+
this.states.clear();
|
|
67
|
+
}
|
|
68
|
+
drain() {
|
|
69
|
+
if (this.running || this.disposed) return;
|
|
70
|
+
const entry = [...this.states.entries()].find(([, state]) => state.job && !state.timer && !state.active);
|
|
71
|
+
if (!entry) return;
|
|
72
|
+
const [conversationId, state] = entry;
|
|
73
|
+
const job = state.job;
|
|
74
|
+
const options = state.options;
|
|
75
|
+
state.job = void 0;
|
|
76
|
+
const generation = state.generation;
|
|
77
|
+
const controller = new AbortController();
|
|
78
|
+
state.controller = controller;
|
|
79
|
+
const startedAt = Date.now();
|
|
80
|
+
const waitMs = startedAt - (state.queuedAt ?? startedAt);
|
|
81
|
+
const isCurrent = () => !this.disposed && !controller.signal.aborted && state.generation === generation && !state.active;
|
|
82
|
+
this.running = true;
|
|
83
|
+
let timeout;
|
|
84
|
+
const deadline = new Promise((_, reject) => {
|
|
85
|
+
timeout = setTimeout(() => {
|
|
86
|
+
controller.abort();
|
|
87
|
+
reject(/* @__PURE__ */ new Error("Idle compaction deadline exceeded"));
|
|
88
|
+
}, options.timeoutMs);
|
|
89
|
+
state.deadline = timeout;
|
|
90
|
+
timeout.unref?.();
|
|
91
|
+
});
|
|
92
|
+
const operation = Promise.resolve().then(() => job(controller.signal, isCurrent));
|
|
93
|
+
Promise.race([operation, deadline]).then((outcome) => {
|
|
94
|
+
this.metrics[outcome]++;
|
|
95
|
+
if (outcome === "committed") state.eligibleAt = Date.now() + options.cooldownMs;
|
|
96
|
+
const fields = {
|
|
97
|
+
conversationId,
|
|
98
|
+
outcome,
|
|
99
|
+
waitMs,
|
|
100
|
+
durationMs: Date.now() - startedAt
|
|
101
|
+
};
|
|
102
|
+
if (outcome === "skipped") log.debug(fields, "Idle compaction skipped");
|
|
103
|
+
else log.info(fields, "Idle compaction finished");
|
|
104
|
+
}).catch((err) => {
|
|
105
|
+
if (state.generation === generation) {
|
|
106
|
+
this.metrics.failed++;
|
|
107
|
+
state.eligibleAt = Date.now() + options.cooldownMs;
|
|
108
|
+
log.warn({
|
|
109
|
+
err,
|
|
110
|
+
conversationId,
|
|
111
|
+
durationMs: Date.now() - startedAt
|
|
112
|
+
}, "Idle compaction failed; retry deferred");
|
|
113
|
+
}
|
|
114
|
+
}).finally(() => {
|
|
115
|
+
clearTimeout(timeout);
|
|
116
|
+
if (state.deadline === timeout) state.deadline = void 0;
|
|
117
|
+
if (state.controller === controller) state.controller = void 0;
|
|
118
|
+
});
|
|
119
|
+
const release = () => {
|
|
120
|
+
this.running = false;
|
|
121
|
+
this.drain();
|
|
122
|
+
};
|
|
123
|
+
operation.then(release, release);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
//#endregion
|
|
127
|
+
export { IdleCompactionScheduler };
|
|
@@ -8,6 +8,7 @@ function isReviewOutput(value) {
|
|
|
8
8
|
return !!value && typeof value === "object" && !Array.isArray(value) && value.type === "review";
|
|
9
9
|
}
|
|
10
10
|
async function runProcessDirect(deps, input) {
|
|
11
|
+
deps.sessionStore?.idleCompaction?.interrupt(input.conversationId);
|
|
11
12
|
const { channel, chatId } = await deps.resolveSessionEndpoint(input.conversationId);
|
|
12
13
|
deps.initSessionContext(input.conversationId, channel, chatId, input.origin);
|
|
13
14
|
try {
|
|
@@ -138,6 +138,7 @@ function pushAssistantReceipt(queue, text, runId, metadata) {
|
|
|
138
138
|
}
|
|
139
139
|
async function* runProcessDirectStreaming(deps, input) {
|
|
140
140
|
const conversationId = input.conversationId ?? resolveAgentMainConversationId({ agentId: resolveDefaultAgentId() });
|
|
141
|
+
deps.sessionStore?.idleCompaction?.interrupt(conversationId);
|
|
141
142
|
const isConnectionResume = Boolean(input.runId && getConnectionResumeInput(conversationId, input.runId));
|
|
142
143
|
const isClarificationResume = Boolean(input.runId && getClarificationResumeInput(conversationId, input.runId));
|
|
143
144
|
const isInternalResume = isConnectionResume || isClarificationResume;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
3
|
import { init_attachment_ref, parseNoteAttachmentTarget } from "../notes/attachment-ref.js";
|
|
4
|
-
import { init_agent_scope, resolveAgentHomeDir, resolveDefaultAgentId } from "./agent-scope.js";
|
|
5
|
-
import { extractTextContent } from "./context/workspace.js";
|
|
6
4
|
import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
|
|
7
5
|
import { applyConfigOverrides } from "../config/runtime-overrides.js";
|
|
6
|
+
import { init_agent_scope, resolveAgentHomeDir, resolveDefaultAgentId } from "./agent-scope.js";
|
|
8
7
|
import { init_agent_session_key, resolveAgentIdFromConversationId } from "../routing/agent-session-key.js";
|
|
9
8
|
import { extractProfileAgentId, resolveEffectiveAgentConfigForSession } from "../config/agent-profile.js";
|
|
10
9
|
import { init_providers, resolveModel } from "../providers/index.js";
|
|
10
|
+
import { extractTextContent } from "./context/workspace.js";
|
|
11
11
|
import { effectiveWorkspacePathForSession } from "../session/session-workspace.js";
|
|
12
12
|
import { getProjectForSession } from "../projects/workspace.js";
|
|
13
13
|
import { runWithEmbeddedExecutionSession } from "./embedded/execution-context.js";
|
|
@@ -878,6 +878,7 @@ var AgentService = class {
|
|
|
878
878
|
}
|
|
879
879
|
}
|
|
880
880
|
dispose() {
|
|
881
|
+
this.sessionStore.idleCompaction.dispose();
|
|
881
882
|
this.sessionTracker.dispose();
|
|
882
883
|
this.sessionState.disposeAll();
|
|
883
884
|
this.agentManager.dispose();
|
|
@@ -6,8 +6,8 @@ import { ResponseLanguageSchema, init_response_language } from "../../i18n/respo
|
|
|
6
6
|
import { resolveEffectiveAgentConfigForSession } from "../../config/agent-profile.js";
|
|
7
7
|
import { normalizeWorkingDirectoryInput } from "../../session/session-workspace.js";
|
|
8
8
|
import { getProjectWorkspacePathForSession } from "../../projects/workspace.js";
|
|
9
|
-
import { getModelThinking } from "../../providers/model-thinking.js";
|
|
10
9
|
import { isPersonalConversation } from "../../personal-agent/repository.js";
|
|
10
|
+
import { getModelThinking } from "../../providers/model-thinking.js";
|
|
11
11
|
import { savePersonalModelConfig } from "../../personal-agent/model-config.js";
|
|
12
12
|
import { normalizeReasoningLevel, normalizeThinkLevel, normalizeVerboseLevel } from "../transcript/thinking-types.js";
|
|
13
13
|
import "../../session/index.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { init_write_file_atomic, writeTextAtomicSync } from "../../infra/write-file-atomic.js";
|
|
2
1
|
import { init_paths, resolveSkillsLockPath } from "../../config/paths.js";
|
|
2
|
+
import { init_write_file_atomic, writeTextAtomicSync } from "../../infra/write-file-atomic.js";
|
|
3
3
|
import { existsSync, readFileSync } from "node:fs";
|
|
4
4
|
//#region src/agent/skills/hub-lock.ts
|
|
5
5
|
/**
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { resolveStateDir } from "../../config/paths-state.js";
|
|
2
2
|
import { createLogger } from "../../utils/logger/index.js";
|
|
3
3
|
import { init_logger } from "../../utils/logger.js";
|
|
4
|
-
import { parseFrontmatter } from "../../markdown/frontmatter.js";
|
|
5
4
|
import { init_paths } from "../../config/paths.js";
|
|
5
|
+
import { parseFrontmatter } from "../../markdown/frontmatter.js";
|
|
6
6
|
import { findInstallSpec, hasBinary, installSkill } from "./installer.js";
|
|
7
7
|
import { applySkillEnvOverrides, createSkillConfigManager, getSkillEnvironment, isSkillEnabled, resolveSkillConfig, validateSkillConfig } from "./config.js";
|
|
8
8
|
import { parseSkillToolConditions } from "./skill-tool-gating.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { parseFrontmatter } from "../../markdown/frontmatter.js";
|
|
2
1
|
import { init_paths, resolveSkillsDir } from "../../config/paths.js";
|
|
2
|
+
import { parseFrontmatter } from "../../markdown/frontmatter.js";
|
|
3
3
|
import { loadSkillsLock } from "./hub-lock.js";
|
|
4
4
|
import { dirname, join, resolve, sep } from "node:path";
|
|
5
5
|
import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { parseFrontmatter } from "../../markdown/frontmatter.js";
|
|
2
1
|
import { init_paths, resolveSkillsDir } from "../../config/paths.js";
|
|
2
|
+
import { parseFrontmatter } from "../../markdown/frontmatter.js";
|
|
3
3
|
import { resolveWorkspaceSkillsDir } from "./workspace-skills-dir.js";
|
|
4
4
|
import { formatScanSummary, scanSkillDirectory } from "./scanner.js";
|
|
5
5
|
import { fuzzyFindText, normalizeForFuzzyMatch, normalizeToLF, restoreLineEndings } from "../tools/edit-diff.js";
|
|
@@ -207,7 +207,7 @@ var TaskJudgeService = class {
|
|
|
207
207
|
expectedRunVersion: run.version,
|
|
208
208
|
receipt: {
|
|
209
209
|
status: "succeeded",
|
|
210
|
-
summary: payload.assistantPlainText
|
|
210
|
+
summary: payload.assistantPlainText || "Agent run completed",
|
|
211
211
|
changes: [],
|
|
212
212
|
evidence,
|
|
213
213
|
verification: {
|
|
@@ -62,6 +62,7 @@ import { createDesktopPetTool } from "./desktop-pet-tool.js";
|
|
|
62
62
|
import { createManagedJobTool } from "./managed-job-tool.js";
|
|
63
63
|
import { createImageTool } from "./image-tool.js";
|
|
64
64
|
import { createImageGenerateTool } from "./image-generate-tool.js";
|
|
65
|
+
import { createPersonalReadTool } from "./personal-read-tool.js";
|
|
65
66
|
import "./index.js";
|
|
66
67
|
import { createPersonalTaskTool } from "./personal-task-tool.js";
|
|
67
68
|
import { createPersonalRequestTools } from "./personal-request-tool.js";
|
|
@@ -279,7 +280,14 @@ var AgentToolsFactory = class AgentToolsFactory {
|
|
|
279
280
|
canAccessMemory: () => currentAccess().knowledge
|
|
280
281
|
});
|
|
281
282
|
const optionalTools = [imageTool, imageGenerateTool].filter((t) => t != null);
|
|
282
|
-
const readTool = createReadFileTool(workspace, {
|
|
283
|
+
const readTool = createReadFileTool(workspace, {
|
|
284
|
+
profileMarkdownRoot: options?.profileMarkdownRoot,
|
|
285
|
+
...personalToolsConfigured ? {
|
|
286
|
+
defaultMaxLines: 150,
|
|
287
|
+
maxOutputBytes: 8e3,
|
|
288
|
+
maxReadBytes: 12e3
|
|
289
|
+
} : {}
|
|
290
|
+
});
|
|
283
291
|
const writeTool = createWriteFileTool(workspace, { profileMarkdownRoot: options?.profileMarkdownRoot });
|
|
284
292
|
const applyPatchTool = createApplyPatchTool(workspace);
|
|
285
293
|
const listDir = createListDirTool(workspace);
|
|
@@ -395,7 +403,11 @@ var AgentToolsFactory = class AgentToolsFactory {
|
|
|
395
403
|
})] : [],
|
|
396
404
|
createSendMediaTool(workspace, bus, deliveryContext),
|
|
397
405
|
createPublishArtifactsTool(workspace),
|
|
398
|
-
createReadMediaTool(
|
|
406
|
+
createReadMediaTool(personalToolsConfigured ? {
|
|
407
|
+
textOnly: true,
|
|
408
|
+
maxChars: 8e3,
|
|
409
|
+
maxReadBytes: 12e3
|
|
410
|
+
} : void 0),
|
|
399
411
|
...isShareToolAvailable(cfg) ? [createCreateShareTool({
|
|
400
412
|
workspace,
|
|
401
413
|
getConfig: () => this.deps.getConfig?.()
|
|
@@ -461,6 +473,7 @@ var AgentToolsFactory = class AgentToolsFactory {
|
|
|
461
473
|
getCurrentConversationId: () => this.deps.getCurrentContext()?.conversationId
|
|
462
474
|
})] : [],
|
|
463
475
|
...this.deps.getSessionStore && getPrimary ? [createSessionSearchTool({
|
|
476
|
+
localOnly: personalToolsConfigured,
|
|
464
477
|
getSessionStore: this.deps.getSessionStore,
|
|
465
478
|
getPrimaryModel: getPrimary,
|
|
466
479
|
getCurrentConversationId: () => this.deps.getCurrentContext()?.conversationId,
|
|
@@ -474,6 +487,7 @@ var AgentToolsFactory = class AgentToolsFactory {
|
|
|
474
487
|
...browserEnabled && this.deps.getBrowserAutomationService ? [createBrowserAutomationTool({ getBrowserAutomationService: this.deps.getBrowserAutomationService })] : [],
|
|
475
488
|
...this.deps.getAutomationService || this.deps.getSceneAccess || this.deps.getProjectService || this.deps.getNotesService || this.deps.getLocalAppService || this.deps.getChatPreviewService || this.deps.dispatchTaskEvents || this.deps.dispatchTaskRuns ? [createXopcUseTool(productToolDeps), ...personalToolsConfigured ? [
|
|
476
489
|
createPersonalTaskTool(productToolDeps),
|
|
490
|
+
createPersonalReadTool(productToolDeps),
|
|
477
491
|
...createPersonalRequestTools(productToolDeps),
|
|
478
492
|
createPersonalPreferenceTool({
|
|
479
493
|
getCurrentConversationId: () => this.deps.getCurrentContext()?.conversationId,
|
|
@@ -42,3 +42,4 @@ export { createImageTool, resolveImageModelConfigForTool } from './image-tool.js
|
|
|
42
42
|
export { createImageGenerateTool, resolveImageGenerationModelConfigForTool } from './image-generate-tool.js';
|
|
43
43
|
export { truncateHead, truncateTail, truncateLine, formatSize, type TruncationResult, type TruncationOptions, DEFAULT_MAX_LINES, DEFAULT_MAX_BYTES, GREP_MAX_LINE_LENGTH, } from './truncate.js';
|
|
44
44
|
export { normalizeToLF, restoreLineEndings, normalizeForFuzzyMatch, fuzzyFindText, stripBom, generateDiffString, type FuzzyMatchResult, } from './edit-diff.js';
|
|
45
|
+
export { createPersonalReadTool } from './personal-read-tool.js';
|
|
@@ -45,4 +45,5 @@ import { createDesktopPetTool } from "./desktop-pet-tool.js";
|
|
|
45
45
|
import { createManagedJobTool } from "./managed-job-tool.js";
|
|
46
46
|
import { createImageTool } from "./image-tool.js";
|
|
47
47
|
import { createImageGenerateTool, resolveImageGenerationModelConfigForTool } from "./image-generate-tool.js";
|
|
48
|
-
|
|
48
|
+
import { createPersonalReadTool } from "./personal-read-tool.js";
|
|
49
|
+
export { BrowserRuntime, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_TOOL_METADATA, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, TodoStore, ToolConcurrencyController, assertBrowserUrlAllowed, createApplyPatchTool, createAutomationTool, createBrowserAutomationTool, createClarifyTool, createCreateShareTool, createDataBatchTool, createDelegateTool, createDesktopPetTool, createExecCommandTool, createFindTool, createGrepTool, createImageGenerateTool, createImageTool, createKnowledgeGetTool, createKnowledgeSearchTool, createKnowledgeWriteTool, createListDirTool, createManagedJobTool, createMemoryMaintenanceTool, createMessageTool, createPersonalReadTool, createPublishArtifactsTool, createReadFileTool, createReadMediaTool, createSendMediaTool, createSessionRecallTool, createSessionSearchTool, createSessionStatusTool, createSkillInstallTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createSkillsMarketplaceSearchTool, createTodoTool, createToolManualTool, createUpdatePlanTool, createUserContextGetTool, createUserContextSearchTool, createUserContextUpdateTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowManageTool, createWorkflowTool, createWriteFileTool, createXopcUseTool, findTool, formatSize, fuzzyFindText, generateDiffString, getToolMetadata, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, resolveToolLockMode, restoreLineEndings, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
|
|
@@ -15,12 +15,14 @@ function clampMaxBytes(raw) {
|
|
|
15
15
|
if (typeof raw !== "number" || !Number.isFinite(raw) || raw <= 0) return DEFAULT_MAX_BYTES;
|
|
16
16
|
return Math.min(Math.floor(raw), HARD_MAX_BYTES);
|
|
17
17
|
}
|
|
18
|
-
function createReadMediaTool() {
|
|
18
|
+
function createReadMediaTool(options) {
|
|
19
19
|
return {
|
|
20
20
|
name: "read_media",
|
|
21
21
|
label: "Read Media Attachment",
|
|
22
22
|
description: "Read an attachment by media:// URI. Use this for xopc-media-uri attachments in user messages.",
|
|
23
23
|
parameters: ReadMediaSchema,
|
|
24
|
+
supportsParallel: true,
|
|
25
|
+
idempotent: true,
|
|
24
26
|
async execute(_toolCallId, params, _signal) {
|
|
25
27
|
const uri = typeof params.uri === "string" ? params.uri.trim() : "";
|
|
26
28
|
if (!uri) return {
|
|
@@ -34,7 +36,7 @@ function createReadMediaTool() {
|
|
|
34
36
|
}
|
|
35
37
|
};
|
|
36
38
|
try {
|
|
37
|
-
const { buffer, path } = await readMediaReference(uri, clampMaxBytes(params.maxBytes));
|
|
39
|
+
const { buffer, path } = await readMediaReference(uri, Math.min(clampMaxBytes(params.maxBytes), options?.maxReadBytes ?? HARD_MAX_BYTES));
|
|
38
40
|
const mimeType = mimeTypeFromMediaPath(path);
|
|
39
41
|
const metadata = {
|
|
40
42
|
ok: true,
|
|
@@ -43,14 +45,35 @@ function createReadMediaTool() {
|
|
|
43
45
|
size: buffer.byteLength,
|
|
44
46
|
path
|
|
45
47
|
};
|
|
46
|
-
if (isLikelyText(mimeType))
|
|
48
|
+
if (isLikelyText(mimeType)) {
|
|
49
|
+
const fullText = buffer.toString("utf8");
|
|
50
|
+
const maxChars = options?.maxChars ?? fullText.length;
|
|
51
|
+
const truncated = fullText.length > maxChars;
|
|
52
|
+
return {
|
|
53
|
+
content: [{
|
|
54
|
+
type: "text",
|
|
55
|
+
text: fullText.slice(0, maxChars) + (truncated ? "\n[Attachment truncated; delegate full analysis to a specialist.]" : "")
|
|
56
|
+
}],
|
|
57
|
+
details: {
|
|
58
|
+
...metadata,
|
|
59
|
+
kind: "text",
|
|
60
|
+
truncated,
|
|
61
|
+
...truncated && options?.textOnly ? {
|
|
62
|
+
requiresSpecialist: true,
|
|
63
|
+
reason: "large_attachment"
|
|
64
|
+
} : {}
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
if (options?.textOnly) return {
|
|
47
69
|
content: [{
|
|
48
70
|
type: "text",
|
|
49
|
-
text:
|
|
71
|
+
text: "Binary attachment: delegate document parsing or media analysis to a specialist."
|
|
50
72
|
}],
|
|
51
73
|
details: {
|
|
52
74
|
...metadata,
|
|
53
|
-
kind: "
|
|
75
|
+
kind: "binary",
|
|
76
|
+
requiresSpecialist: true
|
|
54
77
|
}
|
|
55
78
|
};
|
|
56
79
|
return {
|
|
@@ -68,6 +91,22 @@ function createReadMediaTool() {
|
|
|
68
91
|
}
|
|
69
92
|
};
|
|
70
93
|
} catch (err) {
|
|
94
|
+
if (options?.textOnly && err?.code === "MEDIA_READ_LIMIT") {
|
|
95
|
+
const size = err.size;
|
|
96
|
+
return {
|
|
97
|
+
content: [{
|
|
98
|
+
type: "text",
|
|
99
|
+
text: `Attachment is large (${size} bytes; local read limit ${options.maxReadBytes ?? HARD_MAX_BYTES} bytes). Tell the user briefly, then delegate reading and processing with this URI: ${uri}`
|
|
100
|
+
}],
|
|
101
|
+
details: {
|
|
102
|
+
ok: true,
|
|
103
|
+
uri,
|
|
104
|
+
size,
|
|
105
|
+
requiresSpecialist: true,
|
|
106
|
+
reason: "large_attachment"
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
71
110
|
const message = err instanceof Error ? err.message : String(err);
|
|
72
111
|
return {
|
|
73
112
|
content: [{
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { CapabilityDispatcher } from "../../capabilities/runtime/dispatcher.js";
|
|
2
|
+
import { registerNoteReadCapabilities } from "../../notes/capabilities/read.js";
|
|
3
|
+
import { registerProjectReadCapabilities } from "../../projects/capabilities/read.js";
|
|
4
|
+
import { registerAutomationReadCapabilities } from "../../automations/capabilities/read.js";
|
|
5
|
+
import { Type } from "@sinclair/typebox";
|
|
6
|
+
//#region src/agent/tools/personal-read-tool.ts
|
|
7
|
+
const schema = Type.Object({
|
|
8
|
+
kind: Type.Union([
|
|
9
|
+
Type.Literal("note"),
|
|
10
|
+
Type.Literal("project"),
|
|
11
|
+
Type.Literal("automation")
|
|
12
|
+
]),
|
|
13
|
+
command: Type.Union([Type.Literal("list"), Type.Literal("get")]),
|
|
14
|
+
id: Type.Optional(Type.String()),
|
|
15
|
+
search: Type.Optional(Type.String({ maxLength: 500 })),
|
|
16
|
+
projectId: Type.Optional(Type.String()),
|
|
17
|
+
offset: Type.Optional(Type.Integer({ minimum: 0 })),
|
|
18
|
+
limit: Type.Optional(Type.Integer({
|
|
19
|
+
minimum: 1,
|
|
20
|
+
maximum: 10
|
|
21
|
+
}))
|
|
22
|
+
});
|
|
23
|
+
const fields = [
|
|
24
|
+
"id",
|
|
25
|
+
"name",
|
|
26
|
+
"title",
|
|
27
|
+
"status",
|
|
28
|
+
"kind",
|
|
29
|
+
"projectId",
|
|
30
|
+
"description",
|
|
31
|
+
"markdown",
|
|
32
|
+
"objective",
|
|
33
|
+
"enabled",
|
|
34
|
+
"createdAt",
|
|
35
|
+
"updatedAt",
|
|
36
|
+
"createdAtMs",
|
|
37
|
+
"updatedAtMs",
|
|
38
|
+
"trigger",
|
|
39
|
+
"action",
|
|
40
|
+
"state"
|
|
41
|
+
];
|
|
42
|
+
/** Small projections keep local reads from expanding the next model request. */
|
|
43
|
+
function compact(value, textLimit) {
|
|
44
|
+
if (!value || typeof value !== "object") return {};
|
|
45
|
+
const source = value;
|
|
46
|
+
const result = {};
|
|
47
|
+
const truncatedFields = [];
|
|
48
|
+
for (const key of fields) {
|
|
49
|
+
const entry = source[key];
|
|
50
|
+
if (typeof entry === "string") {
|
|
51
|
+
result[key] = entry.slice(0, textLimit);
|
|
52
|
+
if (entry.length > textLimit) truncatedFields.push(key);
|
|
53
|
+
} else if (typeof entry === "number" || typeof entry === "boolean" || entry === null) result[key] = entry;
|
|
54
|
+
else if (entry && typeof entry === "object" && !Array.isArray(entry)) result[key] = Object.fromEntries(Object.entries(entry).slice(0, 12).filter(([, item]) => [
|
|
55
|
+
"string",
|
|
56
|
+
"number",
|
|
57
|
+
"boolean"
|
|
58
|
+
].includes(typeof item) || item === null).map(([field, item]) => [field, typeof item === "string" ? item.slice(0, 200) : item]));
|
|
59
|
+
}
|
|
60
|
+
if (truncatedFields.length) result.truncatedFields = truncatedFields;
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
function createPersonalReadTool(deps) {
|
|
64
|
+
const dispatcher = new CapabilityDispatcher();
|
|
65
|
+
if (deps.getNotesService) registerNoteReadCapabilities(dispatcher, () => {
|
|
66
|
+
const notes = deps.getNotesService();
|
|
67
|
+
if (!notes) throw new Error("Notes service unavailable");
|
|
68
|
+
return notes;
|
|
69
|
+
});
|
|
70
|
+
const projects = deps.getProjectService?.();
|
|
71
|
+
if (projects) registerProjectReadCapabilities(dispatcher, projects);
|
|
72
|
+
const automations = deps.getAutomationService?.();
|
|
73
|
+
if (automations) registerAutomationReadCapabilities(dispatcher, automations, projects);
|
|
74
|
+
return {
|
|
75
|
+
name: "personal_read",
|
|
76
|
+
label: "Read local objects",
|
|
77
|
+
description: "Read local notes, projects or automation state. Only list/get; bounded excerpts, no network or model calls. Use personal_task for delegated tasks.",
|
|
78
|
+
parameters: schema,
|
|
79
|
+
supportsParallel: true,
|
|
80
|
+
idempotent: true,
|
|
81
|
+
async execute(_id, raw, signal) {
|
|
82
|
+
const input = raw;
|
|
83
|
+
if (![
|
|
84
|
+
"note",
|
|
85
|
+
"project",
|
|
86
|
+
"automation"
|
|
87
|
+
].includes(input.kind) || !["list", "get"].includes(input.command)) throw new Error("Only local note/project/automation list/get is supported");
|
|
88
|
+
if (input.command === "get" && !input.id?.trim()) throw new Error("id is required");
|
|
89
|
+
if (input.kind === "automation" && input.search) throw new Error("Automation search is unsupported; use list");
|
|
90
|
+
const operation = `xopc.${input.kind === "note" ? "notes" : input.kind === "project" ? "projects" : "automations"}.${input.command}`;
|
|
91
|
+
const limit = Math.min(10, Math.max(1, input.limit ?? 5));
|
|
92
|
+
const offset = Math.max(0, input.offset ?? 0);
|
|
93
|
+
const args = input.command === "get" ? { id: input.id } : input.kind === "automation" ? { ...input.projectId ? { projectId: input.projectId } : {} } : {
|
|
94
|
+
limit,
|
|
95
|
+
offset,
|
|
96
|
+
...input.search ? { search: input.search } : {},
|
|
97
|
+
...input.kind === "note" && input.projectId ? { projectId: input.projectId } : {}
|
|
98
|
+
};
|
|
99
|
+
const result = await dispatcher.call(operation, args, {
|
|
100
|
+
principalId: `agent:${deps.getCurrentAgentId?.() ?? "main"}`,
|
|
101
|
+
surface: "agent",
|
|
102
|
+
scopes: ["workspace.read", "automations.read"],
|
|
103
|
+
allowedCapabilities: [operation],
|
|
104
|
+
authorize: deps.authorizeCapability ?? (() => true),
|
|
105
|
+
signal
|
|
106
|
+
});
|
|
107
|
+
let payload;
|
|
108
|
+
if (input.command === "get") payload = {
|
|
109
|
+
kind: input.kind,
|
|
110
|
+
item: compact(result[input.kind], 6e3),
|
|
111
|
+
excerpts: true
|
|
112
|
+
};
|
|
113
|
+
else {
|
|
114
|
+
const rows = result.items ?? [];
|
|
115
|
+
const selected = input.kind === "automation" ? rows.slice(offset, offset + limit) : rows;
|
|
116
|
+
payload = {
|
|
117
|
+
kind: input.kind,
|
|
118
|
+
items: selected.map((row) => compact(row, 200)),
|
|
119
|
+
offset,
|
|
120
|
+
total: result.total ?? rows.length,
|
|
121
|
+
nextOffset: selected.length === limit ? offset + selected.length : void 0,
|
|
122
|
+
excerpts: true
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
const serialized = JSON.stringify(payload);
|
|
126
|
+
const requiresSpecialist = input.command === "get" && (serialized.length > 12e3 || Boolean(payload.item?.truncatedFields));
|
|
127
|
+
if (requiresSpecialist) payload = {
|
|
128
|
+
...payload,
|
|
129
|
+
requiresSpecialist: true,
|
|
130
|
+
reason: "large_object",
|
|
131
|
+
id: input.id,
|
|
132
|
+
guidance: "Briefly tell the user the material is large, then delegate full reading and processing using this object kind and ID."
|
|
133
|
+
};
|
|
134
|
+
const output = JSON.stringify(payload);
|
|
135
|
+
return {
|
|
136
|
+
content: [{
|
|
137
|
+
type: "text",
|
|
138
|
+
text: output.length <= 12e3 ? output : JSON.stringify({
|
|
139
|
+
kind: input.kind,
|
|
140
|
+
excerpt: output.slice(0, 1e4),
|
|
141
|
+
truncated: true,
|
|
142
|
+
requiresSpecialist: true,
|
|
143
|
+
id: input.id
|
|
144
|
+
})
|
|
145
|
+
}],
|
|
146
|
+
details: {
|
|
147
|
+
localOnly: true,
|
|
148
|
+
requiresSpecialist: requiresSpecialist || output.length > 12e3
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
//#endregion
|
|
155
|
+
export { createPersonalReadTool };
|
|
@@ -3,9 +3,9 @@ import { init_agent_config } from "../../agent-config/index.js";
|
|
|
3
3
|
import { AgentCatalogRepository, init_repository } from "../../agent-catalog/repository.js";
|
|
4
4
|
import { resolveEffectiveAgentConfigForAgent } from "../../config/agent-profile.js";
|
|
5
5
|
import { init_providers, isProviderConfiguredSync, resolveModel } from "../../providers/index.js";
|
|
6
|
+
import { isPersonalConversation } from "../../personal-agent/repository.js";
|
|
6
7
|
import { TaskOriginRepository } from "../../tasks/task-origin-repository.js";
|
|
7
8
|
import { createXopcUseTool } from "./xopc-use-tool.js";
|
|
8
|
-
import { isPersonalConversation } from "../../personal-agent/repository.js";
|
|
9
9
|
import { PERSONAL_WORKER_RESULT_GUIDANCE } from "../../personal-agent/communication.js";
|
|
10
10
|
import { randomUUID } from "node:crypto";
|
|
11
11
|
import { Type } from "@sinclair/typebox";
|
|
@@ -2,5 +2,8 @@ import type { AgentTool } from '@earendil-works/pi-agent-core';
|
|
|
2
2
|
export interface CreateReadFileToolOptions {
|
|
3
3
|
/** When set and the path is a bare profile filename (e.g. SOUL.md), try this root if not in workspace. */
|
|
4
4
|
profileMarkdownRoot?: string;
|
|
5
|
+
defaultMaxLines?: number;
|
|
6
|
+
maxOutputBytes?: number;
|
|
7
|
+
maxReadBytes?: number;
|
|
5
8
|
}
|
|
6
9
|
export declare function createReadFileTool(workspace: string, options?: CreateReadFileToolOptions): AgentTool;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { checkedFilePath, readWorkspaceFileAsync } from "../sandbox/fileAccess.js";
|
|
2
2
|
import { dataScheduler } from "../data-acquisition/scheduler.js";
|
|
3
3
|
import { checkFileSafety } from "../prompt/safety.js";
|
|
4
|
-
import {
|
|
4
|
+
import { formatSize, truncateHead } from "./truncate.js";
|
|
5
5
|
import { isBareProfileMarkdownFileName, resolvePathUnderWorkspace, resolveProfileMarkdownPathIfBareName } from "./tool-paths.js";
|
|
6
6
|
import { stat } from "fs/promises";
|
|
7
7
|
import { Type } from "@sinclair/typebox";
|
|
@@ -29,11 +29,13 @@ function createReadFileTool(workspace, options) {
|
|
|
29
29
|
supportsParallel: true,
|
|
30
30
|
idempotent: true,
|
|
31
31
|
async execute(_toolCallId, params, signal) {
|
|
32
|
-
return dataScheduler.run(workspace, signal, () => executeReadFile(workspace, options
|
|
32
|
+
return dataScheduler.run(workspace, signal, () => executeReadFile(workspace, options, params, signal));
|
|
33
33
|
}
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
|
-
async function executeReadFile(workspace,
|
|
36
|
+
async function executeReadFile(workspace, options, params, signal) {
|
|
37
|
+
const profileMarkdownRoot = options?.profileMarkdownRoot;
|
|
38
|
+
const maxOutputBytes = options?.maxOutputBytes ?? 51200;
|
|
37
39
|
try {
|
|
38
40
|
const safety = checkFileSafety("read", params.path);
|
|
39
41
|
if (!safety.allowed) return {
|
|
@@ -60,6 +62,18 @@ async function executeReadFile(workspace, profileMarkdownRoot, params, signal) {
|
|
|
60
62
|
}
|
|
61
63
|
} else throw e;
|
|
62
64
|
}
|
|
65
|
+
if (options?.maxReadBytes && stats.size > options.maxReadBytes) return {
|
|
66
|
+
content: [{
|
|
67
|
+
type: "text",
|
|
68
|
+
text: `File is large (${formatSize(stats.size)}; local read limit ${formatSize(options.maxReadBytes)}). Tell the user briefly, then delegate reading and processing. Path: ${normalized}`
|
|
69
|
+
}],
|
|
70
|
+
details: {
|
|
71
|
+
path: normalized,
|
|
72
|
+
size: stats.size,
|
|
73
|
+
requiresSpecialist: true,
|
|
74
|
+
reason: "large_file"
|
|
75
|
+
}
|
|
76
|
+
};
|
|
63
77
|
if (stats.size > MAX_FILE_SIZE) return {
|
|
64
78
|
content: [{
|
|
65
79
|
type: "text",
|
|
@@ -72,12 +86,12 @@ async function executeReadFile(workspace, profileMarkdownRoot, params, signal) {
|
|
|
72
86
|
const lines = content.split("\n");
|
|
73
87
|
if (offset > lines.length) throw new Error(`Offset ${offset} exceeds ${lines.length} lines`);
|
|
74
88
|
const truncation = truncateHead(lines.slice(offset - 1).join("\n"), {
|
|
75
|
-
maxLines: params.limit || DEFAULT_MAX_LINES,
|
|
76
|
-
maxBytes:
|
|
89
|
+
maxLines: params.limit || options?.defaultMaxLines || DEFAULT_MAX_LINES,
|
|
90
|
+
maxBytes: maxOutputBytes
|
|
77
91
|
});
|
|
78
92
|
let outputText = truncation.content;
|
|
79
|
-
if (truncation.truncated) if (truncation.firstLineExceedsLimit) outputText = `(Line exceeds ${formatSize(
|
|
80
|
-
else outputText += `\n\n[Lines ${offset}-${offset + truncation.outputLines - 1} of ${lines.length}; continue with offset=${offset + truncation.outputLines}]`;
|
|
93
|
+
if (truncation.truncated) if (truncation.firstLineExceedsLimit) outputText = `(Line exceeds ${formatSize(maxOutputBytes)})`;
|
|
94
|
+
else outputText += options?.maxReadBytes ? `\n\n[File excerpt only. Tell the user briefly and delegate full reading and processing. Path: ${normalized}]` : `\n\n[Lines ${offset}-${offset + truncation.outputLines - 1} of ${lines.length}; continue with offset=${offset + truncation.outputLines}]`;
|
|
81
95
|
return {
|
|
82
96
|
content: [{
|
|
83
97
|
type: "text",
|
|
@@ -87,7 +101,11 @@ async function executeReadFile(workspace, profileMarkdownRoot, params, signal) {
|
|
|
87
101
|
path: normalized,
|
|
88
102
|
offset,
|
|
89
103
|
totalLines: lines.length,
|
|
90
|
-
truncated: truncation.truncated
|
|
104
|
+
truncated: truncation.truncated,
|
|
105
|
+
...options?.maxReadBytes && truncation.truncated ? {
|
|
106
|
+
requiresSpecialist: true,
|
|
107
|
+
reason: "large_file"
|
|
108
|
+
} : {}
|
|
91
109
|
}
|
|
92
110
|
};
|
|
93
111
|
} catch (error) {
|