@oh-my-pi/pi-coding-agent 15.12.3 → 15.13.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/CHANGELOG.md +347 -7
- package/dist/cli.js +1615 -1231
- package/dist/types/async/job-manager.d.ts +15 -0
- package/dist/types/autolearn/controller.d.ts +25 -0
- package/dist/types/autolearn/managed-skills.d.ts +45 -0
- package/dist/types/autoresearch/state.d.ts +1 -1
- package/dist/types/autoresearch/tools/init-experiment.d.ts +1 -1
- package/dist/types/autoresearch/tools/log-experiment.d.ts +1 -1
- package/dist/types/autoresearch/tools/run-experiment.d.ts +1 -1
- package/dist/types/autoresearch/tools/update-notes.d.ts +1 -1
- package/dist/types/autoresearch/types.d.ts +1 -1
- package/dist/types/cli/args.d.ts +19 -2
- package/dist/types/cli/models-cli.d.ts +49 -0
- package/dist/types/cli/session-picker.d.ts +1 -1
- package/dist/types/cli/setup-cli.d.ts +1 -1
- package/dist/types/cli/setup-model-picker.d.ts +14 -0
- package/dist/types/collab/protocol.d.ts +1 -1
- package/dist/types/commands/launch.d.ts +0 -3
- package/dist/types/commands/models.d.ts +33 -0
- package/dist/types/commands/say.d.ts +24 -0
- package/dist/types/commands/token.d.ts +25 -0
- package/dist/types/commit/agentic/tools/analyze-file.d.ts +1 -1
- package/dist/types/commit/agentic/tools/git-file-diff.d.ts +1 -1
- package/dist/types/commit/agentic/tools/git-hunk.d.ts +1 -1
- package/dist/types/commit/agentic/tools/git-overview.d.ts +1 -1
- package/dist/types/commit/agentic/tools/propose-changelog.d.ts +1 -1
- package/dist/types/commit/agentic/tools/propose-commit.d.ts +1 -1
- package/dist/types/commit/agentic/tools/recent-commits.d.ts +1 -1
- package/dist/types/commit/agentic/tools/schemas.d.ts +1 -1
- package/dist/types/commit/agentic/tools/split-commit.d.ts +1 -1
- package/dist/types/commit/changelog/generate.d.ts +1 -1
- package/dist/types/commit/shared-llm.d.ts +1 -1
- package/dist/types/config/keybindings.d.ts +3 -3
- package/dist/types/config/model-registry.d.ts +17 -0
- package/dist/types/config/models-config-schema.d.ts +13 -1
- package/dist/types/config/models-config.d.ts +8 -2
- package/dist/types/config/settings-schema.d.ts +281 -58
- package/dist/types/edit/hashline/params.d.ts +1 -1
- package/dist/types/edit/modes/apply-patch.d.ts +1 -1
- package/dist/types/edit/modes/patch.d.ts +1 -1
- package/dist/types/edit/modes/replace.d.ts +1 -1
- package/dist/types/export/html/index.d.ts +2 -1
- package/dist/types/extensibility/custom-commands/types.d.ts +2 -2
- package/dist/types/extensibility/custom-tools/types.d.ts +2 -2
- package/dist/types/extensibility/extensions/model-api.d.ts +17 -0
- package/dist/types/extensibility/extensions/runner.d.ts +3 -1
- package/dist/types/extensibility/extensions/types.d.ts +49 -3
- package/dist/types/extensibility/hooks/index.d.ts +2 -1
- package/dist/types/extensibility/hooks/types.d.ts +2 -2
- package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +9 -0
- package/dist/types/extensibility/plugins/loader.d.ts +11 -0
- package/dist/types/extensibility/shared-events.d.ts +1 -1
- package/dist/types/extensibility/skills.d.ts +10 -0
- package/dist/types/goals/guided-setup.d.ts +18 -0
- package/dist/types/goals/state.d.ts +1 -1
- package/dist/types/goals/tools/goal-tool.d.ts +1 -1
- package/dist/types/hindsight/transcript.d.ts +1 -1
- package/dist/types/index.d.ts +5 -0
- package/dist/types/internal-urls/local-protocol.d.ts +4 -2
- package/dist/types/lsp/types.d.ts +1 -1
- package/dist/types/main.d.ts +4 -3
- package/dist/types/mcp/manager.d.ts +8 -0
- package/dist/types/mcp/startup-events.d.ts +11 -0
- package/dist/types/memories/index.d.ts +7 -0
- package/dist/types/memory-backend/local-backend.d.ts +4 -3
- package/dist/types/mnemopi/config.d.ts +28 -0
- package/dist/types/modes/acp/acp-agent.d.ts +1 -2
- package/dist/types/modes/components/agent-hub.d.ts +6 -0
- package/dist/types/modes/components/assistant-message.d.ts +1 -2
- package/dist/types/modes/components/compaction-summary-message.d.ts +15 -1
- package/dist/types/modes/components/custom-editor.d.ts +39 -1
- package/dist/types/modes/components/custom-editor.test.d.ts +1 -0
- package/dist/types/modes/components/index.d.ts +1 -0
- package/dist/types/modes/components/logout-account-selector.d.ts +8 -0
- package/dist/types/modes/components/session-selector.d.ts +1 -1
- package/dist/types/modes/components/status-line/component.d.ts +9 -5
- package/dist/types/modes/components/status-line/types.d.ts +2 -1
- package/dist/types/modes/components/tool-execution.d.ts +26 -16
- package/dist/types/modes/components/transcript-container.d.ts +23 -2
- package/dist/types/modes/components/tree-selector.d.ts +1 -1
- package/dist/types/modes/components/usage-row.d.ts +3 -0
- package/dist/types/modes/controllers/command-controller.d.ts +2 -2
- package/dist/types/modes/controllers/event-controller.d.ts +0 -17
- package/dist/types/modes/controllers/input-controller.d.ts +14 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +3 -1
- package/dist/types/modes/gradient-highlight.d.ts +9 -4
- package/dist/types/modes/image-references.d.ts +6 -0
- package/dist/types/modes/interactive-mode.d.ts +27 -6
- package/dist/types/modes/magic-keywords.d.ts +13 -1
- package/dist/types/modes/rpc/rpc-mode.d.ts +35 -1
- package/dist/types/modes/rpc/rpc-types.d.ts +9 -1
- package/dist/types/modes/runtime-init.d.ts +4 -0
- package/dist/types/modes/theme/theme.d.ts +13 -2
- package/dist/types/modes/types.d.ts +8 -7
- package/dist/types/modes/utils/ui-helpers.d.ts +1 -1
- package/dist/types/registry/agent-registry.d.ts +17 -0
- package/dist/types/secrets/obfuscator.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +28 -35
- package/dist/types/session/agent-storage.d.ts +2 -1
- package/dist/types/session/indexed-session-storage.d.ts +3 -3
- package/dist/types/session/messages.d.ts +8 -10
- package/dist/types/session/session-context.d.ts +39 -0
- package/dist/types/session/session-entries.d.ts +159 -0
- package/dist/types/session/session-listing.d.ts +69 -0
- package/dist/types/session/session-loader.d.ts +16 -0
- package/dist/types/session/session-manager.d.ts +85 -462
- package/dist/types/session/session-migrations.d.ts +12 -0
- package/dist/types/session/session-paths.d.ts +25 -0
- package/dist/types/session/session-persistence.d.ts +8 -0
- package/dist/types/session/session-storage.d.ts +11 -7
- package/dist/types/session/snapcompact-inline.d.ts +12 -1
- package/dist/types/session/snapcompact-savings-journal.d.ts +46 -0
- package/dist/types/session/tool-choice-queue.d.ts +6 -6
- package/dist/types/slash-commands/helpers/logout.d.ts +15 -0
- package/dist/types/stt/asr-client.d.ts +90 -0
- package/dist/types/stt/asr-protocol.d.ts +97 -0
- package/dist/types/stt/asr-worker.d.ts +2 -0
- package/dist/types/stt/downloader.d.ts +38 -0
- package/dist/types/stt/endpointer.d.ts +59 -0
- package/dist/types/stt/index.d.ts +5 -1
- package/dist/types/stt/models.d.ts +120 -0
- package/dist/types/stt/recorder.d.ts +17 -0
- package/dist/types/stt/stt-controller.d.ts +6 -0
- package/dist/types/stt/transcriber.d.ts +5 -7
- package/dist/types/stt/wav.d.ts +29 -0
- package/dist/types/system-prompt.d.ts +4 -0
- package/dist/types/task/executor.d.ts +2 -0
- package/dist/types/task/index.d.ts +9 -1
- package/dist/types/task/types.d.ts +37 -1
- package/dist/types/tools/ask.d.ts +1 -1
- package/dist/types/tools/ast-edit.d.ts +1 -1
- package/dist/types/tools/ast-grep.d.ts +1 -1
- package/dist/types/tools/bash.d.ts +3 -3
- package/dist/types/tools/browser/cmux/cmux-tab.d.ts +202 -0
- package/dist/types/tools/browser/cmux/rpc.d.ts +70 -0
- package/dist/types/tools/browser/cmux/socket-client.d.ts +19 -0
- package/dist/types/tools/browser/registry.d.ts +16 -3
- package/dist/types/tools/browser/render.d.ts +2 -0
- package/dist/types/tools/browser/tab-protocol.d.ts +2 -0
- package/dist/types/tools/browser/tab-supervisor.d.ts +16 -4
- package/dist/types/tools/browser.d.ts +3 -1
- package/dist/types/tools/checkpoint.d.ts +1 -1
- package/dist/types/tools/debug.d.ts +1 -1
- package/dist/types/tools/eval-render.d.ts +1 -1
- package/dist/types/tools/eval.d.ts +1 -1
- package/dist/types/tools/find.d.ts +1 -1
- package/dist/types/tools/gh.d.ts +1 -1
- package/dist/types/tools/image-gen.d.ts +1 -1
- package/dist/types/tools/index.d.ts +14 -2
- package/dist/types/tools/inspect-image.d.ts +1 -1
- package/dist/types/tools/irc.d.ts +2 -1
- package/dist/types/tools/job.d.ts +1 -1
- package/dist/types/tools/learn.d.ts +51 -0
- package/dist/types/tools/manage-skill.d.ts +40 -0
- package/dist/types/tools/memory-edit.d.ts +1 -1
- package/dist/types/tools/memory-recall.d.ts +1 -1
- package/dist/types/tools/memory-reflect.d.ts +1 -1
- package/dist/types/tools/memory-retain.d.ts +1 -1
- package/dist/types/tools/plan-mode-guard.d.ts +10 -0
- package/dist/types/tools/read.d.ts +1 -1
- package/dist/types/tools/render-mermaid.d.ts +1 -1
- package/dist/types/tools/renderers.d.ts +7 -11
- package/dist/types/tools/resolve.d.ts +1 -1
- package/dist/types/tools/review.d.ts +1 -1
- package/dist/types/tools/search-tool-bm25.d.ts +1 -1
- package/dist/types/tools/search.d.ts +1 -1
- package/dist/types/tools/ssh.d.ts +2 -2
- package/dist/types/tools/todo.d.ts +2 -2
- package/dist/types/tools/tts.d.ts +26 -1
- package/dist/types/tools/write.d.ts +2 -2
- package/dist/types/tts/downloader.d.ts +20 -0
- package/dist/types/tts/index.d.ts +8 -0
- package/dist/types/tts/models.d.ts +82 -0
- package/dist/types/tts/player.d.ts +32 -0
- package/dist/types/tts/runtime.d.ts +6 -0
- package/dist/types/tts/streaming-player.d.ts +41 -0
- package/dist/types/tts/tts-client.d.ts +93 -0
- package/dist/types/tts/tts-protocol.d.ts +95 -0
- package/dist/types/tts/tts-worker.d.ts +2 -0
- package/dist/types/tts/vocalizer.d.ts +41 -0
- package/dist/types/tts/wav.d.ts +8 -0
- package/dist/types/utils/clipboard.d.ts +4 -3
- package/dist/types/utils/image-loading.d.ts +18 -1
- package/dist/types/utils/thinking-display.d.ts +17 -0
- package/dist/types/utils/tool-choice.d.ts +8 -0
- package/dist/types/utils/tools-manager.d.ts +2 -1
- package/dist/types/utils/tools-manager.test.d.ts +1 -0
- package/dist/types/web/scrapers/github.d.ts +1 -1
- package/dist/types/web/search/index.d.ts +1 -1
- package/package.json +17 -16
- package/src/async/job-manager.ts +49 -0
- package/src/autolearn/controller.ts +139 -0
- package/src/autolearn/managed-skills.ts +257 -0
- package/src/autoresearch/state.ts +1 -1
- package/src/autoresearch/storage.ts +2 -1
- package/src/autoresearch/tools/init-experiment.ts +1 -1
- package/src/autoresearch/tools/log-experiment.ts +1 -1
- package/src/autoresearch/tools/run-experiment.ts +1 -1
- package/src/autoresearch/tools/update-notes.ts +1 -1
- package/src/autoresearch/types.ts +1 -1
- package/src/cli/args.ts +56 -10
- package/src/cli/auth-gateway-cli.ts +1 -1
- package/src/cli/bench-cli.ts +1 -1
- package/src/cli/dry-balance-cli.ts +1 -1
- package/src/cli/models-cli.ts +427 -0
- package/src/cli/session-picker.ts +2 -1
- package/src/cli/setup-cli.ts +148 -47
- package/src/cli/setup-model-picker.ts +43 -0
- package/src/cli-commands.ts +3 -0
- package/src/cli.ts +45 -13
- package/src/collab/host.ts +10 -13
- package/src/collab/protocol.ts +1 -1
- package/src/commands/launch.ts +0 -3
- package/src/commands/models.ts +61 -0
- package/src/commands/say.ts +102 -0
- package/src/commands/setup.ts +1 -1
- package/src/commands/token.ts +89 -0
- package/src/commit/agentic/tools/analyze-file.ts +4 -1
- package/src/commit/agentic/tools/git-file-diff.ts +1 -1
- package/src/commit/agentic/tools/git-hunk.ts +1 -1
- package/src/commit/agentic/tools/git-overview.ts +1 -1
- package/src/commit/agentic/tools/propose-changelog.ts +1 -1
- package/src/commit/agentic/tools/propose-commit.ts +1 -1
- package/src/commit/agentic/tools/recent-commits.ts +1 -1
- package/src/commit/agentic/tools/schemas.ts +1 -1
- package/src/commit/agentic/tools/split-commit.ts +1 -1
- package/src/commit/analysis/summary.ts +1 -1
- package/src/commit/changelog/generate.ts +1 -1
- package/src/commit/shared-llm.ts +1 -1
- package/src/config/keybindings.ts +2 -2
- package/src/config/model-discovery.ts +11 -5
- package/src/config/model-registry.ts +79 -21
- package/src/config/model-resolver.ts +2 -2
- package/src/config/models-config-schema.ts +5 -2
- package/src/config/models-config.ts +2 -1
- package/src/config/settings-schema.ts +266 -32
- package/src/config/settings.ts +10 -0
- package/src/discovery/builtin.ts +23 -1
- package/src/discovery/claude-plugins.ts +44 -5
- package/src/discovery/helpers.ts +41 -1
- package/src/edit/hashline/params.ts +1 -1
- package/src/edit/modes/apply-patch.ts +1 -1
- package/src/edit/modes/patch.ts +1 -1
- package/src/edit/modes/replace.ts +1 -1
- package/src/eval/__tests__/budget-bridge.test.ts +1 -1
- package/src/eval/agent-bridge.ts +1 -1
- package/src/eval/completion-bridge.ts +1 -1
- package/src/eval/js/shared/prelude.txt +69 -17
- package/src/export/html/index.ts +3 -6
- package/src/export/html/template.js +24 -2
- package/src/export/html/tool-views.generated.js +2 -2
- package/src/extensibility/custom-commands/loader.ts +1 -1
- package/src/extensibility/custom-commands/types.ts +2 -2
- package/src/extensibility/custom-tools/loader.ts +1 -1
- package/src/extensibility/custom-tools/types.ts +2 -2
- package/src/extensibility/extensions/loader.ts +2 -2
- package/src/extensibility/extensions/model-api.ts +41 -0
- package/src/extensibility/extensions/runner.ts +4 -0
- package/src/extensibility/extensions/types.ts +54 -3
- package/src/extensibility/extensions/wrapper.ts +41 -5
- package/src/extensibility/hooks/index.ts +2 -1
- package/src/extensibility/hooks/loader.ts +1 -1
- package/src/extensibility/hooks/types.ts +2 -2
- package/src/extensibility/plugins/legacy-pi-compat.ts +43 -13
- package/src/extensibility/plugins/loader.ts +30 -19
- package/src/extensibility/plugins/manager.ts +221 -90
- package/src/extensibility/shared-events.ts +1 -1
- package/src/extensibility/skills.ts +101 -5
- package/src/goals/guided-setup.ts +133 -0
- package/src/goals/state.ts +1 -1
- package/src/goals/tools/goal-tool.ts +1 -1
- package/src/hindsight/transcript.ts +1 -1
- package/src/index.ts +5 -0
- package/src/internal-urls/docs-index.generated.ts +13 -10
- package/src/internal-urls/history-protocol.ts +1 -1
- package/src/internal-urls/local-protocol.ts +29 -7
- package/src/lsp/types.ts +1 -1
- package/src/main.ts +27 -32
- package/src/mcp/config-writer.ts +7 -3
- package/src/mcp/manager.ts +11 -0
- package/src/mcp/startup-events.ts +21 -0
- package/src/mcp/transports/stdio.ts +2 -1
- package/src/memories/index.ts +149 -12
- package/src/memories/storage.ts +2 -1
- package/src/memory-backend/local-backend.ts +11 -5
- package/src/mnemopi/backend.ts +1 -0
- package/src/mnemopi/config.ts +112 -12
- package/src/modes/acp/acp-agent.ts +8 -53
- package/src/modes/acp/acp-event-mapper.ts +5 -1
- package/src/modes/components/agent-hub.ts +51 -5
- package/src/modes/components/assistant-message.ts +12 -44
- package/src/modes/components/compaction-summary-message.ts +125 -26
- package/src/modes/components/custom-editor.test.ts +96 -0
- package/src/modes/components/custom-editor.ts +164 -8
- package/src/modes/components/index.ts +1 -0
- package/src/modes/components/logout-account-selector.ts +130 -0
- package/src/modes/components/mcp-add-wizard.ts +1 -1
- package/src/modes/components/model-selector.ts +2 -2
- package/src/modes/components/session-selector.ts +1 -1
- package/src/modes/components/settings-defs.ts +7 -0
- package/src/modes/components/status-line/component.ts +54 -157
- package/src/modes/components/status-line/segments.ts +1 -1
- package/src/modes/components/status-line/types.ts +2 -1
- package/src/modes/components/tool-execution.ts +82 -43
- package/src/modes/components/transcript-container.ts +70 -1
- package/src/modes/components/tree-selector.ts +1 -1
- package/src/modes/components/usage-row.ts +18 -0
- package/src/modes/components/user-message.ts +4 -2
- package/src/modes/controllers/command-controller.ts +14 -16
- package/src/modes/controllers/event-controller.ts +101 -73
- package/src/modes/controllers/extension-ui-controller.ts +6 -0
- package/src/modes/controllers/input-controller.ts +311 -57
- package/src/modes/controllers/mcp-command-controller.ts +44 -3
- package/src/modes/controllers/selector-controller.ts +68 -12
- package/src/modes/controllers/streaming-reveal.ts +4 -3
- package/src/modes/gradient-highlight.ts +21 -9
- package/src/modes/image-references.ts +20 -0
- package/src/modes/interactive-mode.ts +288 -48
- package/src/modes/magic-keywords.ts +27 -5
- package/src/modes/rpc/rpc-mode.ts +146 -14
- package/src/modes/rpc/rpc-subagents.ts +2 -2
- package/src/modes/rpc/rpc-types.ts +8 -2
- package/src/modes/runtime-init.ts +28 -3
- package/src/modes/theme/theme.ts +99 -51
- package/src/modes/types.ts +6 -7
- package/src/modes/utils/hotkeys-markdown.ts +1 -1
- package/src/modes/utils/ui-helpers.ts +36 -7
- package/src/priority.json +5 -1
- package/src/prompts/agents/task.md +1 -0
- package/src/prompts/goals/guided-goal-interview.md +8 -0
- package/src/prompts/goals/guided-goal-system.md +12 -0
- package/src/prompts/memories/read-path.md +6 -0
- package/src/prompts/system/autolearn-guidance-learn.md +1 -0
- package/src/prompts/system/autolearn-guidance.md +7 -0
- package/src/prompts/system/autolearn-nudge.md +3 -0
- package/src/prompts/system/eager-task.md +7 -0
- package/src/prompts/system/eager-todo.md +11 -6
- package/src/prompts/system/empty-stop-retry.md +4 -6
- package/src/prompts/system/subagent-system-prompt.md +4 -0
- package/src/prompts/system/system-prompt.md +10 -5
- package/src/prompts/system/title-marker-instruction.md +1 -0
- package/src/prompts/system/title-system-marker.md +16 -0
- package/src/prompts/tools/job.md +1 -0
- package/src/prompts/tools/learn.md +7 -0
- package/src/prompts/tools/manage-skill.md +9 -0
- package/src/prompts/tools/task.md +3 -0
- package/src/registry/agent-registry.ts +30 -0
- package/src/sdk.ts +103 -43
- package/src/secrets/obfuscator.ts +1 -1
- package/src/session/agent-session.ts +331 -318
- package/src/session/agent-storage.ts +18 -9
- package/src/session/history-storage.ts +3 -2
- package/src/session/indexed-session-storage.ts +7 -10
- package/src/session/messages.ts +9 -11
- package/src/session/session-context.ts +352 -0
- package/src/session/session-dump-format.ts +4 -2
- package/src/session/session-entries.ts +194 -0
- package/src/session/session-listing.ts +588 -0
- package/src/session/session-loader.ts +106 -0
- package/src/session/session-manager.ts +968 -3064
- package/src/session/session-migrations.ts +78 -0
- package/src/session/session-paths.ts +193 -0
- package/src/session/session-persistence.ts +131 -0
- package/src/session/session-storage.ts +91 -30
- package/src/session/snapcompact-inline.ts +21 -1
- package/src/session/snapcompact-savings-journal.ts +113 -0
- package/src/session/tool-choice-queue.ts +23 -11
- package/src/slash-commands/builtin-registry.ts +40 -4
- package/src/slash-commands/helpers/logout.ts +88 -0
- package/src/stt/asr-client.ts +520 -0
- package/src/stt/asr-protocol.ts +65 -0
- package/src/stt/asr-worker.ts +790 -0
- package/src/stt/downloader.ts +107 -47
- package/src/stt/endpointer.ts +259 -0
- package/src/stt/index.ts +5 -1
- package/src/stt/models.ts +150 -0
- package/src/stt/recorder.ts +247 -60
- package/src/stt/stt-controller.ts +201 -22
- package/src/stt/transcriber.ts +37 -68
- package/src/stt/wav.ts +173 -0
- package/src/system-prompt.ts +8 -0
- package/src/task/agents.ts +1 -2
- package/src/task/executor.ts +49 -15
- package/src/task/index.ts +60 -6
- package/src/task/render.ts +83 -8
- package/src/task/types.ts +54 -1
- package/src/tools/ask.ts +9 -1
- package/src/tools/ast-edit.ts +1 -1
- package/src/tools/ast-grep.ts +1 -1
- package/src/tools/bash.ts +5 -4
- package/src/tools/browser/cmux/cmux-tab.ts +1264 -0
- package/src/tools/browser/cmux/rpc.ts +156 -0
- package/src/tools/browser/cmux/socket-client.ts +309 -0
- package/src/tools/browser/registry.ts +37 -3
- package/src/tools/browser/render.ts +6 -1
- package/src/tools/browser/tab-protocol.ts +2 -0
- package/src/tools/browser/tab-supervisor.ts +189 -18
- package/src/tools/browser/tab-worker.ts +1 -1
- package/src/tools/browser.ts +16 -1
- package/src/tools/checkpoint.ts +1 -1
- package/src/tools/debug.ts +1 -1
- package/src/tools/eval-render.ts +4 -3
- package/src/tools/eval.ts +11 -6
- package/src/tools/fetch.ts +13 -2
- package/src/tools/find.ts +1 -1
- package/src/tools/gh.ts +1 -1
- package/src/tools/github-cache.ts +2 -1
- package/src/tools/image-gen.ts +1 -1
- package/src/tools/index.ts +43 -5
- package/src/tools/inspect-image.ts +3 -1
- package/src/tools/irc.ts +11 -3
- package/src/tools/job.ts +15 -3
- package/src/tools/learn.ts +144 -0
- package/src/tools/manage-skill.ts +104 -0
- package/src/tools/memory-edit.ts +1 -1
- package/src/tools/memory-recall.ts +1 -1
- package/src/tools/memory-reflect.ts +1 -1
- package/src/tools/memory-retain.ts +1 -1
- package/src/tools/plan-mode-guard.ts +53 -19
- package/src/tools/read.ts +8 -2
- package/src/tools/render-mermaid.ts +1 -1
- package/src/tools/renderers.ts +7 -11
- package/src/tools/report-tool-issue.ts +3 -2
- package/src/tools/resolve.ts +1 -1
- package/src/tools/review.ts +1 -1
- package/src/tools/search-tool-bm25.ts +1 -1
- package/src/tools/search.ts +1 -1
- package/src/tools/ssh.ts +5 -4
- package/src/tools/todo.ts +2 -2
- package/src/tools/tts.ts +204 -93
- package/src/tools/write.ts +19 -3
- package/src/tts/downloader.ts +64 -0
- package/src/tts/index.ts +8 -0
- package/src/tts/models.ts +137 -0
- package/src/tts/player.ts +137 -0
- package/src/tts/runtime.ts +21 -0
- package/src/tts/streaming-player.ts +266 -0
- package/src/tts/tts-client.ts +647 -0
- package/src/tts/tts-protocol.ts +60 -0
- package/src/tts/tts-worker.ts +497 -0
- package/src/tts/vocalizer.ts +162 -0
- package/src/tts/wav.ts +58 -0
- package/src/utils/clipboard.ts +35 -18
- package/src/utils/image-loading.ts +35 -4
- package/src/utils/thinking-display.ts +37 -0
- package/src/utils/title-generator.ts +48 -5
- package/src/utils/tool-choice.ts +16 -0
- package/src/utils/tools-manager.test.ts +25 -0
- package/src/utils/tools-manager.ts +19 -1
- package/src/web/scrapers/github.ts +96 -0
- package/src/web/search/index.ts +14 -1
- package/src/web/search/providers/searxng.ts +13 -1
- package/dist/types/cli/list-models.d.ts +0 -30
- package/dist/types/stt/setup.d.ts +0 -18
- package/src/cli/list-models.ts +0 -194
- package/src/stt/setup.ts +0 -52
- package/src/stt/transcribe.py +0 -70
package/src/cli/setup-cli.ts
CHANGED
|
@@ -4,12 +4,18 @@
|
|
|
4
4
|
* Handles `omp setup` for onboarding and `omp setup <component>` for optional dependencies.
|
|
5
5
|
*/
|
|
6
6
|
import * as path from "node:path";
|
|
7
|
-
import { $which, APP_NAME, getPythonEnvDir } from "@oh-my-pi/pi-utils";
|
|
7
|
+
import { $which, APP_NAME, getProjectDir, getPythonEnvDir } from "@oh-my-pi/pi-utils";
|
|
8
8
|
import { $ } from "bun";
|
|
9
9
|
import chalk from "chalk";
|
|
10
|
+
import { Settings, settings } from "../config/settings";
|
|
10
11
|
import { theme } from "../modes/theme/theme";
|
|
12
|
+
import { downloadSttModel, isSttModelCached } from "../stt/downloader";
|
|
13
|
+
import { isSttModelKey, STT_MODEL_OPTIONS } from "../stt/models";
|
|
14
|
+
import { detectRecorder, ensureRecorder } from "../stt/recorder";
|
|
15
|
+
import { downloadTtsModel, isTtsLocalModelKey, isTtsModelCached, TTS_LOCAL_MODEL_OPTIONS } from "../tts";
|
|
16
|
+
import { selectSetupModel } from "./setup-model-picker";
|
|
11
17
|
|
|
12
|
-
export type SetupComponent = "python" | "
|
|
18
|
+
export type SetupComponent = "python" | "speech";
|
|
13
19
|
|
|
14
20
|
export interface SetupCommandArgs {
|
|
15
21
|
component: SetupComponent;
|
|
@@ -19,7 +25,7 @@ export interface SetupCommandArgs {
|
|
|
19
25
|
};
|
|
20
26
|
}
|
|
21
27
|
|
|
22
|
-
const VALID_COMPONENTS: SetupComponent[] = ["python", "
|
|
28
|
+
const VALID_COMPONENTS: SetupComponent[] = ["python", "speech"];
|
|
23
29
|
|
|
24
30
|
const MANAGED_PYTHON_ENV = getPythonEnvDir();
|
|
25
31
|
|
|
@@ -114,8 +120,8 @@ export async function runSetupCommand(cmd: SetupCommandArgs): Promise<void> {
|
|
|
114
120
|
case "python":
|
|
115
121
|
await handlePythonSetup(cmd.flags);
|
|
116
122
|
break;
|
|
117
|
-
case "
|
|
118
|
-
await
|
|
123
|
+
case "speech":
|
|
124
|
+
await handleSpeechSetup(cmd.flags);
|
|
119
125
|
break;
|
|
120
126
|
}
|
|
121
127
|
}
|
|
@@ -149,58 +155,153 @@ async function handlePythonSetup(flags: { json?: boolean; check?: boolean }): Pr
|
|
|
149
155
|
process.exit(1);
|
|
150
156
|
}
|
|
151
157
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
158
|
+
/**
|
|
159
|
+
* One installable speech dependency. `isReady`/`status` are read-only probes;
|
|
160
|
+
* `pick` (optional) lets an interactive user choose + persist a model; `ensure`
|
|
161
|
+
* performs the download, streaming a normalized progress event.
|
|
162
|
+
*/
|
|
163
|
+
interface SpeechComponent {
|
|
164
|
+
name: string;
|
|
165
|
+
isReady(): Promise<boolean>;
|
|
166
|
+
status(): Promise<string>;
|
|
167
|
+
pick?(): Promise<boolean>;
|
|
168
|
+
ensure(onProgress: (progress: { stage: string; percent?: number }) => void): Promise<void>;
|
|
169
|
+
}
|
|
155
170
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
171
|
+
function buildSpeechComponents(): SpeechComponent[] {
|
|
172
|
+
return [
|
|
173
|
+
{
|
|
174
|
+
name: "Recorder",
|
|
175
|
+
isReady: async () => detectRecorder() !== null,
|
|
176
|
+
status: async () => {
|
|
177
|
+
const recorder = detectRecorder();
|
|
178
|
+
return recorder ? `${recorder.tool} (${recorder.bin})` : "none — ffmpeg will be downloaded";
|
|
179
|
+
},
|
|
180
|
+
ensure: async onProgress => {
|
|
181
|
+
await ensureRecorder(onProgress);
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
name: "Speech-to-Text model",
|
|
186
|
+
isReady: () => isSttModelCached(settings.get("stt.modelName")),
|
|
187
|
+
status: async () => {
|
|
188
|
+
const key = settings.get("stt.modelName");
|
|
189
|
+
return (await isSttModelCached(key)) ? key : `${key} — not downloaded`;
|
|
190
|
+
},
|
|
191
|
+
pick: async () => {
|
|
192
|
+
const chosen = await selectSetupModel(
|
|
193
|
+
"Speech-to-Text model",
|
|
194
|
+
[...STT_MODEL_OPTIONS],
|
|
195
|
+
settings.get("stt.modelName"),
|
|
196
|
+
);
|
|
197
|
+
if (chosen === null) return false;
|
|
198
|
+
if (isSttModelKey(chosen)) {
|
|
199
|
+
settings.set("stt.modelName", chosen);
|
|
200
|
+
await settings.flush();
|
|
201
|
+
}
|
|
202
|
+
return true;
|
|
203
|
+
},
|
|
204
|
+
ensure: onProgress =>
|
|
205
|
+
downloadSttModel(settings.get("stt.modelName"), progress =>
|
|
206
|
+
onProgress({ stage: `Downloading ${progress.label} model`, percent: progress.percent }),
|
|
207
|
+
),
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
name: "Text-to-Speech model",
|
|
211
|
+
isReady: () => isTtsModelCached(settings.get("tts.localModel")),
|
|
212
|
+
status: async () => {
|
|
213
|
+
const key = settings.get("tts.localModel");
|
|
214
|
+
return (await isTtsModelCached(key)) ? key : `${key} — model/runtime not installed`;
|
|
215
|
+
},
|
|
216
|
+
pick: async () => {
|
|
217
|
+
const chosen = await selectSetupModel(
|
|
218
|
+
"Text-to-Speech model",
|
|
219
|
+
[...TTS_LOCAL_MODEL_OPTIONS],
|
|
220
|
+
settings.get("tts.localModel"),
|
|
221
|
+
);
|
|
222
|
+
if (chosen === null) return false;
|
|
223
|
+
if (isTtsLocalModelKey(chosen)) {
|
|
224
|
+
settings.set("tts.localModel", chosen);
|
|
225
|
+
await settings.flush();
|
|
226
|
+
}
|
|
227
|
+
return true;
|
|
228
|
+
},
|
|
229
|
+
ensure: async onProgress => {
|
|
230
|
+
const ok = await downloadTtsModel(settings.get("tts.localModel"), progress =>
|
|
231
|
+
onProgress({ stage: progress.stage, percent: progress.percent }),
|
|
232
|
+
);
|
|
233
|
+
if (!ok) throw new Error("Failed to download the local text-to-speech model.");
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
];
|
|
237
|
+
}
|
|
161
238
|
|
|
162
|
-
|
|
239
|
+
/**
|
|
240
|
+
* Unified `omp setup speech` flow. Drives every {@link SpeechComponent} through
|
|
241
|
+
* one path: report (`--json`/`--check`) or install (interactive pick + ensure
|
|
242
|
+
* with single-line progress; non-TTY skips pickers and installs configured
|
|
243
|
+
* values).
|
|
244
|
+
*/
|
|
245
|
+
async function handleSpeechSetup(flags: { json?: boolean; check?: boolean }): Promise<void> {
|
|
246
|
+
await Settings.init({ cwd: getProjectDir() });
|
|
247
|
+
const components = buildSpeechComponents();
|
|
163
248
|
|
|
164
|
-
if (
|
|
165
|
-
|
|
249
|
+
if (flags.json) {
|
|
250
|
+
const report: Record<string, { ready: boolean; status: string }> = {};
|
|
251
|
+
let allReady = true;
|
|
252
|
+
for (const component of components) {
|
|
253
|
+
const ready = await component.isReady();
|
|
254
|
+
if (!ready) allReady = false;
|
|
255
|
+
report[component.name] = { ready, status: await component.status() };
|
|
256
|
+
}
|
|
257
|
+
console.log(JSON.stringify(report, null, 2));
|
|
258
|
+
if (!allReady) process.exit(1);
|
|
166
259
|
return;
|
|
167
260
|
}
|
|
168
261
|
|
|
169
262
|
if (flags.check) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
console.error(chalk.yellow(`\n${theme.status.warning} No recording tool found`));
|
|
181
|
-
console.error(chalk.dim(status.recorder.installHint));
|
|
263
|
+
console.log(chalk.bold("Speech dependencies:"));
|
|
264
|
+
let allReady = true;
|
|
265
|
+
for (const component of components) {
|
|
266
|
+
const ready = await component.isReady();
|
|
267
|
+
if (!ready) allReady = false;
|
|
268
|
+
const mark = ready ? chalk.green("[ok]") : chalk.yellow("[missing]");
|
|
269
|
+
console.log(` ${mark} ${component.name}: ${await component.status()}`);
|
|
270
|
+
}
|
|
271
|
+
if (!allReady) process.exit(1);
|
|
272
|
+
return;
|
|
182
273
|
}
|
|
183
274
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if (
|
|
190
|
-
console.
|
|
191
|
-
|
|
275
|
+
const interactive = Boolean(process.stdout.isTTY);
|
|
276
|
+
for (const component of components) {
|
|
277
|
+
if (interactive && component.pick) {
|
|
278
|
+
await component.pick();
|
|
279
|
+
}
|
|
280
|
+
if (await component.isReady()) {
|
|
281
|
+
console.log(chalk.green(`${theme.status.success} ${component.name} ready`));
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
console.log(chalk.dim(`Preparing ${component.name}...`));
|
|
285
|
+
try {
|
|
286
|
+
await component.ensure(progress => {
|
|
287
|
+
const percent = typeof progress.percent === "number" ? ` (${progress.percent}%)` : "";
|
|
288
|
+
process.stdout.write(`\r${chalk.dim(`${progress.stage}${percent}`)}\x1b[K`);
|
|
289
|
+
});
|
|
290
|
+
process.stdout.write("\n");
|
|
291
|
+
} catch (err) {
|
|
292
|
+
process.stdout.write("\n");
|
|
293
|
+
const msg = err instanceof Error ? err.message : `Failed to set up ${component.name}`;
|
|
294
|
+
console.error(chalk.red(`${theme.status.error} ${msg}`));
|
|
192
295
|
process.exit(1);
|
|
193
296
|
}
|
|
194
297
|
}
|
|
195
298
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
process.exit(1);
|
|
203
|
-
}
|
|
299
|
+
console.log(chalk.green(`\n${theme.status.success} Speech is ready`));
|
|
300
|
+
console.log(
|
|
301
|
+
chalk.dim(
|
|
302
|
+
"Enable speech-to-text via stt.enabled, then hold Space to talk (or bind app.stt.toggle); enable the speech-generation tool via speechgen.enabled; speak replies aloud via speech.enabled.",
|
|
303
|
+
),
|
|
304
|
+
);
|
|
204
305
|
}
|
|
205
306
|
|
|
206
307
|
/**
|
|
@@ -215,7 +316,7 @@ ${chalk.bold("Usage:")}
|
|
|
215
316
|
|
|
216
317
|
${chalk.bold("Components:")}
|
|
217
318
|
python Verify a Python 3 interpreter is reachable for code execution
|
|
218
|
-
|
|
319
|
+
speech Pick + download the speech-to-text and text-to-speech models and an audio recorder
|
|
219
320
|
|
|
220
321
|
${chalk.bold("Options:")}
|
|
221
322
|
-c, --check Check if dependencies are installed without installing
|
|
@@ -224,8 +325,8 @@ ${chalk.bold("Options:")}
|
|
|
224
325
|
${chalk.bold("Examples:")}
|
|
225
326
|
${APP_NAME} setup Run the onboarding wizard
|
|
226
327
|
${APP_NAME} setup python Check Python execution dependencies
|
|
227
|
-
${APP_NAME} setup
|
|
228
|
-
${APP_NAME} setup
|
|
328
|
+
${APP_NAME} setup speech Set up speech (pick STT + TTS models, install a recorder)
|
|
329
|
+
${APP_NAME} setup speech --check Check if speech dependencies are available
|
|
229
330
|
${APP_NAME} setup python --check Check if Python execution is available
|
|
230
331
|
`);
|
|
231
332
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standalone TUI model picker used by `omp setup speech`.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors {@link ./session-picker.ts} for the standalone-TUI lifecycle: spin up
|
|
5
|
+
* a one-shot {@link TUI} over a {@link SelectList}, resolve on select/cancel, and
|
|
6
|
+
* tear the UI down. The standalone TUI auto-renders on input, so no manual
|
|
7
|
+
* render wiring is needed beyond `addChild`/`setFocus`/`start`.
|
|
8
|
+
*/
|
|
9
|
+
import { ProcessTerminal, type SelectItem, SelectList, TUI } from "@oh-my-pi/pi-tui";
|
|
10
|
+
import { getSelectListTheme } from "../modes/theme/theme";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Show a single-column model picker and resolve with the chosen item's value,
|
|
14
|
+
* or `null` if the user cancelled. `currentValue` pre-selects the matching row.
|
|
15
|
+
*/
|
|
16
|
+
export async function selectSetupModel(
|
|
17
|
+
title: string,
|
|
18
|
+
items: SelectItem[],
|
|
19
|
+
currentValue: string,
|
|
20
|
+
): Promise<string | null> {
|
|
21
|
+
const { promise, resolve } = Promise.withResolvers<string | null>();
|
|
22
|
+
const ui = new TUI(new ProcessTerminal());
|
|
23
|
+
let resolved = false;
|
|
24
|
+
|
|
25
|
+
const finish = (value: string | null): void => {
|
|
26
|
+
if (resolved) return;
|
|
27
|
+
resolved = true;
|
|
28
|
+
ui.stop();
|
|
29
|
+
resolve(value);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const list = new SelectList(items, Math.min(items.length, 10), getSelectListTheme());
|
|
33
|
+
const currentIndex = items.findIndex(item => item.value === currentValue);
|
|
34
|
+
if (currentIndex >= 0) list.setSelectedIndex(currentIndex);
|
|
35
|
+
list.onSelect = item => finish(item.value);
|
|
36
|
+
list.onCancel = () => finish(null);
|
|
37
|
+
|
|
38
|
+
process.stdout.write(`${title}\n`);
|
|
39
|
+
ui.addChild(list);
|
|
40
|
+
ui.setFocus(list);
|
|
41
|
+
ui.start();
|
|
42
|
+
return promise;
|
|
43
|
+
}
|
package/src/cli-commands.ts
CHANGED
|
@@ -27,7 +27,9 @@ export const commands: CommandEntry[] = [
|
|
|
27
27
|
{ name: "grievances", load: () => import("./commands/grievances").then(m => m.default) },
|
|
28
28
|
{ name: "install", load: () => import("./commands/install").then(m => m.default) },
|
|
29
29
|
{ name: "join", load: () => import("./commands/join").then(m => m.default) },
|
|
30
|
+
{ name: "models", load: () => import("./commands/models").then(m => m.default) },
|
|
30
31
|
{ name: "plugin", load: () => import("./commands/plugin").then(m => m.default) },
|
|
32
|
+
{ name: "say", load: () => import("./commands/say").then(m => m.default) },
|
|
31
33
|
{ name: "setup", load: () => import("./commands/setup").then(m => m.default) },
|
|
32
34
|
{ name: "shell", load: () => import("./commands/shell").then(m => m.default) },
|
|
33
35
|
{ name: "read", load: () => import("./commands/read").then(m => m.default) },
|
|
@@ -36,6 +38,7 @@ export const commands: CommandEntry[] = [
|
|
|
36
38
|
{ name: "update", load: () => import("./commands/update").then(m => m.default) },
|
|
37
39
|
{ name: "usage", load: () => import("./commands/usage").then(m => m.default) },
|
|
38
40
|
{ name: "tiny-models", load: () => import("./commands/tiny-models").then(m => m.default) },
|
|
41
|
+
{ name: "token", load: () => import("./commands/token").then(m => m.default) },
|
|
39
42
|
{ name: "worktree", load: () => import("./commands/worktree").then(m => m.default), aliases: ["wt"] },
|
|
40
43
|
{ name: "search", load: () => import("./commands/web-search").then(m => m.default), aliases: ["q"] },
|
|
41
44
|
];
|
package/src/cli.ts
CHANGED
|
@@ -56,6 +56,8 @@ async function showHelp(config: CliConfig): Promise<void> {
|
|
|
56
56
|
async function runSmokeTest(): Promise<void> {
|
|
57
57
|
const { smokeTestSyncWorker, startServer } = await import("@oh-my-pi/omp-stats");
|
|
58
58
|
const { smokeTestTinyTitleWorker } = await import("./tiny/title-client");
|
|
59
|
+
const { smokeTestSttWorker } = await import("./stt/asr-client");
|
|
60
|
+
const { smokeTestTtsWorker } = await import("./tts/tts-client");
|
|
59
61
|
await smokeTestSyncWorker();
|
|
60
62
|
|
|
61
63
|
const statsServer = await startServer(0);
|
|
@@ -71,6 +73,8 @@ async function runSmokeTest(): Promise<void> {
|
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
await smokeTestTinyTitleWorker();
|
|
76
|
+
await smokeTestSttWorker();
|
|
77
|
+
await smokeTestTtsWorker();
|
|
74
78
|
process.stdout.write("smoke-test: ok\n");
|
|
75
79
|
}
|
|
76
80
|
|
|
@@ -78,6 +82,8 @@ const TINY_WORKER_ARGS = new Set(["--tiny-worker", "__tiny_worker"]);
|
|
|
78
82
|
const STATS_SYNC_WORKER_ARG = "__omp_stats_sync_worker";
|
|
79
83
|
const TAB_WORKER_ARG = "__omp_tab_worker";
|
|
80
84
|
const JS_EVAL_WORKER_ARG = "__omp_js_eval_worker";
|
|
85
|
+
const STT_WORKER_ARG = "__omp_stt_worker";
|
|
86
|
+
const TTS_WORKER_ARG = "__omp_tts_worker";
|
|
81
87
|
|
|
82
88
|
async function runWorkerEntrypoint(arg: string | undefined): Promise<boolean> {
|
|
83
89
|
if (arg === STATS_SYNC_WORKER_ARG) {
|
|
@@ -110,21 +116,34 @@ async function runWorkerEntrypoint(arg: string | undefined): Promise<boolean> {
|
|
|
110
116
|
await import("./eval/js/worker-entry");
|
|
111
117
|
return true;
|
|
112
118
|
}
|
|
119
|
+
if (arg === STT_WORKER_ARG) {
|
|
120
|
+
const { startSttWorker } = await import("./stt/asr-worker");
|
|
121
|
+
await runIpcSubprocessWorker(startSttWorker);
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
if (arg === TTS_WORKER_ARG) {
|
|
125
|
+
const { startTtsWorker } = await import("./tts/tts-worker");
|
|
126
|
+
await runIpcSubprocessWorker(startTtsWorker);
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
113
129
|
return false;
|
|
114
130
|
}
|
|
115
131
|
|
|
116
132
|
/**
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
* `@huggingface/transformers`)
|
|
121
|
-
*
|
|
122
|
-
*
|
|
133
|
+
* Boot a subprocess-isolated transformers.js worker over the parent's IPC
|
|
134
|
+
* channel and block until the parent disconnects. The tiny-model, STT, and TTS
|
|
135
|
+
* workers each run `onnxruntime-node` (loaded transitively by
|
|
136
|
+
* `@huggingface/transformers`) in a child address space because its NAPI
|
|
137
|
+
* finalizer segfaults Bun on shutdown (issue #1606); the parent `SIGKILL`s the
|
|
138
|
+
* child so that finalizer never runs in either process. This wires `process`
|
|
139
|
+
* IPC to the worker's typed transport, keeps the event loop alive while the
|
|
140
|
+
* worker is idle, and hard-kills the process on parent `disconnect`.
|
|
123
141
|
*/
|
|
124
|
-
async function
|
|
125
|
-
|
|
142
|
+
async function runIpcSubprocessWorker<In, Out>(
|
|
143
|
+
start: (transport: { send(message: Out): void; onMessage(handler: (message: In) => void): () => void }) => void,
|
|
144
|
+
): Promise<void> {
|
|
126
145
|
const { promise: shuttingDown, resolve: shutdown } = Promise.withResolvers<void>();
|
|
127
|
-
const send = (message:
|
|
146
|
+
const send = (message: Out): void => {
|
|
128
147
|
// `process.send` only exists when spawned with an IPC channel; the
|
|
129
148
|
// parent always spawns us that way. If it's missing, the parent
|
|
130
149
|
// vanished and there's no one to talk to.
|
|
@@ -139,10 +158,10 @@ async function runTinyWorker(): Promise<void> {
|
|
|
139
158
|
shutdown();
|
|
140
159
|
}
|
|
141
160
|
};
|
|
142
|
-
|
|
161
|
+
start({
|
|
143
162
|
send,
|
|
144
163
|
onMessage(handler) {
|
|
145
|
-
const wrap = (data: unknown): void => handler(data as
|
|
164
|
+
const wrap = (data: unknown): void => handler(data as In);
|
|
146
165
|
process.on("message", wrap);
|
|
147
166
|
return () => {
|
|
148
167
|
process.off("message", wrap);
|
|
@@ -151,8 +170,8 @@ async function runTinyWorker(): Promise<void> {
|
|
|
151
170
|
});
|
|
152
171
|
const keepalive = setInterval(() => {}, 2 ** 30);
|
|
153
172
|
// Parent went away (crashed, SIGKILL, etc.) — commit suicide so we don't
|
|
154
|
-
// linger as an orphan. SIGKILL via `process.kill` keeps us symmetrical
|
|
155
|
-
//
|
|
173
|
+
// linger as an orphan. SIGKILL via `process.kill` keeps us symmetrical with
|
|
174
|
+
// the parent's hard-kill on shutdown: skip every JS/native finalizer.
|
|
156
175
|
process.on("disconnect", () => shutdown());
|
|
157
176
|
try {
|
|
158
177
|
await shuttingDown;
|
|
@@ -162,6 +181,19 @@ async function runTinyWorker(): Promise<void> {
|
|
|
162
181
|
process.kill(process.pid, "SIGKILL");
|
|
163
182
|
}
|
|
164
183
|
|
|
184
|
+
/**
|
|
185
|
+
* Hidden subcommand that boots the tiny-model worker inside this process over
|
|
186
|
+
* the parent's IPC channel. The agent's main process spawns the same binary
|
|
187
|
+
* with this flag so `onnxruntime-node` (loaded transitively by
|
|
188
|
+
* `@huggingface/transformers`) lives in a child address space. The parent
|
|
189
|
+
* `SIGKILL`s the child on shutdown so the NAPI finalizer never runs in either
|
|
190
|
+
* process — that finalizer segfaults Bun on Windows (issue #1606).
|
|
191
|
+
*/
|
|
192
|
+
async function runTinyWorker(): Promise<void> {
|
|
193
|
+
const { startTinyTitleWorker } = await import("./tiny/worker");
|
|
194
|
+
await runIpcSubprocessWorker(startTinyTitleWorker);
|
|
195
|
+
}
|
|
196
|
+
|
|
165
197
|
/** Run the CLI with the given argv (no `process.argv` prefix). */
|
|
166
198
|
export async function runCli(argv: string[]): Promise<void> {
|
|
167
199
|
if (argv[0] === "--smoke-test") {
|
package/src/collab/host.ts
CHANGED
|
@@ -20,7 +20,7 @@ import { AgentLifecycleManager } from "../registry/agent-lifecycle";
|
|
|
20
20
|
import { AgentRegistry } from "../registry/agent-registry";
|
|
21
21
|
import type { AgentSessionEvent } from "../session/agent-session";
|
|
22
22
|
import { stripImagesFromMessage, USER_INTERRUPT_LABEL } from "../session/messages";
|
|
23
|
-
import type { SessionEntry as StoredSessionEntry } from "../session/session-
|
|
23
|
+
import type { SessionEntry as StoredSessionEntry } from "../session/session-entries";
|
|
24
24
|
import { TASK_SUBAGENT_LIFECYCLE_CHANNEL, TASK_SUBAGENT_PROGRESS_CHANNEL } from "../task";
|
|
25
25
|
import { generateRoomKey, generateWriteToken, importRoomKey } from "./crypto";
|
|
26
26
|
import {
|
|
@@ -365,13 +365,8 @@ export class CollabHost {
|
|
|
365
365
|
const name = peer.name;
|
|
366
366
|
const content: string | (TextContent | ImageContent)[] =
|
|
367
367
|
images && images.length > 0 ? [{ type: "text", text }, ...images] : text;
|
|
368
|
-
const details: CollabPromptDetails
|
|
368
|
+
const details: CollabPromptDetails = { from: name };
|
|
369
369
|
if (this.#ctx.session.isStreaming) {
|
|
370
|
-
// Mid-turn guest prompts are steered: register the pending-display twin
|
|
371
|
-
// so queuedMessageCount reflects the queued steer (host pending bar +
|
|
372
|
-
// guests' "queued ×N" badge). The tag dequeues the entry when the agent
|
|
373
|
-
// consumes the message (mirrors the skill-prompt path).
|
|
374
|
-
details.__pendingDisplayTag = this.#ctx.session.enqueueCustomMessageDisplay(text, "steer");
|
|
375
370
|
this.#ctx.updatePendingMessagesDisplay();
|
|
376
371
|
this.#ctx.ui.requestRender();
|
|
377
372
|
this.#scheduleStateBroadcast();
|
|
@@ -385,7 +380,7 @@ export class CollabHost {
|
|
|
385
380
|
details,
|
|
386
381
|
attribution: "user",
|
|
387
382
|
},
|
|
388
|
-
{ streamingBehavior: "steer" },
|
|
383
|
+
{ streamingBehavior: "steer", queueChipText: text },
|
|
389
384
|
)
|
|
390
385
|
.catch(err => {
|
|
391
386
|
logger.warn("collab guest prompt failed", { error: String(err) });
|
|
@@ -416,21 +411,23 @@ export class CollabHost {
|
|
|
416
411
|
|
|
417
412
|
#buildState(): CollabSessionState {
|
|
418
413
|
const session = this.#ctx.session;
|
|
419
|
-
// Context numbers come from the status line's breakdown
|
|
420
|
-
//
|
|
421
|
-
//
|
|
414
|
+
// Context numbers come from the status line's memoized breakdown so guests
|
|
415
|
+
// render exactly the same anchored, provider-real count the host's own
|
|
416
|
+
// status line shows.
|
|
422
417
|
const breakdown = this.#ctx.statusLine.getCachedContextBreakdown();
|
|
418
|
+
const tokens = breakdown.usedTokens;
|
|
423
419
|
return {
|
|
424
420
|
isStreaming: session.isStreaming,
|
|
421
|
+
isAborting: session.isAborting,
|
|
425
422
|
queuedMessageCount: session.queuedMessageCount,
|
|
426
423
|
sessionName: session.sessionName,
|
|
427
424
|
cwd: this.#ctx.sessionManager.getCwd(),
|
|
428
425
|
model: session.model,
|
|
429
426
|
thinkingLevel: session.thinkingLevel,
|
|
430
427
|
contextUsage: {
|
|
431
|
-
tokens
|
|
428
|
+
tokens,
|
|
432
429
|
contextWindow: breakdown.contextWindow,
|
|
433
|
-
percent: breakdown.contextWindow > 0 ? (
|
|
430
|
+
percent: tokens !== null && breakdown.contextWindow > 0 ? (tokens / breakdown.contextWindow) * 100 : null,
|
|
434
431
|
},
|
|
435
432
|
participants: this.participants,
|
|
436
433
|
};
|
package/src/collab/protocol.ts
CHANGED
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
} from "@oh-my-pi/pi-wire";
|
|
26
26
|
import type { ContextUsage } from "../extensibility/extensions/types";
|
|
27
27
|
import type { AgentSessionEvent } from "../session/agent-session";
|
|
28
|
-
import type { SessionEntry, SessionHeader } from "../session/session-
|
|
28
|
+
import type { SessionEntry, SessionHeader } from "../session/session-entries";
|
|
29
29
|
|
|
30
30
|
export type {
|
|
31
31
|
CollabPromptDetails,
|
package/src/commands/launch.ts
CHANGED
|
@@ -124,9 +124,6 @@ export default class Index extends Command {
|
|
|
124
124
|
export: Flags.string({
|
|
125
125
|
description: "Export session file to HTML and exit",
|
|
126
126
|
}),
|
|
127
|
-
"list-models": Flags.string({
|
|
128
|
-
description: "List available models (with optional fuzzy search)",
|
|
129
|
-
}),
|
|
130
127
|
"no-title": Flags.boolean({
|
|
131
128
|
description: "Disable title auto-generation",
|
|
132
129
|
}),
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* List, search, and refresh available models.
|
|
3
|
+
*/
|
|
4
|
+
import { APP_NAME } from "@oh-my-pi/pi-utils";
|
|
5
|
+
import { Args, Command, Flags } from "@oh-my-pi/pi-utils/cli";
|
|
6
|
+
import { resolveModelsArgs, runModelsCommand } from "../cli/models-cli";
|
|
7
|
+
|
|
8
|
+
export default class Models extends Command {
|
|
9
|
+
static description = "List, search, and refresh available models";
|
|
10
|
+
|
|
11
|
+
static args = {
|
|
12
|
+
action: Args.string({
|
|
13
|
+
description: "ls (default) | find | refresh | canonical | <provider>",
|
|
14
|
+
required: false,
|
|
15
|
+
}),
|
|
16
|
+
pattern: Args.string({
|
|
17
|
+
description: "Filter/search substring, or provider name (required for find)",
|
|
18
|
+
required: false,
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
static flags = {
|
|
23
|
+
json: Flags.boolean({ description: "Output JSON" }),
|
|
24
|
+
extension: Flags.string({
|
|
25
|
+
char: "e",
|
|
26
|
+
description: "Load an extension file before listing (repeatable)",
|
|
27
|
+
multiple: true,
|
|
28
|
+
}),
|
|
29
|
+
"no-extensions": Flags.boolean({
|
|
30
|
+
description: "Disable extension discovery (explicit -e paths still work)",
|
|
31
|
+
}),
|
|
32
|
+
config: Flags.string({
|
|
33
|
+
description: "Load an extra config.yml-style overlay for this run (repeatable)",
|
|
34
|
+
multiple: true,
|
|
35
|
+
}),
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
static examples = [
|
|
39
|
+
`# List every available model, grouped by provider\n ${APP_NAME} models`,
|
|
40
|
+
`# List one provider's models (any provider name works)\n ${APP_NAME} models openai-codex`,
|
|
41
|
+
`# Find models by substring\n ${APP_NAME} models find minimax`,
|
|
42
|
+
`# Force a fresh catalog fetch (replaces rm -rf ~/.omp/models.db)\n ${APP_NAME} models refresh`,
|
|
43
|
+
`# Show the coalesced canonical model view\n ${APP_NAME} models canonical`,
|
|
44
|
+
`# Machine-readable output\n ${APP_NAME} models --json`,
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
async run(): Promise<void> {
|
|
48
|
+
const { args, flags } = await this.parse(Models);
|
|
49
|
+
const { action, pattern } = resolveModelsArgs(args.action, args.pattern);
|
|
50
|
+
await runModelsCommand({
|
|
51
|
+
action,
|
|
52
|
+
pattern,
|
|
53
|
+
flags: {
|
|
54
|
+
json: flags.json,
|
|
55
|
+
extensions: flags.extension,
|
|
56
|
+
noExtensions: flags["no-extensions"],
|
|
57
|
+
config: flags.config,
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|