@oh-my-pi/pi-coding-agent 15.10.10 → 15.10.12
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 +142 -7
- package/dist/cli.js +23108 -0
- package/dist/tokenizers.linux-x64-gnu-xcjh3jwk.node +0 -0
- package/dist/types/async/job-manager.d.ts +18 -0
- package/dist/types/cli/args.d.ts +2 -1
- package/dist/types/cli/dry-balance-cli.d.ts +1 -1
- package/dist/types/cli/gallery-cli.d.ts +1 -1
- package/dist/types/cli/gallery-fixtures/types.d.ts +1 -1
- package/dist/types/cli/usage-cli.d.ts +72 -0
- package/dist/types/cli-commands.d.ts +12 -0
- package/dist/types/commands/launch.d.ts +5 -1
- package/dist/types/commands/read.d.ts +1 -1
- package/dist/types/commands/usage.d.ts +25 -0
- package/dist/types/config/api-key-resolver.d.ts +3 -0
- package/dist/types/config/append-only-context-mode.d.ts +2 -1
- package/dist/types/config/model-discovery.d.ts +55 -0
- package/dist/types/config/model-registry.d.ts +8 -219
- package/dist/types/config/model-resolver.d.ts +34 -10
- package/dist/types/config/model-roles.d.ts +28 -0
- package/dist/types/config/models-config-schema.d.ts +523 -42
- package/dist/types/config/models-config.d.ts +385 -0
- package/dist/types/config/settings-schema.d.ts +41 -8
- package/dist/types/config/settings.d.ts +8 -1
- package/dist/types/debug/log-viewer.d.ts +1 -1
- package/dist/types/debug/raw-sse.d.ts +1 -1
- package/dist/types/edit/hashline/noop-loop-guard.d.ts +72 -0
- package/dist/types/eval/backend.d.ts +0 -2
- package/dist/types/eval/idle-timeout.d.ts +0 -4
- package/dist/types/eval/js/shared/rewrite-imports.d.ts +6 -6
- package/dist/types/eval/py/executor.d.ts +5 -0
- package/dist/types/eval/py/kernel.d.ts +6 -1
- package/dist/types/eval/py/runtime.d.ts +9 -0
- package/dist/types/exec/bash-executor.d.ts +2 -0
- package/dist/types/export/html/template.generated.d.ts +1 -1
- package/dist/types/extensibility/extensions/runner.d.ts +3 -2
- package/dist/types/extensibility/extensions/types.d.ts +6 -3
- package/dist/types/hindsight/mental-models.d.ts +17 -8
- package/dist/types/internal-urls/artifact-protocol.d.ts +2 -2
- package/dist/types/internal-urls/types.d.ts +1 -1
- package/dist/types/lsp/edits.d.ts +9 -0
- package/dist/types/lsp/index.d.ts +2 -2
- package/dist/types/lsp/types.d.ts +2 -0
- package/dist/types/lsp/utils.d.ts +3 -0
- package/dist/types/mcp/json-rpc.d.ts +5 -0
- package/dist/types/memory-backend/index.d.ts +1 -0
- package/dist/types/memory-backend/runtime.d.ts +4 -0
- package/dist/types/memory-backend/types.d.ts +66 -1
- package/dist/types/mnemopi/state.d.ts +11 -1
- package/dist/types/modes/components/agent-dashboard.d.ts +1 -1
- package/dist/types/modes/components/assistant-message.d.ts +3 -1
- package/dist/types/modes/components/bash-execution.d.ts +1 -1
- package/dist/types/modes/components/copy-selector.d.ts +1 -1
- package/dist/types/modes/components/dynamic-border.d.ts +1 -1
- package/dist/types/modes/components/extensions/extension-dashboard.d.ts +1 -1
- package/dist/types/modes/components/extensions/extension-list.d.ts +1 -1
- package/dist/types/modes/components/extensions/inspector-panel.d.ts +1 -1
- package/dist/types/modes/components/footer.d.ts +1 -1
- package/dist/types/modes/components/hook-editor.d.ts +5 -0
- package/dist/types/modes/components/hook-input.d.ts +4 -0
- package/dist/types/modes/components/hook-selector.d.ts +1 -1
- package/dist/types/modes/components/model-selector.d.ts +1 -1
- package/dist/types/modes/components/plan-review-overlay.d.ts +1 -1
- package/dist/types/modes/components/session-observer-overlay.d.ts +1 -1
- package/dist/types/modes/components/session-selector.d.ts +1 -1
- package/dist/types/modes/components/status-line/component.d.ts +1 -1
- package/dist/types/modes/components/tiny-title-download-progress.d.ts +1 -1
- package/dist/types/modes/components/transcript-container.d.ts +25 -6
- package/dist/types/modes/components/tree-selector.d.ts +1 -1
- package/dist/types/modes/components/user-message-selector.d.ts +1 -1
- package/dist/types/modes/components/user-message.d.ts +2 -1
- package/dist/types/modes/components/visual-truncate.d.ts +1 -1
- package/dist/types/modes/components/welcome.d.ts +19 -3
- package/dist/types/modes/controllers/mcp-command-controller.d.ts +1 -1
- package/dist/types/modes/controllers/streaming-reveal.d.ts +1 -1
- package/dist/types/modes/index.d.ts +3 -3
- package/dist/types/modes/interactive-mode.d.ts +8 -3
- package/dist/types/modes/oauth-manual-input.d.ts +7 -0
- package/dist/types/modes/rpc/rpc-client.d.ts +39 -2
- package/dist/types/modes/rpc/rpc-mode.d.ts +31 -2
- package/dist/types/modes/rpc/rpc-subagents.d.ts +24 -0
- package/dist/types/modes/rpc/rpc-types.d.ts +75 -1
- package/dist/types/modes/setup-wizard/index.d.ts +5 -1
- package/dist/types/modes/setup-wizard/lazy.d.ts +2 -0
- package/dist/types/modes/setup-wizard/scenes/sign-in.d.ts +1 -1
- package/dist/types/modes/setup-wizard/scenes/types.d.ts +1 -1
- package/dist/types/modes/setup-wizard/scenes/web-search.d.ts +1 -1
- package/dist/types/modes/setup-wizard/wizard-overlay.d.ts +1 -1
- package/dist/types/modes/types.d.ts +4 -1
- package/dist/types/secrets/index.d.ts +1 -1
- package/dist/types/secrets/obfuscator.d.ts +8 -2
- package/dist/types/session/agent-session.d.ts +15 -3
- package/dist/types/session/auth-broker-config.d.ts +4 -0
- package/dist/types/session/session-manager.d.ts +1 -1
- package/dist/types/session/streaming-output.d.ts +23 -0
- package/dist/types/slash-commands/acp-builtins.d.ts +16 -0
- package/dist/types/slash-commands/builtin-registry.d.ts +1 -0
- package/dist/types/slash-commands/helpers/stats-dashboard.d.ts +13 -0
- package/dist/types/slash-commands/types.d.ts +1 -1
- package/dist/types/ssh/connection-manager.d.ts +8 -0
- package/dist/types/system-prompt.d.ts +2 -0
- package/dist/types/task/executor.d.ts +1 -0
- package/dist/types/task/index.d.ts +2 -2
- package/dist/types/task/parallel.d.ts +2 -2
- package/dist/types/task/types.d.ts +8 -0
- package/dist/types/task/worktree.d.ts +2 -0
- package/dist/types/thinking.d.ts +4 -0
- package/dist/types/tiny/title-client.d.ts +11 -0
- package/dist/types/tiny/title-protocol.d.ts +1 -0
- package/dist/types/tools/ask.d.ts +4 -0
- package/dist/types/tools/conflict-detect.d.ts +16 -0
- package/dist/types/tools/github-cache.d.ts +7 -0
- package/dist/types/tools/index.d.ts +6 -0
- package/dist/types/tools/sqlite-reader.d.ts +3 -0
- package/dist/types/tui/output-block.d.ts +3 -3
- package/dist/types/utils/changelog.d.ts +8 -0
- package/dist/types/utils/git.d.ts +15 -2
- package/dist/types/utils/title-generator.d.ts +3 -2
- package/dist/types/web/scrapers/readthedocs.d.ts +3 -0
- package/dist/types/web/scrapers/types.d.ts +12 -0
- package/dist/types/web/search/providers/codex.d.ts +1 -1
- package/dist/types/web/search/providers/gemini.d.ts +1 -1
- package/examples/extensions/tools.ts +5 -4
- package/package.json +14 -11
- package/scripts/build-binary.ts +18 -23
- package/scripts/bundle-dist.ts +81 -0
- package/scripts/{dev-launch → omp} +1 -1
- package/scripts/{dev-launch-preload.ts → omp.ts} +1 -1
- package/src/async/job-manager.ts +57 -3
- package/src/auto-thinking/classifier.ts +1 -0
- package/src/autoresearch/dashboard.ts +1 -1
- package/src/autoresearch/prompt-setup.md +6 -6
- package/src/autoresearch/prompt.md +6 -6
- package/src/capability/fs.ts +10 -0
- package/src/cli/args.ts +4 -1
- package/src/cli/auth-gateway-cli.ts +1 -3
- package/src/cli/dry-balance-cli.ts +1 -1
- package/src/cli/gallery-cli.ts +1 -1
- package/src/cli/gallery-fixtures/fs.ts +1 -1
- package/src/cli/gallery-fixtures/types.ts +5 -1
- package/src/cli/list-models.ts +2 -1
- package/src/cli/usage-cli.ts +603 -0
- package/src/cli-commands.ts +30 -0
- package/src/cli.ts +76 -13
- package/src/commands/complete.ts +1 -1
- package/src/commands/launch.ts +5 -1
- package/src/commands/read.ts +6 -3
- package/src/commands/usage.ts +35 -0
- package/src/commit/agentic/agent.ts +1 -1
- package/src/commit/model-selection.ts +4 -3
- package/src/config/api-key-resolver.ts +8 -6
- package/src/config/append-only-context-mode.ts +6 -12
- package/src/config/model-discovery.ts +554 -0
- package/src/config/model-registry.ts +320 -1041
- package/src/config/model-resolver.ts +173 -156
- package/src/config/model-roles.ts +74 -0
- package/src/config/models-config-schema.ts +57 -8
- package/src/config/models-config.ts +129 -0
- package/src/config/settings-schema.ts +61 -19
- package/src/config/settings.ts +98 -4
- package/src/dap/client.ts +124 -37
- package/src/dap/session.ts +259 -158
- package/src/debug/log-viewer.ts +1 -1
- package/src/debug/raw-sse.ts +1 -1
- package/src/edit/diff.ts +47 -3
- package/src/edit/hashline/block-resolver.ts +20 -1
- package/src/edit/hashline/diff.ts +36 -1
- package/src/edit/hashline/execute.ts +47 -4
- package/src/edit/hashline/noop-loop-guard.ts +99 -0
- package/src/edit/index.ts +16 -1
- package/src/edit/modes/patch.ts +52 -0
- package/src/edit/modes/replace.ts +56 -22
- package/src/edit/notebook.ts +22 -2
- package/src/edit/renderer.ts +36 -10
- package/src/eval/__tests__/completion-bridge.test.ts +1 -1
- package/src/eval/backend.ts +0 -2
- package/src/eval/completion-bridge.ts +3 -1
- package/src/eval/idle-timeout.ts +2 -9
- package/src/eval/js/context-manager.ts +6 -8
- package/src/eval/js/executor.ts +6 -2
- package/src/eval/js/index.ts +0 -2
- package/src/eval/js/shared/helpers.ts +5 -6
- package/src/eval/js/shared/local-module-loader.ts +1 -1
- package/src/eval/js/shared/prelude.txt +62 -1
- package/src/eval/js/shared/rewrite-imports.ts +40 -22
- package/src/eval/js/shared/runtime.ts +1 -1
- package/src/eval/py/executor.ts +29 -7
- package/src/eval/py/index.ts +6 -3
- package/src/eval/py/kernel.ts +43 -4
- package/src/eval/py/runner.py +107 -3
- package/src/eval/py/runtime.ts +37 -0
- package/src/exec/bash-executor.ts +85 -4
- package/src/export/html/template.generated.ts +1 -1
- package/src/export/html/template.js +3 -1
- package/src/extensibility/extensions/get-commands-handler.ts +2 -1
- package/src/extensibility/extensions/runner.ts +6 -1
- package/src/extensibility/extensions/types.ts +6 -2
- package/src/extensibility/plugins/legacy-pi-compat.ts +20 -3
- package/src/hindsight/bank.ts +17 -2
- package/src/hindsight/mental-models.ts +59 -12
- package/src/hindsight/state.ts +6 -1
- package/src/internal-urls/artifact-protocol.ts +11 -2
- package/src/internal-urls/docs-index.generated.ts +11 -11
- package/src/internal-urls/issue-pr-protocol.ts +12 -5
- package/src/internal-urls/router.ts +1 -1
- package/src/internal-urls/types.ts +1 -1
- package/src/lib/xai-http.ts +1 -1
- package/src/lsp/client.ts +118 -38
- package/src/lsp/clients/biome-client.ts +101 -39
- package/src/lsp/edits.ts +143 -95
- package/src/lsp/index.ts +31 -22
- package/src/lsp/render.ts +1 -1
- package/src/lsp/types.ts +2 -0
- package/src/lsp/utils.ts +28 -10
- package/src/main.ts +183 -23
- package/src/mcp/json-rpc.ts +35 -5
- package/src/mcp/transports/stdio.ts +7 -1
- package/src/memories/index.ts +4 -1
- package/src/memory-backend/index.ts +1 -0
- package/src/memory-backend/local-backend.ts +9 -0
- package/src/memory-backend/off-backend.ts +9 -0
- package/src/memory-backend/runtime.ts +66 -0
- package/src/memory-backend/types.ts +81 -1
- package/src/mnemopi/backend.ts +176 -7
- package/src/mnemopi/state.ts +38 -2
- package/src/modes/acp/acp-agent.ts +119 -11
- package/src/modes/components/agent-dashboard.ts +10 -7
- package/src/modes/components/assistant-message.ts +32 -28
- package/src/modes/components/bash-execution.ts +1 -1
- package/src/modes/components/copy-selector.ts +1 -1
- package/src/modes/components/diff.ts +13 -2
- package/src/modes/components/dynamic-border.ts +12 -3
- package/src/modes/components/extensions/extension-dashboard.ts +8 -5
- package/src/modes/components/extensions/extension-list.ts +1 -1
- package/src/modes/components/extensions/inspector-panel.ts +1 -1
- package/src/modes/components/footer.ts +4 -2
- package/src/modes/components/history-search.ts +1 -1
- package/src/modes/components/hook-editor.ts +8 -0
- package/src/modes/components/hook-input.ts +8 -0
- package/src/modes/components/hook-selector.ts +2 -2
- package/src/modes/components/model-selector.ts +4 -2
- package/src/modes/components/plan-review-overlay.ts +1 -1
- package/src/modes/components/session-observer-overlay.ts +2 -2
- package/src/modes/components/session-selector.ts +1 -1
- package/src/modes/components/settings-selector.ts +5 -1
- package/src/modes/components/status-line/component.ts +119 -35
- package/src/modes/components/tiny-title-download-progress.ts +1 -1
- package/src/modes/components/transcript-container.ts +258 -53
- package/src/modes/components/tree-selector.ts +3 -3
- package/src/modes/components/user-message-selector.ts +1 -1
- package/src/modes/components/user-message.ts +17 -5
- package/src/modes/components/visual-truncate.ts +1 -1
- package/src/modes/components/welcome.ts +108 -26
- package/src/modes/controllers/command-controller.ts +11 -4
- package/src/modes/controllers/event-controller.ts +73 -4
- package/src/modes/controllers/input-controller.ts +2 -1
- package/src/modes/controllers/mcp-command-controller.ts +39 -4
- package/src/modes/controllers/selector-controller.ts +1 -1
- package/src/modes/controllers/streaming-reveal.ts +85 -18
- package/src/modes/index.ts +3 -21
- package/src/modes/interactive-mode.ts +42 -18
- package/src/modes/oauth-manual-input.ts +30 -3
- package/src/modes/rpc/rpc-client.ts +154 -3
- package/src/modes/rpc/rpc-mode.ts +97 -12
- package/src/modes/rpc/rpc-subagents.ts +265 -0
- package/src/modes/rpc/rpc-types.ts +81 -1
- package/src/modes/setup-wizard/index.ts +12 -2
- package/src/modes/setup-wizard/lazy.ts +16 -0
- package/src/modes/setup-wizard/scenes/glyph.ts +1 -1
- package/src/modes/setup-wizard/scenes/providers.ts +1 -1
- package/src/modes/setup-wizard/scenes/sign-in.ts +1 -1
- package/src/modes/setup-wizard/scenes/theme.ts +1 -1
- package/src/modes/setup-wizard/scenes/types.ts +1 -1
- package/src/modes/setup-wizard/scenes/web-search.ts +1 -1
- package/src/modes/setup-wizard/wizard-overlay.ts +1 -1
- package/src/modes/types.ts +4 -1
- package/src/prompts/agents/explore.md +2 -2
- package/src/prompts/agents/librarian.md +1 -2
- package/src/prompts/agents/oracle.md +1 -1
- package/src/prompts/agents/plan.md +5 -5
- package/src/prompts/agents/task.md +5 -5
- package/src/prompts/ci-green-request.md +5 -7
- package/src/prompts/goals/goal-budget-limit.md +2 -2
- package/src/prompts/goals/goal-continuation.md +4 -4
- package/src/prompts/goals/goal-mode-active.md +1 -1
- package/src/prompts/memories/read-path.md +1 -1
- package/src/prompts/memories/stage_one_system.md +2 -2
- package/src/prompts/review-custom-request.md +1 -1
- package/src/prompts/system/agent-creation-architect.md +2 -2
- package/src/prompts/system/auto-continue.md +1 -1
- package/src/prompts/system/background-tan-dispatch.md +1 -1
- package/src/prompts/system/btw-user.md +2 -2
- package/src/prompts/system/commit-message-system.md +13 -1
- package/src/prompts/system/custom-system-prompt.md +1 -1
- package/src/prompts/system/eager-todo.md +2 -2
- package/src/prompts/system/irc-incoming.md +1 -1
- package/src/prompts/system/manual-continue.md +1 -1
- package/src/prompts/system/omfg-user.md +3 -4
- package/src/prompts/system/orchestrate-notice.md +9 -9
- package/src/prompts/system/plan-mode-active.md +4 -4
- package/src/prompts/system/plan-mode-subagent.md +4 -5
- package/src/prompts/system/plan-mode-tool-decision-reminder.md +1 -1
- package/src/prompts/system/project-prompt.md +2 -2
- package/src/prompts/system/subagent-system-prompt.md +4 -4
- package/src/prompts/system/system-prompt.md +13 -24
- package/src/prompts/system/title-system.md +2 -2
- package/src/prompts/system/ttsr-tool-reminder.md +1 -1
- package/src/prompts/system/workflow-notice.md +1 -1
- package/src/prompts/tools/ast-edit.md +1 -1
- package/src/prompts/tools/ast-grep.md +2 -2
- package/src/prompts/tools/bash.md +5 -7
- package/src/prompts/tools/browser.md +7 -7
- package/src/prompts/tools/debug.md +1 -1
- package/src/prompts/tools/eval.md +3 -3
- package/src/prompts/tools/find.md +0 -1
- package/src/prompts/tools/github.md +8 -7
- package/src/prompts/tools/goal.md +1 -1
- package/src/prompts/tools/image-gen.md +1 -1
- package/src/prompts/tools/inspect-image-system.md +1 -1
- package/src/prompts/tools/irc.md +15 -15
- package/src/prompts/tools/lsp.md +2 -2
- package/src/prompts/tools/patch.md +2 -2
- package/src/prompts/tools/read.md +3 -4
- package/src/prompts/tools/recall.md +1 -1
- package/src/prompts/tools/reflect.md +1 -1
- package/src/prompts/tools/render-mermaid.md +2 -2
- package/src/prompts/tools/replace.md +4 -10
- package/src/prompts/tools/rewind.md +2 -2
- package/src/prompts/tools/search-tool-bm25.md +1 -9
- package/src/prompts/tools/search.md +0 -1
- package/src/prompts/tools/ssh.md +0 -4
- package/src/prompts/tools/task.md +2 -3
- package/src/prompts/tools/todo.md +1 -1
- package/src/sdk.ts +31 -11
- package/src/secrets/index.ts +8 -1
- package/src/secrets/obfuscator.ts +39 -18
- package/src/session/agent-session.ts +223 -64
- package/src/session/auth-broker-config.ts +30 -1
- package/src/session/session-manager.ts +2 -2
- package/src/session/streaming-output.ts +188 -11
- package/src/slash-commands/acp-builtins.ts +24 -0
- package/src/slash-commands/builtin-registry.ts +40 -0
- package/src/slash-commands/helpers/stats-dashboard.ts +85 -0
- package/src/slash-commands/types.ts +1 -1
- package/src/ssh/connection-manager.ts +27 -0
- package/src/system-prompt.ts +14 -0
- package/src/task/commands.ts +2 -1
- package/src/task/executor.ts +74 -65
- package/src/task/index.ts +146 -68
- package/src/task/parallel.ts +3 -3
- package/src/task/render.ts +20 -5
- package/src/task/types.ts +9 -0
- package/src/task/worktree.ts +64 -56
- package/src/thinking.ts +9 -1
- package/src/tiny/title-client.ts +60 -16
- package/src/tiny/title-protocol.ts +1 -1
- package/src/tiny/worker.ts +6 -4
- package/src/tools/archive-reader.ts +30 -2
- package/src/tools/ask.ts +104 -21
- package/src/tools/ast-edit.ts +25 -5
- package/src/tools/auto-generated-guard.ts +20 -3
- package/src/tools/bash-interactive.ts +27 -7
- package/src/tools/bash.ts +100 -18
- package/src/tools/browser/launch.ts +11 -2
- package/src/tools/browser/readable.ts +19 -2
- package/src/tools/browser/registry.ts +4 -1
- package/src/tools/browser/render.ts +2 -2
- package/src/tools/browser/tab-supervisor.ts +55 -16
- package/src/tools/conflict-detect.ts +50 -4
- package/src/tools/debug.ts +1 -1
- package/src/tools/eval-render.ts +5 -5
- package/src/tools/eval.ts +0 -2
- package/src/tools/fetch.ts +33 -10
- package/src/tools/gh-cache-invalidation.ts +63 -8
- package/src/tools/gh-renderer.ts +1 -1
- package/src/tools/gh.ts +172 -29
- package/src/tools/github-cache.ts +70 -6
- package/src/tools/image-gen.ts +14 -13
- package/src/tools/index.ts +13 -1
- package/src/tools/inspect-image.ts +1 -0
- package/src/tools/irc.ts +5 -1
- package/src/tools/job.ts +1 -1
- package/src/tools/read.ts +202 -61
- package/src/tools/render-utils.ts +3 -3
- package/src/tools/resolve.ts +1 -1
- package/src/tools/search.ts +92 -29
- package/src/tools/sqlite-reader.ts +17 -5
- package/src/tools/ssh.ts +8 -8
- package/src/tools/todo.ts +38 -8
- package/src/tools/write.ts +118 -18
- package/src/tui/output-block.ts +4 -4
- package/src/utils/changelog.ts +27 -1
- package/src/utils/commit-message-generator.ts +1 -0
- package/src/utils/file-mentions.ts +2 -1
- package/src/utils/git.ts +267 -13
- package/src/utils/title-generator.ts +24 -5
- package/src/web/scrapers/arxiv.ts +1 -1
- package/src/web/scrapers/go-pkg.ts +1 -1
- package/src/web/scrapers/iacr.ts +1 -1
- package/src/web/scrapers/readthedocs.ts +1 -1
- package/src/web/scrapers/twitter.ts +2 -1
- package/src/web/scrapers/types.ts +87 -8
- package/src/web/scrapers/wikipedia.ts +1 -1
- package/src/web/scrapers/youtube.ts +6 -1
- package/src/web/search/index.ts +1 -1
- package/src/web/search/providers/codex.ts +2 -1
- package/src/web/search/providers/gemini.ts +2 -3
- package/src/web/search/render.ts +8 -6
- package/dist/types/config/model-equivalence.d.ts +0 -24
- package/dist/types/config/model-id-affixes.d.ts +0 -12
- package/dist/types/config/model-provider-priority.d.ts +0 -1
- package/dist/types/exec/idle-timeout-watchdog.d.ts +0 -18
- package/src/config/model-equivalence.ts +0 -875
- package/src/config/model-id-affixes.ts +0 -81
- package/src/config/model-provider-priority.ts +0 -56
- package/src/exec/idle-timeout-watchdog.ts +0 -126
package/src/utils/git.ts
CHANGED
|
@@ -27,6 +27,7 @@ export interface GitRepository {
|
|
|
27
27
|
gitEntryPath: string;
|
|
28
28
|
headPath: string;
|
|
29
29
|
repoRoot: string;
|
|
30
|
+
isReftable?: boolean;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
export interface GitStatusSummary {
|
|
@@ -476,6 +477,31 @@ async function resolveCommonDir(gitDir: string): Promise<string> {
|
|
|
476
477
|
if (!relative) return gitDir;
|
|
477
478
|
return path.resolve(gitDir, relative);
|
|
478
479
|
}
|
|
480
|
+
function isLinkedWorktree(repository: GitRepository): boolean {
|
|
481
|
+
return (
|
|
482
|
+
repository.gitDir !== repository.commonDir &&
|
|
483
|
+
getEntryTypeSync(path.join(repository.gitDir, "commondir")) === "file"
|
|
484
|
+
);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
async function isLinkedWorktreeAsync(repository: GitRepository): Promise<boolean> {
|
|
488
|
+
return (
|
|
489
|
+
repository.gitDir !== repository.commonDir &&
|
|
490
|
+
(await getEntryType(path.join(repository.gitDir, "commondir"))) === "file"
|
|
491
|
+
);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
function primaryRootFromRepositorySync(repository: GitRepository): string {
|
|
495
|
+
if (path.basename(repository.commonDir) === ".git") return path.dirname(repository.commonDir);
|
|
496
|
+
if (isLinkedWorktree(repository)) return repository.commonDir;
|
|
497
|
+
return repository.repoRoot;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
async function primaryRootFromRepository(repository: GitRepository): Promise<string> {
|
|
501
|
+
if (path.basename(repository.commonDir) === ".git") return path.dirname(repository.commonDir);
|
|
502
|
+
if (await isLinkedWorktreeAsync(repository)) return repository.commonDir;
|
|
503
|
+
return repository.repoRoot;
|
|
504
|
+
}
|
|
479
505
|
|
|
480
506
|
function resolveRepoFromEntrySync(repoRoot: string, gitEntryPath: string, entryType: EntryType): GitRepository | null {
|
|
481
507
|
const gitDir = resolveGitDirSync(gitEntryPath, entryType);
|
|
@@ -560,7 +586,174 @@ function parsePackedRefs(content: string | null, targetRef: string): string | nu
|
|
|
560
586
|
return null;
|
|
561
587
|
}
|
|
562
588
|
|
|
589
|
+
function stripGitConfigComments(line: string): string {
|
|
590
|
+
let clean = "";
|
|
591
|
+
let inQuotes = false;
|
|
592
|
+
for (let i = 0; i < line.length; i++) {
|
|
593
|
+
const char = line[i];
|
|
594
|
+
if (char === '"') {
|
|
595
|
+
inQuotes = !inQuotes;
|
|
596
|
+
clean += char;
|
|
597
|
+
} else if (!inQuotes && (char === ";" || char === "#")) {
|
|
598
|
+
break;
|
|
599
|
+
} else {
|
|
600
|
+
clean += char;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
return clean.trim();
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
function parseGitConfigHasReftable(content: string): boolean {
|
|
607
|
+
let inExtensions = false;
|
|
608
|
+
for (const line of content.split("\n")) {
|
|
609
|
+
const trimmed = stripGitConfigComments(line);
|
|
610
|
+
if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
611
|
+
const section = trimmed.slice(1, -1).trim().toLowerCase();
|
|
612
|
+
inExtensions = section === "extensions";
|
|
613
|
+
} else if (inExtensions) {
|
|
614
|
+
const eqIndex = trimmed.indexOf("=");
|
|
615
|
+
if (eqIndex !== -1) {
|
|
616
|
+
const key = trimmed.slice(0, eqIndex).trim().toLowerCase();
|
|
617
|
+
let value = trimmed.slice(eqIndex + 1).trim();
|
|
618
|
+
if (key === "refstorage") {
|
|
619
|
+
if (value.startsWith('"') && value.endsWith('"')) {
|
|
620
|
+
value = value.slice(1, -1).trim();
|
|
621
|
+
}
|
|
622
|
+
const lowerValue = value.toLowerCase();
|
|
623
|
+
if (lowerValue === "reftable" || lowerValue.startsWith("reftable:")) {
|
|
624
|
+
return true;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
return false;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
function isReftableRepoSync(repository: GitRepository): boolean {
|
|
634
|
+
if (repository.isReftable !== undefined) return repository.isReftable;
|
|
635
|
+
const configPath = path.join(repository.commonDir, "config");
|
|
636
|
+
const content = readOptionalTextSync(configPath);
|
|
637
|
+
repository.isReftable = content ? parseGitConfigHasReftable(content) : false;
|
|
638
|
+
return repository.isReftable;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
async function isReftableRepo(repository: GitRepository): Promise<boolean> {
|
|
642
|
+
if (repository.isReftable !== undefined) return repository.isReftable;
|
|
643
|
+
const configPath = path.join(repository.commonDir, "config");
|
|
644
|
+
const content = await readOptionalText(configPath);
|
|
645
|
+
repository.isReftable = content ? parseGitConfigHasReftable(content) : false;
|
|
646
|
+
return repository.isReftable;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
async function resolveHeadStateReftable(repository: GitRepository, signal?: AbortSignal): Promise<GitHeadState | null> {
|
|
650
|
+
throwIfAborted(signal);
|
|
651
|
+
const symResult = await git(repository.repoRoot, ["symbolic-ref", "HEAD"], { readOnly: true, signal }).catch(err => {
|
|
652
|
+
if (signal?.aborted || (err instanceof Error && (err.name === "AbortError" || err.name === "ToolAbortError"))) {
|
|
653
|
+
throw err;
|
|
654
|
+
}
|
|
655
|
+
return null;
|
|
656
|
+
});
|
|
657
|
+
throwIfAborted(signal);
|
|
658
|
+
const revResult = await git(repository.repoRoot, ["rev-parse", "--verify", "HEAD"], {
|
|
659
|
+
readOnly: true,
|
|
660
|
+
signal,
|
|
661
|
+
}).catch(err => {
|
|
662
|
+
if (signal?.aborted || (err instanceof Error && (err.name === "AbortError" || err.name === "ToolAbortError"))) {
|
|
663
|
+
throw err;
|
|
664
|
+
}
|
|
665
|
+
return null;
|
|
666
|
+
});
|
|
667
|
+
const commit = revResult && revResult.exitCode === 0 ? revResult.stdout.trim() || null : null;
|
|
668
|
+
|
|
669
|
+
if (symResult && symResult.exitCode === 0) {
|
|
670
|
+
const ref = symResult.stdout.trim();
|
|
671
|
+
const branchName = ref.startsWith(LOCAL_BRANCH_PREFIX) ? ref.slice(LOCAL_BRANCH_PREFIX.length) : null;
|
|
672
|
+
return {
|
|
673
|
+
...repository,
|
|
674
|
+
kind: "ref",
|
|
675
|
+
ref,
|
|
676
|
+
branchName,
|
|
677
|
+
commit,
|
|
678
|
+
headContent: `${HEAD_REF_PREFIX} ${ref}`,
|
|
679
|
+
};
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
return {
|
|
683
|
+
...repository,
|
|
684
|
+
kind: "detached",
|
|
685
|
+
commit,
|
|
686
|
+
headContent: commit || "",
|
|
687
|
+
};
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
function resolveHeadStateReftableSync(repository: GitRepository): GitHeadState | null {
|
|
691
|
+
ensureAvailable();
|
|
692
|
+
const symArgs = withShortLivedGitConfig(withNoOptionalLocks(["symbolic-ref", "HEAD"]));
|
|
693
|
+
const symResult = Bun.spawnSync(["git", ...symArgs], {
|
|
694
|
+
cwd: repository.repoRoot,
|
|
695
|
+
stdout: "pipe",
|
|
696
|
+
stderr: "pipe",
|
|
697
|
+
windowsHide: true,
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
const revArgs = withShortLivedGitConfig(withNoOptionalLocks(["rev-parse", "--verify", "HEAD"]));
|
|
701
|
+
const revResult = Bun.spawnSync(["git", ...revArgs], {
|
|
702
|
+
cwd: repository.repoRoot,
|
|
703
|
+
stdout: "pipe",
|
|
704
|
+
stderr: "pipe",
|
|
705
|
+
windowsHide: true,
|
|
706
|
+
});
|
|
707
|
+
const commit = revResult.exitCode === 0 ? new TextDecoder().decode(revResult.stdout).trim() || null : null;
|
|
708
|
+
|
|
709
|
+
if (symResult.exitCode === 0) {
|
|
710
|
+
const ref = new TextDecoder().decode(symResult.stdout).trim();
|
|
711
|
+
const branchName = ref.startsWith(LOCAL_BRANCH_PREFIX) ? ref.slice(LOCAL_BRANCH_PREFIX.length) : null;
|
|
712
|
+
return {
|
|
713
|
+
...repository,
|
|
714
|
+
kind: "ref",
|
|
715
|
+
ref,
|
|
716
|
+
branchName,
|
|
717
|
+
commit,
|
|
718
|
+
headContent: `${HEAD_REF_PREFIX} ${ref}`,
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
return {
|
|
723
|
+
...repository,
|
|
724
|
+
kind: "detached",
|
|
725
|
+
commit,
|
|
726
|
+
headContent: commit || "",
|
|
727
|
+
};
|
|
728
|
+
}
|
|
729
|
+
|
|
563
730
|
function readRefSync(repository: GitRepository, targetRef: string): string | null {
|
|
731
|
+
if (isReftableRepoSync(repository)) {
|
|
732
|
+
ensureAvailable();
|
|
733
|
+
const symArgs = withShortLivedGitConfig(withNoOptionalLocks(["symbolic-ref", targetRef]));
|
|
734
|
+
const symResult = Bun.spawnSync(["git", ...symArgs], {
|
|
735
|
+
cwd: repository.repoRoot,
|
|
736
|
+
stdout: "pipe",
|
|
737
|
+
stderr: "pipe",
|
|
738
|
+
windowsHide: true,
|
|
739
|
+
});
|
|
740
|
+
if (symResult.exitCode === 0) {
|
|
741
|
+
const stdoutText = new TextDecoder().decode(symResult.stdout).trim();
|
|
742
|
+
return `${HEAD_REF_PREFIX} ${stdoutText}`;
|
|
743
|
+
}
|
|
744
|
+
const revArgs = withShortLivedGitConfig(withNoOptionalLocks(["rev-parse", "--verify", targetRef]));
|
|
745
|
+
const revResult = Bun.spawnSync(["git", ...revArgs], {
|
|
746
|
+
cwd: repository.repoRoot,
|
|
747
|
+
stdout: "pipe",
|
|
748
|
+
stderr: "pipe",
|
|
749
|
+
windowsHide: true,
|
|
750
|
+
});
|
|
751
|
+
if (revResult.exitCode === 0) {
|
|
752
|
+
return new TextDecoder().decode(revResult.stdout).trim() || null;
|
|
753
|
+
}
|
|
754
|
+
return null;
|
|
755
|
+
}
|
|
756
|
+
|
|
564
757
|
for (const dir of getRefLookupDirs(repository)) {
|
|
565
758
|
const value = normalizeRefValue(readOptionalTextSync(path.join(dir, targetRef)));
|
|
566
759
|
if (value) return value;
|
|
@@ -572,7 +765,42 @@ function readRefSync(repository: GitRepository, targetRef: string): string | nul
|
|
|
572
765
|
return null;
|
|
573
766
|
}
|
|
574
767
|
|
|
575
|
-
async function readRef(repository: GitRepository, targetRef: string): Promise<string | null> {
|
|
768
|
+
async function readRef(repository: GitRepository, targetRef: string, signal?: AbortSignal): Promise<string | null> {
|
|
769
|
+
if (await isReftableRepo(repository)) {
|
|
770
|
+
throwIfAborted(signal);
|
|
771
|
+
const symResult = await git(repository.repoRoot, ["symbolic-ref", targetRef], { readOnly: true, signal }).catch(
|
|
772
|
+
err => {
|
|
773
|
+
if (
|
|
774
|
+
signal?.aborted ||
|
|
775
|
+
(err instanceof Error && (err.name === "AbortError" || err.name === "ToolAbortError"))
|
|
776
|
+
) {
|
|
777
|
+
throw err;
|
|
778
|
+
}
|
|
779
|
+
return null;
|
|
780
|
+
},
|
|
781
|
+
);
|
|
782
|
+
if (symResult && symResult.exitCode === 0) {
|
|
783
|
+
return `${HEAD_REF_PREFIX} ${symResult.stdout.trim()}`;
|
|
784
|
+
}
|
|
785
|
+
throwIfAborted(signal);
|
|
786
|
+
const revResult = await git(repository.repoRoot, ["rev-parse", "--verify", targetRef], {
|
|
787
|
+
readOnly: true,
|
|
788
|
+
signal,
|
|
789
|
+
}).catch(err => {
|
|
790
|
+
if (
|
|
791
|
+
signal?.aborted ||
|
|
792
|
+
(err instanceof Error && (err.name === "AbortError" || err.name === "ToolAbortError"))
|
|
793
|
+
) {
|
|
794
|
+
throw err;
|
|
795
|
+
}
|
|
796
|
+
return null;
|
|
797
|
+
});
|
|
798
|
+
if (revResult && revResult.exitCode === 0) {
|
|
799
|
+
return revResult.stdout.trim() || null;
|
|
800
|
+
}
|
|
801
|
+
return null;
|
|
802
|
+
}
|
|
803
|
+
|
|
576
804
|
for (const dir of getRefLookupDirs(repository)) {
|
|
577
805
|
const value = normalizeRefValue(await readOptionalText(path.join(dir, targetRef)));
|
|
578
806
|
if (value) return value;
|
|
@@ -997,7 +1225,7 @@ export const branch = {
|
|
|
997
1225
|
const repository = await resolveRepository(cwd);
|
|
998
1226
|
if (repository) {
|
|
999
1227
|
for (const refPath of DEFAULT_BRANCH_REFS) {
|
|
1000
|
-
const target = await readRef(repository, refPath);
|
|
1228
|
+
const target = await readRef(repository, refPath, signal);
|
|
1001
1229
|
const branchName = parseDefaultBranchRef(refPath, target);
|
|
1002
1230
|
if (branchName) return branchName;
|
|
1003
1231
|
}
|
|
@@ -1095,7 +1323,7 @@ export const ref = {
|
|
|
1095
1323
|
async exists(cwd: string, refName: string, signal?: AbortSignal): Promise<boolean> {
|
|
1096
1324
|
if (refName === "HEAD") return (await head.sha(cwd, signal)) !== null;
|
|
1097
1325
|
const repository = await resolveRepository(cwd);
|
|
1098
|
-
if (repository && refName.startsWith("refs/")) return (await readRef(repository, refName)) !== null;
|
|
1326
|
+
if (repository && refName.startsWith("refs/")) return (await readRef(repository, refName, signal)) !== null;
|
|
1099
1327
|
const result = await git(cwd, ["show-ref", "--verify", "--quiet", refName], { readOnly: true, signal });
|
|
1100
1328
|
return result.exitCode === 0;
|
|
1101
1329
|
},
|
|
@@ -1104,7 +1332,7 @@ export const ref = {
|
|
|
1104
1332
|
async resolve(cwd: string, refName: string, signal?: AbortSignal): Promise<string | null> {
|
|
1105
1333
|
if (refName === "HEAD") return head.sha(cwd, signal);
|
|
1106
1334
|
const repository = await resolveRepository(cwd);
|
|
1107
|
-
if (repository && refName.startsWith("refs/")) return readRef(repository, refName);
|
|
1335
|
+
if (repository && refName.startsWith("refs/")) return readRef(repository, refName, signal);
|
|
1108
1336
|
const result = await git(cwd, ["rev-parse", refName], { readOnly: true, signal });
|
|
1109
1337
|
if (result.exitCode !== 0) return null;
|
|
1110
1338
|
return result.stdout.trim() || null;
|
|
@@ -1397,9 +1625,12 @@ export const ls = {
|
|
|
1397
1625
|
|
|
1398
1626
|
export const head = {
|
|
1399
1627
|
/** Full HEAD state (branch, commit, repo info). */
|
|
1400
|
-
async resolve(cwd: string): Promise<GitHeadState | null> {
|
|
1628
|
+
async resolve(cwd: string, signal?: AbortSignal): Promise<GitHeadState | null> {
|
|
1401
1629
|
const repository = await resolveRepository(cwd);
|
|
1402
1630
|
if (!repository) return null;
|
|
1631
|
+
if (await isReftableRepo(repository)) {
|
|
1632
|
+
return resolveHeadStateReftable(repository, signal);
|
|
1633
|
+
}
|
|
1403
1634
|
const content = await readOptionalText(repository.headPath);
|
|
1404
1635
|
if (content === null) return null;
|
|
1405
1636
|
return parseHeadState(repository, content);
|
|
@@ -1409,6 +1640,9 @@ export const head = {
|
|
|
1409
1640
|
resolveSync(cwd: string): GitHeadState | null {
|
|
1410
1641
|
const repository = resolveRepositorySync(cwd);
|
|
1411
1642
|
if (!repository) return null;
|
|
1643
|
+
if (isReftableRepoSync(repository)) {
|
|
1644
|
+
return resolveHeadStateReftableSync(repository);
|
|
1645
|
+
}
|
|
1412
1646
|
const content = readOptionalTextSync(repository.headPath);
|
|
1413
1647
|
if (content === null) return null;
|
|
1414
1648
|
return parseHeadStateSync(repository, content);
|
|
@@ -1416,7 +1650,7 @@ export const head = {
|
|
|
1416
1650
|
|
|
1417
1651
|
/** Current HEAD commit SHA. */
|
|
1418
1652
|
async sha(cwd: string, signal?: AbortSignal): Promise<string | null> {
|
|
1419
|
-
const headState = await head.resolve(cwd);
|
|
1653
|
+
const headState = await head.resolve(cwd, signal);
|
|
1420
1654
|
if (headState?.commit) return headState.commit;
|
|
1421
1655
|
const result = await git(cwd, ["rev-parse", "HEAD"], { readOnly: true, signal });
|
|
1422
1656
|
if (result.exitCode !== 0) return null;
|
|
@@ -1445,13 +1679,10 @@ export const repo = {
|
|
|
1445
1679
|
return result.stdout.trim() || null;
|
|
1446
1680
|
},
|
|
1447
1681
|
|
|
1448
|
-
/** Resolve the primary
|
|
1682
|
+
/** Resolve the primary checkout root, or the shared common dir for bare-repo worktrees. */
|
|
1449
1683
|
async primaryRoot(cwd: string, signal?: AbortSignal): Promise<string | null> {
|
|
1450
1684
|
const repository = await resolveRepository(cwd);
|
|
1451
|
-
if (repository)
|
|
1452
|
-
if (path.basename(repository.commonDir) === ".git") return path.dirname(repository.commonDir);
|
|
1453
|
-
return repository.repoRoot;
|
|
1454
|
-
}
|
|
1685
|
+
if (repository) return primaryRootFromRepository(repository);
|
|
1455
1686
|
const repoRoot = await repo.root(cwd, signal);
|
|
1456
1687
|
if (!repoRoot) return null;
|
|
1457
1688
|
const commonDir = await runText(repoRoot, ["rev-parse", "--path-format=absolute", "--git-common-dir"], {
|
|
@@ -1462,6 +1693,19 @@ export const repo = {
|
|
|
1462
1693
|
return repoRoot;
|
|
1463
1694
|
},
|
|
1464
1695
|
|
|
1696
|
+
/**
|
|
1697
|
+
* Sync sibling of {@link primaryRoot}. Resolves only via on-disk `.git`/
|
|
1698
|
+
* `commondir` walking — no subprocess fallback — so it stays usable from
|
|
1699
|
+
* paths where async I/O is impractical (e.g. `computeBankScope`). Returns
|
|
1700
|
+
* `null` when `cwd` is outside a repository. Bare-repo worktrees resolve to
|
|
1701
|
+
* the shared common dir (`foo.git`) because they have no primary checkout.
|
|
1702
|
+
*/
|
|
1703
|
+
primaryRootSync(cwd: string): string | null {
|
|
1704
|
+
const repository = resolveRepositorySync(cwd);
|
|
1705
|
+
if (!repository) return null;
|
|
1706
|
+
return primaryRootFromRepositorySync(repository);
|
|
1707
|
+
},
|
|
1708
|
+
|
|
1465
1709
|
/** Full GitRepository metadata (sync). */
|
|
1466
1710
|
resolveSync(cwd: string): GitRepository | null {
|
|
1467
1711
|
return resolveRepositorySync(cwd);
|
|
@@ -1471,11 +1715,21 @@ export const repo = {
|
|
|
1471
1715
|
resolve(cwd: string): Promise<GitRepository | null> {
|
|
1472
1716
|
return resolveRepository(cwd);
|
|
1473
1717
|
},
|
|
1718
|
+
|
|
1719
|
+
/** Check if the repository uses the reftable reference storage format (sync). */
|
|
1720
|
+
isReftableSync(repository: GitRepository): boolean {
|
|
1721
|
+
return isReftableRepoSync(repository);
|
|
1722
|
+
},
|
|
1723
|
+
|
|
1724
|
+
/** Check if the repository uses the reftable reference storage format. */
|
|
1725
|
+
isReftable(repository: GitRepository): Promise<boolean> {
|
|
1726
|
+
return isReftableRepo(repository);
|
|
1727
|
+
},
|
|
1474
1728
|
};
|
|
1475
1729
|
|
|
1476
1730
|
// Helper used during head resolution — defined here to reference `head` namespace.
|
|
1477
|
-
async function resolveHead(cwd: string): Promise<GitHeadState | null> {
|
|
1478
|
-
return head.resolve(cwd);
|
|
1731
|
+
async function resolveHead(cwd: string, signal?: AbortSignal): Promise<GitHeadState | null> {
|
|
1732
|
+
return head.resolve(cwd, signal);
|
|
1479
1733
|
}
|
|
1480
1734
|
|
|
1481
1735
|
// ════════════════════════════════════════════════════════════════════════════
|
|
@@ -33,7 +33,7 @@ const setTitleTool: Tool = {
|
|
|
33
33
|
title: {
|
|
34
34
|
type: "string",
|
|
35
35
|
description:
|
|
36
|
-
'
|
|
36
|
+
'The generated session title, or exactly "none" when the message carries no concrete task yet.',
|
|
37
37
|
},
|
|
38
38
|
},
|
|
39
39
|
required: ["title"],
|
|
@@ -137,6 +137,7 @@ export async function raceFirstNonNull<T>(
|
|
|
137
137
|
* to produce request metadata (e.g. user_id for session attribution). Using a
|
|
138
138
|
* resolver instead of a pre-evaluated value ensures the metadata's account_uuid
|
|
139
139
|
* reflects the credential actually selected for this request.
|
|
140
|
+
* @param customSystemPrompt Optional title-specific system prompt override
|
|
140
141
|
*/
|
|
141
142
|
export async function generateSessionTitle(
|
|
142
143
|
firstMessage: string,
|
|
@@ -145,6 +146,7 @@ export async function generateSessionTitle(
|
|
|
145
146
|
sessionId?: string,
|
|
146
147
|
currentModel?: Model<Api>,
|
|
147
148
|
metadataResolver?: (provider: string) => Record<string, unknown> | undefined,
|
|
149
|
+
customSystemPrompt?: string,
|
|
148
150
|
): Promise<string | null> {
|
|
149
151
|
// Defer titling for greetings / acknowledgements / empty input. The default
|
|
150
152
|
// tiny title model can't reliably decline trivial input, so this happens
|
|
@@ -155,13 +157,26 @@ export async function generateSessionTitle(
|
|
|
155
157
|
return null;
|
|
156
158
|
}
|
|
157
159
|
|
|
160
|
+
const titleSystemPrompt = customSystemPrompt?.trim() || undefined;
|
|
158
161
|
const tinyModel = settings.get("providers.tinyModel");
|
|
159
162
|
if (tinyModel === ONLINE_TINY_TITLE_MODEL_KEY) {
|
|
160
|
-
return generateTitleOnline(
|
|
163
|
+
return generateTitleOnline(
|
|
164
|
+
firstMessage,
|
|
165
|
+
registry,
|
|
166
|
+
settings,
|
|
167
|
+
sessionId,
|
|
168
|
+
currentModel,
|
|
169
|
+
metadataResolver,
|
|
170
|
+
undefined,
|
|
171
|
+
titleSystemPrompt,
|
|
172
|
+
);
|
|
161
173
|
}
|
|
162
174
|
|
|
163
175
|
const onlineAbortController = new AbortController();
|
|
164
|
-
const
|
|
176
|
+
const localTitlePromise = titleSystemPrompt
|
|
177
|
+
? tinyTitleClient.generate(tinyModel, firstMessage, { systemPrompt: titleSystemPrompt })
|
|
178
|
+
: tinyTitleClient.generate(tinyModel, firstMessage);
|
|
179
|
+
const localTitle = localTitlePromise.then(
|
|
165
180
|
title => title || null,
|
|
166
181
|
err => {
|
|
167
182
|
logger.warn("title-generator: local model error", {
|
|
@@ -181,6 +196,7 @@ export async function generateSessionTitle(
|
|
|
181
196
|
currentModel,
|
|
182
197
|
metadataResolver,
|
|
183
198
|
onlineAbortController.signal,
|
|
199
|
+
titleSystemPrompt,
|
|
184
200
|
);
|
|
185
201
|
|
|
186
202
|
return raceFirstNonNull(localTitle, startOnline, TITLE_LOCAL_FALLBACK_DELAY_MS, () => {
|
|
@@ -196,6 +212,7 @@ export async function generateTitleOnline(
|
|
|
196
212
|
currentModel?: Model<Api>,
|
|
197
213
|
metadataResolver?: (provider: string) => Record<string, unknown> | undefined,
|
|
198
214
|
signal?: AbortSignal,
|
|
215
|
+
customSystemPrompt?: string,
|
|
199
216
|
): Promise<string | null> {
|
|
200
217
|
const model = getTitleModel(registry, settings, currentModel);
|
|
201
218
|
if (!model) {
|
|
@@ -203,6 +220,8 @@ export async function generateTitleOnline(
|
|
|
203
220
|
return null;
|
|
204
221
|
}
|
|
205
222
|
|
|
223
|
+
const titleSystemPrompt = customSystemPrompt?.trim() || undefined;
|
|
224
|
+
const systemPrompt = titleSystemPrompt ?? TITLE_SYSTEM_PROMPT;
|
|
206
225
|
const userMessage = formatTitleUserMessage(firstMessage);
|
|
207
226
|
const modelName = `${model.provider}/${model.id}`;
|
|
208
227
|
const modelContext = {
|
|
@@ -234,12 +253,12 @@ export async function generateTitleOnline(
|
|
|
234
253
|
const response = await completeSimple(
|
|
235
254
|
model,
|
|
236
255
|
{
|
|
237
|
-
systemPrompt: [
|
|
256
|
+
systemPrompt: [systemPrompt],
|
|
238
257
|
messages: [{ role: "user", content: userMessage, timestamp: Date.now() }],
|
|
239
258
|
tools: [setTitleTool],
|
|
240
259
|
},
|
|
241
260
|
{
|
|
242
|
-
apiKey: registry.resolver(model.provider, { sessionId, baseUrl: model.baseUrl }),
|
|
261
|
+
apiKey: registry.resolver(model.provider, { sessionId, baseUrl: model.baseUrl, modelId: model.id }),
|
|
243
262
|
maxTokens,
|
|
244
263
|
disableReasoning: true,
|
|
245
264
|
toolChoice: { type: "tool", name: SET_TITLE_TOOL_NAME },
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { parseHTML } from "linkedom";
|
|
2
1
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
3
2
|
import { buildResult, loadPage } from "./types";
|
|
4
3
|
import { convertWithMarkit, fetchBinary } from "./utils";
|
|
@@ -31,6 +30,7 @@ export const handleArxiv: SpecialHandler = async (
|
|
|
31
30
|
if (!result.ok) return null;
|
|
32
31
|
|
|
33
32
|
// Parse the Atom feed response
|
|
33
|
+
const { parseHTML } = await import("linkedom");
|
|
34
34
|
const doc = parseHTML(result.content).document;
|
|
35
35
|
const entry = doc.querySelector("entry");
|
|
36
36
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { tryParseJson } from "@oh-my-pi/pi-utils";
|
|
2
|
-
import { parseHTML } from "linkedom";
|
|
3
2
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
4
3
|
import { buildResult, htmlToBasicMarkdown, loadPage } from "./types";
|
|
5
4
|
|
|
@@ -97,6 +96,7 @@ export const handleGoPkg: SpecialHandler = async (
|
|
|
97
96
|
});
|
|
98
97
|
}
|
|
99
98
|
|
|
99
|
+
const { parseHTML } = await import("linkedom");
|
|
100
100
|
const doc = parseHTML(pageResult.content).document;
|
|
101
101
|
|
|
102
102
|
// Extract actual module path from breadcrumb or header
|
package/src/web/scrapers/iacr.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { parseHTML } from "linkedom";
|
|
2
1
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
3
2
|
import { buildResult, loadPage } from "./types";
|
|
4
3
|
import { convertWithMarkit, fetchBinary } from "./utils";
|
|
@@ -30,6 +29,7 @@ export const handleIacr: SpecialHandler = async (
|
|
|
30
29
|
|
|
31
30
|
if (!result.ok) return null;
|
|
32
31
|
|
|
32
|
+
const { parseHTML } = await import("linkedom");
|
|
33
33
|
const doc = parseHTML(result.content).document;
|
|
34
34
|
|
|
35
35
|
// Extract metadata from the page
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Read the Docs handler for web-fetch
|
|
3
3
|
*/
|
|
4
|
-
import { parseHTML } from "linkedom";
|
|
5
4
|
import { buildResult, htmlToBasicMarkdown, loadPage, type RenderResult, type SpecialHandler } from "./types";
|
|
6
5
|
|
|
7
6
|
export const handleReadTheDocs: SpecialHandler = async (
|
|
@@ -39,6 +38,7 @@ export const handleReadTheDocs: SpecialHandler = async (
|
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
// Parse HTML
|
|
41
|
+
const { parseHTML } = await import("linkedom");
|
|
42
42
|
const root = parseHTML(result.content).document;
|
|
43
43
|
|
|
44
44
|
// Extract main content from common Read the Docs selectors
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { HTMLElement } from "linkedom";
|
|
2
2
|
import { ToolAbortError } from "../../tools/tool-errors";
|
|
3
3
|
import type { RenderResult, SpecialHandler } from "./types";
|
|
4
4
|
import { buildResult, loadPage } from "./types";
|
|
@@ -33,6 +33,7 @@ export const handleTwitter: SpecialHandler = async (
|
|
|
33
33
|
|
|
34
34
|
if (result.ok && result.content.length > 500) {
|
|
35
35
|
// Parse the Nitter HTML
|
|
36
|
+
const { parseHTML } = await import("linkedom");
|
|
36
37
|
const doc = parseHTML(result.content).document;
|
|
37
38
|
|
|
38
39
|
// Extract tweet content
|