@pellux/goodvibes-sdk 0.38.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contracts/artifacts/operator-contract.json +3171 -929
- package/dist/daemon.d.ts +2 -0
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +4 -0
- package/dist/events/surfaces.d.ts +25 -3
- package/dist/events/surfaces.d.ts.map +1 -1
- package/dist/events/surfaces.js +22 -1
- package/dist/events/workflows.d.ts +7 -6
- package/dist/events/workflows.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/platform/agents/archetypes.d.ts.map +1 -1
- package/dist/platform/agents/archetypes.js +7 -0
- package/dist/platform/agents/index.d.ts +1 -0
- package/dist/platform/agents/index.d.ts.map +1 -1
- package/dist/platform/agents/index.js +1 -0
- package/dist/platform/agents/orchestrator-runner.d.ts +13 -0
- package/dist/platform/agents/orchestrator-runner.d.ts.map +1 -1
- package/dist/platform/agents/orchestrator-runner.js +14 -0
- package/dist/platform/agents/orchestrator.d.ts +38 -6
- package/dist/platform/agents/orchestrator.d.ts.map +1 -1
- package/dist/platform/agents/orchestrator.js +66 -18
- package/dist/platform/agents/planner-decomposition-runner.d.ts +38 -0
- package/dist/platform/agents/planner-decomposition-runner.d.ts.map +1 -0
- package/dist/platform/agents/planner-decomposition-runner.js +113 -0
- package/dist/platform/agents/turn-knowledge-injection.d.ts +88 -3
- package/dist/platform/agents/turn-knowledge-injection.d.ts.map +1 -1
- package/dist/platform/agents/turn-knowledge-injection.js +147 -30
- package/dist/platform/agents/worktree.d.ts +126 -8
- package/dist/platform/agents/worktree.d.ts.map +1 -1
- package/dist/platform/agents/worktree.js +240 -19
- package/dist/platform/agents/wrfc-controller.d.ts +23 -0
- package/dist/platform/agents/wrfc-controller.d.ts.map +1 -1
- package/dist/platform/agents/wrfc-controller.js +158 -32
- package/dist/platform/agents/wrfc-gate-runtime.d.ts +9 -0
- package/dist/platform/agents/wrfc-gate-runtime.d.ts.map +1 -1
- package/dist/platform/agents/wrfc-gate-runtime.js +7 -3
- package/dist/platform/agents/wrfc-gates.d.ts +1 -1
- package/dist/platform/agents/wrfc-gates.d.ts.map +1 -1
- package/dist/platform/agents/wrfc-gates.js +7 -1
- package/dist/platform/agents/wrfc-types.d.ts +23 -3
- package/dist/platform/agents/wrfc-types.d.ts.map +1 -1
- package/dist/platform/automation/types.d.ts +9 -1
- package/dist/platform/automation/types.d.ts.map +1 -1
- package/dist/platform/calendar/calendar-api-shared.d.ts +25 -0
- package/dist/platform/calendar/calendar-api-shared.d.ts.map +1 -0
- package/dist/platform/calendar/calendar-api-shared.js +100 -0
- package/dist/platform/calendar/calendar-connector.d.ts +79 -0
- package/dist/platform/calendar/calendar-connector.d.ts.map +1 -0
- package/dist/platform/calendar/calendar-connector.js +155 -0
- package/dist/platform/calendar/google-calendar-api.d.ts +25 -0
- package/dist/platform/calendar/google-calendar-api.d.ts.map +1 -0
- package/dist/platform/calendar/google-calendar-api.js +89 -0
- package/dist/platform/calendar/http-fetch-adapter.d.ts +25 -0
- package/dist/platform/calendar/http-fetch-adapter.d.ts.map +1 -0
- package/dist/platform/calendar/http-fetch-adapter.js +25 -0
- package/dist/platform/calendar/ics-parser.d.ts +35 -0
- package/dist/platform/calendar/ics-parser.d.ts.map +1 -0
- package/dist/platform/calendar/ics-parser.js +236 -0
- package/dist/platform/calendar/index.d.ts +41 -0
- package/dist/platform/calendar/index.d.ts.map +1 -0
- package/dist/platform/calendar/index.js +49 -0
- package/dist/platform/calendar/merged-calendar-model.d.ts +67 -0
- package/dist/platform/calendar/merged-calendar-model.d.ts.map +1 -0
- package/dist/platform/calendar/merged-calendar-model.js +181 -0
- package/dist/platform/calendar/microsoft-graph-api.d.ts +25 -0
- package/dist/platform/calendar/microsoft-graph-api.d.ts.map +1 -0
- package/dist/platform/calendar/microsoft-graph-api.js +95 -0
- package/dist/platform/calendar/oauth-flow.d.ts +62 -0
- package/dist/platform/calendar/oauth-flow.d.ts.map +1 -0
- package/dist/platform/calendar/oauth-flow.js +305 -0
- package/dist/platform/calendar/oauth-providers.d.ts +43 -0
- package/dist/platform/calendar/oauth-providers.d.ts.map +1 -0
- package/dist/platform/calendar/oauth-providers.js +120 -0
- package/dist/platform/calendar/oauth-token-store.d.ts +72 -0
- package/dist/platform/calendar/oauth-token-store.d.ts.map +1 -0
- package/dist/platform/calendar/oauth-token-store.js +189 -0
- package/dist/platform/calendar/oauth-types.d.ts +274 -0
- package/dist/platform/calendar/oauth-types.d.ts.map +1 -0
- package/dist/platform/calendar/oauth-types.js +22 -0
- package/dist/platform/calendar/rrule.d.ts +39 -0
- package/dist/platform/calendar/rrule.d.ts.map +1 -0
- package/dist/platform/calendar/rrule.js +261 -0
- package/dist/platform/calendar/subscription-store.d.ts +118 -0
- package/dist/platform/calendar/subscription-store.d.ts.map +1 -0
- package/dist/platform/calendar/subscription-store.js +293 -0
- package/dist/platform/calendar/types.d.ts +170 -0
- package/dist/platform/calendar/types.d.ts.map +1 -0
- package/dist/platform/calendar/types.js +21 -0
- package/dist/platform/companion/companion-chat-attachments.d.ts +29 -0
- package/dist/platform/companion/companion-chat-attachments.d.ts.map +1 -0
- package/dist/platform/companion/companion-chat-attachments.js +121 -0
- package/dist/platform/companion/companion-chat-broker-bridge.d.ts +40 -0
- package/dist/platform/companion/companion-chat-broker-bridge.d.ts.map +1 -0
- package/dist/platform/companion/companion-chat-broker-bridge.js +14 -0
- package/dist/platform/companion/companion-chat-broker-sync.d.ts +38 -0
- package/dist/platform/companion/companion-chat-broker-sync.d.ts.map +1 -0
- package/dist/platform/companion/companion-chat-broker-sync.js +80 -0
- package/dist/platform/companion/companion-chat-gc.d.ts +63 -0
- package/dist/platform/companion/companion-chat-gc.d.ts.map +1 -0
- package/dist/platform/companion/companion-chat-gc.js +38 -0
- package/dist/platform/companion/companion-chat-manager.d.ts +67 -20
- package/dist/platform/companion/companion-chat-manager.d.ts.map +1 -1
- package/dist/platform/companion/companion-chat-manager.js +130 -144
- package/dist/platform/companion/companion-chat-persistence.d.ts +9 -1
- package/dist/platform/companion/companion-chat-persistence.d.ts.map +1 -1
- package/dist/platform/companion/companion-chat-persistence.js +10 -2
- package/dist/platform/companion/companion-chat-routes.d.ts +2 -1
- package/dist/platform/companion/companion-chat-routes.d.ts.map +1 -1
- package/dist/platform/companion/companion-chat-routes.js +37 -4
- package/dist/platform/config/credential-status.d.ts +28 -0
- package/dist/platform/config/credential-status.d.ts.map +1 -0
- package/dist/platform/config/credential-status.js +75 -0
- package/dist/platform/config/index.d.ts +25 -0
- package/dist/platform/config/index.d.ts.map +1 -1
- package/dist/platform/config/index.js +18 -0
- package/dist/platform/config/manager.d.ts +9 -0
- package/dist/platform/config/manager.d.ts.map +1 -1
- package/dist/platform/config/manager.js +21 -2
- package/dist/platform/config/migrations.d.ts +48 -0
- package/dist/platform/config/migrations.d.ts.map +1 -0
- package/dist/platform/config/migrations.js +54 -0
- package/dist/platform/config/schema-domain-core.d.ts +10 -1
- package/dist/platform/config/schema-domain-core.d.ts.map +1 -1
- package/dist/platform/config/schema-domain-core.js +46 -3
- package/dist/platform/config/schema-types.d.ts +13 -7
- package/dist/platform/config/schema-types.d.ts.map +1 -1
- package/dist/platform/config/schema.d.ts.map +1 -1
- package/dist/platform/config/schema.js +2 -0
- package/dist/platform/control-plane/approval-broker.d.ts +11 -0
- package/dist/platform/control-plane/approval-broker.d.ts.map +1 -1
- package/dist/platform/control-plane/approval-broker.js +17 -1
- package/dist/platform/control-plane/approval-hunk-apply.d.ts +77 -0
- package/dist/platform/control-plane/approval-hunk-apply.d.ts.map +1 -0
- package/dist/platform/control-plane/approval-hunk-apply.js +80 -0
- package/dist/platform/control-plane/gateway-disabled-response.d.ts +20 -0
- package/dist/platform/control-plane/gateway-disabled-response.d.ts.map +1 -0
- package/dist/platform/control-plane/gateway-disabled-response.js +24 -0
- package/dist/platform/control-plane/gateway-scope-enforcement.d.ts +68 -0
- package/dist/platform/control-plane/gateway-scope-enforcement.d.ts.map +1 -0
- package/dist/platform/control-plane/gateway-scope-enforcement.js +91 -0
- package/dist/platform/control-plane/gateway-utils.d.ts +17 -0
- package/dist/platform/control-plane/gateway-utils.d.ts.map +1 -1
- package/dist/platform/control-plane/gateway-utils.js +30 -0
- package/dist/platform/control-plane/gateway.d.ts +12 -2
- package/dist/platform/control-plane/gateway.d.ts.map +1 -1
- package/dist/platform/control-plane/gateway.js +27 -31
- package/dist/platform/control-plane/index.d.ts +6 -1
- package/dist/platform/control-plane/index.d.ts.map +1 -1
- package/dist/platform/control-plane/index.js +4 -0
- package/dist/platform/control-plane/invoke-input-validation.d.ts +56 -0
- package/dist/platform/control-plane/invoke-input-validation.d.ts.map +1 -0
- package/dist/platform/control-plane/invoke-input-validation.js +163 -0
- package/dist/platform/control-plane/method-catalog-admin.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-admin.js +12 -1
- package/dist/platform/control-plane/method-catalog-calendar.d.ts +16 -0
- package/dist/platform/control-plane/method-catalog-calendar.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-calendar.js +21 -0
- package/dist/platform/control-plane/method-catalog-channels.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-channels.js +32 -3
- package/dist/platform/control-plane/method-catalog-control-automation.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-control-automation.js +19 -34
- package/dist/platform/control-plane/method-catalog-control-companion.d.ts +15 -0
- package/dist/platform/control-plane/method-catalog-control-companion.d.ts.map +1 -0
- package/dist/platform/control-plane/method-catalog-control-companion.js +133 -0
- package/dist/platform/control-plane/method-catalog-control-core.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-control-core.js +104 -122
- package/dist/platform/control-plane/method-catalog-control.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-control.js +4 -0
- package/dist/platform/control-plane/method-catalog-email.d.ts +17 -0
- package/dist/platform/control-plane/method-catalog-email.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-email.js +21 -0
- package/dist/platform/control-plane/method-catalog-events.d.ts +28 -0
- package/dist/platform/control-plane/method-catalog-events.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-events.js +74 -1
- package/dist/platform/control-plane/method-catalog-fleet.d.ts +24 -0
- package/dist/platform/control-plane/method-catalog-fleet.d.ts.map +1 -0
- package/dist/platform/control-plane/method-catalog-fleet.js +65 -0
- package/dist/platform/control-plane/method-catalog-route-reconcile.d.ts +84 -0
- package/dist/platform/control-plane/method-catalog-route-reconcile.d.ts.map +1 -0
- package/dist/platform/control-plane/method-catalog-route-reconcile.js +103 -0
- package/dist/platform/control-plane/method-catalog-shared.d.ts +29 -0
- package/dist/platform/control-plane/method-catalog-shared.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog.d.ts +9 -0
- package/dist/platform/control-plane/method-catalog.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog.js +32 -3
- package/dist/platform/control-plane/operator-contract-schemas-admin.d.ts +8 -0
- package/dist/platform/control-plane/operator-contract-schemas-admin.d.ts.map +1 -1
- package/dist/platform/control-plane/operator-contract-schemas-admin.js +22 -1
- package/dist/platform/control-plane/operator-contract-schemas-fleet.d.ts +18 -0
- package/dist/platform/control-plane/operator-contract-schemas-fleet.d.ts.map +1 -0
- package/dist/platform/control-plane/operator-contract-schemas-fleet.js +182 -0
- package/dist/platform/control-plane/operator-contract-schemas-permissions.d.ts.map +1 -1
- package/dist/platform/control-plane/operator-contract-schemas-permissions.js +5 -0
- package/dist/platform/control-plane/operator-contract-schemas-runtime.d.ts +29 -0
- package/dist/platform/control-plane/operator-contract-schemas-runtime.d.ts.map +1 -1
- package/dist/platform/control-plane/operator-contract-schemas-runtime.js +57 -3
- package/dist/platform/control-plane/operator-contract-schemas.d.ts +1 -0
- package/dist/platform/control-plane/operator-contract-schemas.d.ts.map +1 -1
- package/dist/platform/control-plane/operator-contract-schemas.js +1 -0
- package/dist/platform/control-plane/operator-contract.d.ts.map +1 -1
- package/dist/platform/control-plane/operator-contract.js +8 -0
- package/dist/platform/control-plane/routes/checkpoints.d.ts +39 -0
- package/dist/platform/control-plane/routes/checkpoints.d.ts.map +1 -0
- package/dist/platform/control-plane/routes/checkpoints.js +166 -0
- package/dist/platform/control-plane/routes/fleet.d.ts +53 -0
- package/dist/platform/control-plane/routes/fleet.d.ts.map +1 -0
- package/dist/platform/control-plane/routes/fleet.js +153 -0
- package/dist/platform/control-plane/routes/gateway-verb-error.d.ts +30 -0
- package/dist/platform/control-plane/routes/gateway-verb-error.d.ts.map +1 -0
- package/dist/platform/control-plane/routes/gateway-verb-error.js +36 -0
- package/dist/platform/control-plane/routes/index.d.ts +0 -6
- package/dist/platform/control-plane/routes/index.d.ts.map +1 -1
- package/dist/platform/control-plane/routes/index.js +5 -5
- package/dist/platform/control-plane/routes/invocation-params.d.ts +23 -0
- package/dist/platform/control-plane/routes/invocation-params.d.ts.map +1 -0
- package/dist/platform/control-plane/routes/invocation-params.js +9 -0
- package/dist/platform/control-plane/routes/register-w3-s2.d.ts +26 -0
- package/dist/platform/control-plane/routes/register-w3-s2.d.ts.map +1 -0
- package/dist/platform/control-plane/routes/register-w3-s2.js +8 -0
- package/dist/platform/control-plane/routes/session-search.d.ts +37 -0
- package/dist/platform/control-plane/routes/session-search.d.ts.map +1 -0
- package/dist/platform/control-plane/routes/session-search.js +113 -0
- package/dist/platform/control-plane/session-broker-gc.d.ts +16 -0
- package/dist/platform/control-plane/session-broker-gc.d.ts.map +1 -1
- package/dist/platform/control-plane/session-broker-gc.js +23 -6
- package/dist/platform/control-plane/session-broker-helpers.d.ts +3 -3
- package/dist/platform/control-plane/session-broker-helpers.d.ts.map +1 -1
- package/dist/platform/control-plane/session-broker-inputs.d.ts +18 -0
- package/dist/platform/control-plane/session-broker-inputs.d.ts.map +1 -1
- package/dist/platform/control-plane/session-broker-inputs.js +34 -0
- package/dist/platform/control-plane/session-broker-sessions.d.ts +102 -3
- package/dist/platform/control-plane/session-broker-sessions.d.ts.map +1 -1
- package/dist/platform/control-plane/session-broker-sessions.js +179 -5
- package/dist/platform/control-plane/session-broker-state.d.ts +20 -1
- package/dist/platform/control-plane/session-broker-state.d.ts.map +1 -1
- package/dist/platform/control-plane/session-broker-state.js +67 -5
- package/dist/platform/control-plane/session-broker.d.ts +51 -38
- package/dist/platform/control-plane/session-broker.d.ts.map +1 -1
- package/dist/platform/control-plane/session-broker.js +183 -75
- package/dist/platform/control-plane/session-store-importer.d.ts +57 -0
- package/dist/platform/control-plane/session-store-importer.d.ts.map +1 -0
- package/dist/platform/control-plane/session-store-importer.js +227 -0
- package/dist/platform/control-plane/session-types.d.ts +142 -7
- package/dist/platform/control-plane/session-types.d.ts.map +1 -1
- package/dist/platform/core/execution-plan.d.ts +43 -1
- package/dist/platform/core/execution-plan.d.ts.map +1 -1
- package/dist/platform/core/execution-plan.js +46 -10
- package/dist/platform/core/index.d.ts +1 -0
- package/dist/platform/core/index.d.ts.map +1 -1
- package/dist/platform/core/index.js +1 -0
- package/dist/platform/core/orchestrator-runtime.d.ts +21 -1
- package/dist/platform/core/orchestrator-runtime.d.ts.map +1 -1
- package/dist/platform/core/orchestrator-tool-runtime.d.ts +7 -0
- package/dist/platform/core/orchestrator-tool-runtime.d.ts.map +1 -1
- package/dist/platform/core/orchestrator-tool-runtime.js +10 -0
- package/dist/platform/core/orchestrator-turn-loop.d.ts +8 -1
- package/dist/platform/core/orchestrator-turn-loop.d.ts.map +1 -1
- package/dist/platform/core/orchestrator-turn-loop.js +6 -0
- package/dist/platform/core/orchestrator.d.ts +6 -0
- package/dist/platform/core/orchestrator.d.ts.map +1 -1
- package/dist/platform/core/orchestrator.js +15 -0
- package/dist/platform/core/plan-decomposition.d.ts +196 -0
- package/dist/platform/core/plan-decomposition.d.ts.map +1 -0
- package/dist/platform/core/plan-decomposition.js +417 -0
- package/dist/platform/core/plan-proposal.d.ts +39 -0
- package/dist/platform/core/plan-proposal.d.ts.map +1 -1
- package/dist/platform/core/wrfc-routing.d.ts +1 -0
- package/dist/platform/core/wrfc-routing.d.ts.map +1 -1
- package/dist/platform/core/wrfc-routing.js +51 -1
- package/dist/platform/daemon/boot.d.ts +63 -0
- package/dist/platform/daemon/boot.d.ts.map +1 -0
- package/dist/platform/daemon/boot.js +60 -0
- package/dist/platform/daemon/cli.js +2 -1
- package/dist/platform/daemon/control-plane.d.ts.map +1 -1
- package/dist/platform/daemon/control-plane.js +50 -1
- package/dist/platform/daemon/facade-composition.d.ts.map +1 -1
- package/dist/platform/daemon/facade-composition.js +6 -0
- package/dist/platform/daemon/facade.d.ts +18 -6
- package/dist/platform/daemon/facade.d.ts.map +1 -1
- package/dist/platform/daemon/facade.js +50 -43
- package/dist/platform/daemon/http/router-route-contexts.d.ts +1 -0
- package/dist/platform/daemon/http/router-route-contexts.d.ts.map +1 -1
- package/dist/platform/daemon/http/router-route-contexts.js +1 -0
- package/dist/platform/daemon/http/router-session-broker-adapter.d.ts +13 -0
- package/dist/platform/daemon/http/router-session-broker-adapter.d.ts.map +1 -0
- package/dist/platform/daemon/http/router-session-broker-adapter.js +27 -0
- package/dist/platform/daemon/http/router.d.ts +1 -1
- package/dist/platform/daemon/http/router.d.ts.map +1 -1
- package/dist/platform/daemon/http/router.js +7 -22
- package/dist/platform/daemon/http/runtime-route-types.d.ts +42 -4
- package/dist/platform/daemon/http/runtime-route-types.d.ts.map +1 -1
- package/dist/platform/daemon/index.d.ts +2 -0
- package/dist/platform/daemon/index.d.ts.map +1 -1
- package/dist/platform/daemon/index.js +1 -0
- package/dist/platform/daemon/service-manager.d.ts +16 -0
- package/dist/platform/daemon/service-manager.d.ts.map +1 -1
- package/dist/platform/daemon/service-manager.js +79 -15
- package/dist/platform/intelligence/tree-sitter/service.d.ts.map +1 -1
- package/dist/platform/intelligence/tree-sitter/service.js +16 -2
- package/dist/platform/knowledge/browser-history/readers.d.ts.map +1 -1
- package/dist/platform/knowledge/browser-history/readers.js +15 -5
- package/dist/platform/knowledge/project-planning/service.d.ts +14 -1
- package/dist/platform/knowledge/project-planning/service.d.ts.map +1 -1
- package/dist/platform/knowledge/project-planning/service.js +77 -0
- package/dist/platform/knowledge/project-planning/types.d.ts +32 -0
- package/dist/platform/knowledge/project-planning/types.d.ts.map +1 -1
- package/dist/platform/orchestration/bookkeeping.d.ts +12 -0
- package/dist/platform/orchestration/bookkeeping.d.ts.map +1 -0
- package/dist/platform/orchestration/bookkeeping.js +91 -0
- package/dist/platform/orchestration/controller-compat.d.ts +14 -0
- package/dist/platform/orchestration/controller-compat.d.ts.map +1 -1
- package/dist/platform/orchestration/controller-compat.js +18 -4
- package/dist/platform/orchestration/engine.d.ts +26 -1
- package/dist/platform/orchestration/engine.d.ts.map +1 -1
- package/dist/platform/orchestration/engine.js +226 -21
- package/dist/platform/orchestration/index.d.ts +6 -4
- package/dist/platform/orchestration/index.d.ts.map +1 -1
- package/dist/platform/orchestration/index.js +3 -2
- package/dist/platform/orchestration/persistence.d.ts.map +1 -1
- package/dist/platform/orchestration/persistence.js +4 -1
- package/dist/platform/orchestration/phase-runner.d.ts +29 -2
- package/dist/platform/orchestration/phase-runner.d.ts.map +1 -1
- package/dist/platform/orchestration/phase-runner.js +98 -25
- package/dist/platform/orchestration/proposal-workstream.d.ts +56 -0
- package/dist/platform/orchestration/proposal-workstream.d.ts.map +1 -0
- package/dist/platform/orchestration/proposal-workstream.js +76 -0
- package/dist/platform/orchestration/scheduler.d.ts +19 -0
- package/dist/platform/orchestration/scheduler.d.ts.map +1 -1
- package/dist/platform/orchestration/scheduler.js +16 -0
- package/dist/platform/orchestration/types.d.ts +286 -1
- package/dist/platform/orchestration/types.d.ts.map +1 -1
- package/dist/platform/orchestration/types.js +32 -0
- package/dist/platform/orchestration/worktree-isolation.d.ts +33 -0
- package/dist/platform/orchestration/worktree-isolation.d.ts.map +1 -0
- package/dist/platform/orchestration/worktree-isolation.js +248 -0
- package/dist/platform/presentation/glyphs.d.ts +91 -0
- package/dist/platform/presentation/glyphs.d.ts.map +1 -0
- package/dist/platform/presentation/glyphs.js +93 -0
- package/dist/platform/presentation/index.d.ts +28 -0
- package/dist/platform/presentation/index.d.ts.map +1 -0
- package/dist/platform/presentation/index.js +27 -0
- package/dist/platform/presentation/thinking-phrases.d.ts +12 -0
- package/dist/platform/presentation/thinking-phrases.d.ts.map +1 -0
- package/dist/platform/presentation/thinking-phrases.js +32 -0
- package/dist/platform/presentation/tones.d.ts +121 -0
- package/dist/platform/presentation/tones.d.ts.map +1 -0
- package/dist/platform/presentation/tones.js +145 -0
- package/dist/platform/presentation/waiting-wording.d.ts +54 -0
- package/dist/platform/presentation/waiting-wording.d.ts.map +1 -0
- package/dist/platform/presentation/waiting-wording.js +51 -0
- package/dist/platform/providers/runtime-snapshot.d.ts.map +1 -1
- package/dist/platform/providers/runtime-snapshot.js +12 -2
- package/dist/platform/runtime/bootstrap-services.d.ts +62 -2
- package/dist/platform/runtime/bootstrap-services.d.ts.map +1 -1
- package/dist/platform/runtime/bootstrap-services.js +217 -50
- package/dist/platform/runtime/daemon-version-compat.d.ts +39 -0
- package/dist/platform/runtime/daemon-version-compat.d.ts.map +1 -0
- package/dist/platform/runtime/daemon-version-compat.js +75 -0
- package/dist/platform/runtime/detached-daemon-runtime.d.ts +26 -0
- package/dist/platform/runtime/detached-daemon-runtime.d.ts.map +1 -0
- package/dist/platform/runtime/detached-daemon-runtime.js +49 -0
- package/dist/platform/runtime/emitters/workflows.d.ts +1 -1
- package/dist/platform/runtime/emitters/workflows.d.ts.map +1 -1
- package/dist/platform/runtime/events/index.d.ts +13 -0
- package/dist/platform/runtime/events/index.d.ts.map +1 -1
- package/dist/platform/runtime/events/index.js +13 -0
- package/dist/platform/runtime/feature-flags/flags.d.ts.map +1 -1
- package/dist/platform/runtime/feature-flags/flags.js +39 -1
- package/dist/platform/runtime/fleet/adapters/orchestration.d.ts +40 -18
- package/dist/platform/runtime/fleet/adapters/orchestration.d.ts.map +1 -1
- package/dist/platform/runtime/fleet/adapters/orchestration.js +138 -34
- package/dist/platform/runtime/fleet/adapters/wrfc.d.ts +13 -0
- package/dist/platform/runtime/fleet/adapters/wrfc.d.ts.map +1 -1
- package/dist/platform/runtime/fleet/adapters/wrfc.js +48 -1
- package/dist/platform/runtime/fleet/registry.d.ts.map +1 -1
- package/dist/platform/runtime/fleet/registry.js +38 -4
- package/dist/platform/runtime/operator-client.d.ts +20 -2
- package/dist/platform/runtime/operator-client.d.ts.map +1 -1
- package/dist/platform/runtime/operator-client.js +11 -1
- package/dist/platform/runtime/provider-accounts/registry.d.ts.map +1 -1
- package/dist/platform/runtime/provider-accounts/registry.js +11 -1
- package/dist/platform/runtime/services.d.ts +9 -7
- package/dist/platform/runtime/services.d.ts.map +1 -1
- package/dist/platform/runtime/services.js +19 -4
- package/dist/platform/runtime/session-spine/client.d.ts +234 -0
- package/dist/platform/runtime/session-spine/client.d.ts.map +1 -0
- package/dist/platform/runtime/session-spine/client.js +449 -0
- package/dist/platform/runtime/session-spine/index.d.ts +12 -0
- package/dist/platform/runtime/session-spine/index.d.ts.map +1 -0
- package/dist/platform/runtime/session-spine/index.js +11 -0
- package/dist/platform/runtime/session-spine/union-cache.d.ts +225 -0
- package/dist/platform/runtime/session-spine/union-cache.d.ts.map +1 -0
- package/dist/platform/runtime/session-spine/union-cache.js +333 -0
- package/dist/platform/runtime/shell-command-ops.d.ts +3 -1
- package/dist/platform/runtime/shell-command-ops.d.ts.map +1 -1
- package/dist/platform/runtime/transports/daemon-http-client-validators.d.ts.map +1 -1
- package/dist/platform/runtime/transports/daemon-http-client-validators.js +22 -0
- package/dist/platform/runtime/transports/daemon-http-client.d.ts.map +1 -1
- package/dist/platform/runtime/transports/daemon-http-client.js +25 -2
- package/dist/platform/runtime/transports/http-types.d.ts +9 -2
- package/dist/platform/runtime/transports/http-types.d.ts.map +1 -1
- package/dist/platform/state/canonical-memory.d.ts +95 -0
- package/dist/platform/state/canonical-memory.d.ts.map +1 -0
- package/dist/platform/state/canonical-memory.js +155 -0
- package/dist/platform/state/code-index-reindex.d.ts +73 -0
- package/dist/platform/state/code-index-reindex.d.ts.map +1 -0
- package/dist/platform/state/code-index-reindex.js +156 -0
- package/dist/platform/state/code-index-store.d.ts.map +1 -1
- package/dist/platform/state/code-index-store.js +10 -2
- package/dist/platform/state/index.d.ts +8 -0
- package/dist/platform/state/index.d.ts.map +1 -1
- package/dist/platform/state/index.js +4 -0
- package/dist/platform/state/memory-recall-contract.d.ts +63 -0
- package/dist/platform/state/memory-recall-contract.d.ts.map +1 -0
- package/dist/platform/state/memory-recall-contract.js +94 -0
- package/dist/platform/state/memory-store.d.ts +2 -0
- package/dist/platform/state/memory-store.d.ts.map +1 -1
- package/dist/platform/state/memory-store.js +4 -0
- package/dist/platform/state/memory-vector-store.d.ts.map +1 -1
- package/dist/platform/state/memory-vector-store.js +13 -2
- package/dist/platform/state/sqlite-store.d.ts +2 -0
- package/dist/platform/state/sqlite-store.d.ts.map +1 -1
- package/dist/platform/state/sqlite-store.js +4 -0
- package/dist/platform/state/vibe-projection.d.ts +67 -0
- package/dist/platform/state/vibe-projection.d.ts.map +1 -0
- package/dist/platform/state/vibe-projection.js +115 -0
- package/dist/platform/tools/agent/index.d.ts.map +1 -1
- package/dist/platform/tools/agent/index.js +8 -0
- package/dist/platform/tools/agent/manager.d.ts +12 -0
- package/dist/platform/tools/agent/manager.d.ts.map +1 -1
- package/dist/platform/tools/agent/manager.js +6 -0
- package/dist/platform/tools/agent/schema.d.ts +26 -0
- package/dist/platform/tools/agent/schema.d.ts.map +1 -1
- package/dist/platform/tools/agent/schema.js +2 -2
- package/dist/platform/tools/agent/wrfc-batch-policy.d.ts +13 -0
- package/dist/platform/tools/agent/wrfc-batch-policy.d.ts.map +1 -1
- package/dist/platform/tools/agent/wrfc-batch-policy.js +60 -0
- package/dist/platform/tools/exec/runtime.d.ts +10 -0
- package/dist/platform/tools/exec/runtime.d.ts.map +1 -1
- package/dist/platform/tools/exec/runtime.js +22 -5
- package/dist/platform/tools/exec/schema.d.ts +1 -1
- package/dist/platform/tools/exec/schema.d.ts.map +1 -1
- package/dist/platform/tools/exec/schema.js +2 -1
- package/dist/platform/tools/index.d.ts +2 -0
- package/dist/platform/tools/index.d.ts.map +1 -1
- package/dist/platform/tools/index.js +2 -0
- package/dist/platform/tools/state/index.d.ts +9 -0
- package/dist/platform/tools/state/index.d.ts.map +1 -1
- package/dist/platform/tools/state/index.js +60 -3
- package/dist/platform/types/foundation-contract.d.ts +1 -1
- package/dist/platform/types/foundation-contract.d.ts.map +1 -1
- package/dist/platform/types/index.d.ts +1 -1
- package/dist/platform/types/index.d.ts.map +1 -1
- package/dist/platform/version.js +1 -1
- package/package.json +21 -9
- package/dist/platform/control-plane/routes/automation.d.ts +0 -3
- package/dist/platform/control-plane/routes/automation.d.ts.map +0 -1
- package/dist/platform/control-plane/routes/automation.js +0 -63
- package/dist/platform/control-plane/routes/context.d.ts +0 -2
- package/dist/platform/control-plane/routes/context.d.ts.map +0 -1
- package/dist/platform/control-plane/routes/context.js +0 -1
- package/dist/platform/control-plane/routes/operator.d.ts +0 -8
- package/dist/platform/control-plane/routes/operator.d.ts.map +0 -1
- package/dist/platform/control-plane/routes/operator.js +0 -415
- package/dist/platform/control-plane/routes/remote.d.ts +0 -3
- package/dist/platform/control-plane/routes/remote.d.ts.map +0 -1
- package/dist/platform/control-plane/routes/remote.js +0 -35
- package/dist/platform/control-plane/routes/sessions.d.ts +0 -3
- package/dist/platform/control-plane/routes/sessions.d.ts.map +0 -1
- package/dist/platform/control-plane/routes/sessions.js +0 -43
- package/dist/platform/control-plane/routes/tasks.d.ts +0 -3
- package/dist/platform/control-plane/routes/tasks.d.ts.map +0 -1
- package/dist/platform/control-plane/routes/tasks.js +0 -22
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SurfaceKind } from '../../events/surfaces.js';
|
|
2
2
|
import type { SharedSessionMessage, SharedSessionRecord } from './session-types.js';
|
|
3
3
|
import type { SharedSessionInputRecord } from './session-intents.js';
|
|
4
4
|
export interface SharedSessionStoreSnapshot extends Record<string, unknown> {
|
|
@@ -20,6 +20,6 @@ export type SharedSessionMessageSender = {
|
|
|
20
20
|
};
|
|
21
21
|
export type SharedSessionEventPublisher = (event: string, payload: unknown) => void;
|
|
22
22
|
export declare function dedupeSessionSurfaceKinds(participants: readonly {
|
|
23
|
-
readonly surfaceKind:
|
|
24
|
-
}[]):
|
|
23
|
+
readonly surfaceKind: SurfaceKind;
|
|
24
|
+
}[]): SurfaceKind[];
|
|
25
25
|
//# sourceMappingURL=session-broker-helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-broker-helpers.d.ts","sourceRoot":"","sources":["../../../src/platform/control-plane/session-broker-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"session-broker-helpers.d.ts","sourceRoot":"","sources":["../../../src/platform/control-plane/session-broker-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAErE,MAAM,WAAW,0BAA2B,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACzE,QAAQ,CAAC,QAAQ,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAClD,QAAQ,CAAC,QAAQ,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACnD,QAAQ,CAAC,MAAM,EAAE,SAAS,wBAAwB,EAAE,CAAC;CACtD;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;CAC/E,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG;IAC7C,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,wBAAwB,GAAG,IAAI,GAAG,SAAS,CAAC;CACzE,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC;CAChG,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;AAEpF,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,SAAS;IAAE,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;CAAE,EAAE,GAC7D,WAAW,EAAE,CAEf"}
|
|
@@ -17,5 +17,23 @@ export declare function recordSharedSessionInput(store: SharedSessionInputStore,
|
|
|
17
17
|
}): SharedSessionInputRecord;
|
|
18
18
|
export declare function updateSharedSessionInput(store: SharedSessionInputStore, sessionId: string, inputId: string, transform: (input: SharedSessionInputRecord) => SharedSessionInputRecord): SharedSessionInputRecord | null;
|
|
19
19
|
export declare function claimNextQueuedSessionInput(store: SharedSessionInputStore, sessionId: string, agentId: string): SharedSessionInputRecord | null;
|
|
20
|
+
/**
|
|
21
|
+
* Collection read for a live surface: filter a session's inputs by state and/or a
|
|
22
|
+
* `since` cursor (createdAt, exclusive), oldest-first, capped to `limit`. With
|
|
23
|
+
* `state: 'queued'` + the last-seen cursor this yields exactly the PENDING inputs
|
|
24
|
+
* a surface has not collected yet (see SharedSessionBroker.getInputsSince).
|
|
25
|
+
*/
|
|
26
|
+
export declare function filterSessionInputsSince(bucket: readonly SharedSessionInputRecord[], options: {
|
|
27
|
+
readonly state?: SharedSessionInputRecord['state'] | undefined;
|
|
28
|
+
readonly since?: number | undefined;
|
|
29
|
+
readonly limit?: number | undefined;
|
|
30
|
+
}): SharedSessionInputRecord[];
|
|
31
|
+
/**
|
|
32
|
+
* Surface delivery marking: advance a queued/delivered input as a live surface
|
|
33
|
+
* collects it (`consumed:false` → 'delivered') or finishes acting on it
|
|
34
|
+
* (`consumed:true` → 'completed'). Only queued/delivered inputs advance; anything
|
|
35
|
+
* else is returned unchanged. Returns null when the input is unknown.
|
|
36
|
+
*/
|
|
37
|
+
export declare function markSurfaceInputDelivered(store: SharedSessionInputStore, sessionId: string, inputId: string, consumed: boolean): SharedSessionInputRecord | null;
|
|
20
38
|
export declare function finalizeAgentSessionInputs(store: SharedSessionInputStore, sessionId: string, agentId: string, nextState: Extract<SharedSessionInputRecord['state'], 'completed' | 'failed' | 'cancelled'>, error?: string): SharedSessionInputRecord[];
|
|
21
39
|
//# sourceMappingURL=session-broker-inputs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-broker-inputs.d.ts","sourceRoot":"","sources":["../../../src/platform/control-plane/session-broker-inputs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,KAAK,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAC/F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG9D,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IACpD,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,wBAAwB,EAAE,CAAC,CAAC;CAC1D;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAK1F;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,uBAAuB,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAShG;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,uBAAuB,EAC9B,KAAK,EAAE;IACL,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,+BAA+B,CAAC;IAClD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC,GACA,wBAAwB,CAkC1B;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,uBAAuB,EAC9B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,wBAAwB,GACvE,wBAAwB,GAAG,IAAI,CAWjC;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,uBAAuB,EAC9B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,wBAAwB,GAAG,IAAI,CAYjC;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,uBAAuB,EAC9B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,OAAO,CAAC,wBAAwB,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC,EAC3F,KAAK,CAAC,EAAE,MAAM,GACb,wBAAwB,EAAE,CAwB5B"}
|
|
1
|
+
{"version":3,"file":"session-broker-inputs.d.ts","sourceRoot":"","sources":["../../../src/platform/control-plane/session-broker-inputs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,KAAK,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAC/F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG9D,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IACpD,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,wBAAwB,EAAE,CAAC,CAAC;CAC1D;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAK1F;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,uBAAuB,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAShG;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,uBAAuB,EAC9B,KAAK,EAAE;IACL,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,+BAA+B,CAAC;IAClD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC,GACA,wBAAwB,CAkC1B;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,uBAAuB,EAC9B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,wBAAwB,GACvE,wBAAwB,GAAG,IAAI,CAWjC;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,uBAAuB,EAC9B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,wBAAwB,GAAG,IAAI,CAYjC;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,SAAS,wBAAwB,EAAE,EAC3C,OAAO,EAAE;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,wBAAwB,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACpJ,wBAAwB,EAAE,CAO5B;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,uBAAuB,EAC9B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,OAAO,GAChB,wBAAwB,GAAG,IAAI,CASjC;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,uBAAuB,EAC9B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,OAAO,CAAC,wBAAwB,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC,EAC3F,KAAK,CAAC,EAAE,MAAM,GACb,wBAAwB,EAAE,CAwB5B"}
|
|
@@ -81,6 +81,40 @@ export function claimNextQueuedSessionInput(store, sessionId, agentId) {
|
|
|
81
81
|
touchSharedSession(store, sessionId);
|
|
82
82
|
return result;
|
|
83
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Collection read for a live surface: filter a session's inputs by state and/or a
|
|
86
|
+
* `since` cursor (createdAt, exclusive), oldest-first, capped to `limit`. With
|
|
87
|
+
* `state: 'queued'` + the last-seen cursor this yields exactly the PENDING inputs
|
|
88
|
+
* a surface has not collected yet (see SharedSessionBroker.getInputsSince).
|
|
89
|
+
*/
|
|
90
|
+
export function filterSessionInputsSince(bucket, options) {
|
|
91
|
+
const filtered = bucket.filter((entry) => {
|
|
92
|
+
if (options.state !== undefined && entry.state !== options.state)
|
|
93
|
+
return false;
|
|
94
|
+
if (options.since !== undefined && entry.createdAt <= options.since)
|
|
95
|
+
return false;
|
|
96
|
+
return true;
|
|
97
|
+
});
|
|
98
|
+
return filtered.slice(-Math.max(1, options.limit ?? 100));
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Surface delivery marking: advance a queued/delivered input as a live surface
|
|
102
|
+
* collects it (`consumed:false` → 'delivered') or finishes acting on it
|
|
103
|
+
* (`consumed:true` → 'completed'). Only queued/delivered inputs advance; anything
|
|
104
|
+
* else is returned unchanged. Returns null when the input is unknown.
|
|
105
|
+
*/
|
|
106
|
+
export function markSurfaceInputDelivered(store, sessionId, inputId, consumed) {
|
|
107
|
+
return updateSharedSessionInput(store, sessionId, inputId, (entry) => {
|
|
108
|
+
if (consumed) {
|
|
109
|
+
if (entry.state !== 'queued' && entry.state !== 'delivered')
|
|
110
|
+
return entry;
|
|
111
|
+
return { ...entry, state: 'completed', updatedAt: Date.now() };
|
|
112
|
+
}
|
|
113
|
+
if (entry.state !== 'queued')
|
|
114
|
+
return entry;
|
|
115
|
+
return { ...entry, state: 'delivered', updatedAt: Date.now() };
|
|
116
|
+
});
|
|
117
|
+
}
|
|
84
118
|
export function finalizeAgentSessionInputs(store, sessionId, agentId, nextState, error) {
|
|
85
119
|
const bucket = store.inputs.get(sessionId);
|
|
86
120
|
if (!bucket)
|
|
@@ -1,6 +1,47 @@
|
|
|
1
1
|
import type { AutomationRouteBinding } from '../automation/routes.js';
|
|
2
|
-
import type { SharedSessionParticipant, SharedSessionRecord,
|
|
2
|
+
import type { CreateSharedSessionInput, ParticipantRouteAttachInput, RegisterSharedSessionInput, SharedSessionCloseReason, SharedSessionParticipant, SharedSessionRecord, SharedSessionRegisterResult } from './session-types.js';
|
|
3
3
|
export declare const RESERVED_SHARED_SESSION_IDS: Set<string>;
|
|
4
|
+
/**
|
|
5
|
+
* Metadata key under which a closed session records WHY it was closed. Kept in
|
|
6
|
+
* `metadata` (not a first-class field) so it rides the wire without a schema
|
|
7
|
+
* change and 0.38 readers ignore it. See {@link SharedSessionCloseReason}.
|
|
8
|
+
*/
|
|
9
|
+
export declare const SESSION_CLOSE_REASON_METADATA_KEY = "closeReason";
|
|
10
|
+
/** Read the close reason off a record's metadata, or undefined when unset/unknown. */
|
|
11
|
+
export declare function readSessionCloseReason(session: SharedSessionRecord): SharedSessionCloseReason | undefined;
|
|
12
|
+
/** Stamp a close reason onto a metadata bag (returns a new object). */
|
|
13
|
+
export declare function withSessionCloseReason(metadata: Record<string, unknown>, reason: SharedSessionCloseReason): Record<string, unknown>;
|
|
14
|
+
/** Strip any close reason from a metadata bag (returns a new object only if needed). */
|
|
15
|
+
export declare function withoutSessionCloseReason(metadata: Record<string, unknown>): Record<string, unknown>;
|
|
16
|
+
/**
|
|
17
|
+
* Metadata flag marking a session as SURFACE-MANAGED: a spine-registered surface
|
|
18
|
+
* (via `sessions.register`) owns turn execution and input collection for it. Set
|
|
19
|
+
* on every register/heartbeat. Steer/follow-up inputs to such a session (when no
|
|
20
|
+
* daemon agent is live) route to the surface as a queued input the surface
|
|
21
|
+
* collects — NOT a daemon executor spawn. Kept in metadata (open record) so it
|
|
22
|
+
* needs no schema change. Daemon-run origins (companion-task/automation, or a
|
|
23
|
+
* plain /task session) never call register and stay executor-routed.
|
|
24
|
+
*/
|
|
25
|
+
export declare const SESSION_SURFACE_MANAGED_METADATA_KEY = "surfaceManaged";
|
|
26
|
+
/** How recently a participant must have been seen to count as a LIVE surface for
|
|
27
|
+
* steer/follow-up routing. A surface heartbeats via `sessions.register`; if the
|
|
28
|
+
* newest heartbeat is older than this, the surface is treated as gone and inputs
|
|
29
|
+
* fall back to the daemon executor path. */
|
|
30
|
+
export declare const SURFACE_ROUTE_FRESHNESS_MS: number;
|
|
31
|
+
export declare function isSurfaceManagedSession(session: SharedSessionRecord): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* True when a participant OTHER than `exclude` (the current input's own surface)
|
|
34
|
+
* was seen within `freshnessMs`. Excluding the sender prevents a steer's own
|
|
35
|
+
* just-attached participant from making a surfaceless session look live.
|
|
36
|
+
*/
|
|
37
|
+
export declare function hasFreshSurfaceParticipant(session: SharedSessionRecord, now: number, freshnessMs: number, exclude?: {
|
|
38
|
+
readonly surfaceId?: string | undefined;
|
|
39
|
+
}): boolean;
|
|
40
|
+
/** Steer/follow-up to this session should route to a live surface (queue-for-surface)
|
|
41
|
+
* rather than spawn a daemon executor. */
|
|
42
|
+
export declare function shouldRouteInputToSurface(session: SharedSessionRecord, now: number, freshnessMs: number, exclude?: {
|
|
43
|
+
readonly surfaceId?: string | undefined;
|
|
44
|
+
}): boolean;
|
|
4
45
|
export interface CreateSharedSessionRecordInput {
|
|
5
46
|
readonly id?: string | undefined;
|
|
6
47
|
readonly title?: string | undefined;
|
|
@@ -8,15 +49,73 @@ export interface CreateSharedSessionRecordInput {
|
|
|
8
49
|
readonly routeBinding?: AutomationRouteBinding | undefined;
|
|
9
50
|
readonly participant?: SharedSessionParticipant | undefined;
|
|
10
51
|
readonly kind?: SharedSessionRecord['kind'] | undefined;
|
|
52
|
+
readonly project?: string | undefined;
|
|
11
53
|
}
|
|
12
54
|
export declare function assertSharedSessionIdAllowed(id: string | undefined): void;
|
|
13
55
|
export declare function createSharedSessionRecord(input: CreateSharedSessionRecordInput): SharedSessionRecord;
|
|
14
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Shape a participant triple into the attach-input the broker's
|
|
58
|
+
* participant/route merge expects. Used by `register` so a heartbeat re-attaches
|
|
59
|
+
* the participant (advancing `lastSeenAt`) without carrying a message body.
|
|
60
|
+
*/
|
|
61
|
+
/** The broker operations {@link registerSharedSession} needs, injected so the
|
|
62
|
+
* register control-flow lives here instead of bloating the broker class. */
|
|
63
|
+
export interface RegisterBrokerOps {
|
|
64
|
+
getSession(id: string): SharedSessionRecord | null;
|
|
65
|
+
createSession(input: CreateSharedSessionInput): Promise<SharedSessionRecord>;
|
|
66
|
+
reopenSession(id: string): Promise<SharedSessionRecord | null>;
|
|
67
|
+
attachParticipant(session: SharedSessionRecord, attach: ParticipantRouteAttachInput): Promise<SharedSessionRecord>;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The idempotent register/heartbeat control-flow with HONEST closed semantics:
|
|
71
|
+
* a brand-new id is created; an existing OPEN id adopts the participant; an
|
|
72
|
+
* existing CLOSED id records the heartbeat but stays closed (returning a conflict
|
|
73
|
+
* marker) UNLESS `reopen: true` is passed. A titled session is never renamed by
|
|
74
|
+
* the heartbeat (that rule lives in {@link attachSharedSessionParticipantAndRoute}).
|
|
75
|
+
*/
|
|
76
|
+
export declare function registerSharedSession(ops: RegisterBrokerOps, input: RegisterSharedSessionInput): Promise<SharedSessionRegisterResult>;
|
|
77
|
+
export declare function participantToAttachInput(participant: SharedSessionParticipant, title?: string): ParticipantRouteAttachInput;
|
|
78
|
+
/** Close a session, recording WHY. Defaults to 'user' — the explicit close verb
|
|
79
|
+
* (daemon `sessions.close`) is a deliberate user/surface action, which does NOT
|
|
80
|
+
* auto-reopen on heartbeat. The reaper passes 'idle-reaped'. */
|
|
81
|
+
export declare function closeSharedSessionRecord(session: SharedSessionRecord, reason?: SharedSessionCloseReason): SharedSessionRecord;
|
|
15
82
|
export declare function reopenSharedSessionRecord(session: SharedSessionRecord): SharedSessionRecord;
|
|
16
83
|
export declare function bindSharedSessionAgent(session: SharedSessionRecord, agentId: string): SharedSessionRecord;
|
|
84
|
+
/**
|
|
85
|
+
* True when a session title is still the auto-generated placeholder (empty or
|
|
86
|
+
* `Session <id>`) and can be named by an incoming register/attach. A real,
|
|
87
|
+
* user-supplied title is never overwritten by this path.
|
|
88
|
+
*/
|
|
89
|
+
export declare function isPlaceholderSessionTitle(title: string, id: string): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Merge a participant + optional route onto a session. This is the HEARTBEAT
|
|
92
|
+
* path — it records the participant and advances lastSeenAt, but it must NOT by
|
|
93
|
+
* itself change lifecycle status (a closed session stays closed; reopening is an
|
|
94
|
+
* explicit verb) and must NOT overwrite a real title (only names a placeholder).
|
|
95
|
+
*/
|
|
17
96
|
export declare function attachSharedSessionParticipantAndRoute(input: {
|
|
18
97
|
readonly session: SharedSessionRecord;
|
|
19
|
-
readonly message:
|
|
98
|
+
readonly message: ParticipantRouteAttachInput;
|
|
20
99
|
readonly binding?: AutomationRouteBinding | undefined;
|
|
21
100
|
}): SharedSessionRecord;
|
|
101
|
+
/**
|
|
102
|
+
* The inverse of {@link attachSharedSessionParticipantAndRoute}: remove EVERY
|
|
103
|
+
* participant bound to `surfaceId` and unbind the route bindings those
|
|
104
|
+
* participants alone held. This is "detach != close != kill" — the session and
|
|
105
|
+
* all other participants keep running; the detached surface simply stops being a
|
|
106
|
+
* routing target (and, filtered by domain, stops receiving session updates).
|
|
107
|
+
*
|
|
108
|
+
* Route pruning is conservative: a routeId is dropped from the session only when
|
|
109
|
+
* NO surviving participant still references it, so detaching one surface never
|
|
110
|
+
* severs another surface's live binding.
|
|
111
|
+
*
|
|
112
|
+
* Returns `{ session, changed }`. `changed` is false when no participant matched
|
|
113
|
+
* `surfaceId` (the caller can treat a no-match detach as an idempotent no-op and
|
|
114
|
+
* skip persistence/emit). Status, title, and closedAt are preserved untouched —
|
|
115
|
+
* detach is never a lifecycle transition.
|
|
116
|
+
*/
|
|
117
|
+
export declare function detachSharedSessionParticipant(session: SharedSessionRecord, surfaceId: string): {
|
|
118
|
+
readonly session: SharedSessionRecord;
|
|
119
|
+
readonly changed: boolean;
|
|
120
|
+
};
|
|
22
121
|
//# sourceMappingURL=session-broker-sessions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-broker-sessions.d.ts","sourceRoot":"","sources":["../../../src/platform/control-plane/session-broker-sessions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,KAAK,EACV,wBAAwB,EACxB,mBAAmB,EACnB
|
|
1
|
+
{"version":3,"file":"session-broker-sessions.d.ts","sourceRoot":"","sources":["../../../src/platform/control-plane/session-broker-sessions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,KAAK,EACV,wBAAwB,EACxB,2BAA2B,EAC3B,0BAA0B,EAC1B,wBAAwB,EACxB,wBAAwB,EACxB,mBAAmB,EACnB,2BAA2B,EAC5B,MAAM,oBAAoB,CAAC;AAI5B,eAAO,MAAM,2BAA2B,aAA0B,CAAC;AAEnE;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,gBAAgB,CAAC;AAE/D,sFAAsF;AACtF,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,mBAAmB,GAAG,wBAAwB,GAAG,SAAS,CAGzG;AAED,uEAAuE;AACvE,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,MAAM,EAAE,wBAAwB,GAC/B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzB;AAED,wFAAwF;AACxF,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKpG;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,oCAAoC,mBAAmB,CAAC;AAErE;;;4CAG4C;AAC5C,eAAO,MAAM,0BAA0B,QAAgB,CAAC;AAExD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAE7E;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,mBAAmB,EAC5B,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACpD,OAAO,CAKT;AAED;0CAC0C;AAC1C,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,mBAAmB,EAC5B,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACpD,OAAO,CAET;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACxD,QAAQ,CAAC,YAAY,CAAC,EAAE,sBAAsB,GAAG,SAAS,CAAC;IAC3D,QAAQ,CAAC,WAAW,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;IAC5D,QAAQ,CAAC,IAAI,CAAC,EAAE,mBAAmB,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACxD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAMzE;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,8BAA8B,GAAG,mBAAmB,CA8BpG;AAED;;;;GAIG;AACH;4EAC4E;AAC5E,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAAC;IACnD,aAAa,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC7E,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IAC/D,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,2BAA2B,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACpH;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,iBAAiB,EACtB,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC,2BAA2B,CAAC,CA0BtC;AAED,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,wBAAwB,EACrC,KAAK,CAAC,EAAE,MAAM,GACb,2BAA2B,CAW7B;AAED;;gEAEgE;AAChE,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,mBAAmB,EAC5B,MAAM,GAAE,wBAAiC,GACxC,mBAAmB,CAUrB;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,mBAAmB,GAAG,mBAAmB,CAU3F;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,GAAG,mBAAmB,CASzG;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAG5E;AAED;;;;;GAKG;AACH,wBAAgB,sCAAsC,CAAC,KAAK,EAAE;IAC5D,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,2BAA2B,CAAC;IAC9C,QAAQ,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,SAAS,CAAC;CACvD,GAAG,mBAAmB,CAqCtB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,mBAAmB,EAC5B,SAAS,EAAE,MAAM,GAChB;IAAE,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAqBtE"}
|
|
@@ -2,6 +2,64 @@ import { randomUUID } from 'node:crypto';
|
|
|
2
2
|
import { dedupeSessionSurfaceKinds } from './session-broker-helpers.js';
|
|
3
3
|
import { upsertSessionParticipant } from './session-broker-state.js';
|
|
4
4
|
export const RESERVED_SHARED_SESSION_IDS = new Set(['', 'system']);
|
|
5
|
+
/**
|
|
6
|
+
* Metadata key under which a closed session records WHY it was closed. Kept in
|
|
7
|
+
* `metadata` (not a first-class field) so it rides the wire without a schema
|
|
8
|
+
* change and 0.38 readers ignore it. See {@link SharedSessionCloseReason}.
|
|
9
|
+
*/
|
|
10
|
+
export const SESSION_CLOSE_REASON_METADATA_KEY = 'closeReason';
|
|
11
|
+
/** Read the close reason off a record's metadata, or undefined when unset/unknown. */
|
|
12
|
+
export function readSessionCloseReason(session) {
|
|
13
|
+
const raw = session.metadata?.[SESSION_CLOSE_REASON_METADATA_KEY];
|
|
14
|
+
return raw === 'idle-reaped' || raw === 'user' || raw === 'surface' ? raw : undefined;
|
|
15
|
+
}
|
|
16
|
+
/** Stamp a close reason onto a metadata bag (returns a new object). */
|
|
17
|
+
export function withSessionCloseReason(metadata, reason) {
|
|
18
|
+
return { ...metadata, [SESSION_CLOSE_REASON_METADATA_KEY]: reason };
|
|
19
|
+
}
|
|
20
|
+
/** Strip any close reason from a metadata bag (returns a new object only if needed). */
|
|
21
|
+
export function withoutSessionCloseReason(metadata) {
|
|
22
|
+
if (!(SESSION_CLOSE_REASON_METADATA_KEY in metadata))
|
|
23
|
+
return metadata;
|
|
24
|
+
const next = { ...metadata };
|
|
25
|
+
delete next[SESSION_CLOSE_REASON_METADATA_KEY];
|
|
26
|
+
return next;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Metadata flag marking a session as SURFACE-MANAGED: a spine-registered surface
|
|
30
|
+
* (via `sessions.register`) owns turn execution and input collection for it. Set
|
|
31
|
+
* on every register/heartbeat. Steer/follow-up inputs to such a session (when no
|
|
32
|
+
* daemon agent is live) route to the surface as a queued input the surface
|
|
33
|
+
* collects — NOT a daemon executor spawn. Kept in metadata (open record) so it
|
|
34
|
+
* needs no schema change. Daemon-run origins (companion-task/automation, or a
|
|
35
|
+
* plain /task session) never call register and stay executor-routed.
|
|
36
|
+
*/
|
|
37
|
+
export const SESSION_SURFACE_MANAGED_METADATA_KEY = 'surfaceManaged';
|
|
38
|
+
/** How recently a participant must have been seen to count as a LIVE surface for
|
|
39
|
+
* steer/follow-up routing. A surface heartbeats via `sessions.register`; if the
|
|
40
|
+
* newest heartbeat is older than this, the surface is treated as gone and inputs
|
|
41
|
+
* fall back to the daemon executor path. */
|
|
42
|
+
export const SURFACE_ROUTE_FRESHNESS_MS = 2 * 60 * 1000;
|
|
43
|
+
export function isSurfaceManagedSession(session) {
|
|
44
|
+
return session.metadata?.[SESSION_SURFACE_MANAGED_METADATA_KEY] === true;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* True when a participant OTHER than `exclude` (the current input's own surface)
|
|
48
|
+
* was seen within `freshnessMs`. Excluding the sender prevents a steer's own
|
|
49
|
+
* just-attached participant from making a surfaceless session look live.
|
|
50
|
+
*/
|
|
51
|
+
export function hasFreshSurfaceParticipant(session, now, freshnessMs, exclude) {
|
|
52
|
+
return session.participants.some((participant) => {
|
|
53
|
+
if (exclude?.surfaceId && participant.surfaceId === exclude.surfaceId)
|
|
54
|
+
return false;
|
|
55
|
+
return now - participant.lastSeenAt < freshnessMs;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/** Steer/follow-up to this session should route to a live surface (queue-for-surface)
|
|
59
|
+
* rather than spawn a daemon executor. */
|
|
60
|
+
export function shouldRouteInputToSurface(session, now, freshnessMs, exclude) {
|
|
61
|
+
return isSurfaceManagedSession(session) && hasFreshSurfaceParticipant(session, now, freshnessMs, exclude);
|
|
62
|
+
}
|
|
5
63
|
export function assertSharedSessionIdAllowed(id) {
|
|
6
64
|
if (id === undefined || !RESERVED_SHARED_SESSION_IDS.has(id))
|
|
7
65
|
return;
|
|
@@ -17,6 +75,7 @@ export function createSharedSessionRecord(input) {
|
|
|
17
75
|
return {
|
|
18
76
|
id: sessionId,
|
|
19
77
|
kind: input.kind ?? 'tui',
|
|
78
|
+
project: input.project?.trim() || 'unknown',
|
|
20
79
|
title: input.title?.trim() || input.routeBinding?.title || `Session ${sessionId}`,
|
|
21
80
|
status: 'active',
|
|
22
81
|
createdAt: now,
|
|
@@ -37,7 +96,56 @@ export function createSharedSessionRecord(input) {
|
|
|
37
96
|
},
|
|
38
97
|
};
|
|
39
98
|
}
|
|
40
|
-
|
|
99
|
+
/**
|
|
100
|
+
* The idempotent register/heartbeat control-flow with HONEST closed semantics:
|
|
101
|
+
* a brand-new id is created; an existing OPEN id adopts the participant; an
|
|
102
|
+
* existing CLOSED id records the heartbeat but stays closed (returning a conflict
|
|
103
|
+
* marker) UNLESS `reopen: true` is passed. A titled session is never renamed by
|
|
104
|
+
* the heartbeat (that rule lives in {@link attachSharedSessionParticipantAndRoute}).
|
|
105
|
+
*/
|
|
106
|
+
export async function registerSharedSession(ops, input) {
|
|
107
|
+
const existing = ops.getSession(input.sessionId);
|
|
108
|
+
if (!existing) {
|
|
109
|
+
const created = await ops.createSession({
|
|
110
|
+
id: input.sessionId,
|
|
111
|
+
...(input.kind !== undefined ? { kind: input.kind } : {}),
|
|
112
|
+
...(input.project !== undefined ? { project: input.project } : {}),
|
|
113
|
+
...(input.title !== undefined ? { title: input.title } : {}),
|
|
114
|
+
participant: input.participant,
|
|
115
|
+
});
|
|
116
|
+
return { record: created, reopened: false };
|
|
117
|
+
}
|
|
118
|
+
const attach = participantToAttachInput(input.participant, input.title);
|
|
119
|
+
if (existing.status === 'closed') {
|
|
120
|
+
// Reopen honesty: a session the SYSTEM reaper closed ('idle-reaped') reopens
|
|
121
|
+
// automatically on the next participant heartbeat — the surface never
|
|
122
|
+
// deliberately closed it, so re-registering is not a conflict. An explicit
|
|
123
|
+
// 'user'/'surface' close stays closed (honest conflict) unless reopen:true.
|
|
124
|
+
const systemReaped = readSessionCloseReason(existing) === 'idle-reaped';
|
|
125
|
+
if (input.reopen === true || systemReaped) {
|
|
126
|
+
const reopened = (await ops.reopenSession(existing.id)) ?? existing;
|
|
127
|
+
return { record: await ops.attachParticipant(reopened, attach), reopened: true };
|
|
128
|
+
}
|
|
129
|
+
return { record: await ops.attachParticipant(existing, attach), reopened: false, conflict: { status: 'closed' } };
|
|
130
|
+
}
|
|
131
|
+
return { record: await ops.attachParticipant(existing, attach), reopened: false };
|
|
132
|
+
}
|
|
133
|
+
export function participantToAttachInput(participant, title) {
|
|
134
|
+
return {
|
|
135
|
+
surfaceKind: participant.surfaceKind,
|
|
136
|
+
surfaceId: participant.surfaceId,
|
|
137
|
+
externalId: participant.externalId,
|
|
138
|
+
userId: participant.userId,
|
|
139
|
+
displayName: participant.displayName,
|
|
140
|
+
routeId: participant.routeId,
|
|
141
|
+
...(title ? { title } : {}),
|
|
142
|
+
body: '',
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/** Close a session, recording WHY. Defaults to 'user' — the explicit close verb
|
|
146
|
+
* (daemon `sessions.close`) is a deliberate user/surface action, which does NOT
|
|
147
|
+
* auto-reopen on heartbeat. The reaper passes 'idle-reaped'. */
|
|
148
|
+
export function closeSharedSessionRecord(session, reason = 'user') {
|
|
41
149
|
const now = Date.now();
|
|
42
150
|
return {
|
|
43
151
|
...session,
|
|
@@ -45,6 +153,7 @@ export function closeSharedSessionRecord(session) {
|
|
|
45
153
|
activeAgentId: undefined,
|
|
46
154
|
updatedAt: now,
|
|
47
155
|
closedAt: now,
|
|
156
|
+
metadata: withSessionCloseReason(session.metadata, reason),
|
|
48
157
|
};
|
|
49
158
|
}
|
|
50
159
|
export function reopenSharedSessionRecord(session) {
|
|
@@ -53,6 +162,9 @@ export function reopenSharedSessionRecord(session) {
|
|
|
53
162
|
status: 'active',
|
|
54
163
|
updatedAt: Date.now(),
|
|
55
164
|
closedAt: undefined,
|
|
165
|
+
// A reopened session is no longer closed-for-any-reason; clear the marker so
|
|
166
|
+
// it never carries a stale close reason on the wire.
|
|
167
|
+
metadata: withoutSessionCloseReason(session.metadata),
|
|
56
168
|
};
|
|
57
169
|
}
|
|
58
170
|
export function bindSharedSessionAgent(session, agentId) {
|
|
@@ -65,6 +177,21 @@ export function bindSharedSessionAgent(session, agentId) {
|
|
|
65
177
|
lastActivityAt: now,
|
|
66
178
|
};
|
|
67
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* True when a session title is still the auto-generated placeholder (empty or
|
|
182
|
+
* `Session <id>`) and can be named by an incoming register/attach. A real,
|
|
183
|
+
* user-supplied title is never overwritten by this path.
|
|
184
|
+
*/
|
|
185
|
+
export function isPlaceholderSessionTitle(title, id) {
|
|
186
|
+
const trimmed = title.trim();
|
|
187
|
+
return trimmed.length === 0 || trimmed === `Session ${id}`;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Merge a participant + optional route onto a session. This is the HEARTBEAT
|
|
191
|
+
* path — it records the participant and advances lastSeenAt, but it must NOT by
|
|
192
|
+
* itself change lifecycle status (a closed session stays closed; reopening is an
|
|
193
|
+
* explicit verb) and must NOT overwrite a real title (only names a placeholder).
|
|
194
|
+
*/
|
|
68
195
|
export function attachSharedSessionParticipantAndRoute(input) {
|
|
69
196
|
const nextRouteIds = input.binding?.id
|
|
70
197
|
? [...new Set([...input.session.routeIds, input.binding.id])]
|
|
@@ -78,12 +205,23 @@ export function attachSharedSessionParticipantAndRoute(input) {
|
|
|
78
205
|
routeId: input.binding?.id,
|
|
79
206
|
lastSeenAt: Date.now(),
|
|
80
207
|
});
|
|
208
|
+
const incomingTitle = input.message.title?.trim();
|
|
209
|
+
const title = incomingTitle && isPlaceholderSessionTitle(input.session.title, input.session.id)
|
|
210
|
+
? incomingTitle
|
|
211
|
+
: input.session.title;
|
|
212
|
+
const now = Date.now();
|
|
81
213
|
return {
|
|
82
214
|
...input.session,
|
|
83
|
-
title
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
215
|
+
title,
|
|
216
|
+
// Status is intentionally preserved: the participant merge is a heartbeat and
|
|
217
|
+
// cannot flip a closed session back to active. Reopening is an explicit verb.
|
|
218
|
+
status: input.session.status,
|
|
219
|
+
updatedAt: now,
|
|
220
|
+
// A register heartbeat IS session activity: advance lastActivityAt (not only
|
|
221
|
+
// the participant's lastSeenAt) so the idle-empty reaper does not close a
|
|
222
|
+
// live, message-less surface session out from under a heartbeating participant.
|
|
223
|
+
lastActivityAt: now,
|
|
224
|
+
closedAt: input.session.closedAt,
|
|
87
225
|
routeIds: nextRouteIds,
|
|
88
226
|
participants,
|
|
89
227
|
surfaceKinds: dedupeSessionSurfaceKinds(participants),
|
|
@@ -92,3 +230,39 @@ export function attachSharedSessionParticipantAndRoute(input) {
|
|
|
92
230
|
},
|
|
93
231
|
};
|
|
94
232
|
}
|
|
233
|
+
/**
|
|
234
|
+
* The inverse of {@link attachSharedSessionParticipantAndRoute}: remove EVERY
|
|
235
|
+
* participant bound to `surfaceId` and unbind the route bindings those
|
|
236
|
+
* participants alone held. This is "detach != close != kill" — the session and
|
|
237
|
+
* all other participants keep running; the detached surface simply stops being a
|
|
238
|
+
* routing target (and, filtered by domain, stops receiving session updates).
|
|
239
|
+
*
|
|
240
|
+
* Route pruning is conservative: a routeId is dropped from the session only when
|
|
241
|
+
* NO surviving participant still references it, so detaching one surface never
|
|
242
|
+
* severs another surface's live binding.
|
|
243
|
+
*
|
|
244
|
+
* Returns `{ session, changed }`. `changed` is false when no participant matched
|
|
245
|
+
* `surfaceId` (the caller can treat a no-match detach as an idempotent no-op and
|
|
246
|
+
* skip persistence/emit). Status, title, and closedAt are preserved untouched —
|
|
247
|
+
* detach is never a lifecycle transition.
|
|
248
|
+
*/
|
|
249
|
+
export function detachSharedSessionParticipant(session, surfaceId) {
|
|
250
|
+
const remaining = session.participants.filter((participant) => participant.surfaceId !== surfaceId);
|
|
251
|
+
if (remaining.length === session.participants.length) {
|
|
252
|
+
return { session, changed: false };
|
|
253
|
+
}
|
|
254
|
+
const survivingRouteIds = new Set(remaining
|
|
255
|
+
.map((participant) => participant.routeId)
|
|
256
|
+
.filter((routeId) => typeof routeId === 'string'));
|
|
257
|
+
const routeIds = session.routeIds.filter((routeId) => survivingRouteIds.has(routeId));
|
|
258
|
+
return {
|
|
259
|
+
session: {
|
|
260
|
+
...session,
|
|
261
|
+
updatedAt: Date.now(),
|
|
262
|
+
participants: remaining,
|
|
263
|
+
surfaceKinds: dedupeSessionSurfaceKinds(remaining),
|
|
264
|
+
routeIds,
|
|
265
|
+
},
|
|
266
|
+
changed: true,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
@@ -9,11 +9,30 @@ export declare function loadSessionBrokerState(snapshot: SharedSessionStoreSnaps
|
|
|
9
9
|
readonly messages: Map<string, SharedSessionMessage[]>;
|
|
10
10
|
readonly inputs: Map<string, SharedSessionInputRecord[]>;
|
|
11
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* Build the durable snapshot with a PER-SESSION message cap.
|
|
14
|
+
*
|
|
15
|
+
* `maxPersistedMessagesPerSession` bounds each session's retained bodies
|
|
16
|
+
* independently — NOT the flattened total. The old global slice-after-flatten
|
|
17
|
+
* behaviour silently dropped whole sessions' transcripts (the oldest ones) once
|
|
18
|
+
* the combined message count crossed the cap, while `messageCount` stayed
|
|
19
|
+
* inflated. Capping per session keeps every session's most recent bodies and,
|
|
20
|
+
* when a session IS truncated, stamps `retainedMessageCount` so the loss is
|
|
21
|
+
* honest rather than silent (see {@link SharedSessionRecord.retainedMessageCount}).
|
|
22
|
+
*/
|
|
12
23
|
export declare function createSessionBrokerSnapshot(state: {
|
|
13
24
|
readonly sessions: ReadonlyMap<string, SharedSessionRecord>;
|
|
14
25
|
readonly messages: ReadonlyMap<string, readonly SharedSessionMessage[]>;
|
|
15
26
|
readonly inputs: ReadonlyMap<string, readonly SharedSessionInputRecord[]>;
|
|
16
|
-
},
|
|
27
|
+
}, maxPersistedMessagesPerSession: number): SharedSessionStoreSnapshot;
|
|
17
28
|
export declare function upsertSessionParticipant(participants: readonly SharedSessionParticipant[], participant: SharedSessionParticipant): SharedSessionParticipant[];
|
|
29
|
+
/**
|
|
30
|
+
* Boot-time reconciliation of a freshly-loaded broker state (mutates in place):
|
|
31
|
+
* cancels inputs stuck in `spawned`/`delivered` from a prior run (agent state is
|
|
32
|
+
* unknown after a restart) and clears stale `activeAgentId` on every session.
|
|
33
|
+
* Returns the set of session ids whose input buckets changed so the caller can
|
|
34
|
+
* refresh their pending counts.
|
|
35
|
+
*/
|
|
36
|
+
export declare function reconcileSessionBrokerBoot(sessions: Map<string, SharedSessionRecord>, inputs: Map<string, SharedSessionInputRecord[]>): Set<string>;
|
|
18
37
|
export declare function countPendingSessionInputs(records: readonly SharedSessionInputRecord[]): number;
|
|
19
38
|
//# sourceMappingURL=session-broker-state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-broker-state.d.ts","sourceRoot":"","sources":["../../../src/platform/control-plane/session-broker-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AAC9E,OAAO,KAAK,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"session-broker-state.d.ts","sourceRoot":"","sources":["../../../src/platform/control-plane/session-broker-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AAC9E,OAAO,KAAK,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AA8Q9G,wBAAgB,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,mBAAmB,CAAC,GAAG,mBAAmB,EAAE,CAE1F;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG,oBAAoB,EAAE,CAE5F;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,wBAAwB,CAAC,GAAG,wBAAwB,EAAE,CAElG;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,0BAA0B,GAAG,IAAI,GAAG,SAAS,GAAG;IAC/F,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IACpD,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,EAAE,CAAC,CAAC;IACvD,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,wBAAwB,EAAE,CAAC,CAAC;CAC1D,CAsCA;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE;IACL,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAC5D,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,oBAAoB,EAAE,CAAC,CAAC;IACxE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,wBAAwB,EAAE,CAAC,CAAC;CAC3E,EACD,8BAA8B,EAAE,MAAM,GACrC,0BAA0B,CA2B5B;AAED,wBAAgB,wBAAwB,CACtC,YAAY,EAAE,SAAS,wBAAwB,EAAE,EACjD,WAAW,EAAE,wBAAwB,GACpC,wBAAwB,EAAE,CAM5B;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,EAC1C,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,wBAAwB,EAAE,CAAC,GAC9C,GAAG,CAAC,MAAM,CAAC,CAkBb;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,SAAS,wBAAwB,EAAE,GAAG,MAAM,CAI9F"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SHARED_SESSION_INPUT_INTENTS, SHARED_SESSION_INPUT_STATES, } from './session-intents.js';
|
|
2
2
|
import { isRecord } from '../utils/record-coerce.js';
|
|
3
|
-
const SESSION_KINDS = new Set(['tui', 'companion-task', 'companion-chat']);
|
|
3
|
+
const SESSION_KINDS = new Set(['tui', 'agent', 'webui', 'companion-task', 'companion-chat', 'automation']);
|
|
4
4
|
const SESSION_STATUSES = new Set(['active', 'closed']);
|
|
5
5
|
const MESSAGE_ROLES = new Set(['user', 'assistant', 'system']);
|
|
6
6
|
function isFiniteNumber(value) {
|
|
@@ -78,6 +78,7 @@ function normalizeSessionRecord(value, messages, inputs) {
|
|
|
78
78
|
validateOptionalNumber(value['updatedAt']);
|
|
79
79
|
validateOptionalNumber(value['lastActivityAt']);
|
|
80
80
|
validateOptionalNumber(value['messageCount']);
|
|
81
|
+
validateOptionalNumber(value['retainedMessageCount']);
|
|
81
82
|
validateOptionalNumber(value['pendingInputCount']);
|
|
82
83
|
validateOptionalNumber(value['lastMessageAt']);
|
|
83
84
|
validateOptionalNumber(value['closedAt']);
|
|
@@ -120,6 +121,7 @@ function normalizeSessionRecord(value, messages, inputs) {
|
|
|
120
121
|
kind: typeof value['kind'] === 'string' && SESSION_KINDS.has(value['kind'])
|
|
121
122
|
? value['kind']
|
|
122
123
|
: 'tui',
|
|
124
|
+
project: typeof value['project'] === 'string' && value['project'].length > 0 ? value['project'] : 'unknown',
|
|
123
125
|
title: typeof value['title'] === 'string' && value['title'].trim().length > 0 ? value['title'] : `Session ${id}`,
|
|
124
126
|
status: typeof value['status'] === 'string' && SESSION_STATUSES.has(value['status'])
|
|
125
127
|
? value['status']
|
|
@@ -130,6 +132,9 @@ function normalizeSessionRecord(value, messages, inputs) {
|
|
|
130
132
|
...(closedAt !== undefined ? { closedAt } : {}),
|
|
131
133
|
lastActivityAt,
|
|
132
134
|
messageCount: Math.max(isFiniteNumber(value['messageCount']) ? value['messageCount'] : 0, messages.length),
|
|
135
|
+
...(isFiniteNumber(value['retainedMessageCount']) && value['retainedMessageCount'] < Math.max(isFiniteNumber(value['messageCount']) ? value['messageCount'] : 0, messages.length)
|
|
136
|
+
? { retainedMessageCount: value['retainedMessageCount'] }
|
|
137
|
+
: {}),
|
|
133
138
|
pendingInputCount: Math.max(isFiniteNumber(value['pendingInputCount']) ? value['pendingInputCount'] : 0, countPendingSessionInputs(inputs)),
|
|
134
139
|
routeIds,
|
|
135
140
|
surfaceKinds,
|
|
@@ -284,12 +289,43 @@ export function loadSessionBrokerState(snapshot) {
|
|
|
284
289
|
}
|
|
285
290
|
return { sessions, messages, inputs };
|
|
286
291
|
}
|
|
287
|
-
|
|
288
|
-
|
|
292
|
+
/**
|
|
293
|
+
* Build the durable snapshot with a PER-SESSION message cap.
|
|
294
|
+
*
|
|
295
|
+
* `maxPersistedMessagesPerSession` bounds each session's retained bodies
|
|
296
|
+
* independently — NOT the flattened total. The old global slice-after-flatten
|
|
297
|
+
* behaviour silently dropped whole sessions' transcripts (the oldest ones) once
|
|
298
|
+
* the combined message count crossed the cap, while `messageCount` stayed
|
|
299
|
+
* inflated. Capping per session keeps every session's most recent bodies and,
|
|
300
|
+
* when a session IS truncated, stamps `retainedMessageCount` so the loss is
|
|
301
|
+
* honest rather than silent (see {@link SharedSessionRecord.retainedMessageCount}).
|
|
302
|
+
*/
|
|
303
|
+
export function createSessionBrokerSnapshot(state, maxPersistedMessagesPerSession) {
|
|
304
|
+
const cap = Math.max(1, maxPersistedMessagesPerSession);
|
|
305
|
+
const cappedMessages = [];
|
|
306
|
+
const retainedBySession = new Map();
|
|
307
|
+
for (const [sessionId, bucket] of state.messages.entries()) {
|
|
308
|
+
const retained = sortMessages(bucket).slice(-cap);
|
|
309
|
+
for (const message of retained)
|
|
310
|
+
cappedMessages.push(message);
|
|
311
|
+
retainedBySession.set(sessionId, retained.length);
|
|
312
|
+
}
|
|
289
313
|
const inputs = [...state.inputs.values()].flatMap((bucket) => bucket);
|
|
314
|
+
const sessions = sortSessions(state.sessions.values()).map((session) => {
|
|
315
|
+
const retained = retainedBySession.get(session.id) ?? 0;
|
|
316
|
+
if (retained < session.messageCount) {
|
|
317
|
+
return { ...session, retainedMessageCount: retained };
|
|
318
|
+
}
|
|
319
|
+
// Nothing pruned — drop any stale marker so the common case carries none.
|
|
320
|
+
if (session.retainedMessageCount !== undefined) {
|
|
321
|
+
const { retainedMessageCount: _drop, ...rest } = session;
|
|
322
|
+
return rest;
|
|
323
|
+
}
|
|
324
|
+
return session;
|
|
325
|
+
});
|
|
290
326
|
return {
|
|
291
|
-
sessions
|
|
292
|
-
messages: sortMessages(
|
|
327
|
+
sessions,
|
|
328
|
+
messages: sortMessages(cappedMessages),
|
|
293
329
|
inputs: sortInputs(inputs),
|
|
294
330
|
};
|
|
295
331
|
}
|
|
@@ -300,6 +336,32 @@ export function upsertSessionParticipant(participants, participant) {
|
|
|
300
336
|
participant,
|
|
301
337
|
];
|
|
302
338
|
}
|
|
339
|
+
/**
|
|
340
|
+
* Boot-time reconciliation of a freshly-loaded broker state (mutates in place):
|
|
341
|
+
* cancels inputs stuck in `spawned`/`delivered` from a prior run (agent state is
|
|
342
|
+
* unknown after a restart) and clears stale `activeAgentId` on every session.
|
|
343
|
+
* Returns the set of session ids whose input buckets changed so the caller can
|
|
344
|
+
* refresh their pending counts.
|
|
345
|
+
*/
|
|
346
|
+
export function reconcileSessionBrokerBoot(sessions, inputs) {
|
|
347
|
+
const restartReason = 'daemon restart — agent state unknown';
|
|
348
|
+
const changed = new Set();
|
|
349
|
+
for (const [sessionId, bucket] of inputs.entries()) {
|
|
350
|
+
for (let i = 0; i < bucket.length; i++) {
|
|
351
|
+
const entry = bucket[i];
|
|
352
|
+
if (entry.state === 'spawned' || entry.state === 'delivered') {
|
|
353
|
+
bucket[i] = { ...entry, state: 'cancelled', updatedAt: Date.now(), error: restartReason };
|
|
354
|
+
changed.add(sessionId);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
for (const [sessionId, session] of sessions.entries()) {
|
|
359
|
+
if (session.activeAgentId) {
|
|
360
|
+
sessions.set(sessionId, { ...session, activeAgentId: undefined, updatedAt: Date.now() });
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
return changed;
|
|
364
|
+
}
|
|
303
365
|
export function countPendingSessionInputs(records) {
|
|
304
366
|
return records.filter((entry) => entry.state === 'queued' || entry.state === 'delivered' || entry.state === 'spawned').length;
|
|
305
367
|
}
|