@pellux/goodvibes-tui 2.0.13 → 2.0.15
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/.goodvibes/GOODVIBES.md +1 -1
- package/.goodvibes/agents/reviewer.md +8 -8
- package/.goodvibes/skills/add-provider/SKILL.md +22 -22
- package/CHANGELOG.md +61 -0
- package/README.md +40 -29
- package/docs/README.md +1 -1
- package/docs/foundation-artifacts/README.md +5 -5
- package/docs/foundation-artifacts/operator-contract.json +123 -123
- package/package.json +12 -10
- package/scripts/postinstall.js +3 -3
- package/src/audio/activation-sound.ts +7 -7
- package/src/audio/capture.ts +7 -7
- package/src/audio/onnxruntime-assets.d.ts +1 -1
- package/src/audio/player.ts +4 -4
- package/src/audio/spoken-turn-wiring.ts +4 -4
- package/src/audio/voice-capture-wiring.ts +5 -5
- package/src/audio/voice-input-session.ts +3 -3
- package/src/audio/wake-inference.ts +13 -8
- package/src/audio/wake-runtime.ts +10 -10
- package/src/cli/completions/generate.ts +2 -2
- package/src/cli/doctor.ts +13 -13
- package/src/cli/ensure-goodvibes-gitignore.ts +3 -3
- package/src/cli/entrypoint.ts +3 -3
- package/src/cli/help.ts +6 -6
- package/src/cli/hooks-command.ts +4 -4
- package/src/cli/hooks-report.ts +4 -4
- package/src/cli/launch-auto-update.ts +17 -17
- package/src/cli/management-commands.ts +8 -8
- package/src/cli/management-utils.ts +3 -3
- package/src/cli/management.ts +1 -1
- package/src/cli/plugin-bundles-command.ts +10 -10
- package/src/cli/plugin-command.ts +9 -9
- package/src/cli/service-posture.ts +1 -1
- package/src/cli/status.ts +10 -10
- package/src/cli/surface-command.ts +4 -4
- package/src/cli/tui-startup.ts +23 -23
- package/src/config/run-daemon-config-migration.ts +3 -3
- package/src/config/secret-config.ts +10 -10
- package/src/config/surface.ts +1 -1
- package/src/config/tui-extension-settings.ts +8 -8
- package/src/core/active-model-identity.ts +7 -7
- package/src/core/approval-alert.ts +5 -5
- package/src/core/bookmark-navigation.ts +3 -3
- package/src/core/budget-breach-notifier.ts +6 -6
- package/src/core/compaction-receipt.ts +8 -8
- package/src/core/composer-state.ts +2 -2
- package/src/core/context-usage.ts +1 -1
- package/src/core/conversation-compaction-render.ts +3 -3
- package/src/core/conversation-event-navigation.ts +2 -2
- package/src/core/conversation-fold.ts +9 -9
- package/src/core/conversation-line-cache.ts +14 -14
- package/src/core/conversation-render-context.ts +6 -6
- package/src/core/conversation-rendering.ts +27 -30
- package/src/core/conversation-search-expansion.ts +6 -6
- package/src/core/conversation-splash-state.ts +3 -3
- package/src/core/conversation-turn-structure.ts +13 -13
- package/src/core/conversation-types.ts +3 -3
- package/src/core/conversation-user-receipts.ts +5 -5
- package/src/core/conversation.ts +17 -17
- package/src/core/format-user-error.ts +5 -5
- package/src/core/long-task-notifier.ts +9 -9
- package/src/core/memory-diagnostics-gateway.ts +8 -8
- package/src/core/memory-provenance.ts +5 -5
- package/src/core/model-routing-chip.ts +3 -3
- package/src/core/pairing-tailscale-gateway.ts +3 -3
- package/src/core/permission-mode.ts +5 -5
- package/src/core/power-chip-source.ts +3 -3
- package/src/core/power-status.ts +8 -8
- package/src/core/rewind-receipt.ts +6 -6
- package/src/core/session-resume-core.ts +8 -8
- package/src/core/stream-event-wiring.ts +36 -36
- package/src/core/stream-stall-watchdog.ts +4 -4
- package/src/core/system-message-noise.ts +7 -7
- package/src/core/system-message-router.ts +10 -10
- package/src/core/terminal-notifier.ts +5 -5
- package/src/core/turn-budget-outcome.ts +5 -5
- package/src/core/turn-cancellation.ts +3 -3
- package/src/core/turn-event-wiring.ts +16 -16
- package/src/core/voice-capture-status.ts +2 -2
- package/src/core/voice-provision-gateway.ts +12 -12
- package/src/core/voice-provision-status.ts +19 -19
- package/src/core/voice-stt-gateway.ts +6 -6
- package/src/core/wake-provision-runner.ts +7 -7
- package/src/core/wake-provision-status.ts +17 -17
- package/src/core/workstream-notification.ts +8 -8
- package/src/export/gist-uploader.ts +7 -7
- package/src/input/autocomplete.ts +3 -3
- package/src/input/bookmark-modal.ts +1 -1
- package/src/input/command-args-hint.ts +2 -2
- package/src/input/command-reference.ts +9 -9
- package/src/input/command-registry.ts +32 -32
- package/src/input/commands/acp-runtime.ts +6 -6
- package/src/input/commands/calendar-runtime.ts +9 -9
- package/src/input/commands/channel-pairing.ts +11 -11
- package/src/input/commands/channel-runtime.ts +1 -1
- package/src/input/commands/checkin-runtime.ts +4 -4
- package/src/input/commands/checkpoint-runtime.ts +4 -4
- package/src/input/commands/ci-runtime.ts +4 -4
- package/src/input/commands/cluster-runtime.ts +3 -3
- package/src/input/commands/codebase-runtime.ts +16 -16
- package/src/input/commands/config.ts +6 -6
- package/src/input/commands/connection-status.ts +12 -12
- package/src/input/commands/context-window.ts +2 -2
- package/src/input/commands/cost-attribution-format.ts +4 -4
- package/src/input/commands/cost-runtime.ts +2 -2
- package/src/input/commands/devices-runtime.ts +7 -7
- package/src/input/commands/diff-runtime.ts +2 -2
- package/src/input/commands/editor-runtime.ts +1 -1
- package/src/input/commands/eval.ts +4 -4
- package/src/input/commands/experience-runtime.ts +1 -1
- package/src/input/commands/git-runtime.ts +3 -3
- package/src/input/commands/graph-runtime.ts +3 -3
- package/src/input/commands/guidance-runtime.ts +1 -1
- package/src/input/commands/health-metrics-format.ts +2 -2
- package/src/input/commands/health-runtime.ts +8 -8
- package/src/input/commands/hosted-runtime.ts +13 -13
- package/src/input/commands/image-runtime.ts +6 -6
- package/src/input/commands/intelligence-runtime.ts +2 -2
- package/src/input/commands/local-auth-runtime.ts +3 -3
- package/src/input/commands/local-provider-runtime.ts +3 -3
- package/src/input/commands/local-runtime.ts +7 -7
- package/src/input/commands/mail-runtime.ts +9 -9
- package/src/input/commands/mcp-runtime.ts +1 -1
- package/src/input/commands/memory.ts +13 -13
- package/src/input/commands/notify-runtime.ts +1 -1
- package/src/input/commands/operator-panel-runtime.ts +8 -8
- package/src/input/commands/operator-rpc.ts +3 -3
- package/src/input/commands/operator-runtime.ts +3 -3
- package/src/input/commands/palette-runtime.ts +1 -1
- package/src/input/commands/payment-card-intake.ts +17 -17
- package/src/input/commands/permissions-provenance.ts +7 -7
- package/src/input/commands/permissions-runtime.ts +1 -1
- package/src/input/commands/planning-runtime.ts +9 -9
- package/src/input/commands/platform-services-runtime.ts +2 -2
- package/src/input/commands/policy-dispatch.ts +6 -6
- package/src/input/commands/power-runtime.ts +6 -6
- package/src/input/commands/principals-runtime.ts +3 -3
- package/src/input/commands/product-runtime.ts +3 -3
- package/src/input/commands/profile-render.ts +13 -13
- package/src/input/commands/profile-runtime.ts +13 -13
- package/src/input/commands/profile-types.ts +13 -13
- package/src/input/commands/provider-accounts-runtime.ts +5 -5
- package/src/input/commands/provider.ts +10 -10
- package/src/input/commands/qrcode-runtime.ts +3 -3
- package/src/input/commands/queue-runtime.ts +6 -6
- package/src/input/commands/recall-files-config.ts +4 -4
- package/src/input/commands/recall-files-git.ts +3 -3
- package/src/input/commands/recall-files.ts +12 -12
- package/src/input/commands/recall-query.ts +3 -3
- package/src/input/commands/recall-review.ts +3 -3
- package/src/input/commands/recall-shared.ts +1 -1
- package/src/input/commands/relay-runtime.ts +5 -5
- package/src/input/commands/remote-runtime.ts +3 -3
- package/src/input/commands/review-runtime.ts +8 -8
- package/src/input/commands/rewind-runtime.ts +21 -21
- package/src/input/commands/runtime-services.ts +1 -2
- package/src/input/commands/schedule-nl.ts +2 -2
- package/src/input/commands/schedule-runtime.ts +2 -2
- package/src/input/commands/secret-runtime.ts +3 -3
- package/src/input/commands/session-content.ts +7 -7
- package/src/input/commands/session-picker-filter.ts +3 -3
- package/src/input/commands/session-workflow.ts +10 -10
- package/src/input/commands/session.ts +15 -15
- package/src/input/commands/settings-sync-runtime.ts +2 -2
- package/src/input/commands/share-runtime.ts +4 -4
- package/src/input/commands/shell-core.ts +11 -11
- package/src/input/commands/tasks-runtime.ts +4 -4
- package/src/input/commands/test-runtime.ts +6 -6
- package/src/input/commands/tts-runtime.ts +4 -4
- package/src/input/commands/update-runtime.ts +27 -27
- package/src/input/commands/websearch-runtime.ts +2 -2
- package/src/input/commands/work-plan-runtime.ts +2 -2
- package/src/input/commands/workstream-attempt-dependents.ts +4 -4
- package/src/input/commands/workstream-attempts.ts +16 -16
- package/src/input/commands/workstream-runtime.ts +36 -36
- package/src/input/commands/worktree-runtime.ts +6 -6
- package/src/input/composer-capture.ts +5 -5
- package/src/input/concealed-input.ts +2 -2
- package/src/input/config-modal-types.ts +16 -16
- package/src/input/config-modal.ts +30 -30
- package/src/input/daemon-owned-settings-descriptions.ts +4 -4
- package/src/input/delete-key-policy.ts +1 -1
- package/src/input/exec-env-scrub-config.ts +7 -7
- package/src/input/feature-unit-layout.ts +5 -5
- package/src/input/feed-context-factory.ts +38 -38
- package/src/input/file-picker.ts +1 -1
- package/src/input/handler-command-route.ts +2 -2
- package/src/input/handler-content-actions.ts +8 -8
- package/src/input/handler-feed-routes.ts +13 -13
- package/src/input/handler-feed.ts +31 -31
- package/src/input/handler-interactions.ts +2 -2
- package/src/input/handler-modal-routes.ts +13 -13
- package/src/input/handler-modal-stack.ts +1 -1
- package/src/input/handler-modal-token-routes.ts +1 -1
- package/src/input/handler-onboarding-daemon-adopt.ts +6 -6
- package/src/input/handler-picker-routes.ts +7 -7
- package/src/input/handler-prompt-buffer.ts +1 -1
- package/src/input/handler-shortcuts.ts +12 -12
- package/src/input/handler-types.ts +3 -3
- package/src/input/handler-ui-state.ts +1 -1
- package/src/input/handler.ts +9 -9
- package/src/input/input-history.ts +1 -1
- package/src/input/keybindings.ts +13 -13
- package/src/input/kill-ring.ts +7 -11
- package/src/input/model-picker-filter.ts +3 -3
- package/src/input/model-picker-items.ts +5 -5
- package/src/input/model-picker-types.ts +2 -2
- package/src/input/model-picker.ts +18 -18
- package/src/input/onboarding/onboarding-feature-units.ts +9 -13
- package/src/input/onboarding/onboarding-provider-key-fields.ts +3 -3
- package/src/input/onboarding/onboarding-runtime-status.ts +3 -3
- package/src/input/onboarding/onboarding-wizard-apply.ts +6 -6
- package/src/input/onboarding/onboarding-wizard-cloudflare-step.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-constants.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-external-surfaces.ts +4 -4
- package/src/input/onboarding/onboarding-wizard-network-adopt.ts +6 -6
- package/src/input/onboarding/onboarding-wizard-steps.ts +2 -2
- package/src/input/panel-integration-actions.ts +3 -3
- package/src/input/panel-mouse-geometry.ts +1 -1
- package/src/input/panel-paste-flood-guard.ts +9 -9
- package/src/input/payments-config.ts +15 -15
- package/src/input/profile-picker-modal.ts +1 -1
- package/src/input/provider-key-intake.ts +9 -9
- package/src/input/relay-settings-descriptions.ts +3 -3
- package/src/input/sandbox-exec-config.ts +9 -9
- package/src/input/search.ts +18 -18
- package/src/input/selection-modal-queue.ts +10 -10
- package/src/input/selection-modal.ts +2 -2
- package/src/input/session-picker-modal.ts +7 -7
- package/src/input/settings-modal-activation.ts +1 -1
- package/src/input/settings-modal-adjustment.ts +2 -2
- package/src/input/settings-modal-commit.ts +6 -6
- package/src/input/settings-modal-connections.ts +2 -2
- package/src/input/settings-modal-data.ts +29 -29
- package/src/input/settings-modal-mutations.ts +7 -7
- package/src/input/settings-modal-reset.ts +3 -3
- package/src/input/settings-modal-search.ts +6 -6
- package/src/input/settings-modal-secrets.ts +3 -3
- package/src/input/settings-modal-types.ts +16 -16
- package/src/input/settings-modal.ts +4 -4
- package/src/input/voice-local-settings.ts +3 -3
- package/src/input/worktree-setup-config.ts +8 -8
- package/src/main.ts +15 -15
- package/src/panels/agent-inspector-shared.ts +5 -5
- package/src/panels/base-panel.ts +3 -3
- package/src/panels/builtin/agent.ts +3 -3
- package/src/panels/builtin/development.ts +4 -4
- package/src/panels/builtin/knowledge.ts +1 -1
- package/src/panels/builtin/operations.ts +12 -12
- package/src/panels/builtin/session.ts +8 -8
- package/src/panels/builtin/shared.ts +6 -6
- package/src/panels/builtin-modals.ts +8 -8
- package/src/panels/confirm-state.ts +5 -5
- package/src/panels/cost-tracker-panel.ts +22 -22
- package/src/panels/diff-panel.ts +20 -20
- package/src/panels/diff-review-model.ts +5 -5
- package/src/panels/diff-review-panel.ts +5 -5
- package/src/panels/eval-registry.ts +2 -2
- package/src/panels/expandable-list-panel.ts +5 -5
- package/src/panels/fleet-acts.ts +20 -20
- package/src/panels/fleet-deep-link.ts +5 -5
- package/src/panels/fleet-gateway.ts +12 -12
- package/src/panels/fleet-observed-render.ts +11 -11
- package/src/panels/fleet-panel-format.ts +14 -14
- package/src/panels/fleet-panel-worktree-detail.ts +8 -8
- package/src/panels/fleet-panel.ts +34 -34
- package/src/panels/fleet-read-model.ts +49 -49
- package/src/panels/fleet-spawn.ts +15 -15
- package/src/panels/fleet-steer.ts +7 -7
- package/src/panels/fleet-stop.ts +5 -5
- package/src/panels/fleet-tabs.ts +14 -14
- package/src/panels/fleet-transcript.ts +26 -26
- package/src/panels/git-panel.ts +8 -8
- package/src/panels/hosted-session-feed.ts +13 -13
- package/src/panels/hosted-session-panel.ts +7 -7
- package/src/panels/index.ts +1 -1
- package/src/panels/local-auth-panel.ts +15 -15
- package/src/panels/memory-consolidation-gateway.ts +8 -8
- package/src/panels/modals/devices-modal.ts +8 -8
- package/src/panels/modals/hooks-modal.ts +1 -1
- package/src/panels/modals/keybindings-modal.ts +5 -5
- package/src/panels/modals/knowledge-modal.ts +2 -2
- package/src/panels/modals/local-auth-modal.ts +4 -4
- package/src/panels/modals/marketplace-modal.ts +3 -3
- package/src/panels/modals/memory-modal.ts +19 -19
- package/src/panels/modals/modal-surface-helpers.ts +1 -1
- package/src/panels/modals/modal-theme.ts +3 -3
- package/src/panels/modals/pairing-modal.ts +19 -19
- package/src/panels/modals/planning-modal.ts +4 -4
- package/src/panels/modals/plugins-modal.ts +1 -1
- package/src/panels/modals/policy-modal.ts +4 -4
- package/src/panels/modals/provider-health-modal.ts +1 -1
- package/src/panels/modals/remote-modal.ts +1 -1
- package/src/panels/modals/sandbox-modal.ts +2 -2
- package/src/panels/modals/security-modal.ts +4 -4
- package/src/panels/modals/services-modal.ts +1 -1
- package/src/panels/modals/work-plan-modal.ts +4 -4
- package/src/panels/notifications-feed.ts +6 -6
- package/src/panels/notifications-panel.ts +6 -6
- package/src/panels/panel-confirm-overlay.ts +4 -4
- package/src/panels/panel-manager.ts +13 -13
- package/src/panels/plugins-panel.ts +6 -6
- package/src/panels/polish-core.ts +2 -2
- package/src/panels/polish-tables.ts +2 -2
- package/src/panels/polish.ts +1 -1
- package/src/panels/project-planning-answer-actions.ts +3 -3
- package/src/panels/scrollable-list-panel.ts +15 -15
- package/src/panels/search-focus.ts +1 -1
- package/src/panels/session-maintenance.ts +1 -1
- package/src/panels/skills-panel.ts +3 -3
- package/src/panels/token-budget-panel.ts +11 -11
- package/src/panels/types.ts +14 -14
- package/src/panels/workstream-graph-render.ts +5 -5
- package/src/panels/wrfc-panel-format.ts +1 -1
- package/src/permissions/broker-approval-card.ts +13 -13
- package/src/permissions/hunk-selection.ts +13 -13
- package/src/permissions/prompt.ts +22 -22
- package/src/permissions/sandbox-exec-gate.ts +5 -5
- package/src/providers/provider-classification.ts +1 -1
- package/src/providers/reasoning-effort-surface.ts +12 -12
- package/src/renderer/ansi-sanitize.ts +5 -6
- package/src/renderer/autocomplete-overlay.ts +5 -5
- package/src/renderer/block-actions-overlay.ts +1 -1
- package/src/renderer/bookmark-modal.ts +1 -1
- package/src/renderer/code-block.ts +2 -2
- package/src/renderer/compaction-history-modal.ts +4 -4
- package/src/renderer/compaction-preview.ts +5 -5
- package/src/renderer/compaction-quality.ts +5 -5
- package/src/renderer/composer-fragments.ts +6 -6
- package/src/renderer/compositor.ts +9 -9
- package/src/renderer/config-modal.ts +3 -3
- package/src/renderer/context-inspector.ts +1 -1
- package/src/renderer/context-status-hint.ts +10 -10
- package/src/renderer/conversation-layout.ts +2 -2
- package/src/renderer/conversation-overlays.ts +2 -2
- package/src/renderer/conversation-surface.ts +6 -6
- package/src/renderer/diff.ts +4 -4
- package/src/renderer/fleet-tab-strip.ts +2 -2
- package/src/renderer/footer-tips.ts +4 -4
- package/src/renderer/fullscreen-primitives.ts +1 -1
- package/src/renderer/git-status.ts +5 -5
- package/src/renderer/header-line.ts +5 -5
- package/src/renderer/help-overlay.ts +5 -5
- package/src/renderer/hint-grammar.ts +2 -2
- package/src/renderer/layout.ts +1 -1
- package/src/renderer/markdown-inline.ts +3 -3
- package/src/renderer/markdown-table.ts +7 -7
- package/src/renderer/modal-factory.ts +3 -3
- package/src/renderer/model-picker-overlay.ts +2 -2
- package/src/renderer/model-workspace.ts +7 -7
- package/src/renderer/onboarding/onboarding-wizard.ts +1 -1
- package/src/renderer/overlay-box.ts +1 -1
- package/src/renderer/panel-composite.ts +5 -5
- package/src/renderer/panel-workspace-bar.ts +1 -1
- package/src/renderer/process-indicator.ts +8 -8
- package/src/renderer/profile-picker-modal.ts +3 -3
- package/src/renderer/prompt-content-width.ts +1 -1
- package/src/renderer/search-overlay.ts +3 -3
- package/src/renderer/selection-modal-overlay.ts +6 -6
- package/src/renderer/semantic-diff.ts +6 -7
- package/src/renderer/session-picker-modal.ts +24 -24
- package/src/renderer/settings-modal-connections.ts +3 -3
- package/src/renderer/settings-modal-helpers.ts +16 -16
- package/src/renderer/settings-modal.ts +10 -10
- package/src/renderer/shell-surface.ts +8 -8
- package/src/renderer/status-glyphs.ts +6 -6
- package/src/renderer/syntax-highlighter.ts +2 -3
- package/src/renderer/system-message.ts +3 -3
- package/src/renderer/tab-strip.ts +2 -2
- package/src/renderer/term-caps.ts +12 -12
- package/src/renderer/terminal-bg-probe.ts +10 -10
- package/src/renderer/terminal-escapes.ts +1 -1
- package/src/renderer/theme-mode-config.ts +3 -3
- package/src/renderer/theme.ts +34 -34
- package/src/renderer/thinking.ts +1 -1
- package/src/renderer/tool-call.ts +5 -5
- package/src/renderer/tool-result-expanded-lines.ts +3 -3
- package/src/renderer/tool-result-summary.ts +6 -6
- package/src/renderer/turn-injection.ts +9 -9
- package/src/renderer/ui-factory.ts +33 -33
- package/src/renderer/ui-primitives.ts +4 -4
- package/src/runtime/bootstrap-command-parts.ts +3 -3
- package/src/runtime/bootstrap-core.ts +21 -21
- package/src/runtime/bootstrap-hook-bridge.ts +8 -8
- package/src/runtime/bootstrap-shell.ts +9 -9
- package/src/runtime/bootstrap.ts +16 -16
- package/src/runtime/client/approval-updates.ts +3 -3
- package/src/runtime/client/build-floors.ts +7 -7
- package/src/runtime/client/daemon-attach-handshake.ts +5 -5
- package/src/runtime/client/fleet-union.ts +7 -7
- package/src/runtime/client/host-service-status.ts +2 -2
- package/src/runtime/client/hosted-exit.ts +4 -4
- package/src/runtime/client/hosted-roster.ts +4 -4
- package/src/runtime/client/hosted-session-stream.ts +5 -5
- package/src/runtime/client/hosted-sessions.ts +8 -8
- package/src/runtime/client/operator-endpoint.ts +14 -14
- package/src/runtime/client/spine-adoption.ts +8 -8
- package/src/runtime/context-accounting-source.ts +4 -4
- package/src/runtime/context.ts +2 -2
- package/src/runtime/conversation-rewind-port.ts +6 -6
- package/src/runtime/credential-composition.ts +2 -2
- package/src/runtime/daemon-attach-notices.ts +6 -6
- package/src/runtime/diagnostics/panels/index.ts +1 -1
- package/src/runtime/diagnostics/panels/ops.ts +2 -2
- package/src/runtime/disposal-wiring.ts +6 -6
- package/src/runtime/index.ts +11 -11
- package/src/runtime/install-self-check-startup.ts +4 -4
- package/src/runtime/install-self-check.ts +6 -6
- package/src/runtime/interaction-seams.ts +4 -4
- package/src/runtime/knowledge-services.ts +2 -2
- package/src/runtime/legacy-daemon-migration.ts +37 -37
- package/src/runtime/legacy-daemon-reconcile.ts +30 -30
- package/src/runtime/memory-governance-services.ts +3 -3
- package/src/runtime/memory-spine-transport.ts +3 -3
- package/src/runtime/notification-dispatch.ts +4 -4
- package/src/runtime/onboarding/apply.ts +1 -1
- package/src/runtime/onboarding/derivation.ts +1 -1
- package/src/runtime/onboarding/fast-path.ts +7 -7
- package/src/runtime/onboarding/progress.ts +2 -2
- package/src/runtime/onboarding/provider-key-capture.ts +4 -4
- package/src/runtime/onboarding/snapshot.ts +2 -2
- package/src/runtime/onboarding/state.ts +4 -4
- package/src/runtime/onboarding/types.ts +4 -4
- package/src/runtime/orchestrator-core-services.ts +5 -5
- package/src/runtime/path-shadow-startup.ts +3 -3
- package/src/runtime/perf/panel-contracts.ts +1 -1
- package/src/runtime/power-keepawake-remote.ts +6 -6
- package/src/runtime/process-lifecycle.ts +14 -14
- package/src/runtime/provider-fallback.ts +3 -3
- package/src/runtime/recovery-autosave.ts +3 -3
- package/src/runtime/recovery-decisions.ts +19 -19
- package/src/runtime/recovery-offer-wiring.ts +4 -4
- package/src/runtime/recovery-prompt.ts +20 -20
- package/src/runtime/relay-reachability-bridge.ts +3 -3
- package/src/runtime/release-artifacts.ts +1 -1
- package/src/runtime/resume-notice.ts +20 -20
- package/src/runtime/runtime-services-types.ts +20 -20
- package/src/runtime/services.ts +20 -20
- package/src/runtime/session-continuity-hints.ts +1 -1
- package/src/runtime/session-inbound-inputs.ts +12 -12
- package/src/runtime/session-resume-liveness-confirm.ts +4 -4
- package/src/runtime/session-spine-transport.ts +3 -3
- package/src/runtime/store/domains/panels.ts +2 -2
- package/src/runtime/store/domains/ui-perf.ts +2 -2
- package/src/runtime/store/index.ts +1 -1
- package/src/runtime/store/selectors/index.ts +1 -1
- package/src/runtime/store/state.ts +2 -2
- package/src/runtime/ui-services.ts +3 -3
- package/src/runtime/workspace-checkpointing.ts +3 -3
- package/src/runtime/wrfc-persistence.ts +15 -15
- package/src/scripts/process-messages.ts +1 -1
- package/src/shell/blocking-input.ts +9 -9
- package/src/shell/recovery-input-helpers.ts +2 -2
- package/src/shell/retry-affordance.ts +9 -9
- package/src/shell/ui-openers.ts +14 -14
- package/src/shell/voice-capture-shell.ts +3 -3
- package/src/tools/wrfc-agent-guard.ts +4 -4
- package/src/utils/browser.ts +2 -2
- package/src/utils/format-duration.ts +3 -3
- package/src/utils/format-number.ts +2 -2
- package/src/utils/splash-lines.ts +4 -4
- package/src/utils/terminal-width.ts +6 -6
- package/src/verification/verification-ledger.ts +25 -25
- package/src/version.ts +3 -3
|
@@ -34,14 +34,14 @@ export interface StreamMetrics {
|
|
|
34
34
|
/**
|
|
35
35
|
* callId of the currently executing tool call; cleared when execution
|
|
36
36
|
* completes. This is the real orchestrator callId (from TOOL_EXECUTING),
|
|
37
|
-
* so a per-tool cancel affordance targets exactly the running call
|
|
37
|
+
* so a per-tool cancel affordance targets exactly the running call, never
|
|
38
38
|
* the synthetic 'live' render id.
|
|
39
39
|
*/
|
|
40
40
|
activeToolCallId: string | undefined;
|
|
41
41
|
/**
|
|
42
42
|
* Epoch ms of the most recent STREAM_START or STREAM_DELTA; undefined when
|
|
43
|
-
* idle (no turn in flight). Read every render frame
|
|
44
|
-
* watchdog's one-shot hint
|
|
43
|
+
* idle (no turn in flight). Read every render frame, not just on the
|
|
44
|
+
* watchdog's one-shot hint, so "ms since last byte" can be computed even
|
|
45
45
|
* when no new SDK event has arrived at all (a no-delta stall watchdog for
|
|
46
46
|
* the render loop itself, independent of the low-priority system message).
|
|
47
47
|
*/
|
|
@@ -57,13 +57,13 @@ export interface StreamMetrics {
|
|
|
57
57
|
* provider call reconnects after a transport error rather than failing the
|
|
58
58
|
* turn. Read structurally off the event feed (see looseTurnsFeed below), so a
|
|
59
59
|
* turn that never retries simply leaves these undefined. Cleared on
|
|
60
|
-
* STREAM_DELTA
|
|
60
|
+
* STREAM_DELTA, a byte arriving means the reconnect succeeded.
|
|
61
61
|
*/
|
|
62
62
|
reconnectAttempt: number | undefined;
|
|
63
63
|
reconnectMaxAttempts: number | undefined;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
/** The idle initial StreamMetrics
|
|
66
|
+
/** The idle initial StreamMetrics, mutated in place by wireStreamEventMetrics handlers. */
|
|
67
67
|
export function createStreamMetrics(): StreamMetrics {
|
|
68
68
|
return {
|
|
69
69
|
startTime: 0, deltaCount: 0, tokenSpeed: 0, ttftMs: undefined, ttftRecorded: false,
|
|
@@ -113,7 +113,7 @@ interface FailoverOptimizer {
|
|
|
113
113
|
readonly enabled: boolean;
|
|
114
114
|
testFallback(profile?: Record<string, unknown>): { readonly chain: readonly FailoverChainNode[] };
|
|
115
115
|
recordFallbackTransition(from: string, to: string, reason: string): void;
|
|
116
|
-
/** Recent fallback transitions
|
|
116
|
+
/** Recent fallback transitions, read by the routing chip to skip double-narrating a failover. */
|
|
117
117
|
readonly fallbackLog: readonly { readonly from: string; readonly to: string; readonly reason: string; readonly ts: number }[];
|
|
118
118
|
}
|
|
119
119
|
|
|
@@ -123,8 +123,8 @@ interface StreamSystemMessageRouter {
|
|
|
123
123
|
low(message: string): void;
|
|
124
124
|
/**
|
|
125
125
|
* Unconditional conversation delivery (see system-message-router.ts). Used
|
|
126
|
-
* for provider-switch notices: which backend serves a turn
|
|
127
|
-
* who bills for it
|
|
126
|
+
* for provider-switch notices: which backend serves a turn, and therefore
|
|
127
|
+
* who bills for it, is never ambient chatter that a routing preference or
|
|
128
128
|
* the noise gate may filter out. Optional so bare test doubles that supply
|
|
129
129
|
* only high/low still type-check; announce() below falls back to high().
|
|
130
130
|
*/
|
|
@@ -133,7 +133,7 @@ interface StreamSystemMessageRouter {
|
|
|
133
133
|
|
|
134
134
|
/**
|
|
135
135
|
* Loosely-typed variant of the turns event feed, used only to subscribe to
|
|
136
|
-
* STREAM_STALL
|
|
136
|
+
* STREAM_STALL, a proposed event the SDK's TurnEvent union does not carry, so
|
|
137
137
|
* `events.turns.on` rejects the name at compile time. See the subscription site
|
|
138
138
|
* below. `events.turns.on` stays fully typed against the real union everywhere
|
|
139
139
|
* else in this file, STREAM_RETRY included.
|
|
@@ -181,14 +181,14 @@ export interface WireStreamEventMetricsOptions {
|
|
|
181
181
|
* the optimizer is enabled and a viable next provider exists in the chain.
|
|
182
182
|
*
|
|
183
183
|
* The re-submission rolls the conversation back to its pre-submission
|
|
184
|
-
* message count, which deletes everything the failed turn added
|
|
184
|
+
* message count, which deletes everything the failed turn added, including
|
|
185
185
|
* a failover notice appended before the call. So the notice is passed IN
|
|
186
186
|
* rather than emitted before: the caller re-posts it after its rollback, and
|
|
187
187
|
* it survives to be read. Implementations that do not roll back may ignore
|
|
188
188
|
* the argument, but must then post the notice themselves.
|
|
189
189
|
*
|
|
190
190
|
* Returns whether the turn was actually re-submitted. False means there was
|
|
191
|
-
* nothing to retry (no pre-submission snapshot
|
|
191
|
+
* nothing to retry (no pre-submission snapshot, the failed turn did not
|
|
192
192
|
* come from the composer) and the notice was NOT posted, so the caller must
|
|
193
193
|
* narrate the switch and surface the error itself rather than let a turn end
|
|
194
194
|
* in silence on a backend the user did not choose.
|
|
@@ -211,7 +211,7 @@ export interface WireStreamEventMetricsOptions {
|
|
|
211
211
|
readonly isApprovalPending?: (() => boolean) | undefined;
|
|
212
212
|
/**
|
|
213
213
|
* Stall watchdog threshold in ms. Defaults to the watchdog's own default (STALL_THRESHOLD_MS,
|
|
214
|
-
* 30 000). Exposed only so unit tests can drive the stall path without waiting 30s
|
|
214
|
+
* 30 000). Exposed only so unit tests can drive the stall path without waiting 30s, production
|
|
215
215
|
* callers omit it.
|
|
216
216
|
*/
|
|
217
217
|
readonly stallThresholdMs?: number | undefined;
|
|
@@ -226,7 +226,7 @@ export interface WireStreamEventMetricsOptions {
|
|
|
226
226
|
/**
|
|
227
227
|
* The user's configured model selection (config `provider.model`) as a
|
|
228
228
|
* registry key. Read at the moment of a failover switch so the turn-end
|
|
229
|
-
* restore targets what the user actually chose
|
|
229
|
+
* restore targets what the user actually chose, not whatever the registry
|
|
230
230
|
* happened to hold. Without it, failover still works but no restore or
|
|
231
231
|
* divergence marker is possible, so both are skipped rather than guessed at.
|
|
232
232
|
*/
|
|
@@ -257,7 +257,7 @@ export interface WireStreamEventMetricsResult {
|
|
|
257
257
|
readonly clearFailoverVisited: () => void;
|
|
258
258
|
/**
|
|
259
259
|
* Register a callback that fires whenever a TURN_ERROR is surfaced to the
|
|
260
|
-
* user
|
|
260
|
+
* user, either immediately (no optimizer) or after chain exhaustion.
|
|
261
261
|
* Does NOT fire when the optimizer performs a successful automatic failover
|
|
262
262
|
* (in that case the user sees a [Failover] notice, not an error).
|
|
263
263
|
* Used by main.ts to activate the one-key retry affordance. The callback
|
|
@@ -286,10 +286,10 @@ function buildCostDeltaSuffix(
|
|
|
286
286
|
toRegistryKey: string,
|
|
287
287
|
): string {
|
|
288
288
|
if (!lookup) return '';
|
|
289
|
-
// Registry key format: `provider:modelId
|
|
289
|
+
// Registry key format: `provider:modelId`, modelId may itself contain `:`.
|
|
290
290
|
const fromModelId = fromRegistryKey ? fromRegistryKey.split(':').slice(1).join(':') : '';
|
|
291
291
|
const toModelId = toRegistryKey.split(':').slice(1).join(':');
|
|
292
|
-
// A null catalog answer means honestly unknown
|
|
292
|
+
// A null catalog answer means honestly unknown, treated exactly like the
|
|
293
293
|
// legacy zero-pricing sentinel below.
|
|
294
294
|
const fromCost = (fromModelId ? lookup.getCostFromCatalog(fromModelId) : null) ?? { input: 0, output: 0 };
|
|
295
295
|
const toCost = lookup.getCostFromCatalog(toModelId) ?? { input: 0, output: 0 };
|
|
@@ -308,13 +308,13 @@ function buildCostDeltaSuffix(
|
|
|
308
308
|
|
|
309
309
|
/**
|
|
310
310
|
* Build the billing-class segment of a failover notice, e.g.
|
|
311
|
-
* ` [billing: API key → Subscription
|
|
311
|
+
* ` [billing: API key → Subscription, billing class changed]`.
|
|
312
312
|
*
|
|
313
313
|
* This path is NOT the synthetic provider's tier-isolated failover, which is
|
|
314
314
|
* where the documented "free, paid and subscription tiers never mix" contract
|
|
315
315
|
* lives (docs/providers-and-routing.md:77-128, enforced in the SDK's
|
|
316
316
|
* synthetic.ts by CanonicalModel.tier). The optimizer chain consumed here
|
|
317
|
-
* carries no tier metadata at all
|
|
317
|
+
* carries no tier metadata at all, its nodes are
|
|
318
318
|
* `{ position, providerId, modelId, capable, explanation }` and `explanation`
|
|
319
319
|
* describes functional capability (streaming, tool calling, context size),
|
|
320
320
|
* never billing. So the switch cannot be constrained by a tier it cannot see;
|
|
@@ -329,7 +329,7 @@ function buildCostDeltaSuffix(
|
|
|
329
329
|
function buildBillingSuffix(fromProviderId: string, toProviderId: string): string {
|
|
330
330
|
const from = classifyProviderSetup({ providerId: fromProviderId }).setupLabel;
|
|
331
331
|
const to = classifyProviderSetup({ providerId: toProviderId }).setupLabel;
|
|
332
|
-
const changed = from !== to ? '
|
|
332
|
+
const changed = from !== to ? ': billing class changed' : '';
|
|
333
333
|
return ` [billing: ${from} → ${to}${changed}]`;
|
|
334
334
|
}
|
|
335
335
|
|
|
@@ -381,7 +381,7 @@ export function wireStreamEventMetrics(
|
|
|
381
381
|
* backend while nothing in the session state or the footer had changed to
|
|
382
382
|
* say so. The user's configured selection is authoritative, so the NEXT turn
|
|
383
383
|
* starts from it again. If that backend is still unhealthy, the normal
|
|
384
|
-
* per-turn failover handles it again
|
|
384
|
+
* per-turn failover handles it again, visibly, with a fresh notice, which
|
|
385
385
|
* is exactly the behaviour a sticky override was hiding.
|
|
386
386
|
*
|
|
387
387
|
* The record is kept (not cleared) when the restore itself fails, so the
|
|
@@ -395,12 +395,12 @@ export function wireStreamEventMetrics(
|
|
|
395
395
|
* narrated twice: the switch out is announced by `[Failover] from -> to
|
|
396
396
|
* (reason)` and the switch back by `[Failover] Restored …`, and a second
|
|
397
397
|
* line reading "(reason unknown)" for the same event would be both a
|
|
398
|
-
* duplicate and a lie
|
|
398
|
+
* duplicate and a lie, the reason is known in both cases.
|
|
399
399
|
*
|
|
400
400
|
* A timestamped map rather than a flag cleared around the setCurrentModel
|
|
401
401
|
* call, because MODEL_CHANGED does NOT arrive synchronously: the TUI reads
|
|
402
402
|
* it through the runtime event feed, which delivers after the emitting call
|
|
403
|
-
* has returned (observed live
|
|
403
|
+
* has returned (observed live, a flag cleared in a finally block was always
|
|
404
404
|
* already null by the time the listener ran, and both failover halves got a
|
|
405
405
|
* duplicate chip). Entries expire on the same window the fallback-log
|
|
406
406
|
* correlation uses, so a switch whose event never arrives cannot silence an
|
|
@@ -411,7 +411,7 @@ export function wireStreamEventMetrics(
|
|
|
411
411
|
/**
|
|
412
412
|
* Run a registry switch this module narrates itself, with the chip suppressed
|
|
413
413
|
* for it. Returns the effort-remap sentence when the switch changed the level
|
|
414
|
-
* that goes on the wire, for the CALLER to place
|
|
414
|
+
* that goes on the wire, for the CALLER to place, see
|
|
415
415
|
* reconcileEffortWithServingModel for why it is not announced here.
|
|
416
416
|
*/
|
|
417
417
|
const switchNarrated = (registryKey: string): string | undefined => {
|
|
@@ -431,13 +431,13 @@ export function wireStreamEventMetrics(
|
|
|
431
431
|
*
|
|
432
432
|
* Both halves of a failover come through switchNarrated, so this covers the
|
|
433
433
|
* switch out and the switch back. The requested level is left untouched in
|
|
434
|
-
* config
|
|
434
|
+
* config, the fallback is temporary and the user's choice must survive it,
|
|
435
435
|
* but the level actually sent is the resolved one, and the SDK's own sentence
|
|
436
436
|
* explaining the remap is surfaced verbatim rather than reworded.
|
|
437
437
|
*
|
|
438
438
|
* The sentence is RETURNED rather than announced. On the failover-out path
|
|
439
439
|
* this function runs before retryTurn, and retryTurn rolls the conversation
|
|
440
|
-
* back to its pre-submission message count
|
|
440
|
+
* back to its pre-submission message count, which deleted this notice every
|
|
441
441
|
* time, exactly as it used to delete the failover notice itself. The caller
|
|
442
442
|
* folds it into the notice it hands to retryTurn so it survives the rollback;
|
|
443
443
|
* the restore path, which has no rollback after it, announces it directly.
|
|
@@ -452,7 +452,7 @@ export function wireStreamEventMetrics(
|
|
|
452
452
|
...(serving.reasoningEffort ? { reasoningEffort: serving.reasoningEffort } : {}),
|
|
453
453
|
};
|
|
454
454
|
publishActiveEffortOptions(model);
|
|
455
|
-
// getConfiguredReasoningEffort reads config `provider.reasoningEffort
|
|
455
|
+
// getConfiguredReasoningEffort reads config `provider.reasoningEffort`,
|
|
456
456
|
// the REQUESTED level. It must never be re-seeded from a previously snapped
|
|
457
457
|
// effective value, or a single failover onto a capped model would ratchet
|
|
458
458
|
// the level down for the rest of the session.
|
|
@@ -539,8 +539,8 @@ export function wireStreamEventMetrics(
|
|
|
539
539
|
// Both terminal turn outcomes end the failover's authority over the
|
|
540
540
|
// registry: a completed turn got its answer, a cancelled one will not.
|
|
541
541
|
// (TURN_COMPLETED and TURN_ERROR are mutually exclusive per turn in the SDK
|
|
542
|
-
|
|
543
|
-
// orchestrator-turn-helpers, TURN_ERROR only from the orchestrator's catch
|
|
542
|
+
//, TURN_COMPLETED is emitted only on the success path in
|
|
543
|
+
// orchestrator-turn-helpers, TURN_ERROR only from the orchestrator's catch,
|
|
544
544
|
// so restoring here can never undo a switch whose retry has not run yet.)
|
|
545
545
|
unsubs.push(events.turns.on('TURN_COMPLETED', () => {
|
|
546
546
|
failoverVisited.clear();
|
|
@@ -599,7 +599,7 @@ export function wireStreamEventMetrics(
|
|
|
599
599
|
if (next) {
|
|
600
600
|
const toRegistryKey = `${next.providerId}:${next.modelId}`;
|
|
601
601
|
const errorClass = formatUserFacingErrorLine(errVal);
|
|
602
|
-
// Capture FROM registry key before switching
|
|
602
|
+
// Capture FROM registry key before switching, needed for cost comparison.
|
|
603
603
|
const fromRegistryKey = providerRegistry.getCurrentModel().registryKey;
|
|
604
604
|
// The effort remap that comes with the switch is carried, not announced:
|
|
605
605
|
// retryTurn's rollback below would delete it (see
|
|
@@ -608,7 +608,7 @@ export function wireStreamEventMetrics(
|
|
|
608
608
|
try {
|
|
609
609
|
effortNote = switchNarrated(toRegistryKey);
|
|
610
610
|
} catch (switchErr) {
|
|
611
|
-
// Switch failed
|
|
611
|
+
// Switch failed, fall through to honest error display. This ends the
|
|
612
612
|
// turn, so an EARLIER hop's switch (if this is a second failover
|
|
613
613
|
// within the same turn) loses its authority here just as it would on
|
|
614
614
|
// any other terminal outcome.
|
|
@@ -640,7 +640,7 @@ export function wireStreamEventMetrics(
|
|
|
640
640
|
// No turn to re-submit (the failed turn did not come from the
|
|
641
641
|
// composer, so there is no pre-submission snapshot to roll back to).
|
|
642
642
|
// The registry has still MOVED, so the switch gets narrated here and
|
|
643
|
-
// the original error surfaces
|
|
643
|
+
// the original error surfaces, silence would leave the user on a
|
|
644
644
|
// different backend with no turn running and nothing said about it.
|
|
645
645
|
announce(failoverNotice);
|
|
646
646
|
systemMessageRouter.high(`[Error] ${errorClass}`);
|
|
@@ -651,12 +651,12 @@ export function wireStreamEventMetrics(
|
|
|
651
651
|
return;
|
|
652
652
|
}
|
|
653
653
|
|
|
654
|
-
// Chain exhausted
|
|
654
|
+
// Chain exhausted, all capable candidates have been visited or none exist.
|
|
655
655
|
// The turn is over, so any switch made earlier in it loses its authority:
|
|
656
656
|
// restore the configured selection before surfacing the error, or the
|
|
657
657
|
// user's next turn would silently start on the last fallback tried.
|
|
658
658
|
announce(
|
|
659
|
-
`[Failover] Chain exhausted
|
|
659
|
+
`[Failover] Chain exhausted: no alternative provider available. Original error: ${formatUserFacingErrorLine(errVal)}`,
|
|
660
660
|
);
|
|
661
661
|
restoreConfiguredSelection();
|
|
662
662
|
notifyErrorSurfaced(true);
|
|
@@ -664,7 +664,7 @@ export function wireStreamEventMetrics(
|
|
|
664
664
|
return;
|
|
665
665
|
}
|
|
666
666
|
|
|
667
|
-
// Baseline: optimizer disabled or not wired
|
|
667
|
+
// Baseline: optimizer disabled or not wired, surface error immediately.
|
|
668
668
|
const formatted = formatUserFacingErrorLine(errVal);
|
|
669
669
|
systemMessageRouter.high(`[Error] ${formatted}`);
|
|
670
670
|
notifyErrorSurfaced(false);
|
|
@@ -675,7 +675,7 @@ export function wireStreamEventMetrics(
|
|
|
675
675
|
// start of turn OR mid-stream, after a re-arm) crosses 30s. The transient
|
|
676
676
|
// system message below is the initial alert; streamMetrics.stallEpisode
|
|
677
677
|
// (read every render frame) drives the persistent "stalled Ns" indicator
|
|
678
|
-
// in the thinking fragment, so the two coexist rather than conflict
|
|
678
|
+
// in the thinking fragment, so the two coexist rather than conflict, the
|
|
679
679
|
// message announces the stall, the indicator tracks it ongoing.
|
|
680
680
|
const stallWatchdog = createStreamStallWatchdog({
|
|
681
681
|
events: events.turns,
|
|
@@ -723,7 +723,7 @@ export function wireStreamEventMetrics(
|
|
|
723
723
|
// On every tool-completion path, reset lastDeltaAtMs to "now" so the
|
|
724
724
|
// post-tool silence window starts fresh. Tool execution suppresses stall
|
|
725
725
|
// detection at the render call site (see main.ts), but lastDeltaAtMs itself
|
|
726
|
-
// keeps its pre-tool value the whole time the tool runs
|
|
726
|
+
// keeps its pre-tool value the whole time the tool runs, without this
|
|
727
727
|
// reset, the instant a tool completes (potentially long after the last real
|
|
728
728
|
// delta), the very next frame would read msSinceLastDelta as the full
|
|
729
729
|
// tool-execution duration and immediately report a stall, even though the
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* StreamStallWatchdog
|
|
2
|
+
* StreamStallWatchdog, detects gaps of silence (no STREAM_DELTA) longer than
|
|
3
3
|
* a configurable threshold, whether the gap is at the start of a turn or in
|
|
4
4
|
* the middle of an otherwise-flowing stream, and emits a low-priority hint
|
|
5
5
|
* each time a gap crosses the threshold.
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* clear the timeout (turn finished normally or with error).
|
|
19
19
|
* - If the timeout fires: emit ONE hint for that episode (do not repeat
|
|
20
20
|
* while the same gap continues), then wait for the gap to close (another
|
|
21
|
-
* STREAM_DELTA/STREAM_START) before a further silence can fire again
|
|
21
|
+
* STREAM_DELTA/STREAM_START) before a further silence can fire again,
|
|
22
22
|
* each such re-arm-then-timeout cycle is a new "stall episode" and the
|
|
23
23
|
* episode counter passed to onStall increments each time.
|
|
24
24
|
* - dispose(): clears all subscriptions and any pending timeout.
|
|
@@ -46,13 +46,13 @@ export interface StreamStallWatchdogOptions {
|
|
|
46
46
|
* Called once per stall episode when the no-delta threshold is exceeded.
|
|
47
47
|
* Receives the provider display name and a 1-based episode counter that
|
|
48
48
|
* increments each time a new silence (after a re-arm) crosses the
|
|
49
|
-
* threshold within the same turn
|
|
49
|
+
* threshold within the same turn, so a second mid-stream stall after a
|
|
50
50
|
* recovery is distinguishable from the first.
|
|
51
51
|
*/
|
|
52
52
|
onStall: (providerName: string, episode: number) => void;
|
|
53
53
|
/**
|
|
54
54
|
* Provides the current provider display name at the moment the hint fires.
|
|
55
|
-
* Optional
|
|
55
|
+
* Optional, defaults to 'provider' when not supplied.
|
|
56
56
|
*/
|
|
57
57
|
getProviderName?: () => string;
|
|
58
58
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* System-message noise policy
|
|
2
|
+
* System-message noise policy, decides whether an operational status message
|
|
3
3
|
* should reach the transcript unchanged, be dropped, or be folded. Every noisy
|
|
4
4
|
* source these rules catch is emitted (from the SDK) through
|
|
5
5
|
* SystemMessageRouter, so this one funnel is where first-run plumbing is kept
|
|
@@ -19,9 +19,9 @@ export interface NoiseGateDeps {
|
|
|
19
19
|
export type NoiseVerdict =
|
|
20
20
|
/** Pass through to the transcript unchanged. */
|
|
21
21
|
| { readonly action: 'emit' }
|
|
22
|
-
/** Suppress entirely
|
|
22
|
+
/** Suppress entirely, reachable via another live surface. */
|
|
23
23
|
| { readonly action: 'drop' }
|
|
24
|
-
/** Provider "from last session" replay line
|
|
24
|
+
/** Provider "from last session" replay line, buffer and fold to one line. */
|
|
25
25
|
| { readonly action: 'foldProviderReplay' };
|
|
26
26
|
|
|
27
27
|
const EMIT: NoiseVerdict = { action: 'emit' };
|
|
@@ -42,12 +42,12 @@ const REPLAY_CHAIN_RE = /WRFC chain (\S+) transitioned .* waiting for action/;
|
|
|
42
42
|
* lookup, so it is trivially testable.
|
|
43
43
|
*/
|
|
44
44
|
export function classifyNoise(message: string, deps: NoiseGateDeps): NoiseVerdict {
|
|
45
|
-
// 1b
|
|
45
|
+
// 1b, provider-discovery replay burst ("[Local] …, from last session").
|
|
46
46
|
if (message.startsWith('[Local]') && PROVIDER_REPLAY_RE.test(message)) {
|
|
47
47
|
return FOLD;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
// 1d
|
|
50
|
+
// 1d, periodic "[Agents] N running:" status snapshot. The same live detail
|
|
51
51
|
// is shown in the fleet panel (per-agent activity) and the footer count, so
|
|
52
52
|
// the 30-second transcript churn is dropped. Meaningful lifecycle lines
|
|
53
53
|
// ("[Agents] ✓ …", "[Agents] Cohort …", "[Agents] ✗ …") do not match.
|
|
@@ -55,7 +55,7 @@ export function classifyNoise(message: string, deps: NoiseGateDeps): NoiseVerdic
|
|
|
55
55
|
return DROP;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
// 1c
|
|
58
|
+
// 1c, stale "[Replay] … waiting for action" for a terminal/killed chain.
|
|
59
59
|
if (message.startsWith('[Replay]') && deps.isChainTerminal) {
|
|
60
60
|
const match = REPLAY_CHAIN_RE.exec(message);
|
|
61
61
|
if (match && deps.isChainTerminal(match[1])) return DROP;
|
|
@@ -64,7 +64,7 @@ export function classifyNoise(message: string, deps: NoiseGateDeps): NoiseVerdic
|
|
|
64
64
|
return EMIT;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
/** Provider name from a "[Local] <name> at host:port (…)
|
|
67
|
+
/** Provider name from a "[Local] <name> at host:port (…), from last session" line. */
|
|
68
68
|
export function providerNameFromReplay(message: string): string {
|
|
69
69
|
const match = /^\[Local\]\s+(.+?)\s+at\s/.exec(message);
|
|
70
70
|
if (match) return match[1];
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* SystemMessageRouter
|
|
2
|
+
* SystemMessageRouter, routes system messages to the appropriate surfaces
|
|
3
3
|
* based on their kind and configured routing target.
|
|
4
4
|
*
|
|
5
5
|
* Delivery is resolved from the message KIND ('system' | 'wrfc' |
|
|
6
6
|
* 'operational'), which maps to a configurable routing target
|
|
7
7
|
* (ui.systemMessages / ui.wrfcMessages / ui.operationalMessages, each
|
|
8
8
|
* 'panel' | 'conversation' | 'both'). resolveSystemMessageDelivery() turns
|
|
9
|
-
* that target
|
|
9
|
+
* that target, plus whether a panel is attached, into a { toPanel,
|
|
10
10
|
* toConversation } decision.
|
|
11
11
|
*
|
|
12
12
|
* (the purge): the SystemMessagesPanel this router used to optionally
|
|
13
|
-
* push into was DELETE-disposition (no surviving human surface
|
|
13
|
+
* push into was DELETE-disposition (no surviving human surface, a picker
|
|
14
14
|
* over the old panel registry, not something worth a dedicated console) and
|
|
15
15
|
* has been removed entirely, so this router now always resolves with
|
|
16
16
|
* `hasPanel = false`. Per resolveSystemMessageDelivery's own contract that
|
|
17
17
|
* means EVERY kind/target combination (including 'panel'-only) falls back
|
|
18
|
-
* to `toConversation: true
|
|
18
|
+
* to `toConversation: true`, nothing this router routes can vanish; it all
|
|
19
19
|
* reaches conversation.addTypedSystemMessage(), which the transcript
|
|
20
20
|
* renders as a navigable system line. This is deliberate, not a regression:
|
|
21
21
|
* operational chatter that used to be tucked away in a rarely-opened panel
|
|
@@ -122,7 +122,7 @@ export class SystemMessageRouter {
|
|
|
122
122
|
_priority: SystemMessagePriority,
|
|
123
123
|
kind: SystemMessageKind,
|
|
124
124
|
): void {
|
|
125
|
-
// Noise gate
|
|
125
|
+
// Noise gate, keep first-run plumbing out of the transcript while the
|
|
126
126
|
// information stays reachable via other live surfaces. (item 1.)
|
|
127
127
|
const verdict = classifyNoise(message, this.noiseDeps);
|
|
128
128
|
if (verdict.action === 'drop') return;
|
|
@@ -137,7 +137,7 @@ export class SystemMessageRouter {
|
|
|
137
137
|
/** Post-noise-gate delivery: resolve target and append to the conversation. */
|
|
138
138
|
private deliver(message: string, kind: SystemMessageKind): void {
|
|
139
139
|
const target = this.getTargetForKind(kind);
|
|
140
|
-
// hasPanel is always false now that panel delivery was removed
|
|
140
|
+
// hasPanel is always false now that panel delivery was removed, resolveSystemMessageDelivery's own
|
|
141
141
|
// contract means every target ('panel' | 'conversation' | 'both')
|
|
142
142
|
// resolves toConversation: true in that case (see file doc).
|
|
143
143
|
const delivery = resolveSystemMessageDelivery(target, false);
|
|
@@ -166,17 +166,17 @@ export class SystemMessageRouter {
|
|
|
166
166
|
* Record the folded provider-replay summary and reset the buffer.
|
|
167
167
|
*
|
|
168
168
|
* Papercut sweep item 2: this used to `deliver()` the folded line into the
|
|
169
|
-
* transcript
|
|
169
|
+
* transcript, one line instead of a burst, but still boot plumbing the
|
|
170
170
|
* user never asked to see there ("the transcript at boot shows product
|
|
171
171
|
* signal only"). The persisted-provider set this summarizes is reachable
|
|
172
172
|
* on demand via `/health provider` (providers-modal lists every registered
|
|
173
173
|
* provider, discovered/local ones included) and `/model` (lists every
|
|
174
|
-
* selectable model, discovered ones included)
|
|
174
|
+
* selectable model, discovered ones included), so nothing is lost by
|
|
175
175
|
* keeping it out of the transcript. It still goes to the activity log
|
|
176
176
|
* (.goodvibes/logs/activity.md) for diagnosis. Only this boot-only "— from
|
|
177
177
|
* last session" burst moves; unrelated provider-discovery lines emitted
|
|
178
178
|
* mid-session (e.g. "[Scan] Found …", "[Scan] … no longer reachable") are
|
|
179
|
-
* untouched
|
|
179
|
+
* untouched, they never match PROVIDER_REPLAY_RE, so they never enter this
|
|
180
180
|
* buffer/fold path and keep reaching the transcript as live product signal.
|
|
181
181
|
*/
|
|
182
182
|
flushProviderReplay(): void {
|
|
@@ -229,7 +229,7 @@ export class SystemMessageRouter {
|
|
|
229
229
|
* Route a message that must reach the conversation unconditionally. Skips
|
|
230
230
|
* the noise gate and the configured routing target, and marks the message
|
|
231
231
|
* `isUserReceipt` so the splash check in
|
|
232
|
-
* ConversationManager.rebuildHistory() treats it as real visible content
|
|
232
|
+
* ConversationManager.rebuildHistory() treats it as real visible content,
|
|
233
233
|
* otherwise it would be invisible while the splash still owns the screen.
|
|
234
234
|
*
|
|
235
235
|
* Two callers qualify today:
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* terminal-notifier
|
|
2
|
+
* terminal-notifier, emits in-terminal desktop notifications via the OSC 9
|
|
3
3
|
* escape sequence (`ESC ] 9 ; <text> BEL`) and, optionally, an audible bell.
|
|
4
4
|
*
|
|
5
5
|
* This is distinct from the OS-level desktop notifications the alert classes in
|
|
6
6
|
* this directory fire through the SDK's notifyCompletion: OSC 9 is delivered by
|
|
7
7
|
* the terminal emulator itself, so it works over SSH and inside tmux where a
|
|
8
|
-
* host-side notify daemon is not reachable. The two are complementary
|
|
8
|
+
* host-side notify daemon is not reachable. The two are complementary, a user
|
|
9
9
|
* can enable either, both, or neither.
|
|
10
10
|
*
|
|
11
11
|
* Three signals, each with its own config toggle (documented in
|
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
*
|
|
17
17
|
* Focus rule (per the feature brief): emit only when the terminal is NOT focused
|
|
18
18
|
* if focus is knowable, and unconditionally when the terminal never reported
|
|
19
|
-
* focus
|
|
19
|
+
* focus, exactly FocusTracker.shouldAlertWhenUnfocused(). This is deliberately
|
|
20
20
|
* NOT tied to the alert classes' master `notifyOnlyWhenUnfocused` gate: an
|
|
21
21
|
* in-terminal notification only makes sense for an unattended window.
|
|
22
22
|
*
|
|
23
23
|
* Write discipline: the escape sequence goes out through allowTerminalWrite (so
|
|
24
24
|
* the terminal-output guard passes it rather than intercepting it as stray
|
|
25
25
|
* output) and NEVER after the terminal has been handed back to the shell
|
|
26
|
-
* (isReleased()
|
|
26
|
+
* (isReleased(), the same restore gate the render scheduler honors). No cursor
|
|
27
27
|
* positioning is involved, so an OSC 9 emitted between frames is safe.
|
|
28
28
|
*/
|
|
29
29
|
import { logger } from '@pellux/goodvibes-sdk/platform/utils';
|
|
@@ -64,7 +64,7 @@ export interface TerminalNotifierDeps {
|
|
|
64
64
|
readonly stdout: { write(s: string): boolean };
|
|
65
65
|
readonly configGet: ConfigGet;
|
|
66
66
|
readonly focusTracker: Pick<FocusTracker, 'shouldAlertWhenUnfocused'>;
|
|
67
|
-
/** True once the terminal has been restored to the shell
|
|
67
|
+
/** True once the terminal has been restored to the shell, no writes after that. */
|
|
68
68
|
readonly isReleased: () => boolean;
|
|
69
69
|
}
|
|
70
70
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* turn-budget-outcome.ts
|
|
2
|
+
* turn-budget-outcome.ts, render a turn-budget exhaustion as an honest budget
|
|
3
3
|
* line, distinct from an infrastructure failure.
|
|
4
4
|
*
|
|
5
5
|
* When a member agent spends its whole turn budget the SDK stamps a typed
|
|
6
|
-
* outcome
|
|
7
|
-
* input set it
|
|
6
|
+
* outcome, failureKind 'max_turns' with the ceiling that applied and which
|
|
7
|
+
* input set it, instead of leaving consumers to regex a prose message. This
|
|
8
8
|
* renders that typed outcome in plain language: a budget was reached (not a
|
|
9
9
|
* crash), with the number and where the number came from.
|
|
10
10
|
*/
|
|
@@ -30,14 +30,14 @@ export interface TurnBudgetOutcome {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
|
-
* A short budget line: "reached its turn budget
|
|
33
|
+
* A short budget line: "reached its turn budget, 50 turns (the default limit
|
|
34
34
|
* (agents.maxTurns))". Honest about the fact that the run stopped because it hit
|
|
35
35
|
* a ceiling, not because something broke.
|
|
36
36
|
*/
|
|
37
37
|
export function formatTurnBudgetOutcome(outcome: TurnBudgetOutcome): string {
|
|
38
38
|
const source = describeTurnBudgetSource(outcome.source);
|
|
39
39
|
return outcome.limit !== undefined
|
|
40
|
-
? `reached its turn budget
|
|
40
|
+
? `reached its turn budget: ${outcome.limit} turn${outcome.limit === 1 ? '' : 's'} (${source})`
|
|
41
41
|
: `reached its turn budget (${source})`;
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -7,7 +7,7 @@ import type { SpokenTurnRuntime } from '../audio/spoken-turn-wiring.ts';
|
|
|
7
7
|
* streaming. Extracted from main.ts so the file can stay under its 800-line
|
|
8
8
|
* cap while still wiring `commandContext.isGenerating` (see FIX 1).
|
|
9
9
|
*
|
|
10
|
-
* Returns whether SPEECH was actively stopped
|
|
10
|
+
* Returns whether SPEECH was actively stopped, a Ctrl+C that silenced live
|
|
11
11
|
* TTS is consumed by that job (an earlier replay fix), same as a press that
|
|
12
12
|
* cleared a non-empty prompt; the quit chord starts from a quiet state.
|
|
13
13
|
*/
|
|
@@ -35,14 +35,14 @@ export interface ToolCancelOrchestrator {
|
|
|
35
35
|
/**
|
|
36
36
|
* Builds the "cancel the running tool call" action: stops JUST the currently-
|
|
37
37
|
* running tool call, leaving the turn to continue. The in-process orchestrator
|
|
38
|
-
* holds the per-call AbortController
|
|
38
|
+
* holds the per-call AbortController, this is the local-session equivalent of
|
|
39
39
|
* the sessions.toolCalls.cancel wire verb. The cancelled call settles as a
|
|
40
40
|
* structured "cancelled by user" result (partial output preserved) the model
|
|
41
41
|
* adapts to in the same turn.
|
|
42
42
|
*
|
|
43
43
|
* Target selection is honest: the tracked active callId (the live transcript
|
|
44
44
|
* row) when known, else the sole in-flight call when exactly one is running,
|
|
45
|
-
* else nothing (returns false
|
|
45
|
+
* else nothing (returns false, never guesses which of several to stop).
|
|
46
46
|
* `onCancelled` fires only on a real cancellation, with the callId stopped.
|
|
47
47
|
*/
|
|
48
48
|
export function createCancelToolCall(
|