@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/ask.ts
CHANGED
|
@@ -14,16 +14,16 @@
|
|
|
14
14
|
* - If you recommend a specific option, make that the first option in the list
|
|
15
15
|
* and add "(Recommended)" at the end of the label
|
|
16
16
|
*/
|
|
17
|
-
|
|
18
17
|
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
|
|
19
|
-
import { renderPromptTemplate } from "@oh-my-pi/pi-coding-agent/config/prompt-templates";
|
|
20
|
-
import type { RenderResultOptions } from "@oh-my-pi/pi-coding-agent/extensibility/custom-tools/types";
|
|
21
|
-
import { type Theme, theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
|
22
|
-
import askDescription from "@oh-my-pi/pi-coding-agent/prompts/tools/ask.md" with { type: "text" };
|
|
23
18
|
import type { Component } from "@oh-my-pi/pi-tui";
|
|
24
19
|
import { Text } from "@oh-my-pi/pi-tui";
|
|
25
20
|
import { Type } from "@sinclair/typebox";
|
|
26
|
-
import
|
|
21
|
+
import { renderPromptTemplate } from "../config/prompt-templates";
|
|
22
|
+
import type { RenderResultOptions } from "../extensibility/custom-tools/types";
|
|
23
|
+
import { type Theme, theme } from "../modes/theme/theme";
|
|
24
|
+
import askDescription from "../prompts/tools/ask.md" with { type: "text" };
|
|
25
|
+
import { renderStatusLine } from "../tui";
|
|
26
|
+
import type { ToolSession } from ".";
|
|
27
27
|
import { ToolUIKit } from "./render-utils";
|
|
28
28
|
|
|
29
29
|
// =============================================================================
|
|
@@ -237,7 +237,7 @@ export class AskTool implements AgentTool<typeof askSchema, AskToolDetails> {
|
|
|
237
237
|
const results: QuestionResult[] = [];
|
|
238
238
|
|
|
239
239
|
for (const q of params.questions) {
|
|
240
|
-
const optionLabels = q.options.map(
|
|
240
|
+
const optionLabels = q.options.map(o => o.label);
|
|
241
241
|
const { selectedOptions, customInput } = await askSingleQuestion(
|
|
242
242
|
ui,
|
|
243
243
|
q.question,
|
|
@@ -266,7 +266,7 @@ export class AskTool implements AgentTool<typeof askSchema, AskToolDetails> {
|
|
|
266
266
|
const question = params.question ?? "";
|
|
267
267
|
const options = params.options ?? [];
|
|
268
268
|
const multi = params.multi ?? false;
|
|
269
|
-
const optionLabels = options.map(
|
|
269
|
+
const optionLabels = options.map(o => o.label);
|
|
270
270
|
|
|
271
271
|
if (!question || optionLabels.length === 0) {
|
|
272
272
|
return {
|
|
@@ -381,36 +381,56 @@ export const askToolRenderer = {
|
|
|
381
381
|
const { details } = result;
|
|
382
382
|
if (!details) {
|
|
383
383
|
const txt = result.content[0];
|
|
384
|
-
|
|
384
|
+
const fallback = txt?.type === "text" && txt.text ? txt.text : "";
|
|
385
|
+
const header = renderStatusLine({ icon: "warning", title: "Ask" }, uiTheme);
|
|
386
|
+
return new Text([header, uiTheme.fg("dim", fallback)].join("\n"), 0, 0);
|
|
385
387
|
}
|
|
386
388
|
|
|
387
389
|
// Multi-part results
|
|
388
390
|
if (details.results && details.results.length > 0) {
|
|
389
391
|
const lines: string[] = [];
|
|
390
|
-
|
|
391
|
-
|
|
392
|
+
const hasAnySelection = details.results.some(
|
|
393
|
+
r => r.customInput || (r.selectedOptions && r.selectedOptions.length > 0),
|
|
394
|
+
);
|
|
395
|
+
const header = renderStatusLine(
|
|
396
|
+
{
|
|
397
|
+
icon: hasAnySelection ? "success" : "warning",
|
|
398
|
+
title: "Ask",
|
|
399
|
+
meta: [`${details.results.length} questions`],
|
|
400
|
+
},
|
|
401
|
+
uiTheme,
|
|
402
|
+
);
|
|
403
|
+
lines.push(header);
|
|
404
|
+
|
|
405
|
+
for (let i = 0; i < details.results.length; i++) {
|
|
406
|
+
const r = details.results[i];
|
|
407
|
+
const isLastQuestion = i === details.results.length - 1;
|
|
408
|
+
const branch = isLastQuestion ? uiTheme.tree.last : uiTheme.tree.branch;
|
|
409
|
+
const continuation = isLastQuestion ? " " : `${uiTheme.fg("dim", uiTheme.tree.vertical)} `;
|
|
392
410
|
const hasSelection = r.customInput || r.selectedOptions.length > 0;
|
|
393
411
|
const statusIcon = hasSelection
|
|
394
412
|
? uiTheme.styledSymbol("status.success", "success")
|
|
395
413
|
: uiTheme.styledSymbol("status.warning", "warning");
|
|
396
414
|
|
|
397
|
-
lines.push(
|
|
415
|
+
lines.push(
|
|
416
|
+
` ${uiTheme.fg("dim", branch)} ${statusIcon} ${uiTheme.fg("dim", `[${r.id}]`)} ${uiTheme.fg("accent", r.question)}`,
|
|
417
|
+
);
|
|
398
418
|
|
|
399
419
|
if (r.customInput) {
|
|
400
420
|
lines.push(
|
|
401
|
-
|
|
421
|
+
`${continuation}${uiTheme.fg("dim", uiTheme.tree.last)} ${uiTheme.styledSymbol("status.success", "success")} ${uiTheme.fg("toolOutput", r.customInput)}`,
|
|
402
422
|
);
|
|
403
423
|
} else if (r.selectedOptions.length > 0) {
|
|
404
424
|
for (let j = 0; j < r.selectedOptions.length; j++) {
|
|
405
425
|
const isLast = j === r.selectedOptions.length - 1;
|
|
406
|
-
const
|
|
426
|
+
const optBranch = isLast ? uiTheme.tree.last : uiTheme.tree.branch;
|
|
407
427
|
lines.push(
|
|
408
|
-
|
|
428
|
+
`${continuation}${uiTheme.fg("dim", optBranch)} ${uiTheme.fg("success", uiTheme.checkbox.checked)} ${uiTheme.fg("toolOutput", r.selectedOptions[j])}`,
|
|
409
429
|
);
|
|
410
430
|
}
|
|
411
431
|
} else {
|
|
412
432
|
lines.push(
|
|
413
|
-
|
|
433
|
+
`${continuation}${uiTheme.fg("dim", uiTheme.tree.last)} ${uiTheme.styledSymbol("status.warning", "warning")} ${uiTheme.fg("warning", "Cancelled")}`,
|
|
414
434
|
);
|
|
415
435
|
}
|
|
416
436
|
}
|
|
@@ -425,11 +445,12 @@ export const askToolRenderer = {
|
|
|
425
445
|
}
|
|
426
446
|
|
|
427
447
|
const hasSelection = details.customInput || (details.selectedOptions && details.selectedOptions.length > 0);
|
|
428
|
-
const
|
|
429
|
-
?
|
|
430
|
-
|
|
448
|
+
const header = renderStatusLine(
|
|
449
|
+
{ icon: hasSelection ? "success" : "warning", title: "Ask", description: details.question },
|
|
450
|
+
uiTheme,
|
|
451
|
+
);
|
|
431
452
|
|
|
432
|
-
let text =
|
|
453
|
+
let text = header;
|
|
433
454
|
|
|
434
455
|
if (details.customInput) {
|
|
435
456
|
text += `\n ${uiTheme.fg("dim", uiTheme.tree.last)} ${uiTheme.styledSymbol("status.success", "success")} ${uiTheme.fg("toolOutput", details.customInput)}`;
|
|
@@ -5,11 +5,7 @@
|
|
|
5
5
|
* this interceptor provides helpful error messages directing them to use
|
|
6
6
|
* the specialized tools instead.
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
|
-
import {
|
|
10
|
-
type BashInterceptorRule,
|
|
11
|
-
DEFAULT_BASH_INTERCEPTOR_RULES,
|
|
12
|
-
} from "@oh-my-pi/pi-coding-agent/config/settings-manager";
|
|
8
|
+
import { type BashInterceptorRule, DEFAULT_BASH_INTERCEPTOR_RULES } from "../config/settings-manager";
|
|
13
9
|
|
|
14
10
|
export interface InterceptionResult {
|
|
15
11
|
/** If true, the bash command should be blocked */
|
package/src/tools/bash.ts
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as path from "node:path";
|
|
2
2
|
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
|
|
3
|
-
import { renderPromptTemplate } from "@oh-my-pi/pi-coding-agent/config/prompt-templates";
|
|
4
|
-
import { type BashExecutorOptions, executeBash } from "@oh-my-pi/pi-coding-agent/exec/bash-executor";
|
|
5
|
-
import type { RenderResultOptions } from "@oh-my-pi/pi-coding-agent/extensibility/custom-tools/types";
|
|
6
|
-
import { truncateToVisualLines } from "@oh-my-pi/pi-coding-agent/modes/components/visual-truncate";
|
|
7
|
-
import type { Theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
|
8
|
-
import bashDescription from "@oh-my-pi/pi-coding-agent/prompts/tools/bash.md" with { type: "text" };
|
|
9
|
-
import type { OutputMeta } from "@oh-my-pi/pi-coding-agent/tools/output-meta";
|
|
10
|
-
import { ToolError } from "@oh-my-pi/pi-coding-agent/tools/tool-errors";
|
|
11
3
|
import type { Component } from "@oh-my-pi/pi-tui";
|
|
12
|
-
import { Text
|
|
4
|
+
import { Text } from "@oh-my-pi/pi-tui";
|
|
13
5
|
import { Type } from "@sinclair/typebox";
|
|
14
|
-
|
|
6
|
+
import { renderPromptTemplate } from "../config/prompt-templates";
|
|
7
|
+
import { type BashExecutorOptions, executeBash } from "../exec/bash-executor";
|
|
8
|
+
import type { RenderResultOptions } from "../extensibility/custom-tools/types";
|
|
9
|
+
import { truncateToVisualLines } from "../modes/components/visual-truncate";
|
|
10
|
+
import type { Theme } from "../modes/theme/theme";
|
|
11
|
+
import bashDescription from "../prompts/tools/bash.md" with { type: "text" };
|
|
12
|
+
import { renderOutputBlock, renderStatusLine } from "../tui";
|
|
13
|
+
import type { ToolSession } from ".";
|
|
15
14
|
import { checkBashInterception, checkSimpleLsInterception } from "./bash-interceptor";
|
|
16
|
-
import type {
|
|
15
|
+
import type { OutputMeta } from "./output-meta";
|
|
17
16
|
import { allocateOutputArtifact, createTailBuffer } from "./output-utils";
|
|
18
17
|
import { resolveToCwd } from "./path-utils";
|
|
19
|
-
import {
|
|
18
|
+
import { formatBytes, wrapBrackets } from "./render-utils";
|
|
19
|
+
import { ToolError } from "./tool-errors";
|
|
20
20
|
import { toolResult } from "./tool-result";
|
|
21
21
|
import { DEFAULT_MAX_BYTES } from "./truncate";
|
|
22
22
|
|
|
@@ -106,7 +106,7 @@ export class BashTool implements AgentTool<typeof bashSchema, BashToolDetails> {
|
|
|
106
106
|
env: extraEnv,
|
|
107
107
|
artifactPath,
|
|
108
108
|
artifactId,
|
|
109
|
-
onChunk:
|
|
109
|
+
onChunk: chunk => {
|
|
110
110
|
tailBuffer.append(chunk);
|
|
111
111
|
if (onUpdate) {
|
|
112
112
|
onUpdate({
|
|
@@ -158,35 +158,37 @@ interface BashRenderContext {
|
|
|
158
158
|
timeout?: number;
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
+
function formatBashCommand(args: BashRenderArgs, uiTheme: Theme): string {
|
|
162
|
+
const command = args.command || uiTheme.format.ellipsis;
|
|
163
|
+
const prompt = "$";
|
|
164
|
+
const cwd = process.cwd();
|
|
165
|
+
let displayWorkdir = args.cwd;
|
|
166
|
+
|
|
167
|
+
if (displayWorkdir) {
|
|
168
|
+
const resolvedCwd = path.resolve(cwd);
|
|
169
|
+
const resolvedWorkdir = path.resolve(displayWorkdir);
|
|
170
|
+
if (resolvedWorkdir === resolvedCwd) {
|
|
171
|
+
displayWorkdir = undefined;
|
|
172
|
+
} else {
|
|
173
|
+
const relativePath = path.relative(resolvedCwd, resolvedWorkdir);
|
|
174
|
+
const isWithinCwd =
|
|
175
|
+
relativePath && !relativePath.startsWith("..") && !relativePath.startsWith(`..${path.sep}`);
|
|
176
|
+
if (isWithinCwd) {
|
|
177
|
+
displayWorkdir = relativePath;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return displayWorkdir ? `${prompt} cd ${displayWorkdir} && ${command}` : `${prompt} ${command}`;
|
|
183
|
+
}
|
|
184
|
+
|
|
161
185
|
// Preview line limit when not expanded (matches tool-execution behavior)
|
|
162
186
|
export const BASH_PREVIEW_LINES = 10;
|
|
163
187
|
|
|
164
188
|
export const bashToolRenderer = {
|
|
165
189
|
renderCall(args: BashRenderArgs, uiTheme: Theme): Component {
|
|
166
|
-
const
|
|
167
|
-
const
|
|
168
|
-
const prompt = uiTheme.fg("accent", "$");
|
|
169
|
-
const cwd = process.cwd();
|
|
170
|
-
let displayWorkdir = args.cwd;
|
|
171
|
-
|
|
172
|
-
if (displayWorkdir) {
|
|
173
|
-
const resolvedCwd = resolve(cwd);
|
|
174
|
-
const resolvedWorkdir = resolve(displayWorkdir);
|
|
175
|
-
if (resolvedWorkdir === resolvedCwd) {
|
|
176
|
-
displayWorkdir = undefined;
|
|
177
|
-
} else {
|
|
178
|
-
const relativePath = relative(resolvedCwd, resolvedWorkdir);
|
|
179
|
-
const isWithinCwd = relativePath && !relativePath.startsWith("..") && !relativePath.startsWith(`..${sep}`);
|
|
180
|
-
if (isWithinCwd) {
|
|
181
|
-
displayWorkdir = relativePath;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
const cmdText = displayWorkdir
|
|
187
|
-
? `${prompt} ${uiTheme.fg("dim", `cd ${displayWorkdir} &&`)} ${command}`
|
|
188
|
-
: `${prompt} ${command}`;
|
|
189
|
-
const text = ui.title(cmdText);
|
|
190
|
+
const cmdText = formatBashCommand(args, uiTheme);
|
|
191
|
+
const text = renderStatusLine({ icon: "pending", title: "Bash", description: cmdText }, uiTheme);
|
|
190
192
|
return new Text(text, 0, 0);
|
|
191
193
|
},
|
|
192
194
|
|
|
@@ -194,19 +196,23 @@ export const bashToolRenderer = {
|
|
|
194
196
|
result: {
|
|
195
197
|
content: Array<{ type: string; text?: string }>;
|
|
196
198
|
details?: BashToolDetails;
|
|
199
|
+
isError?: boolean;
|
|
197
200
|
},
|
|
198
201
|
options: RenderResultOptions & { renderContext?: BashRenderContext },
|
|
199
202
|
uiTheme: Theme,
|
|
203
|
+
args?: BashRenderArgs,
|
|
200
204
|
): Component {
|
|
201
|
-
const
|
|
205
|
+
const cmdText = args ? formatBashCommand(args, uiTheme) : undefined;
|
|
206
|
+
const isError = result.isError === true;
|
|
207
|
+
const header = renderStatusLine({ icon: isError ? "error" : "success", title: "Bash" }, uiTheme);
|
|
202
208
|
const { renderContext } = options;
|
|
203
209
|
const details = result.details;
|
|
204
210
|
const expanded = renderContext?.expanded ?? options.expanded;
|
|
205
211
|
const previewLines = renderContext?.previewLines ?? BASH_DEFAULT_PREVIEW_LINES;
|
|
206
212
|
|
|
207
213
|
// Get output from context (preferred) or fall back to result content
|
|
208
|
-
const output = renderContext?.output ??
|
|
209
|
-
const displayOutput = output;
|
|
214
|
+
const output = renderContext?.output ?? result.content?.find(c => c.type === "text")?.text ?? "";
|
|
215
|
+
const displayOutput = output.trimEnd();
|
|
210
216
|
const showingFullOutput = expanded && renderContext?.isFullOutput === true;
|
|
211
217
|
|
|
212
218
|
// Build truncation warning lines (static, doesn't depend on width)
|
|
@@ -214,7 +220,10 @@ export const bashToolRenderer = {
|
|
|
214
220
|
const timeoutSeconds = renderContext?.timeout;
|
|
215
221
|
const timeoutLine =
|
|
216
222
|
typeof timeoutSeconds === "number"
|
|
217
|
-
? uiTheme.fg(
|
|
223
|
+
? uiTheme.fg(
|
|
224
|
+
"dim",
|
|
225
|
+
`${uiTheme.format.bracketLeft}Timeout: ${timeoutSeconds}s${uiTheme.format.bracketRight}`,
|
|
226
|
+
)
|
|
218
227
|
: undefined;
|
|
219
228
|
let warningLine: string | undefined;
|
|
220
229
|
if (truncation && !showingFullOutput) {
|
|
@@ -226,72 +235,57 @@ export const bashToolRenderer = {
|
|
|
226
235
|
warnings.push(`Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines`);
|
|
227
236
|
} else {
|
|
228
237
|
warnings.push(
|
|
229
|
-
`Truncated: ${truncation.outputLines} lines shown (${
|
|
238
|
+
`Truncated: ${truncation.outputLines} lines shown (${formatBytes(truncation.outputBytes)} limit)`,
|
|
230
239
|
);
|
|
231
240
|
}
|
|
232
241
|
if (warnings.length > 0) {
|
|
233
|
-
warningLine = uiTheme.fg("warning",
|
|
242
|
+
warningLine = uiTheme.fg("warning", wrapBrackets(warnings.join(". "), uiTheme));
|
|
234
243
|
}
|
|
235
244
|
}
|
|
236
245
|
|
|
237
|
-
if (!displayOutput) {
|
|
238
|
-
// No output - just show warning if any
|
|
239
|
-
const lines = [timeoutLine, warningLine].filter(Boolean) as string[];
|
|
240
|
-
return new Text(lines.join("\n"), 0, 0);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
if (expanded) {
|
|
244
|
-
// Show all lines when expanded
|
|
245
|
-
const styledOutput = displayOutput
|
|
246
|
-
.split("\n")
|
|
247
|
-
.map((line) => uiTheme.fg("toolOutput", line))
|
|
248
|
-
.join("\n");
|
|
249
|
-
const lines = [styledOutput, timeoutLine, warningLine].filter(Boolean) as string[];
|
|
250
|
-
return new Text(lines.join("\n"), 0, 0);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// Collapsed: use width-aware caching component
|
|
254
|
-
const styledOutput = displayOutput
|
|
255
|
-
.split("\n")
|
|
256
|
-
.map((line) => uiTheme.fg("toolOutput", line))
|
|
257
|
-
.join("\n");
|
|
258
|
-
const textContent = `\n${styledOutput}`;
|
|
259
|
-
|
|
260
|
-
let cachedWidth: number | undefined;
|
|
261
|
-
let cachedLines: string[] | undefined;
|
|
262
|
-
let cachedSkipped: number | undefined;
|
|
263
|
-
|
|
264
246
|
return {
|
|
265
247
|
render: (width: number): string[] => {
|
|
266
|
-
if (cachedLines === undefined || cachedWidth !== width) {
|
|
267
|
-
const result = truncateToVisualLines(textContent, previewLines, width);
|
|
268
|
-
cachedLines = result.visualLines;
|
|
269
|
-
cachedSkipped = result.skippedCount;
|
|
270
|
-
cachedWidth = width;
|
|
271
|
-
}
|
|
272
248
|
const outputLines: string[] = [];
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
"
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
249
|
+
const hasOutput = displayOutput.trim().length > 0;
|
|
250
|
+
if (hasOutput) {
|
|
251
|
+
if (expanded) {
|
|
252
|
+
outputLines.push(...displayOutput.split("\n").map(line => uiTheme.fg("toolOutput", line)));
|
|
253
|
+
} else {
|
|
254
|
+
const styledOutput = displayOutput
|
|
255
|
+
.split("\n")
|
|
256
|
+
.map(line => uiTheme.fg("toolOutput", line))
|
|
257
|
+
.join("\n");
|
|
258
|
+
const textContent = styledOutput;
|
|
259
|
+
const result = truncateToVisualLines(textContent, previewLines, width);
|
|
260
|
+
if (result.skippedCount > 0) {
|
|
261
|
+
outputLines.push(
|
|
262
|
+
uiTheme.fg(
|
|
263
|
+
"dim",
|
|
264
|
+
`${uiTheme.format.ellipsis} (${result.skippedCount} earlier lines, showing ${result.visualLines.length} of ${result.skippedCount + result.visualLines.length}) (ctrl+o to expand)`,
|
|
265
|
+
),
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
outputLines.push(...result.visualLines);
|
|
269
|
+
}
|
|
284
270
|
}
|
|
285
|
-
if (
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
return
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
271
|
+
if (timeoutLine) outputLines.push(timeoutLine);
|
|
272
|
+
if (warningLine) outputLines.push(warningLine);
|
|
273
|
+
|
|
274
|
+
return renderOutputBlock(
|
|
275
|
+
{
|
|
276
|
+
header,
|
|
277
|
+
state: isError ? "error" : "success",
|
|
278
|
+
sections: [
|
|
279
|
+
{ lines: cmdText ? [uiTheme.fg("dim", cmdText)] : [] },
|
|
280
|
+
{ label: uiTheme.fg("toolTitle", "Output"), lines: outputLines },
|
|
281
|
+
],
|
|
282
|
+
width,
|
|
283
|
+
},
|
|
284
|
+
uiTheme,
|
|
285
|
+
);
|
|
294
286
|
},
|
|
287
|
+
invalidate: () => {},
|
|
295
288
|
};
|
|
296
289
|
},
|
|
290
|
+
mergeCallAndResult: true,
|
|
297
291
|
};
|
package/src/tools/calculator.ts
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import type { AgentTool, AgentToolResult } from "@oh-my-pi/pi-agent-core";
|
|
2
|
-
import { renderPromptTemplate } from "@oh-my-pi/pi-coding-agent/config/prompt-templates";
|
|
3
|
-
import type { RenderResultOptions } from "@oh-my-pi/pi-coding-agent/extensibility/custom-tools/types";
|
|
4
|
-
import type { Theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
|
5
|
-
import calculatorDescription from "@oh-my-pi/pi-coding-agent/prompts/tools/calculator.md" with { type: "text" };
|
|
6
2
|
import type { Component } from "@oh-my-pi/pi-tui";
|
|
7
3
|
import { Text } from "@oh-my-pi/pi-tui";
|
|
8
4
|
import { untilAborted } from "@oh-my-pi/pi-utils";
|
|
9
5
|
import { Type } from "@sinclair/typebox";
|
|
10
|
-
import
|
|
6
|
+
import { renderPromptTemplate } from "../config/prompt-templates";
|
|
7
|
+
import type { RenderResultOptions } from "../extensibility/custom-tools/types";
|
|
8
|
+
import type { Theme } from "../modes/theme/theme";
|
|
9
|
+
import calculatorDescription from "../prompts/tools/calculator.md" with { type: "text" };
|
|
10
|
+
import { renderStatusLine, renderTreeList } from "../tui";
|
|
11
|
+
import type { ToolSession } from ".";
|
|
11
12
|
import {
|
|
12
13
|
formatCount,
|
|
13
14
|
formatEmptyMessage,
|
|
14
|
-
|
|
15
|
-
formatMeta,
|
|
16
|
-
formatMoreItems,
|
|
15
|
+
formatErrorMessage,
|
|
17
16
|
PREVIEW_LIMITS,
|
|
18
17
|
TRUNCATE_LENGTHS,
|
|
19
18
|
truncate,
|
|
@@ -418,13 +417,13 @@ export class CalculatorTool implements AgentTool<typeof calculatorSchema, Calcul
|
|
|
418
417
|
signal?: AbortSignal,
|
|
419
418
|
): Promise<AgentToolResult<CalculatorToolDetails>> {
|
|
420
419
|
return untilAborted(signal, async () => {
|
|
421
|
-
const results = calculations.map(
|
|
420
|
+
const results = calculations.map(calc => {
|
|
422
421
|
const value = evaluateExpression(calc.expression);
|
|
423
422
|
const output = `${calc.prefix}${formatResult(value)}${calc.suffix}`;
|
|
424
423
|
return { expression: calc.expression, value, output };
|
|
425
424
|
});
|
|
426
425
|
|
|
427
|
-
const outputText = results.map(
|
|
426
|
+
const outputText = results.map(result => result.output).join("\n");
|
|
428
427
|
return {
|
|
429
428
|
content: [{ type: "text", text: outputText }],
|
|
430
429
|
details: { results },
|
|
@@ -453,16 +452,11 @@ export const calculatorToolRenderer = {
|
|
|
453
452
|
* Format: "Calc <expression> (N calcs)"
|
|
454
453
|
*/
|
|
455
454
|
renderCall(args: CalculatorRenderArgs, uiTheme: Theme): Component {
|
|
456
|
-
const label = uiTheme.fg("toolTitle", uiTheme.bold("Calc"));
|
|
457
455
|
const count = args.calculations?.length ?? 0;
|
|
458
456
|
const firstExpression = args.calculations?.[0]?.expression;
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
}
|
|
463
|
-
const meta: string[] = [];
|
|
464
|
-
if (count > 0) meta.push(formatCount("calc", count));
|
|
465
|
-
text += formatMeta(meta, uiTheme);
|
|
457
|
+
const description = firstExpression ? truncate(firstExpression, TRUNCATE_LENGTHS.TITLE, "...") : undefined;
|
|
458
|
+
const meta = count > 0 ? [formatCount("calc", count)] : [];
|
|
459
|
+
const text = renderStatusLine({ icon: "pending", title: "Calc", description, meta }, uiTheme);
|
|
466
460
|
return new Text(text, 0, 0);
|
|
467
461
|
},
|
|
468
462
|
|
|
@@ -471,46 +465,54 @@ export const calculatorToolRenderer = {
|
|
|
471
465
|
* Collapsed mode shows first N items with expand hint; expanded shows all.
|
|
472
466
|
*/
|
|
473
467
|
renderResult(
|
|
474
|
-
result: { content: Array<{ type: string; text?: string }>; details?: CalculatorToolDetails },
|
|
468
|
+
result: { content: Array<{ type: string; text?: string }>; details?: CalculatorToolDetails; isError?: boolean },
|
|
475
469
|
{ expanded }: RenderResultOptions,
|
|
476
470
|
uiTheme: Theme,
|
|
471
|
+
args?: CalculatorRenderArgs,
|
|
477
472
|
): Component {
|
|
478
473
|
const details = result.details;
|
|
479
|
-
const textContent = result.content?.find(
|
|
474
|
+
const textContent = result.content?.find(c => c.type === "text")?.text ?? "";
|
|
475
|
+
if (result.isError) {
|
|
476
|
+
const header = renderStatusLine({ icon: "error", title: "Calc" }, uiTheme);
|
|
477
|
+
return new Text([header, formatErrorMessage(textContent, uiTheme)].join("\n"), 0, 0);
|
|
478
|
+
}
|
|
480
479
|
|
|
481
480
|
// Prefer structured details; fall back to parsing text content
|
|
482
|
-
let outputs = details?.results?.map(
|
|
481
|
+
let outputs = details?.results?.map(entry => `${entry.expression} = ${entry.output}`) ?? [];
|
|
483
482
|
if (outputs.length === 0 && textContent.trim()) {
|
|
484
|
-
|
|
483
|
+
const rawOutputs = textContent.split("\n").filter(line => line.trim().length > 0);
|
|
484
|
+
const expressions = args?.calculations?.map(calc => calc.expression) ?? [];
|
|
485
|
+
if (expressions.length === rawOutputs.length && expressions.length > 0) {
|
|
486
|
+
outputs = rawOutputs.map((output, index) => `${expressions[index]} = ${output}`);
|
|
487
|
+
} else {
|
|
488
|
+
outputs = rawOutputs;
|
|
489
|
+
}
|
|
485
490
|
}
|
|
486
491
|
|
|
487
492
|
if (outputs.length === 0) {
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
// Limit visible items in collapsed mode
|
|
492
|
-
const maxItems = expanded ? outputs.length : Math.min(outputs.length, COLLAPSED_LIST_LIMIT);
|
|
493
|
-
const hasMore = outputs.length > maxItems;
|
|
494
|
-
const icon = uiTheme.styledSymbol("status.success", "success");
|
|
495
|
-
const summary = uiTheme.fg("dim", formatCount("result", outputs.length));
|
|
496
|
-
const expandHint = formatExpandHint(uiTheme, expanded, hasMore);
|
|
497
|
-
let text = `${icon} ${summary}${expandHint}`;
|
|
498
|
-
|
|
499
|
-
// Render each result as a tree branch
|
|
500
|
-
for (let i = 0; i < maxItems; i += 1) {
|
|
501
|
-
const isLast = i === maxItems - 1 && !hasMore;
|
|
502
|
-
const branch = isLast ? uiTheme.tree.last : uiTheme.tree.branch;
|
|
503
|
-
text += `\n ${uiTheme.fg("dim", branch)} ${uiTheme.fg("toolOutput", outputs[i])}`;
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
// Show overflow indicator for collapsed mode
|
|
507
|
-
if (hasMore) {
|
|
508
|
-
text += `\n ${uiTheme.fg("dim", uiTheme.tree.last)} ${uiTheme.fg(
|
|
509
|
-
"muted",
|
|
510
|
-
formatMoreItems(outputs.length - maxItems, "result", uiTheme),
|
|
511
|
-
)}`;
|
|
493
|
+
const header = renderStatusLine({ icon: "warning", title: "Calc" }, uiTheme);
|
|
494
|
+
return new Text([header, formatEmptyMessage("No results", uiTheme)].join("\n"), 0, 0);
|
|
512
495
|
}
|
|
513
496
|
|
|
514
|
-
|
|
497
|
+
const description = args?.calculations?.[0]?.expression
|
|
498
|
+
? truncate(args.calculations[0].expression, TRUNCATE_LENGTHS.TITLE, "...")
|
|
499
|
+
: undefined;
|
|
500
|
+
const header = renderStatusLine(
|
|
501
|
+
{ icon: "success", title: "Calc", description, meta: [formatCount("result", outputs.length)] },
|
|
502
|
+
uiTheme,
|
|
503
|
+
);
|
|
504
|
+
const lines = renderTreeList(
|
|
505
|
+
{
|
|
506
|
+
items: outputs,
|
|
507
|
+
expanded,
|
|
508
|
+
maxCollapsed: COLLAPSED_LIST_LIMIT,
|
|
509
|
+
itemType: "result",
|
|
510
|
+
renderItem: output => uiTheme.fg("toolOutput", output),
|
|
511
|
+
},
|
|
512
|
+
uiTheme,
|
|
513
|
+
);
|
|
514
|
+
|
|
515
|
+
return new Text([header, ...lines].join("\n"), 0, 0);
|
|
515
516
|
},
|
|
517
|
+
mergeCallAndResult: true,
|
|
516
518
|
};
|
package/src/tools/complete.ts
CHANGED
|
@@ -3,14 +3,13 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Subagents must call this tool to finish and return structured JSON output.
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
6
|
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
|
|
8
7
|
import { StringEnum } from "@oh-my-pi/pi-ai";
|
|
9
|
-
import { subprocessToolRegistry } from "@oh-my-pi/pi-coding-agent/task/subprocess-tool-registry";
|
|
10
8
|
import type { Static, TObject } from "@sinclair/typebox";
|
|
11
9
|
import { Type } from "@sinclair/typebox";
|
|
12
10
|
import Ajv, { type ErrorObject, type ValidateFunction } from "ajv";
|
|
13
|
-
import
|
|
11
|
+
import { subprocessToolRegistry } from "../task/subprocess-tool-registry";
|
|
12
|
+
import type { ToolSession } from ".";
|
|
14
13
|
import { jtdToJsonSchema } from "./jtd-to-json-schema";
|
|
15
14
|
|
|
16
15
|
export interface CompleteDetails {
|
|
@@ -46,7 +45,7 @@ function formatSchema(schema: unknown): string {
|
|
|
46
45
|
function formatAjvErrors(errors: ErrorObject[] | null | undefined): string {
|
|
47
46
|
if (!errors || errors.length === 0) return "Unknown schema validation error.";
|
|
48
47
|
return errors
|
|
49
|
-
.map(
|
|
48
|
+
.map(err => {
|
|
50
49
|
const path = err.instancePath ? `${err.instancePath}: ` : "";
|
|
51
50
|
return `${path}${err.message ?? "invalid"}`;
|
|
52
51
|
})
|
|
@@ -137,6 +136,6 @@ export class CompleteTool implements AgentTool<TObject, CompleteDetails> {
|
|
|
137
136
|
|
|
138
137
|
// Register subprocess tool handler for extraction + termination.
|
|
139
138
|
subprocessToolRegistry.register<CompleteDetails>("complete", {
|
|
140
|
-
extractData:
|
|
139
|
+
extractData: event => event.result?.details as CompleteDetails | undefined,
|
|
141
140
|
shouldTerminate: () => true,
|
|
142
141
|
});
|
package/src/tools/context.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AgentToolContext, ToolCallContext } from "@oh-my-pi/pi-agent-core";
|
|
2
|
-
import type { CustomToolContext } from "
|
|
3
|
-
import type { ExtensionUIContext } from "
|
|
2
|
+
import type { CustomToolContext } from "../extensibility/custom-tools/types";
|
|
3
|
+
import type { ExtensionUIContext } from "../extensibility/extensions/types";
|
|
4
4
|
|
|
5
5
|
declare module "@oh-my-pi/pi-agent-core" {
|
|
6
6
|
interface AgentToolContext extends CustomToolContext {
|