@oh-my-pi/pi-coding-agent 8.0.20 → 8.2.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 +125 -0
- package/docs/session.md +111 -46
- package/examples/custom-tools/hello/index.ts +1 -1
- package/examples/custom-tools/todo/index.ts +3 -4
- package/examples/extensions/api-demo.ts +0 -1
- package/examples/extensions/chalk-logger.ts +2 -3
- package/examples/extensions/hello.ts +0 -1
- package/examples/extensions/pirate.ts +0 -1
- package/examples/extensions/plan-mode.ts +15 -16
- package/examples/extensions/todo.ts +3 -4
- package/examples/extensions/tools.ts +1 -2
- package/examples/extensions/with-deps/index.ts +0 -1
- package/examples/hooks/auto-commit-on-exit.ts +1 -2
- package/examples/hooks/confirm-destructive.ts +0 -1
- package/examples/hooks/custom-compaction.ts +1 -2
- package/examples/hooks/dirty-repo-guard.ts +0 -1
- package/examples/hooks/file-trigger.ts +3 -4
- package/examples/hooks/git-checkpoint.ts +0 -1
- package/examples/hooks/handoff.ts +3 -4
- package/examples/hooks/permission-gate.ts +1 -2
- package/examples/hooks/protected-paths.ts +1 -2
- package/examples/hooks/qna.ts +2 -3
- package/examples/hooks/snake.ts +4 -5
- package/examples/hooks/status-line.ts +0 -1
- package/examples/sdk/01-minimal.ts +2 -3
- package/examples/sdk/02-custom-model.ts +2 -3
- package/examples/sdk/03-custom-prompt.ts +3 -4
- package/examples/sdk/04-skills.ts +2 -3
- package/examples/sdk/06-extensions.ts +1 -2
- package/examples/sdk/06-hooks.ts +6 -7
- package/examples/sdk/07-context-files.ts +0 -1
- package/examples/sdk/08-prompt-templates.ts +0 -1
- package/examples/sdk/08-slash-commands.ts +0 -1
- package/examples/sdk/09-api-keys-and-oauth.ts +0 -1
- package/examples/sdk/10-settings.ts +0 -1
- package/examples/sdk/11-sessions.ts +0 -1
- package/package.json +54 -23
- package/scripts/format-prompts.ts +0 -1
- package/src/capability/context-file.ts +3 -4
- package/src/capability/extension-module.ts +3 -4
- package/src/capability/extension.ts +3 -4
- package/src/capability/fs.ts +20 -21
- package/src/capability/hook.ts +3 -4
- package/src/capability/index.ts +15 -16
- package/src/capability/instruction.ts +3 -4
- package/src/capability/mcp.ts +3 -4
- package/src/capability/prompt.ts +3 -4
- package/src/capability/rule.ts +3 -4
- package/src/capability/settings.ts +2 -3
- package/src/capability/skill.ts +3 -4
- package/src/capability/slash-command.ts +3 -4
- package/src/capability/ssh.ts +3 -4
- package/src/capability/system-prompt.ts +3 -4
- package/src/capability/tool.ts +3 -4
- package/src/cli/args.ts +5 -6
- package/src/cli/config-cli.ts +6 -7
- package/src/cli/file-processor.ts +19 -17
- package/src/cli/jupyter-cli.ts +105 -0
- package/src/cli/list-models.ts +10 -11
- package/src/cli/plugin-cli.ts +20 -25
- package/src/cli/session-picker.ts +2 -3
- package/src/cli/setup-cli.ts +2 -3
- package/src/cli/stats-cli.ts +2 -3
- package/src/cli/update-cli.ts +25 -22
- package/src/commit/agentic/agent.ts +307 -0
- package/src/commit/agentic/fallback.ts +96 -0
- package/src/commit/agentic/index.ts +351 -0
- package/src/commit/agentic/prompts/analyze-file.md +22 -0
- package/src/commit/agentic/prompts/session-user.md +26 -0
- package/src/commit/agentic/prompts/split-confirm.md +1 -0
- package/src/commit/agentic/prompts/system.md +40 -0
- package/src/commit/agentic/state.ts +69 -0
- package/src/commit/agentic/tools/analyze-file.ts +131 -0
- package/src/commit/agentic/tools/git-file-diff.ts +194 -0
- package/src/commit/agentic/tools/git-hunk.ts +50 -0
- package/src/commit/agentic/tools/git-overview.ts +84 -0
- package/src/commit/agentic/tools/index.ts +56 -0
- package/src/commit/agentic/tools/propose-changelog.ts +128 -0
- package/src/commit/agentic/tools/propose-commit.ts +154 -0
- package/src/commit/agentic/tools/recent-commits.ts +81 -0
- package/src/commit/agentic/tools/split-commit.ts +280 -0
- package/src/commit/agentic/topo-sort.ts +44 -0
- package/src/commit/agentic/trivial.ts +51 -0
- package/src/commit/agentic/validation.ts +200 -0
- package/src/commit/analysis/conventional.ts +165 -0
- package/src/commit/analysis/index.ts +4 -0
- package/src/commit/analysis/scope.ts +242 -0
- package/src/commit/analysis/summary.ts +112 -0
- package/src/commit/analysis/validation.ts +66 -0
- package/src/commit/changelog/detect.ts +36 -0
- package/src/commit/changelog/generate.ts +110 -0
- package/src/commit/changelog/index.ts +233 -0
- package/src/commit/changelog/parse.ts +44 -0
- package/src/commit/cli.ts +93 -0
- package/src/commit/git/diff.ts +148 -0
- package/src/commit/git/errors.ts +11 -0
- package/src/commit/git/index.ts +212 -0
- package/src/commit/git/operations.ts +53 -0
- package/src/commit/index.ts +5 -0
- package/src/commit/map-reduce/index.ts +63 -0
- package/src/commit/map-reduce/map-phase.ts +178 -0
- package/src/commit/map-reduce/reduce-phase.ts +145 -0
- package/src/commit/map-reduce/utils.ts +9 -0
- package/src/commit/message.ts +11 -0
- package/src/commit/model-selection.ts +80 -0
- package/src/commit/pipeline.ts +240 -0
- package/src/commit/prompts/analysis-system.md +155 -0
- package/src/commit/prompts/analysis-user.md +41 -0
- package/src/commit/prompts/changelog-system.md +56 -0
- package/src/commit/prompts/changelog-user.md +19 -0
- package/src/commit/prompts/file-observer-system.md +26 -0
- package/src/commit/prompts/file-observer-user.md +9 -0
- package/src/commit/prompts/reduce-system.md +60 -0
- package/src/commit/prompts/reduce-user.md +17 -0
- package/src/commit/prompts/summary-retry.md +4 -0
- package/src/commit/prompts/summary-system.md +52 -0
- package/src/commit/prompts/summary-user.md +13 -0
- package/src/commit/prompts/types-description.md +2 -0
- package/src/commit/types.ts +109 -0
- package/src/commit/utils/exclusions.ts +42 -0
- package/src/config/file-lock.ts +121 -0
- package/src/config/keybindings.ts +6 -8
- package/src/config/model-registry.ts +65 -38
- package/src/config/model-resolver.ts +18 -19
- package/src/config/prompt-templates.ts +11 -11
- package/src/config/settings-manager.ts +141 -50
- package/src/config.ts +64 -66
- package/src/cursor.ts +11 -9
- package/src/discovery/agents-md.ts +11 -12
- package/src/discovery/builtin.ts +68 -73
- package/src/discovery/claude.ts +41 -42
- package/src/discovery/cline.ts +11 -12
- package/src/discovery/codex.ts +52 -53
- package/src/discovery/cursor.ts +9 -10
- package/src/discovery/gemini.ts +17 -22
- package/src/discovery/github.ts +13 -14
- package/src/discovery/helpers.ts +35 -34
- package/src/discovery/index.ts +22 -24
- package/src/discovery/mcp-json.ts +8 -9
- package/src/discovery/ssh.ts +8 -9
- package/src/discovery/vscode.ts +4 -5
- package/src/discovery/windsurf.ts +6 -7
- package/src/exa/company.ts +1 -2
- package/src/exa/index.ts +2 -3
- package/src/exa/linkedin.ts +1 -2
- package/src/exa/mcp-client.ts +14 -16
- package/src/exa/render.ts +10 -11
- package/src/exa/researcher.ts +1 -2
- package/src/exa/search.ts +1 -2
- package/src/exa/types.ts +0 -1
- package/src/exa/websets.ts +1 -2
- package/src/exec/bash-executor.ts +3 -4
- package/src/exec/exec.ts +0 -1
- package/src/export/custom-share.ts +5 -6
- package/src/export/html/index.ts +24 -21
- package/src/export/ttsr.ts +2 -3
- package/src/extensibility/custom-commands/bundled/review/index.ts +7 -8
- package/src/extensibility/custom-commands/loader.ts +18 -15
- package/src/extensibility/custom-commands/types.ts +2 -3
- package/src/extensibility/custom-tools/loader.ts +11 -12
- package/src/extensibility/custom-tools/types.ts +7 -8
- package/src/extensibility/custom-tools/wrapper.ts +2 -3
- package/src/extensibility/extensions/loader.ts +76 -54
- package/src/extensibility/extensions/runner.ts +11 -12
- package/src/extensibility/extensions/types.ts +20 -27
- package/src/extensibility/extensions/wrapper.ts +3 -4
- package/src/extensibility/hooks/index.ts +1 -1
- package/src/extensibility/hooks/loader.ts +9 -10
- package/src/extensibility/hooks/runner.ts +7 -8
- package/src/extensibility/hooks/tool-wrapper.ts +0 -1
- package/src/extensibility/hooks/types.ts +11 -18
- package/src/extensibility/plugins/doctor.ts +3 -3
- package/src/extensibility/plugins/installer.ts +27 -27
- package/src/extensibility/plugins/loader.ts +59 -56
- package/src/extensibility/plugins/manager.ts +211 -171
- package/src/extensibility/plugins/parser.ts +1 -1
- package/src/extensibility/plugins/paths.ts +8 -8
- package/src/extensibility/skills.ts +63 -60
- package/src/extensibility/slash-commands.ts +10 -10
- package/src/index.ts +54 -54
- package/src/internal-urls/agent-protocol.ts +21 -11
- package/src/internal-urls/artifact-protocol.ts +17 -13
- package/src/internal-urls/router.ts +1 -2
- package/src/internal-urls/rule-protocol.ts +3 -4
- package/src/internal-urls/skill-protocol.ts +3 -4
- package/src/ipy/executor.ts +109 -9
- package/src/ipy/gateway-coordinator.ts +79 -90
- package/src/ipy/kernel.ts +32 -30
- package/src/ipy/modules.ts +13 -13
- package/src/lsp/client.ts +21 -10
- package/src/lsp/clients/biome-client.ts +1 -2
- package/src/lsp/clients/index.ts +3 -3
- package/src/lsp/clients/lsp-linter-client.ts +4 -5
- package/src/lsp/config.ts +15 -15
- package/src/lsp/edits.ts +4 -5
- package/src/lsp/index.ts +43 -44
- package/src/lsp/lspmux.ts +8 -8
- package/src/lsp/render.ts +99 -61
- package/src/lsp/utils.ts +3 -3
- package/src/main.ts +71 -37
- package/src/mcp/client.ts +2 -3
- package/src/mcp/config.ts +5 -6
- package/src/mcp/json-rpc.ts +0 -1
- package/src/mcp/loader.ts +6 -7
- package/src/mcp/manager.ts +17 -18
- package/src/mcp/tool-bridge.ts +4 -9
- package/src/mcp/tool-cache.ts +2 -3
- package/src/mcp/transports/http.ts +2 -4
- package/src/mcp/transports/stdio.ts +1 -2
- package/src/migrations.ts +63 -52
- package/src/modes/components/armin.ts +4 -5
- package/src/modes/components/assistant-message.ts +33 -5
- package/src/modes/components/bash-execution.ts +7 -8
- package/src/modes/components/bordered-loader.ts +3 -3
- package/src/modes/components/branch-summary-message.ts +3 -3
- package/src/modes/components/compaction-summary-message.ts +3 -3
- package/src/modes/components/countdown-timer.ts +0 -1
- package/src/modes/components/custom-message.ts +5 -5
- package/src/modes/components/diff.ts +1 -1
- package/src/modes/components/dynamic-border.ts +2 -2
- package/src/modes/components/extensions/extension-dashboard.ts +6 -7
- package/src/modes/components/extensions/extension-list.ts +2 -3
- package/src/modes/components/extensions/inspector-panel.ts +3 -4
- package/src/modes/components/extensions/state-manager.ts +25 -26
- package/src/modes/components/extensions/types.ts +1 -2
- package/src/modes/components/footer.ts +47 -43
- package/src/modes/components/history-search.ts +2 -2
- package/src/modes/components/hook-editor.ts +3 -4
- package/src/modes/components/hook-input.ts +2 -3
- package/src/modes/components/hook-message.ts +5 -5
- package/src/modes/components/hook-selector.ts +2 -3
- package/src/modes/components/keybinding-hints.ts +2 -3
- package/src/modes/components/login-dialog.ts +2 -2
- package/src/modes/components/model-selector.ts +12 -12
- package/src/modes/components/oauth-selector.ts +2 -2
- package/src/modes/components/plugin-settings.ts +20 -20
- package/src/modes/components/python-execution.ts +7 -8
- package/src/modes/components/queue-mode-selector.ts +3 -3
- package/src/modes/components/read-tool-group.ts +2 -2
- package/src/modes/components/session-selector.ts +4 -4
- package/src/modes/components/settings-defs.ts +77 -69
- package/src/modes/components/settings-selector.ts +16 -16
- package/src/modes/components/show-images-selector.ts +2 -2
- package/src/modes/components/status-line/segments.ts +4 -4
- package/src/modes/components/status-line/separators.ts +1 -1
- package/src/modes/components/status-line/types.ts +2 -2
- package/src/modes/components/status-line-segment-editor.ts +7 -8
- package/src/modes/components/status-line.ts +12 -12
- package/src/modes/components/theme-selector.ts +8 -7
- package/src/modes/components/thinking-selector.ts +4 -4
- package/src/modes/components/todo-display.ts +2 -2
- package/src/modes/components/todo-reminder.ts +4 -4
- package/src/modes/components/tool-execution.ts +16 -19
- package/src/modes/components/tree-selector.ts +12 -12
- package/src/modes/components/ttsr-notification.ts +5 -5
- package/src/modes/components/user-message-selector.ts +1 -1
- package/src/modes/components/user-message.ts +1 -1
- package/src/modes/components/visual-truncate.ts +0 -1
- package/src/modes/components/welcome.ts +4 -4
- package/src/modes/controllers/command-controller.ts +46 -47
- package/src/modes/controllers/event-controller.ts +16 -20
- package/src/modes/controllers/extension-ui-controller.ts +40 -46
- package/src/modes/controllers/input-controller.ts +17 -18
- package/src/modes/controllers/selector-controller.ts +103 -91
- package/src/modes/index.ts +3 -3
- package/src/modes/interactive-mode.ts +31 -31
- package/src/modes/print-mode.ts +12 -13
- package/src/modes/rpc/rpc-client.ts +7 -8
- package/src/modes/rpc/rpc-mode.ts +24 -28
- package/src/modes/rpc/rpc-types.ts +3 -4
- package/src/modes/theme/mermaid-cache.ts +89 -0
- package/src/modes/theme/theme.ts +130 -53
- package/src/modes/types.ts +10 -10
- package/src/modes/utils/ui-helpers.ts +17 -17
- package/src/patch/applicator.ts +18 -19
- package/src/patch/diff.ts +1 -2
- package/src/patch/fuzzy.ts +1 -2
- package/src/patch/index.ts +11 -18
- package/src/patch/normalize.ts +4 -4
- package/src/patch/normative.ts +1 -2
- package/src/patch/parser.ts +8 -9
- package/src/patch/shared.ts +43 -16
- package/src/prompts/tools/task.md +2 -0
- package/src/sdk.ts +100 -65
- package/src/session/agent-session.ts +84 -85
- package/src/session/agent-storage.ts +43 -39
- package/src/session/artifacts.ts +32 -10
- package/src/session/auth-storage.ts +50 -39
- package/src/session/compaction/branch-summarization.ts +7 -10
- package/src/session/compaction/compaction.ts +8 -19
- package/src/session/compaction/utils.ts +6 -9
- package/src/session/history-storage.ts +10 -10
- package/src/session/messages.ts +4 -5
- package/src/session/session-manager.ts +76 -65
- package/src/session/session-storage.ts +57 -69
- package/src/session/storage-migration.ts +14 -56
- package/src/session/streaming-output.ts +2 -2
- package/src/ssh/connection-manager.ts +43 -50
- package/src/ssh/ssh-executor.ts +2 -2
- package/src/ssh/sshfs-mount.ts +11 -18
- package/src/system-prompt.ts +28 -35
- package/src/task/agents.ts +45 -30
- package/src/task/commands.ts +6 -7
- package/src/task/discovery.ts +39 -76
- package/src/task/executor.ts +14 -15
- package/src/task/index.ts +40 -34
- package/src/task/output-manager.ts +93 -0
- package/src/task/parallel.ts +0 -1
- package/src/task/render.ts +24 -30
- package/src/task/subprocess-tool-registry.ts +1 -2
- package/src/task/worker-protocol.ts +3 -3
- package/src/task/worker.ts +33 -39
- package/src/task/worktree.ts +19 -19
- package/src/tools/ask.ts +41 -20
- package/src/tools/bash-interceptor.ts +1 -5
- package/src/tools/bash.ts +91 -97
- package/src/tools/calculator.ts +49 -47
- package/src/tools/complete.ts +4 -5
- package/src/tools/context.ts +2 -2
- package/src/tools/fetch.ts +84 -124
- package/src/tools/find.ts +94 -98
- package/src/tools/gemini-image.ts +14 -14
- package/src/tools/grep.ts +100 -116
- package/src/tools/index.ts +80 -55
- package/src/tools/list-limit.ts +1 -1
- package/src/tools/ls.ts +44 -70
- package/src/tools/notebook.ts +51 -67
- package/src/tools/output-meta.ts +3 -4
- package/src/tools/output-utils.ts +2 -2
- package/src/tools/path-utils.ts +5 -5
- package/src/tools/python.ts +104 -217
- package/src/tools/read.ts +92 -33
- package/src/tools/render-utils.ts +8 -23
- package/src/tools/renderers.ts +6 -7
- package/src/tools/review.ts +8 -11
- package/src/tools/ssh.ts +69 -49
- package/src/tools/todo-write.ts +37 -25
- package/src/tools/tool-errors.ts +3 -3
- package/src/tools/tool-result.ts +3 -8
- package/src/tools/write.ts +99 -75
- package/src/tui/code-cell.ts +109 -0
- package/src/tui/file-list.ts +47 -0
- package/src/tui/index.ts +11 -0
- package/src/tui/output-block.ts +72 -0
- package/src/tui/status-line.ts +39 -0
- package/src/tui/tree-list.ts +55 -0
- package/src/tui/types.ts +16 -0
- package/src/tui/utils.ts +48 -0
- package/src/utils/changelog.ts +9 -10
- package/src/utils/clipboard.ts +11 -11
- package/src/utils/file-mentions.ts +4 -10
- package/src/utils/frontmatter.ts +6 -3
- package/src/utils/fuzzy.ts +2 -2
- package/src/utils/image-convert.ts +1 -1
- package/src/utils/image-resize.ts +1 -1
- package/src/utils/mime.ts +2 -2
- package/src/utils/shell-snapshot.ts +11 -13
- package/src/utils/shell.ts +4 -5
- package/src/utils/title-generator.ts +8 -9
- package/src/utils/tools-manager.ts +23 -23
- package/src/vendor/photon/index.js +1099 -1059
- package/src/vendor/photon/photon_rs_bg.wasm +0 -0
- package/src/web/scrapers/artifacthub.ts +1 -1
- package/src/web/scrapers/arxiv.ts +2 -2
- package/src/web/scrapers/bluesky.ts +2 -2
- package/src/web/scrapers/cheatsh.ts +1 -1
- package/src/web/scrapers/chocolatey.ts +2 -2
- package/src/web/scrapers/choosealicense.ts +5 -5
- package/src/web/scrapers/cisa-kev.ts +1 -1
- package/src/web/scrapers/crossref.ts +2 -2
- package/src/web/scrapers/devto.ts +3 -3
- package/src/web/scrapers/discogs.ts +3 -4
- package/src/web/scrapers/discourse.ts +1 -1
- package/src/web/scrapers/dockerhub.ts +1 -1
- package/src/web/scrapers/fdroid.ts +2 -2
- package/src/web/scrapers/firefox-addons.ts +3 -3
- package/src/web/scrapers/flathub.ts +1 -1
- package/src/web/scrapers/github.ts +3 -3
- package/src/web/scrapers/gitlab.ts +4 -4
- package/src/web/scrapers/hackernews.ts +2 -2
- package/src/web/scrapers/huggingface.ts +1 -1
- package/src/web/scrapers/iacr.ts +2 -2
- package/src/web/scrapers/index.ts +0 -1
- package/src/web/scrapers/jetbrains-marketplace.ts +1 -1
- package/src/web/scrapers/lemmy.ts +2 -2
- package/src/web/scrapers/maven.ts +2 -2
- package/src/web/scrapers/mdn.ts +2 -4
- package/src/web/scrapers/metacpan.ts +2 -2
- package/src/web/scrapers/musicbrainz.ts +1 -2
- package/src/web/scrapers/npm.ts +1 -1
- package/src/web/scrapers/nuget.ts +2 -2
- package/src/web/scrapers/nvd.ts +3 -3
- package/src/web/scrapers/ollama.ts +7 -9
- package/src/web/scrapers/opencorporates.ts +2 -2
- package/src/web/scrapers/openlibrary.ts +6 -6
- package/src/web/scrapers/orcid.ts +0 -1
- package/src/web/scrapers/osv.ts +2 -2
- package/src/web/scrapers/packagist.ts +1 -1
- package/src/web/scrapers/pubmed.ts +1 -2
- package/src/web/scrapers/rawg.ts +2 -2
- package/src/web/scrapers/readthedocs.ts +1 -2
- package/src/web/scrapers/repology.ts +2 -2
- package/src/web/scrapers/rfc.ts +1 -1
- package/src/web/scrapers/searchcode.ts +2 -2
- package/src/web/scrapers/semantic-scholar.ts +1 -1
- package/src/web/scrapers/snapcraft.ts +2 -2
- package/src/web/scrapers/sourcegraph.ts +1 -1
- package/src/web/scrapers/spdx.ts +3 -3
- package/src/web/scrapers/spotify.ts +0 -1
- package/src/web/scrapers/twitter.ts +1 -1
- package/src/web/scrapers/types.ts +1 -2
- package/src/web/scrapers/utils.ts +5 -5
- package/src/web/scrapers/wikidata.ts +3 -3
- package/src/web/scrapers/youtube.ts +9 -14
- package/src/web/search/auth.ts +5 -10
- package/src/web/search/index.ts +11 -21
- package/src/web/search/providers/anthropic.ts +3 -9
- package/src/web/search/providers/exa.ts +6 -10
- package/src/web/search/providers/perplexity.ts +5 -5
- package/src/web/search/render.ts +129 -175
- package/tsconfig.json +0 -42
package/src/tools/grep.ts
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
import nodePath from "node:path";
|
|
2
2
|
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
|
|
3
3
|
import { StringEnum } from "@oh-my-pi/pi-ai";
|
|
4
|
-
import { renderPromptTemplate } from "@oh-my-pi/pi-coding-agent/config/prompt-templates";
|
|
5
|
-
import type { RenderResultOptions } from "@oh-my-pi/pi-coding-agent/extensibility/custom-tools/types";
|
|
6
|
-
import { getLanguageFromPath, type Theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
|
7
|
-
import grepDescription from "@oh-my-pi/pi-coding-agent/prompts/tools/grep.md" with { type: "text" };
|
|
8
|
-
import type { OutputMeta } from "@oh-my-pi/pi-coding-agent/tools/output-meta";
|
|
9
|
-
import { ToolAbortError, ToolError } from "@oh-my-pi/pi-coding-agent/tools/tool-errors";
|
|
10
|
-
import { ensureTool } from "@oh-my-pi/pi-coding-agent/utils/tools-manager";
|
|
11
|
-
import { untilAborted } from "@oh-my-pi/pi-coding-agent/utils/utils";
|
|
12
4
|
import type { Component } from "@oh-my-pi/pi-tui";
|
|
13
5
|
import { Text } from "@oh-my-pi/pi-tui";
|
|
14
6
|
import { ptree, readLines } from "@oh-my-pi/pi-utils";
|
|
15
7
|
import { Type } from "@sinclair/typebox";
|
|
16
8
|
import { $ } from "bun";
|
|
17
|
-
import
|
|
9
|
+
import { renderPromptTemplate } from "../config/prompt-templates";
|
|
10
|
+
import type { RenderResultOptions } from "../extensibility/custom-tools/types";
|
|
11
|
+
import type { Theme } from "../modes/theme/theme";
|
|
12
|
+
import grepDescription from "../prompts/tools/grep.md" with { type: "text" };
|
|
13
|
+
import { renderFileList, renderStatusLine, renderTreeList } from "../tui";
|
|
14
|
+
import { ensureTool } from "../utils/tools-manager";
|
|
15
|
+
import { untilAborted } from "../utils/utils";
|
|
16
|
+
import type { ToolSession } from ".";
|
|
18
17
|
import { applyListLimit } from "./list-limit";
|
|
18
|
+
import type { OutputMeta } from "./output-meta";
|
|
19
19
|
import { resolveToCwd } from "./path-utils";
|
|
20
|
-
import {
|
|
20
|
+
import { formatCount, formatEmptyMessage, formatErrorMessage, PREVIEW_LIMITS } from "./render-utils";
|
|
21
|
+
import { ToolAbortError, ToolError } from "./tool-errors";
|
|
21
22
|
import { toolResult } from "./tool-result";
|
|
22
23
|
import { DEFAULT_MAX_COLUMN, type TruncationResult, truncateHead, truncateLine } from "./truncate";
|
|
23
24
|
|
|
@@ -72,8 +73,8 @@ export interface GrepOperations {
|
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
const defaultGrepOperations: GrepOperations = {
|
|
75
|
-
isDirectory: async
|
|
76
|
-
readFile:
|
|
76
|
+
isDirectory: async p => (await Bun.file(p).stat()).isDirectory(),
|
|
77
|
+
readFile: p => Bun.file(p).text(),
|
|
77
78
|
};
|
|
78
79
|
|
|
79
80
|
export interface GrepToolOptions {
|
|
@@ -286,7 +287,7 @@ export class GrepTool implements AgentTool<typeof grepSchema, GrepToolDetails> {
|
|
|
286
287
|
|
|
287
288
|
// For simple output modes (files_with_matches, count), process text directly
|
|
288
289
|
if (effectiveOutputMode === "files_with_matches" || effectiveOutputMode === "count") {
|
|
289
|
-
const stdout = await child.text().catch(
|
|
290
|
+
const stdout = await child.text().catch(x => {
|
|
290
291
|
if (x instanceof ptree.Exception && x.exitCode === 1) {
|
|
291
292
|
return "";
|
|
292
293
|
}
|
|
@@ -302,7 +303,7 @@ export class GrepTool implements AgentTool<typeof grepSchema, GrepToolDetails> {
|
|
|
302
303
|
const lines = stdout
|
|
303
304
|
.trim()
|
|
304
305
|
.split("\n")
|
|
305
|
-
.filter(
|
|
306
|
+
.filter(line => line.length > 0);
|
|
306
307
|
|
|
307
308
|
if (lines.length === 0) {
|
|
308
309
|
const details: GrepToolDetails = {
|
|
@@ -370,7 +371,7 @@ export class GrepTool implements AgentTool<typeof grepSchema, GrepToolDetails> {
|
|
|
370
371
|
|
|
371
372
|
// For count mode, format as "path:count"
|
|
372
373
|
if (effectiveOutputMode === "count") {
|
|
373
|
-
const formatted = processedLines.map(
|
|
374
|
+
const formatted = processedLines.map(line => {
|
|
374
375
|
const separatorIndex = line.lastIndexOf(":");
|
|
375
376
|
const relative = formatPath(separatorIndex === -1 ? line : line.slice(0, separatorIndex));
|
|
376
377
|
const count = separatorIndex === -1 ? "0" : line.slice(separatorIndex + 1);
|
|
@@ -382,7 +383,7 @@ export class GrepTool implements AgentTool<typeof grepSchema, GrepToolDetails> {
|
|
|
382
383
|
matchCount: simpleMatchCount,
|
|
383
384
|
fileCount,
|
|
384
385
|
files: simpleFileList,
|
|
385
|
-
fileMatches: simpleFileList.map(
|
|
386
|
+
fileMatches: simpleFileList.map(path => ({
|
|
386
387
|
path,
|
|
387
388
|
count: simpleFileMatchCounts.get(path) ?? 0,
|
|
388
389
|
})),
|
|
@@ -400,7 +401,7 @@ export class GrepTool implements AgentTool<typeof grepSchema, GrepToolDetails> {
|
|
|
400
401
|
}
|
|
401
402
|
|
|
402
403
|
// For files_with_matches, format paths
|
|
403
|
-
const formatted = processedLines.map(
|
|
404
|
+
const formatted = processedLines.map(line => formatPath(line));
|
|
404
405
|
const output = formatted.join("\n");
|
|
405
406
|
const details: GrepToolDetails = {
|
|
406
407
|
scopePath,
|
|
@@ -546,7 +547,7 @@ export class GrepTool implements AgentTool<typeof grepSchema, GrepToolDetails> {
|
|
|
546
547
|
matchCount,
|
|
547
548
|
fileCount: files.size,
|
|
548
549
|
files: fileList,
|
|
549
|
-
fileMatches: fileList.map(
|
|
550
|
+
fileMatches: fileList.map(path => ({
|
|
550
551
|
path,
|
|
551
552
|
count: fileMatchCounts.get(path) ?? 0,
|
|
552
553
|
})),
|
|
@@ -600,10 +601,6 @@ const COLLAPSED_TEXT_LIMIT = PREVIEW_LIMITS.COLLAPSED_LINES * 2;
|
|
|
600
601
|
export const grepToolRenderer = {
|
|
601
602
|
inline: true,
|
|
602
603
|
renderCall(args: GrepRenderArgs, uiTheme: Theme): Component {
|
|
603
|
-
const ui = new ToolUIKit(uiTheme);
|
|
604
|
-
const label = ui.title("Grep");
|
|
605
|
-
let text = `${uiTheme.format.bullet} ${label} ${uiTheme.fg("accent", args.pattern || "?")}`;
|
|
606
|
-
|
|
607
604
|
const meta: string[] = [];
|
|
608
605
|
if (args.path) meta.push(`in ${args.path}`);
|
|
609
606
|
if (args.glob) meta.push(`glob:${args.glob}`);
|
|
@@ -619,8 +616,10 @@ export const grepToolRenderer = {
|
|
|
619
616
|
if (args.context !== undefined) meta.push(`context:${args.context}`);
|
|
620
617
|
if (args.limit !== undefined) meta.push(`limit:${args.limit}`);
|
|
621
618
|
|
|
622
|
-
text
|
|
623
|
-
|
|
619
|
+
const text = renderStatusLine(
|
|
620
|
+
{ icon: "pending", title: "Grep", description: args.pattern || "?", meta },
|
|
621
|
+
uiTheme,
|
|
622
|
+
);
|
|
624
623
|
return new Text(text, 0, 0);
|
|
625
624
|
},
|
|
626
625
|
|
|
@@ -628,45 +627,39 @@ export const grepToolRenderer = {
|
|
|
628
627
|
result: { content: Array<{ type: string; text?: string }>; details?: GrepToolDetails; isError?: boolean },
|
|
629
628
|
{ expanded }: RenderResultOptions,
|
|
630
629
|
uiTheme: Theme,
|
|
630
|
+
args?: GrepRenderArgs,
|
|
631
631
|
): Component {
|
|
632
|
-
const ui = new ToolUIKit(uiTheme);
|
|
633
632
|
const details = result.details;
|
|
634
633
|
|
|
635
634
|
if (result.isError || details?.error) {
|
|
636
|
-
const errorText = details?.error || result.content?.find(
|
|
637
|
-
return new Text(
|
|
635
|
+
const errorText = details?.error || result.content?.find(c => c.type === "text")?.text || "Unknown error";
|
|
636
|
+
return new Text(formatErrorMessage(errorText, uiTheme), 0, 0);
|
|
638
637
|
}
|
|
639
638
|
|
|
640
639
|
const hasDetailedData = details?.matchCount !== undefined || details?.fileCount !== undefined;
|
|
641
640
|
|
|
642
641
|
if (!hasDetailedData) {
|
|
643
|
-
const textContent = result.content?.find(
|
|
642
|
+
const textContent = result.content?.find(c => c.type === "text")?.text;
|
|
644
643
|
if (!textContent || textContent === "No matches found") {
|
|
645
|
-
return new Text(
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
const lines = textContent.split("\n").filter((line) => line.trim() !== "");
|
|
649
|
-
const maxLines = expanded ? lines.length : Math.min(lines.length, COLLAPSED_TEXT_LIMIT);
|
|
650
|
-
const displayLines = lines.slice(0, maxLines);
|
|
651
|
-
const remaining = lines.length - maxLines;
|
|
652
|
-
const hasMore = remaining > 0;
|
|
653
|
-
|
|
654
|
-
const icon = uiTheme.styledSymbol("status.success", "success");
|
|
655
|
-
const summary = ui.count("item", lines.length);
|
|
656
|
-
const expandHint = ui.expandHint(expanded, hasMore);
|
|
657
|
-
let text = ` ${icon} ${uiTheme.fg("dim", summary)}${expandHint}`;
|
|
658
|
-
|
|
659
|
-
for (let i = 0; i < displayLines.length; i++) {
|
|
660
|
-
const isLast = i === displayLines.length - 1 && remaining === 0;
|
|
661
|
-
const branch = isLast ? uiTheme.tree.last : uiTheme.tree.branch;
|
|
662
|
-
text += `\n ${uiTheme.fg("dim", branch)} ${uiTheme.fg("toolOutput", displayLines[i])}`;
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
if (remaining > 0) {
|
|
666
|
-
text += `\n ${uiTheme.fg("dim", uiTheme.tree.last)} ${uiTheme.fg("muted", ui.moreItems(remaining, "item"))}`;
|
|
644
|
+
return new Text(formatEmptyMessage("No matches found", uiTheme), 0, 0);
|
|
667
645
|
}
|
|
668
|
-
|
|
669
|
-
|
|
646
|
+
const lines = textContent.split("\n").filter(line => line.trim() !== "");
|
|
647
|
+
const description = args?.pattern ?? undefined;
|
|
648
|
+
const header = renderStatusLine(
|
|
649
|
+
{ icon: "success", title: "Grep", description, meta: [formatCount("item", lines.length)] },
|
|
650
|
+
uiTheme,
|
|
651
|
+
);
|
|
652
|
+
const listLines = renderTreeList(
|
|
653
|
+
{
|
|
654
|
+
items: lines,
|
|
655
|
+
expanded,
|
|
656
|
+
maxCollapsed: COLLAPSED_TEXT_LIMIT,
|
|
657
|
+
itemType: "item",
|
|
658
|
+
renderItem: line => uiTheme.fg("toolOutput", line),
|
|
659
|
+
},
|
|
660
|
+
uiTheme,
|
|
661
|
+
);
|
|
662
|
+
return new Text([header, ...listLines].join("\n"), 0, 0);
|
|
670
663
|
}
|
|
671
664
|
|
|
672
665
|
const matchCount = details?.matchCount ?? 0;
|
|
@@ -685,79 +678,70 @@ export const grepToolRenderer = {
|
|
|
685
678
|
const files = details?.files ?? [];
|
|
686
679
|
|
|
687
680
|
if (matchCount === 0) {
|
|
688
|
-
|
|
681
|
+
const header = renderStatusLine(
|
|
682
|
+
{ icon: "warning", title: "Grep", description: args?.pattern, meta: ["0 matches"] },
|
|
683
|
+
uiTheme,
|
|
684
|
+
);
|
|
685
|
+
return new Text([header, formatEmptyMessage("No matches found", uiTheme)].join("\n"), 0, 0);
|
|
689
686
|
}
|
|
690
687
|
|
|
691
|
-
const icon = uiTheme.styledSymbol("status.success", "success");
|
|
692
688
|
const summaryParts =
|
|
693
689
|
mode === "files_with_matches"
|
|
694
|
-
? [
|
|
695
|
-
: [
|
|
696
|
-
const
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
const
|
|
700
|
-
|
|
701
|
-
:
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
const expandHint = ui.expandHint(expanded, hasMoreFiles);
|
|
705
|
-
|
|
706
|
-
let text = ` ${icon} ${uiTheme.fg("dim", summaryText)}${ui.truncationSuffix(truncated)}${scopeLabel}${expandHint}`;
|
|
690
|
+
? [formatCount("file", fileCount)]
|
|
691
|
+
: [formatCount("match", matchCount), formatCount("file", fileCount)];
|
|
692
|
+
const meta = [...summaryParts];
|
|
693
|
+
if (details?.scopePath) meta.push(`in ${details.scopePath}`);
|
|
694
|
+
if (truncated) meta.push(uiTheme.fg("warning", "truncated"));
|
|
695
|
+
const description = args?.pattern ?? undefined;
|
|
696
|
+
const header = renderStatusLine(
|
|
697
|
+
{ icon: truncated ? "warning" : "success", title: "Grep", description, meta },
|
|
698
|
+
uiTheme,
|
|
699
|
+
);
|
|
707
700
|
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
truncationReasons.push(`line length ${limits.columnTruncated.maxColumn}`);
|
|
723
|
-
}
|
|
724
|
-
if (truncation?.artifactId) {
|
|
725
|
-
truncationReasons.push(`full output: artifact://${truncation.artifactId}`);
|
|
701
|
+
if (mode === "content") {
|
|
702
|
+
const textContent = result.content?.find(c => c.type === "text")?.text ?? "";
|
|
703
|
+
const contentLines = textContent.split("\n").filter(line => line.trim().length > 0);
|
|
704
|
+
const matchLines = renderTreeList(
|
|
705
|
+
{
|
|
706
|
+
items: contentLines,
|
|
707
|
+
expanded,
|
|
708
|
+
maxCollapsed: COLLAPSED_TEXT_LIMIT,
|
|
709
|
+
itemType: "match",
|
|
710
|
+
renderItem: line => uiTheme.fg("toolOutput", line),
|
|
711
|
+
},
|
|
712
|
+
uiTheme,
|
|
713
|
+
);
|
|
714
|
+
return new Text([header, ...matchLines].join("\n"), 0, 0);
|
|
726
715
|
}
|
|
727
716
|
|
|
728
|
-
const
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
? ` ${uiTheme.fg("dim", `(${entry.count} match${entry.count !== 1 ? "es" : ""})`)}`
|
|
744
|
-
: "";
|
|
745
|
-
text += `\n ${uiTheme.fg("dim", branch)} ${entryIcon} ${uiTheme.fg("accent", entry.path)}${countLabel}`;
|
|
746
|
-
}
|
|
717
|
+
const fileEntries: Array<{ path: string; count?: number }> = details?.fileMatches?.length
|
|
718
|
+
? details.fileMatches.map(entry => ({ path: entry.path, count: entry.count }))
|
|
719
|
+
: files.map(path => ({ path }));
|
|
720
|
+
const fileLines = renderFileList(
|
|
721
|
+
{
|
|
722
|
+
files: fileEntries.map(entry => ({
|
|
723
|
+
path: entry.path,
|
|
724
|
+
isDirectory: entry.path.endsWith("/"),
|
|
725
|
+
meta: entry.count !== undefined ? `(${entry.count} match${entry.count !== 1 ? "es" : ""})` : undefined,
|
|
726
|
+
})),
|
|
727
|
+
expanded,
|
|
728
|
+
maxCollapsed: COLLAPSED_LIST_LIMIT,
|
|
729
|
+
},
|
|
730
|
+
uiTheme,
|
|
731
|
+
);
|
|
747
732
|
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
}
|
|
733
|
+
const truncationReasons: string[] = [];
|
|
734
|
+
if (limits?.matchLimit) truncationReasons.push(`limit ${limits.matchLimit.reached} matches`);
|
|
735
|
+
if (limits?.resultLimit) truncationReasons.push(`limit ${limits.resultLimit.reached} results`);
|
|
736
|
+
if (limits?.headLimit) truncationReasons.push(`head limit ${limits.headLimit.reached}`);
|
|
737
|
+
if (truncation) truncationReasons.push(truncation.truncatedBy === "lines" ? "line limit" : "size limit");
|
|
738
|
+
if (limits?.columnTruncated) truncationReasons.push(`line length ${limits.columnTruncated.maxColumn}`);
|
|
739
|
+
if (truncation?.artifactId) truncationReasons.push(`full output: artifact://${truncation.artifactId}`);
|
|
756
740
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
}
|
|
741
|
+
const extraLines =
|
|
742
|
+
truncationReasons.length > 0 ? [uiTheme.fg("warning", `truncated: ${truncationReasons.join(", ")}`)] : [];
|
|
760
743
|
|
|
761
|
-
return new Text(
|
|
744
|
+
return new Text([header, ...fileLines, ...extraLines].join("\n"), 0, 0);
|
|
762
745
|
},
|
|
746
|
+
mergeCallAndResult: true,
|
|
763
747
|
};
|
package/src/tools/index.ts
CHANGED
|
@@ -1,6 +1,38 @@
|
|
|
1
|
+
import type { AgentTool } from "@oh-my-pi/pi-agent-core";
|
|
2
|
+
import { logger } from "@oh-my-pi/pi-utils";
|
|
3
|
+
import type { BashInterceptorRule } from "../config/settings-manager";
|
|
4
|
+
import type { InternalUrlRouter } from "../internal-urls";
|
|
5
|
+
import { getPreludeDocs, warmPythonEnvironment } from "../ipy/executor";
|
|
6
|
+
import { checkPythonKernelAvailability } from "../ipy/kernel";
|
|
7
|
+
import { LspTool } from "../lsp";
|
|
8
|
+
import { EditTool } from "../patch";
|
|
9
|
+
import type { ArtifactManager } from "../session/artifacts";
|
|
10
|
+
import { TaskTool } from "../task";
|
|
11
|
+
import type { AgentOutputManager } from "../task/output-manager";
|
|
12
|
+
import type { EventBus } from "../utils/event-bus";
|
|
13
|
+
import { time } from "../utils/timings";
|
|
14
|
+
import { WebSearchTool } from "../web/search";
|
|
15
|
+
import { AskTool } from "./ask";
|
|
16
|
+
import { BashTool } from "./bash";
|
|
17
|
+
import { CalculatorTool } from "./calculator";
|
|
18
|
+
import { CompleteTool } from "./complete";
|
|
19
|
+
import { FetchTool } from "./fetch";
|
|
20
|
+
import { FindTool } from "./find";
|
|
21
|
+
import { GrepTool } from "./grep";
|
|
22
|
+
import { LsTool } from "./ls";
|
|
23
|
+
import { NotebookTool } from "./notebook";
|
|
24
|
+
import { wrapToolsWithMetaNotice } from "./output-meta";
|
|
25
|
+
import { PythonTool } from "./python";
|
|
26
|
+
import { ReadTool } from "./read";
|
|
27
|
+
import { reportFindingTool } from "./review";
|
|
28
|
+
import { loadSshTool } from "./ssh";
|
|
29
|
+
import { TodoWriteTool } from "./todo-write";
|
|
30
|
+
import { WriteTool } from "./write";
|
|
31
|
+
|
|
1
32
|
// Exa MCP tools (22 tools)
|
|
2
|
-
|
|
3
|
-
export
|
|
33
|
+
|
|
34
|
+
export { exaTools } from "../exa";
|
|
35
|
+
export type { ExaRenderDetails, ExaSearchResponse, ExaSearchResult } from "../exa/types";
|
|
4
36
|
export {
|
|
5
37
|
type FileDiagnosticsResult,
|
|
6
38
|
type FileFormatResult,
|
|
@@ -11,9 +43,9 @@ export {
|
|
|
11
43
|
type LspWarmupOptions,
|
|
12
44
|
type LspWarmupResult,
|
|
13
45
|
warmupLspServers,
|
|
14
|
-
} from "
|
|
15
|
-
export { EditTool, type EditToolDetails } from "
|
|
16
|
-
export { BUNDLED_AGENTS, TaskTool } from "
|
|
46
|
+
} from "../lsp";
|
|
47
|
+
export { EditTool, type EditToolDetails } from "../patch";
|
|
48
|
+
export { BUNDLED_AGENTS, TaskTool } from "../task";
|
|
17
49
|
export {
|
|
18
50
|
companyWebSearchTools,
|
|
19
51
|
exaWebSearchTools,
|
|
@@ -31,7 +63,7 @@ export {
|
|
|
31
63
|
webSearchCustomTool,
|
|
32
64
|
webSearchDeepTool,
|
|
33
65
|
webSearchLinkedinTool,
|
|
34
|
-
} from "
|
|
66
|
+
} from "../web/search";
|
|
35
67
|
export { AskTool, type AskToolDetails } from "./ask";
|
|
36
68
|
export { BashTool, type BashToolDetails, type BashToolOptions } from "./bash";
|
|
37
69
|
export { CalculatorTool, type CalculatorToolDetails } from "./calculator";
|
|
@@ -59,35 +91,6 @@ export {
|
|
|
59
91
|
} from "./truncate";
|
|
60
92
|
export { WriteTool, type WriteToolDetails } from "./write";
|
|
61
93
|
|
|
62
|
-
import type { AgentTool } from "@oh-my-pi/pi-agent-core";
|
|
63
|
-
import type { BashInterceptorRule } from "@oh-my-pi/pi-coding-agent/config/settings-manager";
|
|
64
|
-
import type { InternalUrlRouter } from "@oh-my-pi/pi-coding-agent/internal-urls";
|
|
65
|
-
import { getPreludeDocs, warmPythonEnvironment } from "@oh-my-pi/pi-coding-agent/ipy/executor";
|
|
66
|
-
import { checkPythonKernelAvailability } from "@oh-my-pi/pi-coding-agent/ipy/kernel";
|
|
67
|
-
import { LspTool } from "@oh-my-pi/pi-coding-agent/lsp/index";
|
|
68
|
-
import { EditTool } from "@oh-my-pi/pi-coding-agent/patch";
|
|
69
|
-
import type { ArtifactManager } from "@oh-my-pi/pi-coding-agent/session/artifacts";
|
|
70
|
-
import { TaskTool } from "@oh-my-pi/pi-coding-agent/task/index";
|
|
71
|
-
import type { EventBus } from "@oh-my-pi/pi-coding-agent/utils/event-bus";
|
|
72
|
-
import { WebSearchTool } from "@oh-my-pi/pi-coding-agent/web/search/index";
|
|
73
|
-
import { logger } from "@oh-my-pi/pi-utils";
|
|
74
|
-
import { AskTool } from "./ask";
|
|
75
|
-
import { BashTool } from "./bash";
|
|
76
|
-
import { CalculatorTool } from "./calculator";
|
|
77
|
-
import { CompleteTool } from "./complete";
|
|
78
|
-
import { FetchTool } from "./fetch";
|
|
79
|
-
import { FindTool } from "./find";
|
|
80
|
-
import { GrepTool } from "./grep";
|
|
81
|
-
import { LsTool } from "./ls";
|
|
82
|
-
import { NotebookTool } from "./notebook";
|
|
83
|
-
import { wrapToolsWithMetaNotice } from "./output-meta";
|
|
84
|
-
import { PythonTool } from "./python";
|
|
85
|
-
import { ReadTool } from "./read";
|
|
86
|
-
import { reportFindingTool } from "./review";
|
|
87
|
-
import { loadSshTool } from "./ssh";
|
|
88
|
-
import { TodoWriteTool } from "./todo-write";
|
|
89
|
-
import { WriteTool } from "./write";
|
|
90
|
-
|
|
91
94
|
/** Tool type (AgentTool from pi-ai) */
|
|
92
95
|
export type Tool = AgentTool<any, any, any>;
|
|
93
96
|
|
|
@@ -125,6 +128,8 @@ export interface ToolSession {
|
|
|
125
128
|
mcpManager?: import("../mcp/manager").MCPManager;
|
|
126
129
|
/** Internal URL router for agent:// and skill:// URLs */
|
|
127
130
|
internalRouter?: InternalUrlRouter;
|
|
131
|
+
/** Agent output manager for unique agent:// IDs across task invocations */
|
|
132
|
+
agentOutputManager?: AgentOutputManager;
|
|
128
133
|
/** Settings manager for passing to subagents (avoids SQLite access in workers) */
|
|
129
134
|
settingsManager?: { serialize: () => import("@oh-my-pi/pi-coding-agent/config/settings-manager").Settings };
|
|
130
135
|
/** Settings manager (optional) */
|
|
@@ -150,26 +155,26 @@ type ToolFactory = (session: ToolSession) => Tool | null | Promise<Tool | null>;
|
|
|
150
155
|
|
|
151
156
|
export const BUILTIN_TOOLS: Record<string, ToolFactory> = {
|
|
152
157
|
ask: AskTool.createIf,
|
|
153
|
-
bash:
|
|
154
|
-
python:
|
|
155
|
-
calc:
|
|
158
|
+
bash: s => new BashTool(s),
|
|
159
|
+
python: s => new PythonTool(s),
|
|
160
|
+
calc: s => new CalculatorTool(s),
|
|
156
161
|
ssh: loadSshTool,
|
|
157
|
-
edit:
|
|
158
|
-
find:
|
|
159
|
-
grep:
|
|
160
|
-
ls:
|
|
162
|
+
edit: s => new EditTool(s),
|
|
163
|
+
find: s => new FindTool(s),
|
|
164
|
+
grep: s => new GrepTool(s),
|
|
165
|
+
ls: s => new LsTool(s),
|
|
161
166
|
lsp: LspTool.createIf,
|
|
162
|
-
notebook:
|
|
163
|
-
read:
|
|
167
|
+
notebook: s => new NotebookTool(s),
|
|
168
|
+
read: s => new ReadTool(s),
|
|
164
169
|
task: TaskTool.create,
|
|
165
|
-
todo_write:
|
|
166
|
-
fetch:
|
|
167
|
-
web_search:
|
|
168
|
-
write:
|
|
170
|
+
todo_write: s => new TodoWriteTool(s),
|
|
171
|
+
fetch: s => new FetchTool(s),
|
|
172
|
+
web_search: s => new WebSearchTool(s),
|
|
173
|
+
write: s => new WriteTool(s),
|
|
169
174
|
};
|
|
170
175
|
|
|
171
176
|
export const HIDDEN_TOOLS: Record<string, ToolFactory> = {
|
|
172
|
-
complete:
|
|
177
|
+
complete: s => new CompleteTool(s),
|
|
173
178
|
report_finding: () => reportFindingTool,
|
|
174
179
|
};
|
|
175
180
|
|
|
@@ -209,6 +214,7 @@ function getPythonModeFromEnv(): PythonToolMode | null {
|
|
|
209
214
|
* Create tools from BUILTIN_TOOLS registry.
|
|
210
215
|
*/
|
|
211
216
|
export async function createTools(session: ToolSession, toolNames?: string[]): Promise<Tool[]> {
|
|
217
|
+
time("createTools:start");
|
|
212
218
|
const includeComplete = session.requireCompleteTool === true;
|
|
213
219
|
const enableLsp = session.enableLsp ?? true;
|
|
214
220
|
const requestedTools = toolNames && toolNames.length > 0 ? [...new Set(toolNames)] : undefined;
|
|
@@ -218,18 +224,21 @@ export async function createTools(session: ToolSession, toolNames?: string[]): P
|
|
|
218
224
|
pythonMode !== "bash-only" &&
|
|
219
225
|
(requestedTools === undefined || requestedTools.includes("python") || pythonMode === "ipy-only");
|
|
220
226
|
const isTestEnv = process.env.BUN_ENV === "test" || process.env.NODE_ENV === "test";
|
|
227
|
+
const skipPythonWarm = isTestEnv || process.env.OMP_PYTHON_SKIP_CHECK === "1";
|
|
221
228
|
if (shouldCheckPython) {
|
|
222
229
|
const availability = await checkPythonKernelAvailability(session.cwd);
|
|
230
|
+
time("createTools:pythonCheck");
|
|
223
231
|
pythonAvailable = availability.ok;
|
|
224
232
|
if (!availability.ok) {
|
|
225
233
|
logger.warn("Python kernel unavailable, falling back to bash", {
|
|
226
234
|
reason: availability.reason,
|
|
227
235
|
});
|
|
228
|
-
} else if (!
|
|
236
|
+
} else if (!skipPythonWarm && getPreludeDocs().length === 0) {
|
|
229
237
|
const sessionFile = session.getSessionFile?.() ?? undefined;
|
|
230
238
|
const warmSessionId = sessionFile ? `session:${sessionFile}:cwd:${session.cwd}` : `cwd:${session.cwd}`;
|
|
231
239
|
try {
|
|
232
240
|
await warmPythonEnvironment(session.cwd, warmSessionId, session.settings?.getPythonSharedGateway?.());
|
|
241
|
+
time("createTools:warmPython");
|
|
233
242
|
} catch (err) {
|
|
234
243
|
logger.warn("Failed to warm Python environment", {
|
|
235
244
|
error: err instanceof Error ? err.message : String(err),
|
|
@@ -261,22 +270,38 @@ export async function createTools(session: ToolSession, toolNames?: string[]): P
|
|
|
261
270
|
requestedTools.push("complete");
|
|
262
271
|
}
|
|
263
272
|
|
|
264
|
-
const filteredRequestedTools = requestedTools?.filter(
|
|
273
|
+
const filteredRequestedTools = requestedTools?.filter(name => name in allTools && isToolAllowed(name));
|
|
265
274
|
|
|
266
275
|
const entries =
|
|
267
276
|
filteredRequestedTools !== undefined
|
|
268
|
-
? filteredRequestedTools.map(
|
|
277
|
+
? filteredRequestedTools.map(name => [name, allTools[name]] as const)
|
|
269
278
|
: [
|
|
270
279
|
...Object.entries(BUILTIN_TOOLS).filter(([name]) => isToolAllowed(name)),
|
|
271
280
|
...(includeComplete ? ([["complete", HIDDEN_TOOLS.complete]] as const) : []),
|
|
272
281
|
];
|
|
273
|
-
|
|
274
|
-
const
|
|
282
|
+
time("createTools:beforeFactories");
|
|
283
|
+
const slowTools: Array<{ name: string; ms: number }> = [];
|
|
284
|
+
const results = await Promise.all(
|
|
285
|
+
entries.map(async ([name, factory]) => {
|
|
286
|
+
const start = performance.now();
|
|
287
|
+
const tool = await factory(session);
|
|
288
|
+
const elapsed = performance.now() - start;
|
|
289
|
+
if (elapsed > 5) {
|
|
290
|
+
slowTools.push({ name, ms: Math.round(elapsed) });
|
|
291
|
+
}
|
|
292
|
+
return { name, tool };
|
|
293
|
+
}),
|
|
294
|
+
);
|
|
295
|
+
time("createTools:afterFactories");
|
|
296
|
+
if (slowTools.length > 0 && process.env.OMP_TIMING === "1") {
|
|
297
|
+
logger.debug("Tool factory timings", { slowTools });
|
|
298
|
+
}
|
|
299
|
+
const tools = results.filter(r => r.tool !== null).map(r => r.tool as Tool);
|
|
275
300
|
const wrappedTools = wrapToolsWithMetaNotice(tools);
|
|
276
301
|
|
|
277
302
|
if (filteredRequestedTools !== undefined) {
|
|
278
303
|
const allowed = new Set(filteredRequestedTools);
|
|
279
|
-
return wrappedTools.filter(
|
|
304
|
+
return wrappedTools.filter(tool => allowed.has(tool.name));
|
|
280
305
|
}
|
|
281
306
|
|
|
282
307
|
return wrappedTools;
|
package/src/tools/list-limit.ts
CHANGED