@xopcai/xopc 0.0.188 → 0.0.189
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- 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--QoUGhiS.js → activity-store-DTFKTPs8.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-B0yweLNQ.js → agent-avatar-dicebear-DqO25Qe5.js} +1 -1
- package/dist/gateway/static/root/assets/agents-BvdqdER9.js +2 -0
- package/dist/gateway/static/root/assets/{api-5laWqfiE.js → api-DWeXfwVU.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-BXJ8Jiv_.js → app-management-settings-panel-BRpV8PXG.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-DG9n9D1M.js → appearance-settings-3ntKM9nQ.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-nKLsfy6C.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-Ceh5qrZf.js → archive-plugin-Df7Ycj_7.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-jFW7uYf7.js → attachment-load-UHgfZYtj.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-Dh5bdZiN.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-XDlkI1r4.js → binary-plugins-BJah99wE.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-kyKc2IhE.js → block-editor-DNlY5KqF.js} +46 -46
- package/dist/gateway/static/root/assets/browser-settings-page-CRJ_nAuh.js +8 -0
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-BJa5Iz_v.js → browser-workflow-inputs-vyUfdzAd.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-CTQQOsn5.js → browser-workflows-page-C1cKZjx-.js} +2 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-DeQR5BZt.js +7 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-Dn-7MMEo.js → capability-presets-api-D7tkhDMv.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-D7uK3q1p.js +1 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-BgIkWq01.js → channel-recipient-api-BGG2kpJB.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-Bw6Dniyq.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-BrUTz4uU.js +1 -0
- package/dist/gateway/static/root/assets/{connector-logo-TRr9ybf6.js → connector-logo-8YU53RUT.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-k9tMiOL5.js +2 -0
- package/dist/gateway/static/root/assets/{desktop-pet-CSwd00CV.js → desktop-pet-BUuBEJuP.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-CuNQvHGu.js → desktop-pet-settings-BGfVIJM3.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-ct0n5Rje.js → directory-picker-path-field-DrQFfHH_.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-BeRBuMUU.js → extension-debug-page-CEnIFOX-.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DbK-Cwao.js → extension-page-CCqHbexs.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-C9ag5tb5.js → extension-settings-page-DEZw_7zN.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-CC7EvEFp.js → gateway-config-api-CgUE2Ii1.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-Dg8qCiIp.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-B2DmdlwO.js → gateway-startup-retry-DxhKNiCF.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-fl1oC_-5.js → heartbeat-settings-27tRzDEo.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-VA511kMr.js +3 -0
- package/dist/gateway/static/root/assets/{image-generation-api-GMTaS6eI.js → image-generation-api-DCFdc-HD.js} +1 -1
- package/dist/gateway/static/root/assets/index-BvR-i-m6.js +216 -0
- package/dist/gateway/static/root/assets/index-zybP34zk.css +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-DhGYddbI.js → keyboard-shortcuts-settings-Bf2VLtXW.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-CaJq4-wV.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-CmnrBmWi.js → local-apps-page-Ca1RuI13.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-D6hs74o5.js → locale-store-DUW5YE3R.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-BLTCg69e.js +2 -0
- package/dist/gateway/static/root/assets/management-settings-B3Eop1zn.js +1 -0
- package/dist/gateway/static/root/assets/{markdown-split-CZaBPOVn.js → markdown-split-BGOYjgnM.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-CiKvSgCv.js → media-plugins-CT0txyM4.js} +1 -1
- package/dist/gateway/static/root/assets/messages-CMjnbdbn.js +3 -0
- package/dist/gateway/static/root/assets/{notes-page-Bisbzqlz.js → notes-page-DfKgAe78.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-Bp1w9UM1.js +4 -0
- package/dist/gateway/static/root/assets/{page-tabs-BxlwhAbH.js → page-tabs-DNrbCgmC.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-RM8wXxfT.js → preview-open-alternatives-BTqViDOR.js} +1 -1
- package/dist/gateway/static/root/assets/product-delivery-tRr-7IxY.js +1 -0
- package/dist/gateway/static/root/assets/{product-open-page-DdBlibek.js → product-open-page-C_2L4_Iu.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-CZmbPDQN.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-D5pzqfm5.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-CC-XhVGI.js +1 -0
- package/dist/gateway/static/root/assets/{schema-form-BDKbpmXv.js → schema-form-BFLfkDGG.js} +1 -1
- package/dist/gateway/static/root/assets/{schemas-C6onAggk.js → schemas-zIBW3wiV.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-B2eTLVDV.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-CRuZ_bl0.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-zxo5ZGOu.js → settings-form-section-C4GXGeA4.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-DgIp8_S6.js → settings-loading-skeleton-C9a-EbTZ.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-DI9qDH5x.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-layout-97LmwrzC.js → settings-page-layout-D-LWQdI5.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-CJwmPvgs.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-BH7i3g1S.js → share-preview-page-BKSMG9r5.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-YzSDS4G_.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-CwOo8zZk.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-xd1cgSGN.js +2 -0
- package/dist/gateway/static/root/assets/{skills-page.utils-s-a5WV9j.js → skills-page.utils-zsz2HIlZ.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-BxjeMT5k.js → system-settings-panel-IWNDBI1O.js} +1 -1
- package/dist/gateway/static/root/assets/{task-detail-page-BahycnfW.js → task-detail-page-CgtK02kP.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-BRxdsmic.js → theme-store-BkJe7UDo.js} +1 -1
- package/dist/gateway/static/root/assets/time-picker-CstQ___Y.js +1 -0
- package/dist/gateway/static/root/assets/{typed-models-lib-39MjwPSq.js → typed-models-lib-C07LGthO.js} +1 -1
- package/dist/gateway/static/root/assets/{use-save-bar-registration-5aVSjTjO.js → use-save-bar-registration-CQYE0l6z.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-BnQAWS_B.js +1 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-XU-7sBSg.js → voice-api-key-field-Boue1D46.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-CJqu8UHq.js → work-discovery-overlay-bbmvCmc8.js} +1 -1
- package/dist/gateway/static/root/assets/work-discovery-page-CAszL1y8.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-DXtg8Qxl.js → workflow-run-setup-panel-DlHv-GZC.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-DxGzo3-x.js +11 -0
- package/dist/gateway/static/root/index.html +9 -9
- package/dist/package.js +1 -1
- package/dist/packages/endpoint-tools-protocol/src/index.js +184 -0
- package/dist/packages/realtime-client/src/index.js +199 -0
- package/dist/packages/realtime-protocol/src/index.js +83 -0
- package/dist/src/agent/agent-manager.d.ts +1 -0
- package/dist/src/agent/agent-manager.js +1 -0
- package/dist/src/agent/background-review/prompts.d.ts +1 -1
- package/dist/src/agent/background-review/prompts.js +3 -1
- package/dist/src/agent/background-review/run-background-review.d.ts +2 -0
- package/dist/src/agent/background-review/run-background-review.js +5 -2
- package/dist/src/agent/client-error-format.d.ts +1 -1
- package/dist/src/agent/client-error-format.js +1 -1
- package/dist/src/agent/external-tools/endpoint-provider.d.ts +17 -0
- package/dist/src/agent/external-tools/endpoint-provider.js +93 -0
- package/dist/src/agent/external-tools/gateway-tools.js +1 -1
- package/dist/src/agent/external-tools/index.d.ts +4 -5
- package/dist/src/agent/external-tools/index.js +8 -2
- package/dist/src/agent/external-tools/types.d.ts +8 -1
- package/dist/src/agent/external-tools/types.js +2 -1
- package/dist/src/agent/inbound/inbound-loop.js +4 -0
- package/dist/src/agent/inbound/turn-dispatcher.d.ts +9 -8
- package/dist/src/agent/inbound/turn-dispatcher.js +13 -11
- package/dist/src/agent/messaging/command-handler.d.ts +2 -2
- package/dist/src/agent/messaging/command-handler.js +3 -3
- package/dist/src/agent/service/async-queue.d.ts +1 -1
- package/dist/src/agent/service/async-queue.js +1 -1
- package/dist/src/agent/service/direct-turn-helpers.d.ts +1 -1
- package/dist/src/agent/service/direct-turn-helpers.js +1 -1
- package/dist/src/agent/service/process-direct-one-shot.d.ts +3 -1
- package/dist/src/agent/service/process-direct-one-shot.js +1 -1
- package/dist/src/agent/service/process-direct-streaming.d.ts +7 -5
- package/dist/src/agent/service/process-direct-streaming.js +5 -5
- package/dist/src/agent/service.d.ts +1 -1
- package/dist/src/agent/service.js +6 -4
- package/dist/src/agent/service.types.d.ts +2 -0
- package/dist/src/agent/session/index.d.ts +1 -1
- package/dist/src/agent/session/session-context.d.ts +2 -0
- package/dist/src/agent/session/session-context.js +4 -0
- package/dist/src/agent/session/session-state-bag.d.ts +4 -4
- package/dist/src/agent/session/session-state-bag.js +1 -1
- package/dist/src/agent/streaming/reasoning-visibility.d.ts +6 -0
- package/dist/src/agent/streaming/{reasoning-visibility-sse.js → reasoning-visibility.js} +3 -6
- package/dist/src/agent/tools/factory.d.ts +4 -0
- package/dist/src/agent/tools/factory.js +1 -0
- package/dist/src/automations/domain/types.d.ts +2 -1
- package/dist/src/automations/domain/validation.d.ts +1 -1
- package/dist/src/automations/service/action-executor.js +4 -1
- package/dist/src/channels/pairing/pairing-challenge.d.ts +1 -1
- package/dist/src/channels/pairing/pairing-challenge.js +1 -1
- package/dist/src/cli/commands/agent/stream-renderer.js +4 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/config/rules.js +0 -5
- package/dist/src/config/schema.d.ts +3 -5
- package/dist/src/config/schema.js +0 -3
- package/dist/src/config/web-patch.js +0 -1
- package/dist/src/endpoint-tools/auth.d.ts +20 -0
- package/dist/src/endpoint-tools/auth.js +51 -0
- package/dist/src/endpoint-tools/index.d.ts +5 -0
- package/dist/src/endpoint-tools/index.js +6 -0
- package/dist/src/endpoint-tools/invocation-service.d.ts +68 -0
- package/dist/src/endpoint-tools/invocation-service.js +190 -0
- package/dist/src/endpoint-tools/policy.d.ts +10 -0
- package/dist/src/endpoint-tools/policy.js +18 -0
- package/dist/src/endpoint-tools/registry.d.ts +45 -0
- package/dist/src/endpoint-tools/registry.js +121 -0
- package/dist/src/endpoint-tools/runtime.d.ts +23 -0
- package/dist/src/endpoint-tools/runtime.js +86 -0
- package/dist/src/endpoint-tools/upload-service.d.ts +41 -0
- package/dist/src/endpoint-tools/upload-service.js +103 -0
- package/dist/src/extensions/types/hooks.d.ts +1 -1
- package/dist/src/extensions/update.js +1 -1
- package/dist/src/gateway/chat-stream/protocol.d.ts +0 -1
- package/dist/src/gateway/clarify-bridge.d.ts +5 -4
- package/dist/src/gateway/clarify-bridge.js +3 -4
- package/dist/src/gateway/heartbeat/service.js +4 -1
- package/dist/src/gateway/hono/app.js +1 -5
- package/dist/src/gateway/hono/index.d.ts +0 -1
- package/dist/src/gateway/hono/index.js +1 -2
- package/dist/src/gateway/hono/lib/config-payload.d.ts +1 -2
- package/dist/src/gateway/hono/lib/config-payload.js +0 -1
- package/dist/src/gateway/hono/middleware/auth.js +3 -5
- package/dist/src/gateway/hono/routes/agent-stream.js +49 -6
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/gateway.d.ts +2 -2
- package/dist/src/gateway/hono/routes/config-patch/gateway.js +0 -19
- package/dist/src/gateway/hono/routes/deps.d.ts +0 -2
- package/dist/src/gateway/hono/routes/endpoint-tools.d.ts +3 -0
- package/dist/src/gateway/hono/routes/endpoint-tools.js +196 -0
- package/dist/src/gateway/hono/routes/index.js +4 -0
- package/dist/src/gateway/hono/routes/logs.js +0 -4
- package/dist/src/gateway/hono/routes/public-gateway.js +2 -2
- package/dist/src/gateway/hono/routes/realtime.d.ts +3 -0
- package/dist/src/gateway/hono/routes/realtime.js +35 -0
- package/dist/src/gateway/hono/routes/workflows.js +1 -1
- package/dist/src/gateway/hono/routes/you.d.ts +0 -9
- package/dist/src/gateway/hono/routes/you.js +78 -125
- package/dist/src/gateway/index.d.ts +1 -1
- package/dist/src/gateway/index.js +1 -2
- package/dist/src/gateway/protocol.d.ts +1 -7
- package/dist/src/gateway/security/index.js +1 -1
- package/dist/src/gateway/security/operator-scopes.js +1 -1
- package/dist/src/gateway/server.js +4 -4
- package/dist/src/gateway/service/agent-runner.d.ts +11 -9
- package/dist/src/gateway/service/agent-runner.js +18 -18
- package/dist/src/gateway/service/config-coordinator.d.ts +2 -2
- package/dist/src/gateway/service/run-gateway-agent.d.ts +4 -3
- package/dist/src/gateway/service/run-gateway-agent.js +13 -13
- package/dist/src/gateway/service/session-input-coordinator.d.ts +3 -0
- package/dist/src/gateway/service/session-input-coordinator.js +4 -2
- package/dist/src/gateway/service/types.d.ts +0 -5
- package/dist/src/gateway/service.d.ts +7 -6
- package/dist/src/gateway/service.js +43 -26
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/mcp/channel-bridge.d.ts +6 -9
- package/dist/src/mcp/channel-bridge.js +48 -76
- package/dist/src/mcp/channel-server.js +2 -6
- package/dist/src/realtime/broker.d.ts +30 -0
- package/dist/src/realtime/broker.js +97 -0
- package/dist/src/realtime/runtime.d.ts +20 -0
- package/dist/src/realtime/runtime.js +258 -0
- package/dist/src/realtime/tickets.d.ts +15 -0
- package/dist/src/realtime/tickets.js +38 -0
- package/dist/src/realtime/writer.d.ts +15 -0
- package/dist/src/realtime/writer.js +78 -0
- package/dist/src/share/share-config.js +0 -1
- package/dist/src/share/site-share-config.js +0 -1
- package/dist/src/storage/sqlite/endpoint-principal-repository.d.ts +17 -0
- package/dist/src/storage/sqlite/endpoint-principal-repository.js +54 -0
- package/dist/src/storage/sqlite/endpoint-tool-invocation-repository.d.ts +25 -0
- package/dist/src/storage/sqlite/endpoint-tool-invocation-repository.js +42 -0
- package/dist/src/storage/sqlite/index.d.ts +2 -0
- package/dist/src/storage/sqlite/index.js +3 -1
- package/dist/src/storage/sqlite/migrations/109_endpoint_principals.sql +14 -0
- package/dist/src/storage/sqlite/migrations/110_session_input_origin.sql +43 -0
- package/dist/src/storage/sqlite/migrations/111_endpoint_tool_invocations.sql +18 -0
- package/dist/src/storage/sqlite/migrations/112_endpoint_instance_bindings.sql +8 -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/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/session-input-repository.d.ts +3 -0
- package/dist/src/storage/sqlite/session-input-repository.js +5 -3
- package/dist/src/tasks/home-query-service.d.ts +1 -1
- package/dist/src/tui/backends/embedded-backend.js +5 -2
- package/dist/src/tui/backends/{gateway-sse-backend.d.ts → gateway-realtime-backend.d.ts} +13 -10
- package/dist/src/tui/backends/{gateway-sse-backend.js → gateway-realtime-backend.js} +114 -151
- package/dist/src/tui/tui-agent-events.d.ts +0 -1
- package/dist/src/tui/tui-agent-events.js +2 -15
- package/dist/src/tui/tui-backend.d.ts +4 -4
- package/dist/src/tui/tui-run-state.js +0 -4
- package/dist/src/tui/tui-types.d.ts +2 -9
- package/dist/src/tui/tui-types.js +0 -1
- package/dist/src/tui/tui.js +5 -5
- package/dist/src/tunnel/gateway-lifecycle.d.ts +1 -1
- package/dist/src/tunnel/gateway-lifecycle.js +1 -1
- package/dist/src/user-context/actionableInsights.d.ts +14 -0
- package/dist/src/user-context/actionableInsights.js +34 -0
- package/dist/src/user-context/manual-understanding.js +6 -1
- package/dist/src/user-context/projection.d.ts +1 -1
- package/dist/src/user-context/understandingQuality.d.ts +5 -0
- package/dist/src/user-context/understandingQuality.js +44 -0
- package/dist/src/utils/logger/log-stream.d.ts +3 -10
- package/dist/src/utils/logger/log-stream.js +2 -73
- package/dist/src/utils/logger/pino-record.d.ts +1 -1
- package/dist/src/utils/logger/streams.js +1 -1
- package/package.json +6 -3
- package/dist/gateway/static/root/assets/agents-C6OV-gMm.js +0 -2
- package/dist/gateway/static/root/assets/apps-page-Ci14lDeO.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-Q1xmb4Rh.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-DbowrHXD.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-DoZPFdKF.js +0 -7
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-Bt8Hnx0h.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-Bpsebsru.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-DFmdYRE5.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-Tg5kl22i.js +0 -2
- package/dist/gateway/static/root/assets/gateway-settings-9g8uIry9.js +0 -1
- package/dist/gateway/static/root/assets/home-page-Bao9jq_z.js +0 -3
- package/dist/gateway/static/root/assets/index-Cl5n1f_U.css +0 -1
- package/dist/gateway/static/root/assets/index-OJgiMh07.js +0 -223
- package/dist/gateway/static/root/assets/local-app-workbench-page-B69NvtvH.js +0 -2
- package/dist/gateway/static/root/assets/logs-page-Cq3cABqg.js +0 -7
- package/dist/gateway/static/root/assets/messages-D02NNLCZ.js +0 -3
- package/dist/gateway/static/root/assets/notes-workbench-BOZfJFhE.js +0 -4
- package/dist/gateway/static/root/assets/product-delivery-C8JbSj5Y.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-TSKFb2tN.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-BokeBrTT.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-C56anxCX.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-C7TQADrD.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-BDOPKeAX.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-BUPSIa9P.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-BRg766eW.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-DhEAviQ_.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-Ct7AV8ls.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-DoVuprZm.js +0 -2
- package/dist/gateway/static/root/assets/time-picker-BGk_Tbsj.js +0 -1
- package/dist/gateway/static/root/assets/user-context-page-B9K41qmy.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-page-BBVnRHju.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-Bs_tYfst.js +0 -11
- package/dist/src/agent/streaming/reasoning-visibility-sse.d.ts +0 -15
- package/dist/src/gateway/agent-run-relay.d.ts +0 -19
- package/dist/src/gateway/agent-run-relay.js +0 -169
- package/dist/src/gateway/hono/sse.d.ts +0 -53
- package/dist/src/gateway/hono/sse.js +0 -207
- package/dist/src/gateway/service/sse-hub.d.ts +0 -10
- package/dist/src/gateway/service/sse-hub.js +0 -53
- package/dist/src/tui/sse-consumer.d.ts +0 -15
- package/dist/src/tui/sse-consumer.js +0 -73
|
@@ -4,13 +4,15 @@ import { prependEnvelopeTimestamp } from "../../channels/envelope-timestamp.js";
|
|
|
4
4
|
import { transcriptRowsToClientHistory } from "../../session/client-history.js";
|
|
5
5
|
import { parseModelRef } from "../../agent/models/selection.js";
|
|
6
6
|
import { gatewayCredentialAuthorization } from "../../gateway/credential.js";
|
|
7
|
-
import {
|
|
7
|
+
import { RealtimeClient } from "../../../packages/realtime-client/src/index.js";
|
|
8
8
|
import { buildTuiTranscriptTree, transcriptTreeEntryIdToRowNumber } from "../tui-transcript-tree.js";
|
|
9
9
|
import { computeTuiSessionStats } from "../tui-session-stats.js";
|
|
10
|
+
import { createRequire } from "node:module";
|
|
10
11
|
import crypto from "node:crypto";
|
|
11
|
-
//#region src/tui/backends/gateway-
|
|
12
|
+
//#region src/tui/backends/gateway-realtime-backend.ts
|
|
12
13
|
init_logger();
|
|
13
|
-
const log = createLogger("TUI:
|
|
14
|
+
const log = createLogger("TUI:GatewayRealtime");
|
|
15
|
+
const { WebSocket } = createRequire(import.meta.url)("ws");
|
|
14
16
|
function normalizeGatewayModelChoice(model) {
|
|
15
17
|
const providerPrefix = `${model.provider}/`;
|
|
16
18
|
const id = model.id.startsWith(providerPrefix) ? model.id.slice(providerPrefix.length) : model.id;
|
|
@@ -19,19 +21,6 @@ function normalizeGatewayModelChoice(model) {
|
|
|
19
21
|
id
|
|
20
22
|
};
|
|
21
23
|
}
|
|
22
|
-
function isRecord(value) {
|
|
23
|
-
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
24
|
-
}
|
|
25
|
-
function normalizeGatewaySseEvent(evt) {
|
|
26
|
-
if (evt.event !== "agent.stream" || !isRecord(evt.data)) return evt;
|
|
27
|
-
const inner = evt.data.event;
|
|
28
|
-
if (!isRecord(inner) || typeof inner.type !== "string" || !inner.type) return evt;
|
|
29
|
-
return {
|
|
30
|
-
event: inner.type,
|
|
31
|
-
data: inner,
|
|
32
|
-
source: evt.source
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
24
|
/** Fetch wrapper that adds auth headers. */
|
|
36
25
|
async function gatewayFetch(baseUrl, path, credential, init) {
|
|
37
26
|
const authorization = gatewayCredentialAuthorization(credential);
|
|
@@ -46,16 +35,19 @@ async function gatewayFetch(baseUrl, path, credential, init) {
|
|
|
46
35
|
});
|
|
47
36
|
}
|
|
48
37
|
/**
|
|
49
|
-
* TUI backend that communicates with a running xopc gateway via
|
|
38
|
+
* TUI backend that communicates with a running xopc gateway via REST + realtime WebSocket.
|
|
50
39
|
*
|
|
51
|
-
* - Agent input: durable session input REST plus
|
|
52
|
-
* - Broadcast events:
|
|
40
|
+
* - Agent input: durable session input REST plus replayable run topics
|
|
41
|
+
* - Broadcast events: gateway realtime topic
|
|
53
42
|
* - REST calls for sessions, models, etc.
|
|
54
43
|
*/
|
|
55
|
-
var
|
|
44
|
+
var GatewayRealtimeBackend = class {
|
|
56
45
|
baseUrl;
|
|
57
46
|
credential;
|
|
58
|
-
|
|
47
|
+
clientId = `tui-${crypto.randomUUID()}`;
|
|
48
|
+
realtime = null;
|
|
49
|
+
activeRunId = null;
|
|
50
|
+
observedSessionKey = null;
|
|
59
51
|
chatAbort = null;
|
|
60
52
|
onEvent;
|
|
61
53
|
onConnected;
|
|
@@ -69,11 +61,13 @@ var GatewaySseBackend = class {
|
|
|
69
61
|
return this.baseUrl;
|
|
70
62
|
}
|
|
71
63
|
start() {
|
|
72
|
-
this.
|
|
64
|
+
this.startRealtime();
|
|
73
65
|
}
|
|
74
66
|
stop() {
|
|
75
|
-
this.
|
|
76
|
-
this.
|
|
67
|
+
this.realtime?.disconnect();
|
|
68
|
+
this.realtime = null;
|
|
69
|
+
this.activeRunId = null;
|
|
70
|
+
this.observedSessionKey = null;
|
|
77
71
|
this.chatAbort?.abort();
|
|
78
72
|
this.chatAbort = null;
|
|
79
73
|
}
|
|
@@ -95,6 +89,7 @@ var GatewaySseBackend = class {
|
|
|
95
89
|
return (await res.json()).item;
|
|
96
90
|
}
|
|
97
91
|
async sendChat(opts) {
|
|
92
|
+
this.observedSessionKey = opts.sessionKey;
|
|
98
93
|
this.chatAbort?.abort();
|
|
99
94
|
this.chatAbort = new AbortController();
|
|
100
95
|
const signal = this.chatAbort.signal;
|
|
@@ -185,85 +180,18 @@ var GatewaySseBackend = class {
|
|
|
185
180
|
};
|
|
186
181
|
}
|
|
187
182
|
async resumeChat(opts) {
|
|
183
|
+
this.observedSessionKey = opts.sessionKey;
|
|
188
184
|
this.chatAbort?.abort();
|
|
189
185
|
this.chatAbort = new AbortController();
|
|
190
|
-
|
|
191
|
-
this.
|
|
192
|
-
|
|
193
|
-
data: {
|
|
194
|
-
type: "run_start",
|
|
195
|
-
runId: opts.runId,
|
|
196
|
-
sessionKey: opts.sessionKey,
|
|
197
|
-
timestamp: Date.now(),
|
|
198
|
-
payload: { channel: "webchat" }
|
|
199
|
-
},
|
|
200
|
-
source: "agent-resume"
|
|
201
|
-
});
|
|
202
|
-
let res;
|
|
203
|
-
try {
|
|
204
|
-
res = await gatewayFetch(this.baseUrl, "/api/agent/resume", this.credential, {
|
|
205
|
-
method: "POST",
|
|
206
|
-
headers: { Accept: "text/event-stream" },
|
|
207
|
-
body: JSON.stringify({
|
|
208
|
-
runId: opts.runId,
|
|
209
|
-
sessionKey: opts.sessionKey
|
|
210
|
-
}),
|
|
211
|
-
signal
|
|
212
|
-
});
|
|
213
|
-
} catch (error) {
|
|
214
|
-
if (signal.aborted) return {
|
|
215
|
-
ok: false,
|
|
216
|
-
reason: "resume aborted"
|
|
217
|
-
};
|
|
218
|
-
return {
|
|
219
|
-
ok: false,
|
|
220
|
-
reason: error instanceof Error ? error.message : String(error)
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
if (!res.ok) return {
|
|
224
|
-
ok: false,
|
|
225
|
-
reason: (await res.json().catch(() => ({}))).error?.message ?? `Resume failed: ${res.status}`
|
|
226
|
-
};
|
|
227
|
-
if (!(res.headers.get("Content-Type") ?? "").includes("text/event-stream") || !res.body) return {
|
|
228
|
-
ok: false,
|
|
229
|
-
reason: "Resume endpoint did not return an SSE stream"
|
|
230
|
-
};
|
|
231
|
-
(async () => {
|
|
232
|
-
try {
|
|
233
|
-
await consumeSSEStream(res.body, (sseEvent) => {
|
|
234
|
-
if (signal.aborted) return;
|
|
235
|
-
const data = parseSSEData(sseEvent.data);
|
|
236
|
-
if (!data) return;
|
|
237
|
-
this.onEvent?.({
|
|
238
|
-
event: sseEvent.event,
|
|
239
|
-
data,
|
|
240
|
-
source: "agent-resume"
|
|
241
|
-
});
|
|
242
|
-
}, signal);
|
|
243
|
-
} catch (error) {
|
|
244
|
-
if (signal.aborted) return;
|
|
245
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
246
|
-
this.onEvent?.({
|
|
247
|
-
event: "error",
|
|
248
|
-
data: {
|
|
249
|
-
type: "error",
|
|
250
|
-
runId: opts.runId,
|
|
251
|
-
sessionKey: opts.sessionKey,
|
|
252
|
-
timestamp: Date.now(),
|
|
253
|
-
payload: {
|
|
254
|
-
code: "NETWORK_ERROR",
|
|
255
|
-
message: errorMessage
|
|
256
|
-
}
|
|
257
|
-
},
|
|
258
|
-
source: "agent-resume"
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
})();
|
|
186
|
+
this.unsubscribeActiveRun();
|
|
187
|
+
this.activeRunId = opts.runId;
|
|
188
|
+
this.realtime?.subscribe(`run:${opts.runId}`, 0);
|
|
262
189
|
return { ok: true };
|
|
263
190
|
}
|
|
264
191
|
async abortChat(opts) {
|
|
265
192
|
this.chatAbort?.abort();
|
|
266
193
|
this.chatAbort = null;
|
|
194
|
+
this.unsubscribeActiveRun();
|
|
267
195
|
try {
|
|
268
196
|
return { ok: (await (await gatewayFetch(this.baseUrl, "/api/agent/abort", this.credential, {
|
|
269
197
|
method: "POST",
|
|
@@ -274,6 +202,7 @@ var GatewaySseBackend = class {
|
|
|
274
202
|
}
|
|
275
203
|
}
|
|
276
204
|
async submitChatInput(opts) {
|
|
205
|
+
this.observedSessionKey = opts.sessionKey;
|
|
277
206
|
try {
|
|
278
207
|
const res = await gatewayFetch(this.baseUrl, `/api/sessions/${encodeURIComponent(opts.sessionKey)}/inputs`, this.credential, {
|
|
279
208
|
method: "POST",
|
|
@@ -752,65 +681,99 @@ var GatewaySseBackend = class {
|
|
|
752
681
|
return { ok: false };
|
|
753
682
|
}
|
|
754
683
|
}
|
|
755
|
-
|
|
756
|
-
this.
|
|
757
|
-
this.
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
const
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
684
|
+
startRealtime() {
|
|
685
|
+
this.realtime?.disconnect();
|
|
686
|
+
this.realtime = new RealtimeClient({
|
|
687
|
+
clientId: this.clientId,
|
|
688
|
+
clientKind: "tui",
|
|
689
|
+
getWebSocketUrl: () => {
|
|
690
|
+
const url = new URL(this.baseUrl);
|
|
691
|
+
url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
|
|
692
|
+
url.pathname = "/api/realtime/v1/ws";
|
|
693
|
+
url.search = "";
|
|
694
|
+
url.hash = "";
|
|
695
|
+
return url.toString();
|
|
696
|
+
},
|
|
697
|
+
issueTicket: async () => {
|
|
698
|
+
const response = await gatewayFetch(this.baseUrl, "/api/realtime/tickets", this.credential, {
|
|
699
|
+
method: "POST",
|
|
700
|
+
body: JSON.stringify({
|
|
701
|
+
clientId: this.clientId,
|
|
702
|
+
clientKind: "tui"
|
|
703
|
+
})
|
|
767
704
|
});
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
const
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
705
|
+
const body = await response.json().catch(() => null);
|
|
706
|
+
if (!response.ok || !body?.payload?.ticket) throw new Error(body?.error?.message ?? `Realtime ticket failed (${response.status})`);
|
|
707
|
+
return body.payload.ticket;
|
|
708
|
+
},
|
|
709
|
+
createWebSocket: (url) => new WebSocket(url),
|
|
710
|
+
onStateChange: (state, error) => {
|
|
711
|
+
if (state === "connected") this.onConnected?.();
|
|
712
|
+
else if (state === "error") this.onDisconnected?.(error ?? "Realtime connection failed");
|
|
713
|
+
},
|
|
714
|
+
onEvent: (event) => this.handleRealtimeEvent(event),
|
|
715
|
+
onGap: (gap) => {
|
|
716
|
+
this.onGap?.({
|
|
717
|
+
expected: gap.requestedSeq + 1,
|
|
718
|
+
received: gap.earliestSeq
|
|
719
|
+
});
|
|
720
|
+
if (gap.topic === `run:${this.activeRunId}`) {
|
|
721
|
+
const runId = this.activeRunId;
|
|
722
|
+
this.unsubscribeActiveRun();
|
|
723
|
+
this.onEvent?.({
|
|
724
|
+
event: "error",
|
|
725
|
+
data: {
|
|
726
|
+
type: "error",
|
|
727
|
+
runId,
|
|
728
|
+
timestamp: Date.now(),
|
|
729
|
+
payload: {
|
|
730
|
+
code: "REALTIME_GAP",
|
|
731
|
+
message: "Run replay is no longer available"
|
|
732
|
+
}
|
|
733
|
+
},
|
|
734
|
+
source: "realtime-run"
|
|
735
|
+
});
|
|
794
736
|
}
|
|
795
|
-
} catch (error) {
|
|
796
|
-
if (this.eventAbort?.signal.aborted) return;
|
|
797
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
798
|
-
log.warn({
|
|
799
|
-
err: error,
|
|
800
|
-
errorMessage
|
|
801
|
-
}, `Event stream failed: ${errorMessage}`);
|
|
802
|
-
this.onDisconnected?.(errorMessage);
|
|
803
|
-
this.scheduleReconnect();
|
|
804
737
|
}
|
|
805
|
-
};
|
|
806
|
-
|
|
738
|
+
});
|
|
739
|
+
this.realtime.subscribe("gateway");
|
|
740
|
+
this.realtime.subscribe("sessions");
|
|
741
|
+
this.realtime.connect();
|
|
742
|
+
}
|
|
743
|
+
handleRealtimeEvent(event) {
|
|
744
|
+
if (event.topic === `run:${this.activeRunId}`) {
|
|
745
|
+
const data = event.data && typeof event.data === "object" ? {
|
|
746
|
+
...event.data,
|
|
747
|
+
seq: event.seq
|
|
748
|
+
} : event.data;
|
|
749
|
+
this.onEvent?.({
|
|
750
|
+
event: event.event,
|
|
751
|
+
data,
|
|
752
|
+
source: "realtime-run"
|
|
753
|
+
});
|
|
754
|
+
if (event.event === "run_end" || event.event === "error") this.unsubscribeActiveRun();
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
if (event.topic === "gateway") {
|
|
758
|
+
this.onEvent?.({
|
|
759
|
+
event: event.event,
|
|
760
|
+
data: event.data,
|
|
761
|
+
source: "realtime"
|
|
762
|
+
});
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
765
|
+
if (event.topic === "sessions" && event.event === "run.started") {
|
|
766
|
+
const data = event.data;
|
|
767
|
+
if (typeof data?.sessionKey === "string" && data.sessionKey === this.observedSessionKey && typeof data.runId === "string" && data.runId && data.runId !== this.activeRunId) this.resumeChat({
|
|
768
|
+
sessionKey: data.sessionKey,
|
|
769
|
+
runId: data.runId
|
|
770
|
+
});
|
|
771
|
+
}
|
|
807
772
|
}
|
|
808
|
-
|
|
809
|
-
if (this.
|
|
810
|
-
|
|
811
|
-
if (!this.eventAbort?.signal.aborted) this.startEventStream();
|
|
812
|
-
}, 3e3);
|
|
773
|
+
unsubscribeActiveRun() {
|
|
774
|
+
if (this.activeRunId) this.realtime?.unsubscribe(`run:${this.activeRunId}`);
|
|
775
|
+
this.activeRunId = null;
|
|
813
776
|
}
|
|
814
777
|
};
|
|
815
778
|
//#endregion
|
|
816
|
-
export {
|
|
779
|
+
export { GatewayRealtimeBackend };
|
|
@@ -4,7 +4,6 @@ import type { ChatLog } from './components/chat-log.js';
|
|
|
4
4
|
import type { TuiEventSource, TuiState } from './tui-types.js';
|
|
5
5
|
export declare function clearSeenStreamEvents(): void;
|
|
6
6
|
export declare function clearSeenStreamEventsForRun(runId: string): void;
|
|
7
|
-
export declare function shouldSkipDuplicateBroadcastEvent(event: string, data: Record<string, unknown>, state: TuiState, source: TuiEventSource): boolean;
|
|
8
7
|
export declare function dispatchAgentEvent(event: string, data: Record<string, unknown>, state: TuiState, chatLog: ChatLog, tui: TUI, setActivityStatus: (status: string) => void, touchStreamingActivity?: () => void, onRunEnded?: () => void, onAssistantFinalized?: (message: AgentMessage, options?: {
|
|
9
8
|
errorMessage?: string;
|
|
10
9
|
}) => void, source?: TuiEventSource): void;
|
|
@@ -29,22 +29,10 @@ const STREAM_TOUCH_EVENTS = new Set([
|
|
|
29
29
|
"assistant_message_end",
|
|
30
30
|
"progress"
|
|
31
31
|
]);
|
|
32
|
-
const DIRECT_RESPONSE_OWNED_EVENTS = new Set([
|
|
33
|
-
...STREAM_TOUCH_EVENTS,
|
|
34
|
-
"run_end",
|
|
35
|
-
"error"
|
|
36
|
-
]);
|
|
37
32
|
function resolveEventRunId(data, state) {
|
|
38
33
|
if (typeof data.runId === "string" && data.runId) return data.runId;
|
|
39
34
|
return state.activeRunId ?? state.runStatus.runId ?? state.runStatus.lastCompletedRunId;
|
|
40
35
|
}
|
|
41
|
-
function shouldSkipDuplicateBroadcastEvent(event, data, state, source) {
|
|
42
|
-
if (source !== "broadcast") return false;
|
|
43
|
-
if (!DIRECT_RESPONSE_OWNED_EVENTS.has(event)) return false;
|
|
44
|
-
const directRunId = state.runStatus.directStreamRunId;
|
|
45
|
-
if (!directRunId) return false;
|
|
46
|
-
return resolveEventRunId(data, state) === directRunId;
|
|
47
|
-
}
|
|
48
36
|
function streamEventKey(data, state) {
|
|
49
37
|
const runId = resolveEventRunId(data, state);
|
|
50
38
|
const seq = data.seq;
|
|
@@ -52,7 +40,7 @@ function streamEventKey(data, state) {
|
|
|
52
40
|
return `${runId}:${seq}`;
|
|
53
41
|
}
|
|
54
42
|
function shouldSkipSeenStreamEvent(data, state, source) {
|
|
55
|
-
if (source !== "
|
|
43
|
+
if (source !== "realtime-run") return false;
|
|
56
44
|
const key = streamEventKey(data, state);
|
|
57
45
|
if (!key) return false;
|
|
58
46
|
if (seenStreamEventKeys.has(key)) return true;
|
|
@@ -176,7 +164,6 @@ function errorAssistantMessage(errorContent) {
|
|
|
176
164
|
}
|
|
177
165
|
function dispatchAgentEvent(event, data, state, chatLog, tui, setActivityStatus, touchStreamingActivity, onRunEnded, onAssistantFinalized, source = "unknown") {
|
|
178
166
|
if (shouldSkipSeenStreamEvent(data, state, source)) return;
|
|
179
|
-
if (shouldSkipDuplicateBroadcastEvent(event, data, state, source)) return;
|
|
180
167
|
if (STREAM_TOUCH_EVENTS.has(event)) touchStreamingActivity?.();
|
|
181
168
|
const runId = resolveEventRunId(data, state) ?? state.activeRunId ?? "default";
|
|
182
169
|
const p = payload(data);
|
|
@@ -356,4 +343,4 @@ function dispatchAgentEvent(event, data, state, chatLog, tui, setActivityStatus,
|
|
|
356
343
|
}
|
|
357
344
|
const DEFAULT_STREAMING_WATCHDOG_MS = 3e4;
|
|
358
345
|
//#endregion
|
|
359
|
-
export { DEFAULT_STREAMING_WATCHDOG_MS, clearSeenStreamEvents, clearSeenStreamEventsForRun, dispatchAgentEvent
|
|
346
|
+
export { DEFAULT_STREAMING_WATCHDOG_MS, clearSeenStreamEvents, clearSeenStreamEventsForRun, dispatchAgentEvent };
|
|
@@ -19,7 +19,7 @@ export interface TuiInboundAttachment {
|
|
|
19
19
|
size?: number;
|
|
20
20
|
uri?: string;
|
|
21
21
|
}
|
|
22
|
-
/**
|
|
22
|
+
/** Event from an agent run or gateway topic. */
|
|
23
23
|
export interface TuiEvent {
|
|
24
24
|
event: string;
|
|
25
25
|
data: unknown;
|
|
@@ -171,7 +171,7 @@ export interface TuiTranscriptTreeEntry {
|
|
|
171
171
|
isCurrentLeaf?: boolean;
|
|
172
172
|
}
|
|
173
173
|
/**
|
|
174
|
-
* Abstraction over the gateway
|
|
174
|
+
* Abstraction over the realtime gateway or embedded agent backend.
|
|
175
175
|
*
|
|
176
176
|
* Both implementations expose the same surface so the TUI core stays
|
|
177
177
|
* transport-agnostic.
|
|
@@ -183,12 +183,12 @@ export interface TuiBackend {
|
|
|
183
183
|
onEvent?: (evt: TuiEvent) => void;
|
|
184
184
|
onConnected?: () => void;
|
|
185
185
|
onDisconnected?: (reason: string) => void;
|
|
186
|
-
/**
|
|
186
|
+
/** Realtime sequence gap. */
|
|
187
187
|
onGap?: (info: {
|
|
188
188
|
expected: number;
|
|
189
189
|
received: number;
|
|
190
190
|
}) => void;
|
|
191
|
-
/** Start the backend
|
|
191
|
+
/** Start the backend connection or embedded agent service. */
|
|
192
192
|
start(): void;
|
|
193
193
|
/** Stop the backend. */
|
|
194
194
|
stop(): void;
|
|
@@ -6,14 +6,12 @@ const STALE_WATCH_ACTIVITY = new Set([
|
|
|
6
6
|
"running"
|
|
7
7
|
]);
|
|
8
8
|
function markRunEvent(state, phase, runId, event, source, nowMs = Date.now()) {
|
|
9
|
-
const directStreamRunId = (source === "agent-response" || source === "agent-resume") && runId ? runId : state.runStatus.directStreamRunId;
|
|
10
9
|
const isStartingNewRun = phase !== "idle" && state.runStatus.phase === "idle" && (runId === null || state.runStatus.runId === null || state.runStatus.runId !== runId);
|
|
11
10
|
const startedAt = phase === "idle" ? null : isStartingNewRun || state.runStatus.startedAt == null ? nowMs : state.runStatus.startedAt;
|
|
12
11
|
state.runStatus = {
|
|
13
12
|
...state.runStatus,
|
|
14
13
|
phase,
|
|
15
14
|
runId,
|
|
16
|
-
directStreamRunId,
|
|
17
15
|
source,
|
|
18
16
|
lastEvent: event,
|
|
19
17
|
startedAt,
|
|
@@ -26,7 +24,6 @@ function markRunSending(state, nowMs = Date.now()) {
|
|
|
26
24
|
...state.runStatus,
|
|
27
25
|
phase: "sending",
|
|
28
26
|
runId: null,
|
|
29
|
-
directStreamRunId: null,
|
|
30
27
|
lastCompletedRunId: null,
|
|
31
28
|
source: "unknown",
|
|
32
29
|
lastEvent: "send",
|
|
@@ -65,7 +62,6 @@ function resetRunStatus(state) {
|
|
|
65
62
|
...state.runStatus,
|
|
66
63
|
phase: "idle",
|
|
67
64
|
runId: null,
|
|
68
|
-
directStreamRunId: null,
|
|
69
65
|
lastCompletedRunId: null,
|
|
70
66
|
lastEvent: null,
|
|
71
67
|
startedAt: null,
|
|
@@ -28,20 +28,13 @@ export type TuiExitReason = 'exit' | 'signal';
|
|
|
28
28
|
export interface TuiResult {
|
|
29
29
|
exitReason: TuiExitReason;
|
|
30
30
|
}
|
|
31
|
-
/** Parsed SSE event from the stream. */
|
|
32
|
-
export interface ParsedSSEEvent {
|
|
33
|
-
event: string;
|
|
34
|
-
data: string;
|
|
35
|
-
id?: string;
|
|
36
|
-
}
|
|
37
31
|
/** Activity status for the TUI status bar. */
|
|
38
32
|
export type ActivityStatus = 'idle' | 'sending' | 'waiting' | 'streaming' | 'running' | 'compacting' | 'stalled' | 'recovering' | 'aborting';
|
|
39
|
-
export type TuiEventSource = '
|
|
33
|
+
export type TuiEventSource = 'realtime-run' | 'realtime' | 'embedded' | 'unknown';
|
|
40
34
|
export type TuiRunPhase = 'idle' | 'sending' | 'waiting' | 'streaming' | 'tool' | 'progress' | 'stalled' | 'recovering' | 'aborting';
|
|
41
35
|
export interface TuiRunStatus {
|
|
42
36
|
phase: TuiRunPhase;
|
|
43
37
|
runId: string | null;
|
|
44
|
-
directStreamRunId: string | null;
|
|
45
38
|
lastCompletedRunId: string | null;
|
|
46
39
|
source: TuiEventSource;
|
|
47
40
|
lastEvent: string | null;
|
|
@@ -86,7 +79,7 @@ export interface TuiState {
|
|
|
86
79
|
scopedModelRefs: string[] | null;
|
|
87
80
|
/** Last Escape timestamp for double-press actions. */
|
|
88
81
|
lastEscapeAt: number;
|
|
89
|
-
/** Human-readable progress from
|
|
82
|
+
/** Human-readable progress from run `progress` events. */
|
|
90
83
|
progressMessage: string | null;
|
|
91
84
|
/** Session compaction in flight (local /compact handler). */
|
|
92
85
|
isCompacting: boolean;
|
package/dist/src/tui/tui.js
CHANGED
|
@@ -46,7 +46,7 @@ import { createEditorSubmitHandler, createSubmitBurstCoalescer, shouldEnableWind
|
|
|
46
46
|
import { withTuiSuspended } from "./tui-suspend.js";
|
|
47
47
|
import { createInitialState } from "./tui-types.js";
|
|
48
48
|
import { EmbeddedBackend } from "./backends/embedded-backend.js";
|
|
49
|
-
import {
|
|
49
|
+
import { GatewayRealtimeBackend } from "./backends/gateway-realtime-backend.js";
|
|
50
50
|
import { ChatLog } from "./components/chat-log.js";
|
|
51
51
|
import { CustomEditor } from "./components/custom-editor.js";
|
|
52
52
|
import { TuiBottomBar } from "./components/tui-bottom-bar.js";
|
|
@@ -236,7 +236,7 @@ async function runTui(opts) {
|
|
|
236
236
|
extensionRegistry,
|
|
237
237
|
implicitTrustedWorkspace,
|
|
238
238
|
isWorkspaceTrusted: () => projectTrustSessionDecision
|
|
239
|
-
}) : new
|
|
239
|
+
}) : new GatewayRealtimeBackend({
|
|
240
240
|
url: opts.url ?? "http://localhost:3120",
|
|
241
241
|
credential: opts.credential
|
|
242
242
|
});
|
|
@@ -2172,7 +2172,7 @@ async function runTui(opts) {
|
|
|
2172
2172
|
updateFooter();
|
|
2173
2173
|
tui.requestRender();
|
|
2174
2174
|
});
|
|
2175
|
-
if (state.activeRunId) recoverActiveRunFromHistory("
|
|
2175
|
+
if (state.activeRunId) recoverActiveRunFromHistory("realtime reconnect");
|
|
2176
2176
|
updateHeader();
|
|
2177
2177
|
updateFooter();
|
|
2178
2178
|
tui.requestRender();
|
|
@@ -2188,7 +2188,7 @@ async function runTui(opts) {
|
|
|
2188
2188
|
touchStreamingActivity();
|
|
2189
2189
|
if (isLocalMode) setConnectionStatus(`local stopped: ${reason}`);
|
|
2190
2190
|
else {
|
|
2191
|
-
setConnectionStatus(`disconnected${wasConnected || state.historyLoaded ? ` (${reason}). Reconnecting
|
|
2191
|
+
setConnectionStatus(`disconnected${wasConnected || state.historyLoaded ? ` (${reason}). Reconnecting realtime stream…` : `. Ensure gateway is running (xopc gateway) or use --local.`}`);
|
|
2192
2192
|
if (!wasConnected && !state.historyLoaded) {
|
|
2193
2193
|
const gatewayUrl = opts.url ?? "http://localhost:3120";
|
|
2194
2194
|
chatLog.addSystem(`Cannot reach gateway at ${gatewayUrl}.\nStart the gateway (\`xopc gateway\`) or run \`xopc tui --local\` for embedded mode.`);
|
|
@@ -2199,7 +2199,7 @@ async function runTui(opts) {
|
|
|
2199
2199
|
client.onGap = (info) => {
|
|
2200
2200
|
chatLog.addSystem(`⚠️ Event gap: expected ${info.expected}, received ${info.received}. Some updates may be missing.`);
|
|
2201
2201
|
setConnectionStatus(`event gap: expected ${info.expected}, got ${info.received}`);
|
|
2202
|
-
if (state.activeRunId) recoverActiveRunFromHistory("
|
|
2202
|
+
if (state.activeRunId) recoverActiveRunFromHistory("realtime event gap");
|
|
2203
2203
|
else loadSessionHistory({ merge: true });
|
|
2204
2204
|
refreshComposerHistory();
|
|
2205
2205
|
tui.requestRender();
|
|
@@ -2,7 +2,7 @@ import type { Config } from '../config/schema.js';
|
|
|
2
2
|
type TunnelEventSink = {
|
|
3
3
|
emit(type: string, payload: unknown): void;
|
|
4
4
|
};
|
|
5
|
-
/** Publish `tunnel.status` on gateway
|
|
5
|
+
/** Publish `tunnel.status` on the gateway realtime topic when tunnel lifecycle changes. */
|
|
6
6
|
export declare function wireTunnelEventsToGateway(service: TunnelEventSink): void;
|
|
7
7
|
export type ConfigureTunnelFromGatewayConfigOptions = {
|
|
8
8
|
force?: boolean;
|
|
@@ -10,7 +10,7 @@ import { fetchTunnelWellKnown } from "./well-known.js";
|
|
|
10
10
|
init_logger();
|
|
11
11
|
const log = createLogger("Tunnel");
|
|
12
12
|
let tunnelSseWired = false;
|
|
13
|
-
/** Publish `tunnel.status` on gateway
|
|
13
|
+
/** Publish `tunnel.status` on the gateway realtime topic when tunnel lifecycle changes. */
|
|
14
14
|
function wireTunnelEventsToGateway(service) {
|
|
15
15
|
if (tunnelSseWired) return;
|
|
16
16
|
tunnelSseWired = true;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { MemoryRecord } from '../agent/memory/types.js';
|
|
2
|
+
export declare const USER_CONFIRMED_MEMORY_TAG = "user-confirmed";
|
|
3
|
+
export declare const INSIGHT_ACCEPTED_TAG = "insight-action:accepted";
|
|
4
|
+
export declare const INSIGHT_DISMISSED_TAG = "insight-action:dismissed";
|
|
5
|
+
export type ActionableInsightSuggestion = {
|
|
6
|
+
id: string;
|
|
7
|
+
insight: string;
|
|
8
|
+
kind: MemoryRecord['kind'];
|
|
9
|
+
action: 'make_repeatable' | 'start_progress' | 'add_playbook';
|
|
10
|
+
evidenceCount: number;
|
|
11
|
+
confidence?: number;
|
|
12
|
+
sourceName: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function buildActionableInsightSuggestions(records: MemoryRecord[], existingTaskTexts: readonly string[]): ActionableInsightSuggestion[];
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { isActionableUnderstandingContent, isNearDuplicateUnderstanding } from "./understandingQuality.js";
|
|
2
|
+
//#region src/user-context/actionableInsights.ts
|
|
3
|
+
const USER_CONFIRMED_MEMORY_TAG = "user-confirmed";
|
|
4
|
+
const INSIGHT_ACCEPTED_TAG = "insight-action:accepted";
|
|
5
|
+
const INSIGHT_DISMISSED_TAG = "insight-action:dismissed";
|
|
6
|
+
function actionFor(record) {
|
|
7
|
+
if (record.kind === "routine") return "make_repeatable";
|
|
8
|
+
if (record.kind === "long_term_goal") return "start_progress";
|
|
9
|
+
if (record.kind === "task_lesson" || record.kind === "derived_insight") return "add_playbook";
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
function buildActionableInsightSuggestions(records, existingTaskTexts) {
|
|
13
|
+
const selected = [];
|
|
14
|
+
const sorted = records.filter((record) => record.status === "active").filter((record) => record.tags?.includes(USER_CONFIRMED_MEMORY_TAG)).filter((record) => !record.tags?.includes("insight-action:accepted") && !record.tags?.includes("insight-action:dismissed")).filter((record) => isActionableUnderstandingContent(record.content)).filter((record) => record.kind !== "long_term_goal" || record.durability !== "ephemeral").sort((left, right) => right.importance - left.importance || Date.parse(right.updatedAt) - Date.parse(left.updatedAt));
|
|
15
|
+
for (const record of sorted) {
|
|
16
|
+
const action = actionFor(record);
|
|
17
|
+
if (!action) continue;
|
|
18
|
+
if (selected.some((item) => item.action === action && isNearDuplicateUnderstanding(item.insight, record.content))) continue;
|
|
19
|
+
if (action === "start_progress" && existingTaskTexts.some((text) => isNearDuplicateUnderstanding(text, record.content))) continue;
|
|
20
|
+
selected.push({
|
|
21
|
+
id: record.id,
|
|
22
|
+
insight: record.content,
|
|
23
|
+
kind: record.kind,
|
|
24
|
+
action,
|
|
25
|
+
evidenceCount: record.evidence?.length ?? 0,
|
|
26
|
+
confidence: record.confidence,
|
|
27
|
+
sourceName: record.source.provider ?? "local"
|
|
28
|
+
});
|
|
29
|
+
if (selected.length === 5) break;
|
|
30
|
+
}
|
|
31
|
+
return selected;
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { INSIGHT_ACCEPTED_TAG, INSIGHT_DISMISSED_TAG, USER_CONFIRMED_MEMORY_TAG, buildActionableInsightSuggestions };
|
|
@@ -2,6 +2,7 @@ import { listMemoryRecords, upsertMemoryRecord } from "../storage/sqlite/memory-
|
|
|
2
2
|
import "../storage/sqlite/index.js";
|
|
3
3
|
import { nextMemoryReviewAt } from "../agent/memory/lifecycle.js";
|
|
4
4
|
import { isUserContextRecord } from "./projection.js";
|
|
5
|
+
import { USER_CONFIRMED_MEMORY_TAG } from "./actionableInsights.js";
|
|
5
6
|
//#region src/user-context/manual-understanding.ts
|
|
6
7
|
const STATUSES = [
|
|
7
8
|
"candidate",
|
|
@@ -50,7 +51,11 @@ function createManualUnderstanding(input) {
|
|
|
50
51
|
path: "you://manual"
|
|
51
52
|
},
|
|
52
53
|
confidence: 1,
|
|
53
|
-
tags: [
|
|
54
|
+
tags: [
|
|
55
|
+
"user-understanding",
|
|
56
|
+
"explicit-user-memory",
|
|
57
|
+
USER_CONFIRMED_MEMORY_TAG
|
|
58
|
+
],
|
|
54
59
|
status: "active",
|
|
55
60
|
sensitivity: input.sensitivity,
|
|
56
61
|
explicitness: "explicit",
|
|
@@ -68,7 +68,7 @@ export declare function projectPersonalContextSources(definitions: ConnectorDefi
|
|
|
68
68
|
}>;
|
|
69
69
|
}): {
|
|
70
70
|
category: import("../connectors/types.js").ConnectorCategory;
|
|
71
|
-
capabilities: ("
|
|
71
|
+
capabilities: ("tools" | "context" | "events" | "memory_source")[];
|
|
72
72
|
access: {
|
|
73
73
|
context: boolean;
|
|
74
74
|
memory: boolean;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { MemoryKind } from '../agent/memory/types.js';
|
|
2
|
+
export declare function isStandaloneUnderstandingContent(content: string): boolean;
|
|
3
|
+
export declare function isActionableUnderstandingContent(content: string): boolean;
|
|
4
|
+
export declare function isDurableUnderstandingCandidate(kind: MemoryKind, content: string): boolean;
|
|
5
|
+
export declare function isNearDuplicateUnderstanding(left: string, right: string): boolean;
|