@xopcai/xopc 0.0.363 → 0.0.366
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/dist/sidepanel.js +16 -4
- 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-GvR2gZ0T.js → activity-store-SVmnh__i.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DkcXyPH0.js → agent-avatar-dicebear-CS9lg5h2.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-B-l5AaYN.js → agent-defaults-settings-panel-CvUPtxS4.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-plugin-dialog-BY6tPYOK.js → agent-plugin-dialog-1tRxDfjI.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-admin-api-BkXb7VEZ.js → agents-admin-api-CVdFV-cU.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-CdSEoeje.js → agents-gdT0whx9.js} +3 -3
- package/dist/gateway/static/root/assets/{app-management-settings-panel-BtD53cfe.js → app-management-settings-panel-CaxnUxvy.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-BAweWgX_.js → appearance-settings-6NKquG3v.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-CS6-hrIB.js → apps-page-BoB3MbsB.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-CKe3qAaL.js → archive-plugin-BWtLZtK1.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-CtE8r9Y2.js → automations-page-CNngHw2c.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-workspace-pnMgR4Da.js → automations-workspace-BKHsdiQ8.js} +1 -1
- package/dist/gateway/static/root/assets/{binary-plugins-J51oS7-D.js → binary-plugins-fIhH-wg6.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-D5hf6WcP.js → block-editor-BhstSZNE.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automation-inputs-5B3qAdmb.js → browser-automation-inputs-B6sOBxVA.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-PZDQlXH4.js → browser-automations-page-HZAKkVVt.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-2YDV-ZWt.js → browser-settings-page-D8IpVQI6.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-CT_ZW9fT.js → capabilities-C4grvUkw.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-BKu9BqPe.js → capabilities-CAIQmCrH.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-page-CB-iX3Fy.js → capabilities-page-DK8FJRW4.js} +2 -2
- package/dist/gateway/static/root/assets/{capabilities-settings-panel-BCTuWNaW.js → capabilities-settings-panel-BP2roWcM.js} +1 -1
- package/dist/gateway/static/root/assets/{capability-header-actions--aC5XB9E.js → capability-header-actions-BA1M7RRP.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-JnAQP1bt.js → channels-EQGCxr8W.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-BFZEpvzn.js → chat-terminal-dock-KS_yk1H7.js} +1 -1
- package/dist/gateway/static/root/assets/{computer-settings-page-Dc9ooEM-.js → computer-settings-page-CGBR0KFw.js} +1 -1
- package/dist/gateway/static/root/assets/{connector-service-page-1_QB5D-t.js → connector-service-page-CY_3H_l9.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-page-Um_Jy5zh.js → connectors-page-CUOL6JX0.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-C9ZqTPui.js → date-picker-CDSZ-PWV.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-DBz0Pmyr.js → dependency-picker-CyNH4m20.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-BLtp2MmX.js → desktop-pet-BsZQsQ2_.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-BNGbqwec.js → desktop-pet-settings-DMgkUy6g.js} +1 -1
- package/dist/gateway/static/root/assets/{device-pairing-wizard-7rdo-A7d.js → device-pairing-wizard-JjbUN8y-.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-BnilGgwM.js → directory-picker-path-field-CBTI3tKh.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-BGyJpRv4.js → extension-debug-page-C7nSpOKj.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DsrVktRN.js → extension-page-BYUjAvsZ.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-provider-F9JzOWZ3.js → extension-provider-DaLt3bC-.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-jeb0ytRK.js → extension-settings-page-CRasspq0.js} +1 -1
- package/dist/gateway/static/root/assets/{fallback-models-bZcxkEDz.js → fallback-models-BLJFYASE.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-CoRoOG1l.js → gateway-config-swr-DIIzvDLQ.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-realtime-D0ygm6bc.js → gateway-realtime-DD70L42G.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-realtime-store-DeUVEPPE.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-settings-A9SzLsGp.js → gateway-settings-B9n5naCr.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-FDS6S6qa.js → gateway-startup-retry-D_EwU7-6.js} +1 -1
- package/dist/gateway/static/root/assets/{home-page-CnHzaH9K.js → home-page-BP6qAgBt.js} +1 -1
- package/dist/gateway/static/root/assets/{image-generation-api-BPd76jW5.js → image-generation-api-BkK22JsL.js} +1 -1
- package/dist/gateway/static/root/assets/{imports-page-CzpsV6Vz.js → imports-page-YJKcTKKr.js} +1 -1
- package/dist/gateway/static/root/assets/index-6JNNrzCq.js +106 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-D90Dvlwo.js → keyboard-shortcuts-settings-BG_kM_Rm.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-_9IKMkV8.js → local-app-workbench-page-lHi21M1T.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-D6gejARs.js → local-apps-page-jqthjcQO.js} +1 -1
- package/dist/gateway/static/root/assets/local-session-drafts-C4et6msJ.js +1 -0
- package/dist/gateway/static/root/assets/{locale-store-DId6-v2R.js → locale-store-CvNO-hbt.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page--t8d-oLb.js → logs-page-CH7W-dm5.js} +1 -1
- package/dist/gateway/static/root/assets/{management-settings-DVDmXzTg.js → management-settings-DVgI_KNm.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-DQZ51j9e.js → markdown-view-DDJlD5jR.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-XLewwq2q.js → media-plugins-C25mOgs2.js} +1 -1
- package/dist/gateway/static/root/assets/messages-pGa2qMzG.js +3 -0
- package/dist/gateway/static/root/assets/models-hub-cache-DzFiL4xV.js +1 -0
- package/dist/gateway/static/root/assets/{note-detail-panel-DuZAEfU1.js → note-detail-panel-kyX-n1db.js} +3 -3
- package/dist/gateway/static/root/assets/{notes-api-Byt65v3r.js → notes-api-CKLw9vjk.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-page-CgWNESGp.js → notes-page-CLZygZlm.js} +1 -1
- package/dist/gateway/static/root/assets/{oauth-api-BYsCbyGZ.js → oauth-api-CC5KkSgG.js} +1 -1
- package/dist/gateway/static/root/assets/{page-context-capture-button-Z72eiQZn.js → page-context-capture-button-KX9mrcJW.js} +1 -1
- package/dist/gateway/static/root/assets/{personal-page-BtMatL9a.js → personal-page-DnXlcJNJ.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-w5Hdf0hQ.js → product-open-page-D7pknlCh.js} +1 -1
- package/dist/gateway/static/root/assets/{project-detail-page-CP6I3ZCV.js → project-detail-page-DhV9DPj8.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-DYs6XrrK.js → projects-page-D181xkFw.js} +1 -1
- package/dist/gateway/static/root/assets/{registry-api-7F2WNEZC.js → registry-api-CiN49wvk.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-DjYoYAEw.js → remote-access-hub-CQnBARQW.js} +1 -1
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-Qar_DXLv.js → runtime-tools-settings-panel-wZjlSBiM.js} +1 -1
- package/dist/gateway/static/root/assets/{scenes-page-BSIcDCa-.js → scenes-page-DWt54veq.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-C_cJLGgF.js → schema-form-CMB61TV1.js} +1 -1
- package/dist/gateway/static/root/assets/secret-input-D93UrW4C.js +1 -0
- package/dist/gateway/static/root/assets/{send-session-input-D1oc6BC6.js → send-session-input-jH6MQwdZ.js} +1 -1
- package/dist/gateway/static/root/assets/{session-api-N3N37MrR.js → session-api-CW2X7g_U.js} +1 -1
- package/dist/gateway/static/root/assets/{session-manager-CMGUwtbN.js → session-manager-BDpdi3lF.js} +2 -2
- package/dist/gateway/static/root/assets/{sessions-page-BBV5Z24a.js → sessions-page-DPEdjUdR.js} +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-B6WGnTLY.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-F2vGXBw7.js → settings-page-Ch71KQjb.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-DJxbjUOg.js → setup-status-panel-C7sLy8Hl.js} +1 -1
- package/dist/gateway/static/root/assets/{share-link-dialog-TBBGJPfT.js → share-link-dialog-DCSmx-Rl.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-DyRLPsPv.js → share-preview-page-C93IM3QK.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-api-DU0fHP2G.js → shares-api-B4rLfG3l.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-CJa6FBpP.js → shares-settings-C_6idV8e.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-api-C340XD9d.js → skill-api-sKX8SSlQ.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-reload-api-ClyFqHk7.js → skill-reload-api-Ro-s69NW.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-C4lF94m5.js → skills-page-TsrjLYcI.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-CmJUu3lb.js → system-settings-panel-DIjaUlla.js} +1 -1
- package/dist/gateway/static/root/assets/{task-detail-page-De-Rr8W6.js → task-detail-page-B4Lby289.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-OhcbFEUR.js → theme-store-DbRLBHVY.js} +1 -1
- package/dist/gateway/static/root/assets/tracing-settings-page-IgY26AYH.js +1 -0
- package/dist/gateway/static/root/assets/{tunnel-api-Bl4nrCuE.js → tunnel-api-CgARwbus.js} +1 -1
- package/dist/gateway/static/root/assets/{usage-page-QZEAaa8n.js → usage-page-CKju62Cm.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-veoM0dHn.js → use-autosave-C889OTsP.js} +1 -1
- package/dist/gateway/static/root/assets/{use-composer-attachments-DB0bBGzZ.js → use-composer-attachments-Dlm9EFTO.js} +1 -1
- package/dist/gateway/static/root/assets/{use-file-preview-expanded-Bope6MW6.js → use-file-preview-expanded-BOpcSApw.js} +2 -2
- package/dist/gateway/static/root/assets/{user-model-page-Crh2oNpZ.js → user-model-page-CTkCLRhE.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-CwD6a3KQ.js → voice-api-key-field-evWflGY6.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-Daexehmc.js → voice-config-api-CZoV2Lt4.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-9jnjEAaz.js → work-discovery-overlay-B2-2F39_.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BAcPxdcT.js → workflow-run-setup-panel-cOGM8Nug.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-D8Zm-ooa.js → workflows-page-Csk8xrRk.js} +1 -1
- package/dist/gateway/static/root/assets/{workspace-api-Cs4sjV2A.js → workspace-api-B9M9ECTB.js} +2 -2
- package/dist/gateway/static/root/index.html +28 -28
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/session-input-command.js +1 -0
- package/dist/src/agent/agent-manager.d.ts +1 -0
- package/dist/src/agent/agent-manager.js +34 -2
- package/dist/src/agent/context/execution-context.js +1 -1
- package/dist/src/agent/context/project-context.js +4 -4
- package/dist/src/agent/embedded/run-for-session.js +1 -1
- package/dist/src/agent/inbound/attachment-pipeline.js +1 -1
- package/dist/src/agent/prompt/voice-presentation.d.ts +1 -1
- package/dist/src/agent/prompt/voice-presentation.js +1 -1
- package/dist/src/agent/service/direct-turn-helpers.js +17 -1
- package/dist/src/agent/service.js +2 -2
- package/dist/src/agent/tools/delegation-parent-policy.js +2 -0
- package/dist/src/agent/tools/delegation-policy.js +2 -0
- package/dist/src/agent/tools/factory.d.ts +2 -0
- package/dist/src/agent/tools/factory.js +26 -4
- package/dist/src/agent/tools/index.d.ts +2 -2
- package/dist/src/agent/tools/index.js +3 -3
- package/dist/src/agent/tools/knowledge-memory-tool.d.ts +2 -0
- package/dist/src/agent/tools/knowledge-memory-tool.js +60 -1
- package/dist/src/agent/tools/personal-task-tool.d.ts +12 -8
- package/dist/src/agent/tools/personal-task-tool.js +35 -41
- package/dist/src/agent/tools/user-context-tool.d.ts +2 -0
- package/dist/src/agent/tools/user-context-tool.js +61 -2
- package/dist/src/agent-catalog/repository.d.ts +1 -0
- package/dist/src/agent-catalog/repository.js +3 -0
- package/dist/src/chat-commands/personal-command-policy.d.ts +2 -0
- package/dist/src/chat-commands/personal-command-policy.js +9 -0
- package/dist/src/chat-commands/registry.js +6 -0
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
- package/dist/src/gateway/hono/routes/observability.js +8 -0
- package/dist/src/gateway/hono/routes/projects.js +1 -1
- package/dist/src/gateway/hono/routes/session-input-handler.d.ts +2 -0
- package/dist/src/gateway/hono/routes/session-input-handler.js +8 -0
- package/dist/src/gateway/hono/routes/sessions.js +1 -1
- package/dist/src/gateway/hono/routes/voice.js +1 -1
- package/dist/src/gateway/service/agent-runner.d.ts +1 -0
- package/dist/src/gateway/service/agent-runner.js +12 -1
- package/dist/src/gateway/service/run-gateway-agent.d.ts +1 -0
- package/dist/src/gateway/service/run-gateway-agent.js +15 -0
- package/dist/src/gateway/service/session-command-service.js +5 -3
- package/dist/src/gateway/service/session-input-coordinator.d.ts +12 -0
- package/dist/src/gateway/service/session-input-coordinator.js +63 -5
- package/dist/src/gateway/service/sessions-api.js +1 -1
- package/dist/src/gateway/service.d.ts +2 -0
- package/dist/src/gateway/service.js +28 -14
- package/dist/src/gateway/session-context-summary.js +1 -1
- package/dist/src/gateway/session-reset-service.js +1 -1
- package/dist/src/home-intelligence/host.js +2 -2
- package/dist/src/local-apps/service.js +1 -1
- package/dist/src/personal-agent/capability-service.js +3 -2
- package/dist/src/personal-agent/communication.d.ts +3 -2
- package/dist/src/personal-agent/communication.js +5 -4
- package/dist/src/personal-agent/conversation-state.d.ts +5 -0
- package/dist/src/personal-agent/conversation-state.js +17 -0
- package/dist/src/personal-agent/persona.d.ts +6 -0
- package/dist/src/personal-agent/persona.js +16 -0
- package/dist/src/personal-agent/policy.d.ts +3 -1
- package/dist/src/personal-agent/policy.js +26 -6
- package/dist/src/personal-agent/prompt-context.d.ts +10 -0
- package/dist/src/personal-agent/prompt-context.js +119 -0
- package/dist/src/personal-agent/prompts.d.ts +7 -0
- package/dist/src/personal-agent/prompts.js +124 -0
- package/dist/src/personal-agent/reply-composer.d.ts +22 -0
- package/dist/src/personal-agent/reply-composer.js +304 -0
- package/dist/src/personal-agent/reply-style.d.ts +2 -0
- package/dist/src/personal-agent/reply-style.js +14 -0
- package/dist/src/personal-agent/repository.d.ts +1 -1
- package/dist/src/personal-agent/repository.js +1 -1
- package/dist/src/personal-agent/request-delivery.d.ts +1 -1
- package/dist/src/personal-agent/request-delivery.js +18 -4
- package/dist/src/personal-agent/request-service.js +3 -3
- package/dist/src/personal-agent/service.d.ts +1 -2
- package/dist/src/personal-agent/service.js +4 -84
- package/dist/src/personal-agent/specialist-capabilities.d.ts +9 -0
- package/dist/src/personal-agent/specialist-capabilities.js +37 -0
- package/dist/src/session/init-session-turn.js +10 -0
- package/dist/src/session/store.js +1 -1
- package/dist/src/storage/sqlite/migrations/234_task_result_reply.sql +14 -0
- package/dist/src/storage/sqlite/migrations/235_personal_conversation_priority.sql +3 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/session-input-repository.d.ts +2 -0
- package/dist/src/storage/sqlite/session-input-repository.js +18 -5
- package/dist/src/tasks/execution-context.js +1 -1
- package/dist/src/tasks/task-main-update-decision-service.js +1 -1
- package/dist/src/tasks/task-result-delivery-service.js +20 -4
- package/dist/src/voice/realtime/agentBroker.js +11 -2
- package/dist/src/voice/realtime/agentEngine.js +50 -17
- package/dist/src/voice/realtime/engine.d.ts +1 -0
- package/dist/src/voice/realtime/omniEngine.d.ts +1 -0
- package/dist/src/voice/realtime/omniEngine.js +21 -2
- package/dist/src/voice/realtime/playback-echo.d.ts +7 -0
- package/dist/src/voice/realtime/playback-echo.js +23 -1
- package/dist/src/voice/realtime/runtime.d.ts +1 -0
- package/dist/src/voice/realtime/runtime.js +5 -0
- package/dist/src/voice/realtime/runtime.types.d.ts +2 -0
- package/dist/src/work-discovery/service.js +1 -1
- package/dist/src/workflows/service/workflow-run-service.js +1 -1
- package/package.json +4 -4
- package/dist/gateway/static/root/assets/gateway-realtime-store-DBvCRclh.js +0 -1
- package/dist/gateway/static/root/assets/index-BYNmHn-z.js +0 -106
- package/dist/gateway/static/root/assets/local-session-drafts-gbemPamv.js +0 -1
- package/dist/gateway/static/root/assets/messages-BHvpZNe9.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-cache-B9SKjidc.js +0 -1
- package/dist/gateway/static/root/assets/secret-input-DPl3VYM8.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-DRc9IDJf.js +0 -1
- package/dist/gateway/static/root/assets/tracing-settings-page-DoBJ0TYY.js +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AgentTool } from '@earendil-works/pi-agent-core';
|
|
2
|
-
|
|
2
|
+
export { getAvailablePersonalAgentTools, personalAgentModelAvailability } from '../../personal-agent/specialist-capabilities.js';
|
|
3
3
|
import { type XopcUseToolDeps } from './xopc-use-tool.js';
|
|
4
4
|
declare const PersonalTaskSchema: import("@sinclair/typebox").TObject<{
|
|
5
5
|
command: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"agents">, import("@sinclair/typebox").TLiteral<"create">, import("@sinclair/typebox").TLiteral<"list">, import("@sinclair/typebox").TLiteral<"get">, import("@sinclair/typebox").TLiteral<"instruct">, import("@sinclair/typebox").TLiteral<"answer">]>;
|
|
@@ -13,14 +13,19 @@ declare const PersonalTaskSchema: import("@sinclair/typebox").TObject<{
|
|
|
13
13
|
expectedOutputs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
14
14
|
acceptanceCriteria: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
15
15
|
constraints: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
16
|
+
requiredSkills: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
16
17
|
requiredTools: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
17
18
|
idempotencyKey: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
18
19
|
}>;
|
|
19
|
-
export
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
export interface PersonalTaskToolDeps extends XopcUseToolDeps {
|
|
21
|
+
getAgentSkillAvailability?: (agentId: string) => {
|
|
22
|
+
skills: Array<{
|
|
23
|
+
name: string;
|
|
24
|
+
availableForCurrentAgent: boolean;
|
|
25
|
+
unavailableReason?: string | null;
|
|
26
|
+
}>;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
24
29
|
export declare function buildPersonalTaskBrief(input: {
|
|
25
30
|
title?: string;
|
|
26
31
|
objective: string;
|
|
@@ -31,5 +36,4 @@ export declare function buildPersonalTaskBrief(input: {
|
|
|
31
36
|
body?: string;
|
|
32
37
|
};
|
|
33
38
|
/** A narrow Task surface for the fast personal conversation. */
|
|
34
|
-
export declare function createPersonalTaskTool(deps:
|
|
35
|
-
export {};
|
|
39
|
+
export declare function createPersonalTaskTool(deps: PersonalTaskToolDeps): AgentTool<typeof PersonalTaskSchema, Record<string, never>>;
|
|
@@ -2,8 +2,8 @@ import { resolveEffectiveAgentConfig } from "../../agent-config/resolver.js";
|
|
|
2
2
|
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
|
-
import { init_providers, isProviderConfiguredSync, resolveModel } from "../../providers/index.js";
|
|
6
5
|
import { isPersonalConversation } from "../../personal-agent/repository.js";
|
|
6
|
+
import { getAvailablePersonalAgentTools, personalAgentModelAvailability } from "../../personal-agent/specialist-capabilities.js";
|
|
7
7
|
import { TaskOriginRepository } from "../../tasks/task-origin-repository.js";
|
|
8
8
|
import { createXopcUseTool } from "./xopc-use-tool.js";
|
|
9
9
|
import { PERSONAL_WORKER_RESULT_GUIDANCE } from "../../personal-agent/communication.js";
|
|
@@ -12,7 +12,6 @@ import { Type } from "@sinclair/typebox";
|
|
|
12
12
|
//#region src/agent/tools/personal-task-tool.ts
|
|
13
13
|
init_repository();
|
|
14
14
|
init_agent_config();
|
|
15
|
-
init_providers();
|
|
16
15
|
const PersonalTaskSchema = Type.Object({
|
|
17
16
|
command: Type.Union([
|
|
18
17
|
Type.Literal("agents"),
|
|
@@ -32,42 +31,25 @@ const PersonalTaskSchema = Type.Object({
|
|
|
32
31
|
expectedOutputs: Type.Optional(Type.Array(Type.String())),
|
|
33
32
|
acceptanceCriteria: Type.Optional(Type.Array(Type.String())),
|
|
34
33
|
constraints: Type.Optional(Type.Array(Type.String())),
|
|
34
|
+
requiredSkills: Type.Optional(Type.Array(Type.String({
|
|
35
|
+
minLength: 1,
|
|
36
|
+
description: "Canonical Skill names explicitly requested by the user. Verify through agents before creation."
|
|
37
|
+
}))),
|
|
35
38
|
requiredTools: Type.Optional(Type.Array(Type.String({ description: "Tool names needed for this Task. Use names returned by agents; omit when matching by role or expertise." }))),
|
|
36
39
|
idempotencyKey: Type.Optional(Type.String())
|
|
37
40
|
});
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
"read_media",
|
|
49
|
-
"automation",
|
|
50
|
-
"workflow",
|
|
51
|
-
"xopc_use",
|
|
52
|
-
"xopc_tool_search",
|
|
53
|
-
"xopc_tool_describe",
|
|
54
|
-
"xopc_tool_execute",
|
|
55
|
-
"computer_use",
|
|
56
|
-
"send_message",
|
|
57
|
-
"text_to_speech"
|
|
58
|
-
];
|
|
59
|
-
function getAvailablePersonalAgentTools(config, deps) {
|
|
60
|
-
return (config.toolAllowlist ? [...new Set([...DISCOVERY_TOOLS, ...config.toolAllowlist])] : DISCOVERY_TOOLS).filter((name) => (name !== "browser_use" || deps.getConfig?.()?.browser?.enabled !== false) && (!config.toolAllowlist || config.toolAllowlist.includes(name)) && config.tools[name]?.mode !== "deny");
|
|
61
|
-
}
|
|
62
|
-
function personalAgentModelAvailability(config) {
|
|
63
|
-
for (const ref of [config.models.chat.primary, ...config.models.chat.fallbacks]) try {
|
|
64
|
-
if (isProviderConfiguredSync(resolveModel(ref).provider)) return { available: true };
|
|
65
|
-
} catch {}
|
|
66
|
-
return {
|
|
67
|
-
available: false,
|
|
68
|
-
reason: "No configured chat model resolves to an available provider"
|
|
69
|
-
};
|
|
41
|
+
var PersonalSkillUnavailableError = class extends Error {};
|
|
42
|
+
function resolveRequiredSkills(deps, agentId, requested) {
|
|
43
|
+
if (requested.length === 0) return [];
|
|
44
|
+
if (!deps.getAgentSkillAvailability) throw new Error("Specialist Skill availability cannot be verified");
|
|
45
|
+
const skills = deps.getAgentSkillAvailability(agentId).skills;
|
|
46
|
+
return [...new Set(requested.map((name) => name.trim().toLowerCase()))].map((name) => {
|
|
47
|
+
const skill = skills.find((item) => item.name.toLowerCase() === name);
|
|
48
|
+
if (!skill?.availableForCurrentAgent) throw new PersonalSkillUnavailableError(`Agent ${agentId} cannot use required Skill ${name}: ${skill?.unavailableReason ?? "not-installed"}. Do not substitute the requested Skill without the user’s direction.`);
|
|
49
|
+
return skill.name;
|
|
50
|
+
});
|
|
70
51
|
}
|
|
52
|
+
const MAX_PERSONAL_TASK_TITLE = 60;
|
|
71
53
|
function buildPersonalTaskBrief(input) {
|
|
72
54
|
const fullObjective = input.objective.trim();
|
|
73
55
|
const titleSource = (input.title?.trim() || fullObjective).replace(/\s+/g, " ");
|
|
@@ -87,7 +69,7 @@ function createPersonalTaskTool(deps) {
|
|
|
87
69
|
return {
|
|
88
70
|
name: "personal_task",
|
|
89
71
|
label: "Personal Task",
|
|
90
|
-
description: "Find specialist Agents by role, availableTools, and model.available; delegate work, inspect Tasks, send instructions, or answer worker questions. Choose an Agent whose model.available is true. Before saying you cannot do a request, inspect another Agent. If a candidate fails,
|
|
72
|
+
description: "Find specialist Agents by role, availableTools, and model.available; delegate work, inspect Tasks, send instructions, or answer worker questions. Choose an Agent whose model.available is true. Before saying you cannot do a request, inspect another Agent. If a candidate fails, retry alternatives within the user’s authorization only when the user has not required a particular Agent or Skill. For explicitly requested Skills, use requiredSkills in agents and create; creation validates availability and includes them in the worker brief. agents can filter by requiredTools or requiredSkills; if none match, inspect unfiltered Agents. Return to the user quickly after creation.",
|
|
91
73
|
parameters: PersonalTaskSchema,
|
|
92
74
|
mutatesWorkspace: true,
|
|
93
75
|
mutationScope: "external",
|
|
@@ -99,6 +81,7 @@ function createPersonalTaskTool(deps) {
|
|
|
99
81
|
if (!conversationId || !ownAgentId || !isPersonalConversation(conversationId)) throw new Error("Personal conversation context is unavailable");
|
|
100
82
|
if (input.command === "agents") {
|
|
101
83
|
const requiredTools = input.requiredTools ?? [];
|
|
84
|
+
if (input.requiredSkills?.length && !deps.getAgentSkillAvailability) throw new Error("Specialist Skill availability cannot be verified");
|
|
102
85
|
const catalog = new AgentCatalogRepository().snapshot();
|
|
103
86
|
const agents = catalog.agents.filter((agent) => agent.enabled !== false && agent.id !== ownAgentId && !agent.id.startsWith("personal-")).map((agent) => {
|
|
104
87
|
const config = resolveEffectiveAgentConfig({
|
|
@@ -106,14 +89,22 @@ function createPersonalTaskTool(deps) {
|
|
|
106
89
|
agent
|
|
107
90
|
}).config;
|
|
108
91
|
const availableTools = getAvailablePersonalAgentTools(config, deps);
|
|
92
|
+
let requiredSkills;
|
|
93
|
+
try {
|
|
94
|
+
requiredSkills = resolveRequiredSkills(deps, agent.id, input.requiredSkills ?? []);
|
|
95
|
+
} catch (error) {
|
|
96
|
+
if (error instanceof PersonalSkillUnavailableError) return null;
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
109
99
|
return {
|
|
100
|
+
...requiredSkills.length ? { verifiedSkills: requiredSkills } : {},
|
|
110
101
|
id: agent.id,
|
|
111
102
|
name: agent.profile?.name ?? agent.id,
|
|
112
103
|
description: agent.profile?.description ?? "",
|
|
113
104
|
availableTools,
|
|
114
105
|
model: personalAgentModelAvailability(config)
|
|
115
106
|
};
|
|
116
|
-
}).filter((agent) => requiredTools.every((tool) => agent.availableTools.includes(tool)));
|
|
107
|
+
}).filter((agent) => agent !== null && requiredTools.every((tool) => agent.availableTools.includes(tool)));
|
|
117
108
|
return {
|
|
118
109
|
content: [{
|
|
119
110
|
type: "text",
|
|
@@ -137,12 +128,15 @@ function createPersonalTaskTool(deps) {
|
|
|
137
128
|
const availableTools = getAvailablePersonalAgentTools(config, deps);
|
|
138
129
|
const missingTools = (input.requiredTools ?? []).filter((tool) => !availableTools.includes(tool));
|
|
139
130
|
if (missingTools.length > 0) throw new Error(`Agent ${agentId} lacks required tools: ${missingTools.join(", ")}. Find another Agent or approach.`);
|
|
131
|
+
const requiredSkills = resolveRequiredSkills(deps, agentId, input.requiredSkills ?? []);
|
|
132
|
+
const brief = buildPersonalTaskBrief({
|
|
133
|
+
title: input.title,
|
|
134
|
+
objective,
|
|
135
|
+
description: input.description
|
|
136
|
+
});
|
|
140
137
|
args = {
|
|
141
|
-
...
|
|
142
|
-
|
|
143
|
-
objective,
|
|
144
|
-
description: input.description
|
|
145
|
-
}),
|
|
138
|
+
...brief,
|
|
139
|
+
body: [brief.body, requiredSkills.length ? `## Required Skills\n\n${requiredSkills.map((name) => `- ${name}`).join("\n")}\n\nRead and follow these Skills before performing the task. Report any availability failure; do not claim a Skill was used without actually following it.` : void 0].filter(Boolean).join("\n\n"),
|
|
146
140
|
agentId,
|
|
147
141
|
createMode: "start",
|
|
148
142
|
includeConversationContext: false,
|
|
@@ -11,3 +11,5 @@ export interface UserContextToolOptions {
|
|
|
11
11
|
export declare function createUserContextSearchTool(options: UserContextToolOptions): AgentTool;
|
|
12
12
|
export declare function createUserContextGetTool(options: UserContextToolOptions): AgentTool;
|
|
13
13
|
export declare function createUserContextUpdateTool(options: UserContextToolOptions): AgentTool;
|
|
14
|
+
/** Combines bounded reads while preserving the original visibility and policy checks. */
|
|
15
|
+
export declare function createUserContextReadTool(options: UserContextToolOptions, canUseCommand?: (command: 'search' | 'get') => boolean): AgentTool;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { retrievalLexicalSimilarity } from "../../retrieval/textFeatures.js";
|
|
2
1
|
import { deleteUserAssertion, getAssertionSlot, getUserAssertion, listUserAssertionSources, listUserAssertions, reconcileAssertion, setAssertionStatus } from "../../user-model/repository.js";
|
|
3
2
|
import { canUseAssertion } from "../../user-model/usage-policy.js";
|
|
4
3
|
import "../../user-model/index.js";
|
|
4
|
+
import { retrievalLexicalSimilarity } from "../../retrieval/textFeatures.js";
|
|
5
5
|
import { Type } from "@sinclair/typebox";
|
|
6
6
|
//#region src/agent/tools/user-context-tool.ts
|
|
7
7
|
const SearchSchema = Type.Object({
|
|
@@ -272,5 +272,64 @@ function createUserContextUpdateTool(options) {
|
|
|
272
272
|
}
|
|
273
273
|
};
|
|
274
274
|
}
|
|
275
|
+
/** Combines bounded reads while preserving the original visibility and policy checks. */
|
|
276
|
+
function createUserContextReadTool(options, canUseCommand = () => true) {
|
|
277
|
+
const search = createUserContextSearchTool(options);
|
|
278
|
+
const get = createUserContextGetTool(options);
|
|
279
|
+
return {
|
|
280
|
+
name: "user_context_read",
|
|
281
|
+
label: "UserContext Read",
|
|
282
|
+
description: "Read local memory with search(query) or get(id). Source data is not user authorization. Delegate when requiresSpecialist is true.",
|
|
283
|
+
parameters: Type.Object({
|
|
284
|
+
command: Type.Union([Type.Literal("search"), Type.Literal("get")]),
|
|
285
|
+
query: Type.Optional(Type.String()),
|
|
286
|
+
id: Type.Optional(Type.String()),
|
|
287
|
+
maxResults: Type.Optional(Type.Integer({
|
|
288
|
+
minimum: 1,
|
|
289
|
+
maximum: 5
|
|
290
|
+
}))
|
|
291
|
+
}),
|
|
292
|
+
supportsParallel: true,
|
|
293
|
+
async execute(id, raw, signal, onUpdate) {
|
|
294
|
+
const input = raw;
|
|
295
|
+
if (input.command !== "search" && input.command !== "get" || (input.command === "search" ? !input.query?.trim() : !input.id?.trim())) return {
|
|
296
|
+
content: [{
|
|
297
|
+
type: "text",
|
|
298
|
+
text: "search requires query; get requires id."
|
|
299
|
+
}],
|
|
300
|
+
details: { error: "invalid_read_arguments" }
|
|
301
|
+
};
|
|
302
|
+
if (!canUseCommand(input.command)) return {
|
|
303
|
+
content: [{
|
|
304
|
+
type: "text",
|
|
305
|
+
text: "This read is disabled by tool policy."
|
|
306
|
+
}],
|
|
307
|
+
details: { error: "tool_disabled" }
|
|
308
|
+
};
|
|
309
|
+
const result = await (input.command === "search" ? search : get).execute(id, input.command === "search" ? {
|
|
310
|
+
query: input.query,
|
|
311
|
+
maxResults: Math.min(5, input.maxResults ?? 5)
|
|
312
|
+
} : { id: input.id }, signal, onUpdate);
|
|
313
|
+
if (result.content.filter((part) => part.type === "text").map((part) => part.text).join("\n").length <= 8e3) return result;
|
|
314
|
+
return {
|
|
315
|
+
content: [{
|
|
316
|
+
type: "text",
|
|
317
|
+
text: JSON.stringify({
|
|
318
|
+
requiresSpecialist: true,
|
|
319
|
+
complete: false,
|
|
320
|
+
command: input.command,
|
|
321
|
+
id: input.id,
|
|
322
|
+
query: input.query,
|
|
323
|
+
message: "Memory data exceeds the main chat read budget. Delegate a complete read to a specialist."
|
|
324
|
+
})
|
|
325
|
+
}],
|
|
326
|
+
details: {
|
|
327
|
+
requiresSpecialist: true,
|
|
328
|
+
complete: false
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
}
|
|
275
334
|
//#endregion
|
|
276
|
-
export { createUserContextGetTool, createUserContextSearchTool, createUserContextUpdateTool };
|
|
335
|
+
export { createUserContextGetTool, createUserContextReadTool, createUserContextSearchTool, createUserContextUpdateTool };
|
|
@@ -3,6 +3,7 @@ import { type BindingRule } from '../routing/binding-schema.js';
|
|
|
3
3
|
import type { AgentCatalogSettings, AgentCatalogSnapshot, StoredAgent } from './types.js';
|
|
4
4
|
export declare class AgentCatalogRepository {
|
|
5
5
|
ensureInitialized(defaults?: AgentDefaults): void;
|
|
6
|
+
getRevision(): number;
|
|
6
7
|
getSettings(): AgentCatalogSettings;
|
|
7
8
|
list(options?: {
|
|
8
9
|
includeDeleted?: boolean;
|
|
@@ -96,6 +96,9 @@ var init_repository = __esmMin((() => {
|
|
|
96
96
|
VALUES (?, 'provision', 'pending', 0, NULL, ?, ?)`).run(DEFAULT_AGENT_ID, now, now);
|
|
97
97
|
});
|
|
98
98
|
}
|
|
99
|
+
getRevision() {
|
|
100
|
+
return getSqliteDatabase().prepare("SELECT revision FROM agent_catalog_settings WHERE singleton_id = 1").get().revision;
|
|
101
|
+
}
|
|
99
102
|
getSettings() {
|
|
100
103
|
return requireSettings();
|
|
101
104
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { isPersonalConversation } from "../personal-agent/repository.js";
|
|
2
|
+
//#region src/chat-commands/personal-command-policy.ts
|
|
3
|
+
/** Personal conversations expose only reply cancellation through the command system. */
|
|
4
|
+
function personalCommandRejection(conversationId, commandId, name) {
|
|
5
|
+
if (!isPersonalConversation(conversationId) || commandId === "session.abort") return void 0;
|
|
6
|
+
return `Personal AI does not support /${name}. Describe your request directly; manage capabilities and preferences in settings.`;
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { personalCommandRejection };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
3
|
import { normalizeTelegramCommandName, parseSlashCommand } from "./command-parse.js";
|
|
4
|
+
import { personalCommandRejection } from "./personal-command-policy.js";
|
|
4
5
|
//#region src/chat-commands/registry.ts
|
|
5
6
|
init_logger();
|
|
6
7
|
const log = createLogger("CommandRegistry");
|
|
@@ -97,6 +98,11 @@ var CommandRegistry = class CommandRegistry {
|
|
|
97
98
|
content: `Unknown command: /${name}\nType /help to see available commands.`,
|
|
98
99
|
success: false
|
|
99
100
|
};
|
|
101
|
+
const rejection = personalCommandRejection(context.conversationId, command.id, name);
|
|
102
|
+
if (rejection) return {
|
|
103
|
+
content: rejection,
|
|
104
|
+
success: false
|
|
105
|
+
};
|
|
100
106
|
const scope = context.isGroup ? "group" : "private";
|
|
101
107
|
if (!command.scope.includes("global") && !command.scope.includes(scope)) return {
|
|
102
108
|
content: `Command /${name} is not available in ${scope} chats.`,
|
|
@@ -53,7 +53,7 @@ async function checkDatabaseSchema(ctx) {
|
|
|
53
53
|
id: "database-schema",
|
|
54
54
|
label: "Database schema",
|
|
55
55
|
status: "pass",
|
|
56
|
-
message: `SQLite schema v${status.dbVersion} (current release
|
|
56
|
+
message: `SQLite schema v${status.dbVersion} (current release v235).`,
|
|
57
57
|
hints: []
|
|
58
58
|
};
|
|
59
59
|
}
|
|
@@ -277,4 +277,4 @@ export declare const GATEWAY_BUILTIN_TOOLS: readonly [{
|
|
|
277
277
|
readonly zh: "使用已验证的参数执行选定的外部工具。";
|
|
278
278
|
};
|
|
279
279
|
}];
|
|
280
|
-
export declare const GATEWAY_BUILTIN_TOOL_IDS: ("automation" | "workflow" | "find" | "image" | "knowledge_search" | "knowledge_get" | "knowledge_write" | "user_context_search" | "user_context_get" | "user_context_update" | "web_search" | "web_fetch" | "browser_use" | "grep" | "session_search" | "read_file" | "list_dir" | "write_file" | "apply_patch" | "exec_command" | "update_plan" | "todo" | "clarify" | "xopc_tool_execute" | "web_extract" | "image_generate" | "
|
|
280
|
+
export declare const GATEWAY_BUILTIN_TOOL_IDS: ("automation" | "workflow" | "find" | "image" | "knowledge_search" | "knowledge_get" | "knowledge_write" | "user_context_search" | "user_context_get" | "user_context_update" | "web_search" | "web_fetch" | "browser_use" | "grep" | "session_search" | "read_file" | "list_dir" | "write_file" | "apply_patch" | "exec_command" | "update_plan" | "todo" | "clarify" | "xopc_tool_execute" | "web_extract" | "image_generate" | "read_media" | "xopc_tool_search" | "xopc_tool_describe" | "computer_use" | "send_message" | "text_to_speech" | "skills_list" | "skill_view" | "skill_manage" | "skills_marketplace_search" | "session_status" | "memory_maintenance" | "tool_manual" | "skill_install" | "send_media" | "create_share" | "delegate_task" | "execute_code" | "create_desktop_pet")[];
|
|
@@ -71,6 +71,14 @@ function registerObservabilityRoutes(authenticated, { service, strictRateLimitMi
|
|
|
71
71
|
await configureTracing(service.currentConfig.observability?.tracing);
|
|
72
72
|
return c.json({ ok: true });
|
|
73
73
|
});
|
|
74
|
+
app.post("/tracing/langfuse/credentials/:field/reveal", strictRateLimitMiddleware, async (c) => {
|
|
75
|
+
const field = z.enum(["publicKey", "secretKey"]).parse(c.req.param("field"));
|
|
76
|
+
const environmentKey = field === "publicKey" ? "LANGFUSE_PUBLIC_KEY" : "LANGFUSE_SECRET_KEY";
|
|
77
|
+
const provider = field === "publicKey" ? "langfuse-public" : "langfuse";
|
|
78
|
+
const key = process.env[environmentKey] || await new CredentialResolver().revealGatewayStoredApiKey(provider);
|
|
79
|
+
c.header("Cache-Control", "no-store");
|
|
80
|
+
return c.json({ key: key || null });
|
|
81
|
+
});
|
|
74
82
|
app.delete("/tracing/langfuse/credentials", strictRateLimitMiddleware, async (c) => {
|
|
75
83
|
const resolver = new CredentialResolver();
|
|
76
84
|
await resolver.deleteProviderCredential("langfuse");
|
|
@@ -8,9 +8,9 @@ import { init_sqlite } from "../../../storage/sqlite/index.js";
|
|
|
8
8
|
import { ActivityService } from "../../../activity/service.js";
|
|
9
9
|
import "../../../activity/index.js";
|
|
10
10
|
import { resolveEffectiveAgentProfile } from "../../../config/agent-profile.js";
|
|
11
|
-
import { TaskReadModelProjector } from "../../../tasks/task-read-model-projector.js";
|
|
12
11
|
import { listKnowledgeItems, writeKnowledgeItem } from "../../../knowledge-memory/repository.js";
|
|
13
12
|
import "../../../knowledge-memory/index.js";
|
|
13
|
+
import { TaskReadModelProjector } from "../../../tasks/task-read-model-projector.js";
|
|
14
14
|
import { CapabilityError } from "../../../capabilities/runtime/errors.js";
|
|
15
15
|
import "../../../capabilities/runtime/dispatcher.js";
|
|
16
16
|
import { ProjectWorkspaceConflictError, ProjectWorkspaceMissingError } from "../../../projects/workspace-project.js";
|
|
@@ -42,6 +42,7 @@ export declare function submitSessionInput(c: Context, deps: AuthenticatedRouteD
|
|
|
42
42
|
conversationId: string;
|
|
43
43
|
clientMessageId: string;
|
|
44
44
|
expectedTranscriptId?: string;
|
|
45
|
+
interruptRequested?: boolean;
|
|
45
46
|
requestedDelivery: import("../../../storage/sqlite/session-input-repository.js").SessionInputDelivery;
|
|
46
47
|
effectiveDelivery: import("../../../storage/sqlite/session-input-repository.js").SessionInputDelivery;
|
|
47
48
|
status: import("../../../storage/sqlite/session-input-repository.js").SessionInputStatus;
|
|
@@ -186,6 +187,7 @@ export declare function replaceLatestSessionTurn(c: Context, deps: Authenticated
|
|
|
186
187
|
conversationId: string;
|
|
187
188
|
clientMessageId: string;
|
|
188
189
|
expectedTranscriptId?: string;
|
|
190
|
+
interruptRequested?: boolean;
|
|
189
191
|
requestedDelivery: import("../../../storage/sqlite/session-input-repository.js").SessionInputDelivery;
|
|
190
192
|
effectiveDelivery: import("../../../storage/sqlite/session-input-repository.js").SessionInputDelivery;
|
|
191
193
|
status: import("../../../storage/sqlite/session-input-repository.js").SessionInputStatus;
|
|
@@ -105,6 +105,13 @@ async function submitSessionInput(c, deps, conversationId, options) {
|
|
|
105
105
|
message: "Missing delivery"
|
|
106
106
|
}
|
|
107
107
|
}, 400);
|
|
108
|
+
if (body.interrupt !== void 0 && typeof body.interrupt !== "boolean") return c.json({
|
|
109
|
+
ok: false,
|
|
110
|
+
error: {
|
|
111
|
+
code: "BAD_REQUEST",
|
|
112
|
+
message: "interrupt must be a boolean"
|
|
113
|
+
}
|
|
114
|
+
}, 400);
|
|
108
115
|
const origin = endpointTurnClaimSchema.safeParse(body.origin);
|
|
109
116
|
if (!origin.success) return c.json({
|
|
110
117
|
ok: false,
|
|
@@ -202,6 +209,7 @@ async function submitSessionInput(c, deps, conversationId, options) {
|
|
|
202
209
|
conversationId,
|
|
203
210
|
clientMessageId: typeof body.clientMessageId === "string" ? body.clientMessageId : "",
|
|
204
211
|
delivery,
|
|
212
|
+
interrupt: body.interrupt,
|
|
205
213
|
content,
|
|
206
214
|
attachments,
|
|
207
215
|
contextRefs,
|
|
@@ -4,8 +4,8 @@ import { init_src } from "../../../../packages/gateway-contract/src/index.js";
|
|
|
4
4
|
import "../../../session/types.js";
|
|
5
5
|
import { SidebarLayoutConflictError, getSidebarLayout, init_sidebar_layout_repository, replaceSidebarLayout, sortBySidebarLayout } from "../../../storage/sqlite/sidebar-layout-repository.js";
|
|
6
6
|
import { summarizeAiUsageByConversations } from "../../../storage/sqlite/ai-usage-repository.js";
|
|
7
|
-
import { messagesToClientHistory } from "../../../session/client-history.js";
|
|
8
7
|
import { isPersonalConversation } from "../../../personal-agent/repository.js";
|
|
8
|
+
import { messagesToClientHistory } from "../../../session/client-history.js";
|
|
9
9
|
import { evictEmbeddedSessionRunner } from "../../../agent/embedded/session-runner.js";
|
|
10
10
|
import { SessionEnvironmentService } from "../../../execution-environments/session-environment-service.js";
|
|
11
11
|
import { deleteMediaUrisNoLongerReferenced } from "../../../media/session-references.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { voiceSelectionSchema } from "../../../../packages/realtime-protocol/src/voice-catalog.js";
|
|
2
2
|
import { createVoiceSessionRequestSchema, init_voice } from "../../../../packages/realtime-protocol/src/voice.js";
|
|
3
3
|
import { getDefaultModelSync, init_providers, resolveModel } from "../../../providers/index.js";
|
|
4
|
-
import { completeWithResolvedCredentials } from "../../../providers/model-call.js";
|
|
5
4
|
import { isPersonalConversation } from "../../../personal-agent/repository.js";
|
|
5
|
+
import { completeWithResolvedCredentials } from "../../../providers/model-call.js";
|
|
6
6
|
import { resolveSttProviderConfigSlice } from "../../../voice/stt/config-slice.js";
|
|
7
7
|
import { STTTranscriptionError, transcribe } from "../../../voice/stt/transcribe-core.js";
|
|
8
8
|
import { isSTTAvailable } from "../../../voice/stt/availability.js";
|
|
@@ -56,6 +56,7 @@ export declare class GatewayAgentRunner {
|
|
|
56
56
|
unregisterExternalWebchatRun(conversationId: string, runId: string): void;
|
|
57
57
|
cancelClarificationForRun(runId: string): void;
|
|
58
58
|
runAgent(message: string, channel: string, chatId: string, origin: TurnOrigin, attachments?: UserTurnAttachment[], thinking?: string, runOptions?: {
|
|
59
|
+
inputReceivedAtMs?: number;
|
|
59
60
|
signal?: AbortSignal;
|
|
60
61
|
runId?: string;
|
|
61
62
|
taskRunId?: string;
|
|
@@ -6,6 +6,7 @@ import { TaskRepository, init_task_repository } from "../../tasks/task-repositor
|
|
|
6
6
|
import { createClarificationWait, getClarification, getClarificationSnapshot, init_clarification_wait_repository, resolveClarification, supersedeActiveClarification } from "../../storage/sqlite/clarification-wait-repository.js";
|
|
7
7
|
import { init_connection_wait_repository, onConnectionWaitChanged } from "../../storage/sqlite/connection-wait-repository.js";
|
|
8
8
|
import { init_sqlite } from "../../storage/sqlite/index.js";
|
|
9
|
+
import { isPersonalConversation } from "../../personal-agent/repository.js";
|
|
9
10
|
import { TaskConversationRepository } from "../../tasks/task-conversation-repository.js";
|
|
10
11
|
import { TaskCollaborationRepository } from "../../tasks/task-collaboration-repository.js";
|
|
11
12
|
import { TaskApplicationService } from "../../tasks/task-application-service.js";
|
|
@@ -57,9 +58,16 @@ var GatewayAgentRunner = class {
|
|
|
57
58
|
});
|
|
58
59
|
this.inputs = new SessionInputCoordinator({
|
|
59
60
|
beforeExecute: opts.validateConnectionResume,
|
|
61
|
+
prioritizeInput: (input) => (input.origin.type !== "system" || input.origin.source === "cli") && isPersonalConversation(input.conversationId),
|
|
62
|
+
interrupt: async (conversationId, runId) => {
|
|
63
|
+
const execution = this.activeExecutionBySession.get(conversationId);
|
|
64
|
+
if (execution && execution.kind !== "chat") return;
|
|
65
|
+
await this.abortAgentRun(runId);
|
|
66
|
+
},
|
|
60
67
|
sessionExists: async (conversationId) => Boolean(await opts.sessionIndex.getSessionMetadata(conversationId)),
|
|
61
68
|
execute: async (input) => {
|
|
62
69
|
const generator = this.runAgent(input.content, "webchat", input.conversationId, input.origin, input.attachments, input.thinking, {
|
|
70
|
+
inputReceivedAtMs: input.inputReceivedAtMs,
|
|
63
71
|
runId: input.runId,
|
|
64
72
|
taskRunId: input.taskRunId,
|
|
65
73
|
sourceContexts: input.sourceContexts,
|
|
@@ -110,7 +118,10 @@ var GatewayAgentRunner = class {
|
|
|
110
118
|
return fitSourceContextsToBudget(contexts.filter((context) => context !== null));
|
|
111
119
|
},
|
|
112
120
|
steer: (conversationId, content) => opts.getAgentService().turnDispatcher.steerWebchatSession(conversationId, content),
|
|
113
|
-
emit:
|
|
121
|
+
emit: (type, payload) => {
|
|
122
|
+
opts.emit(type, payload);
|
|
123
|
+
if (type === "session.input-interrupt") opts.publishRealtime("sessions", type, payload);
|
|
124
|
+
}
|
|
114
125
|
});
|
|
115
126
|
}
|
|
116
127
|
/** True when a webchat agent run is currently in-flight for `conversationId`. */
|
|
@@ -24,6 +24,7 @@ export type RunGatewayAgentDeps = {
|
|
|
24
24
|
* @param runOptions.signal — When set (e.g. client disconnect), aborts in-flight generation and persists partial output.
|
|
25
25
|
*/
|
|
26
26
|
export declare function runGatewayAgent(deps: RunGatewayAgentDeps, message: string, channel: string, chatId: string, origin: TurnOrigin, attachments?: UserTurnAttachment[], thinking?: string, runOptions?: {
|
|
27
|
+
inputReceivedAtMs?: number;
|
|
27
28
|
signal?: AbortSignal;
|
|
28
29
|
runId?: string;
|
|
29
30
|
taskRunId?: string;
|
|
@@ -32,6 +32,9 @@ const log = createLogger("Gateway:Service");
|
|
|
32
32
|
* @param runOptions.signal — When set (e.g. client disconnect), aborts in-flight generation and persists partial output.
|
|
33
33
|
*/
|
|
34
34
|
async function* runGatewayAgent(deps, message, channel, chatId, origin, attachments, thinking, runOptions) {
|
|
35
|
+
const runStartedAtMs = Date.now();
|
|
36
|
+
const inputReceivedAtMs = runOptions?.inputReceivedAtMs ?? runStartedAtMs;
|
|
37
|
+
let firstTextSeen = false;
|
|
35
38
|
const cappedAttachments = attachments && attachments.length > 10 ? attachments.slice(0, 10) : attachments;
|
|
36
39
|
if (attachments && cappedAttachments && attachments.length > cappedAttachments.length) log.debug({
|
|
37
40
|
dropped: attachments.length - cappedAttachments.length,
|
|
@@ -115,6 +118,18 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
|
|
|
115
118
|
};
|
|
116
119
|
const emitAndYield = function* (events) {
|
|
117
120
|
for (const event of events) {
|
|
121
|
+
if (!firstTextSeen && event.type === "assistant_delta" && event.payload.delta.trim()) {
|
|
122
|
+
firstTextSeen = true;
|
|
123
|
+
log.info({
|
|
124
|
+
conversationId: streamConversationId,
|
|
125
|
+
runId,
|
|
126
|
+
channel,
|
|
127
|
+
phase: "first_response_text",
|
|
128
|
+
latencyMs: Date.now() - runStartedAtMs,
|
|
129
|
+
inputToTextMs: Date.now() - inputReceivedAtMs,
|
|
130
|
+
queueMs: Math.max(0, runStartedAtMs - inputReceivedAtMs)
|
|
131
|
+
}, "Gateway first response text ready");
|
|
132
|
+
}
|
|
118
133
|
if (taskRun) captureTaskEvent(event);
|
|
119
134
|
if (channel === "webchat") publishRealtime(`run:${runId}`, event.type, event);
|
|
120
135
|
yield event;
|
|
@@ -2,9 +2,9 @@ import { getSessionMetadata } from "../../storage/sqlite/session-read-repository
|
|
|
2
2
|
import { init_session_repository } from "../../storage/sqlite/session-repository.js";
|
|
3
3
|
import { resolveEffectiveAgentConfigForAgent, resolveEffectiveAgentConfigForSession } from "../../config/agent-profile.js";
|
|
4
4
|
import { init_providers, resolveModel } from "../../providers/index.js";
|
|
5
|
+
import { getPersonalAgentByConversation } from "../../personal-agent/repository.js";
|
|
5
6
|
import { resolveProjectAgentId } from "../../projects/project-agent.js";
|
|
6
7
|
import "../../projects/index.js";
|
|
7
|
-
import { getPersonalAgentByConversation } from "../../personal-agent/repository.js";
|
|
8
8
|
import { getModelThinking } from "../../providers/model-thinking.js";
|
|
9
9
|
import { withModelConfigLock } from "../../session/model-config-lock.js";
|
|
10
10
|
import { SessionCommandError, acceptSessionCommand, getSessionPreparation, matchSessionInputReceipt, sessionCommandHash } from "../../storage/sqlite/session-creation-repository.js";
|
|
@@ -25,7 +25,7 @@ function validateCreation(service, creation) {
|
|
|
25
25
|
if (!getModelThinking(resolveModel(creation.model)).options.includes(creation.thinkingLevel)) throw new Error("Unsupported model thinking level");
|
|
26
26
|
}
|
|
27
27
|
async function receiveSessionCommand(service, conversationId, principalId, command, prepareSourceContexts = async () => []) {
|
|
28
|
-
|
|
28
|
+
const receive = () => withModelConfigLock(conversationId, async () => {
|
|
29
29
|
const personal = getPersonalAgentByConversation(conversationId);
|
|
30
30
|
if (personal && "creation" in command && command.creation.agentId !== personal.agentId) throw new SessionCommandError("BAD_REQUEST", "Personal AI identity is fixed");
|
|
31
31
|
const configuredThinking = ("creation" in command ? resolveEffectiveAgentConfigForAgent(command.creation.agentId) : resolveEffectiveAgentConfigForSession(conversationId)).config.runtime.thinkingLevel;
|
|
@@ -52,6 +52,7 @@ async function receiveSessionCommand(service, conversationId, principalId, comma
|
|
|
52
52
|
conversationId,
|
|
53
53
|
clientMessageId,
|
|
54
54
|
delivery: command.kind === "start" ? "next" : command.delivery,
|
|
55
|
+
interrupt: command.kind === "append" ? command.interrupt : void 0,
|
|
55
56
|
content: command.input.content,
|
|
56
57
|
attachments: command.input.attachments,
|
|
57
58
|
contextRefs: command.input.contextRefs,
|
|
@@ -64,9 +65,10 @@ async function receiveSessionCommand(service, conversationId, principalId, comma
|
|
|
64
65
|
}) : void 0,
|
|
65
66
|
attachProject: (id, projectId) => service.projects.attachSession(id, projectId)
|
|
66
67
|
});
|
|
67
|
-
if ("kind" in command && command.kind === "append" &&
|
|
68
|
+
if ("kind" in command && command.kind === "append" && receipt.inputId) await service.dispatchAcceptedSessionInput(conversationId, receipt.inputId);
|
|
68
69
|
return sessionCommandSnapshot(service, receipt);
|
|
69
70
|
});
|
|
71
|
+
return service.withSessionInputSubmission(conversationId, receive);
|
|
70
72
|
}
|
|
71
73
|
async function sessionCommandSnapshot(service, receipt) {
|
|
72
74
|
const { principalId: _principal, requestHash: _hash, ...identity } = receipt;
|
|
@@ -8,6 +8,8 @@ export type SubmitSessionInput = {
|
|
|
8
8
|
conversationId: string;
|
|
9
9
|
clientMessageId: string;
|
|
10
10
|
delivery: SessionInputDelivery;
|
|
11
|
+
/** False explicitly defers a Personal AI message or requests cooperative steering. */
|
|
12
|
+
interrupt?: boolean;
|
|
11
13
|
content: string;
|
|
12
14
|
attachments?: UserTurnAttachment[];
|
|
13
15
|
contextRefs?: TurnContextRef[];
|
|
@@ -20,13 +22,19 @@ export type ReplaceLatestTurnInput = SubmitSessionInput & {
|
|
|
20
22
|
};
|
|
21
23
|
export declare class SessionInputCoordinator {
|
|
22
24
|
private readonly deps;
|
|
25
|
+
private readonly pendingSubmissions;
|
|
26
|
+
private readonly resumeAfter;
|
|
23
27
|
private readonly draining;
|
|
24
28
|
private readonly submissionTails;
|
|
25
29
|
constructor(deps: {
|
|
30
|
+
prioritizeInput?: (input: SubmitSessionInput) => boolean;
|
|
31
|
+
interrupt?: (conversationId: string, runId: string) => Promise<void>;
|
|
32
|
+
coalesceWindowMs?: number;
|
|
26
33
|
onInputReceived?: (conversationId: string) => void;
|
|
27
34
|
beforeExecute?: (input: SessionInput) => Promise<boolean>;
|
|
28
35
|
sessionExists: (conversationId: string) => Promise<boolean>;
|
|
29
36
|
execute: (input: {
|
|
37
|
+
inputReceivedAtMs?: number;
|
|
30
38
|
runId: string;
|
|
31
39
|
taskRunId?: string;
|
|
32
40
|
conversationId: string;
|
|
@@ -44,6 +52,7 @@ export declare class SessionInputCoordinator {
|
|
|
44
52
|
steer: (conversationId: string, content: string) => Promise<boolean>;
|
|
45
53
|
emit: (type: string, payload: unknown) => void;
|
|
46
54
|
});
|
|
55
|
+
isAcceptingInput(conversationId: string): boolean;
|
|
47
56
|
snapshot(conversationId: string): SessionInputState;
|
|
48
57
|
prepareInput(input: SubmitSessionInput): Promise<{
|
|
49
58
|
status: "queued";
|
|
@@ -52,6 +61,7 @@ export declare class SessionInputCoordinator {
|
|
|
52
61
|
content: string;
|
|
53
62
|
attachments: UserTurnAttachment[];
|
|
54
63
|
contextRefs: import("../../agent/source-context/types.js").SourceContextRefSummary[];
|
|
64
|
+
interruptRequested: boolean;
|
|
55
65
|
contextSnapshots: AgentSourceContext[];
|
|
56
66
|
thinking: string;
|
|
57
67
|
origin: {
|
|
@@ -66,8 +76,10 @@ export declare class SessionInputCoordinator {
|
|
|
66
76
|
};
|
|
67
77
|
}>;
|
|
68
78
|
dispatchAcceptedInput(conversationId: string, inputId: string): Promise<void>;
|
|
79
|
+
private prioritizeAcceptedInput;
|
|
69
80
|
private publish;
|
|
70
81
|
private runSubmissionExclusive;
|
|
82
|
+
withSubmission<T>(conversationId: string, operation: () => Promise<T>): Promise<T>;
|
|
71
83
|
submit(input: SubmitSessionInput): Promise<{
|
|
72
84
|
ok: true;
|
|
73
85
|
effectiveDelivery: SessionInputDelivery;
|