@oh-my-pi/pi-coding-agent 8.1.0 → 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 +21 -1
- 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 +51 -23
- package/scripts/format-prompts.ts +0 -1
- package/src/capability/context-file.ts +2 -3
- package/src/capability/extension-module.ts +2 -3
- package/src/capability/extension.ts +2 -3
- package/src/capability/fs.ts +20 -21
- package/src/capability/hook.ts +2 -3
- package/src/capability/index.ts +15 -16
- package/src/capability/instruction.ts +2 -3
- package/src/capability/mcp.ts +2 -3
- package/src/capability/prompt.ts +2 -3
- package/src/capability/rule.ts +2 -3
- package/src/capability/settings.ts +1 -2
- package/src/capability/skill.ts +2 -3
- package/src/capability/slash-command.ts +2 -3
- package/src/capability/ssh.ts +2 -3
- package/src/capability/system-prompt.ts +2 -3
- package/src/capability/tool.ts +2 -3
- 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 -21
- 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 +21 -23
- package/src/commit/agentic/fallback.ts +9 -9
- package/src/commit/agentic/index.ts +30 -38
- package/src/commit/agentic/state.ts +1 -6
- package/src/commit/agentic/tools/analyze-file.ts +15 -15
- package/src/commit/agentic/tools/git-file-diff.ts +3 -3
- package/src/commit/agentic/tools/git-hunk.ts +7 -7
- package/src/commit/agentic/tools/git-overview.ts +5 -5
- package/src/commit/agentic/tools/index.ts +14 -14
- package/src/commit/agentic/tools/propose-changelog.ts +6 -6
- package/src/commit/agentic/tools/propose-commit.ts +8 -8
- package/src/commit/agentic/tools/recent-commits.ts +2 -2
- package/src/commit/agentic/tools/split-commit.ts +19 -23
- package/src/commit/agentic/topo-sort.ts +1 -1
- package/src/commit/agentic/trivial.ts +3 -3
- package/src/commit/agentic/validation.ts +12 -12
- package/src/commit/analysis/conventional.ts +7 -11
- package/src/commit/analysis/index.ts +4 -4
- package/src/commit/analysis/scope.ts +4 -4
- package/src/commit/analysis/summary.ts +7 -9
- package/src/commit/analysis/validation.ts +1 -1
- package/src/commit/changelog/detect.ts +6 -6
- package/src/commit/changelog/generate.ts +7 -9
- package/src/commit/changelog/index.ts +13 -13
- package/src/commit/changelog/parse.ts +2 -2
- package/src/commit/cli.ts +1 -1
- package/src/commit/git/diff.ts +3 -3
- package/src/commit/git/index.ts +19 -24
- package/src/commit/index.ts +1 -1
- package/src/commit/map-reduce/index.ts +9 -9
- package/src/commit/map-reduce/map-phase.ts +19 -34
- package/src/commit/map-reduce/reduce-phase.ts +9 -11
- package/src/commit/message.ts +2 -2
- package/src/commit/model-selection.ts +3 -7
- package/src/commit/pipeline.ts +20 -22
- package/src/commit/utils/exclusions.ts +3 -3
- package/src/config/file-lock.ts +17 -7
- package/src/config/keybindings.ts +6 -8
- package/src/config/model-registry.ts +55 -37
- package/src/config/model-resolver.ts +18 -19
- package/src/config/prompt-templates.ts +11 -11
- package/src/config/settings-manager.ts +50 -34
- package/src/config.ts +60 -62
- 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 +16 -18
- 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 +17 -14
- package/src/extensibility/custom-commands/types.ts +1 -2
- package/src/extensibility/custom-tools/loader.ts +10 -11
- package/src/extensibility/custom-tools/types.ts +6 -7
- package/src/extensibility/custom-tools/wrapper.ts +2 -3
- package/src/extensibility/extensions/loader.ts +75 -53
- package/src/extensibility/extensions/runner.ts +11 -12
- package/src/extensibility/extensions/types.ts +19 -26
- package/src/extensibility/extensions/wrapper.ts +3 -4
- package/src/extensibility/hooks/index.ts +1 -1
- package/src/extensibility/hooks/loader.ts +8 -9
- package/src/extensibility/hooks/runner.ts +7 -8
- package/src/extensibility/hooks/tool-wrapper.ts +0 -1
- package/src/extensibility/hooks/types.ts +10 -17
- 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 +46 -46
- 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 +14 -10
- 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 +10 -16
- package/src/lsp/utils.ts +3 -3
- package/src/main.ts +55 -34
- 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 +3 -4
- 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 +60 -49
- package/src/modes/components/armin.ts +4 -5
- package/src/modes/components/assistant-message.ts +6 -6
- 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 +11 -16
- package/src/modes/components/tree-selector.ts +11 -11
- 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 +27 -29
- 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 -25
- package/src/modes/rpc/rpc-types.ts +3 -4
- package/src/modes/theme/mermaid-cache.ts +2 -2
- package/src/modes/theme/theme.ts +128 -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 +10 -11
- 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 +12 -13
- package/src/sdk.ts +60 -63
- package/src/session/agent-session.ts +83 -84
- package/src/session/agent-storage.ts +11 -11
- package/src/session/artifacts.ts +8 -9
- package/src/session/auth-storage.ts +25 -29
- 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 +2 -3
- 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 +27 -34
- 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 +33 -36
- package/src/task/output-manager.ts +3 -4
- package/src/task/parallel.ts +0 -1
- package/src/task/render.ts +19 -20
- package/src/task/subprocess-tool-registry.ts +1 -2
- package/src/task/worker-protocol.ts +3 -3
- package/src/task/worker.ts +32 -38
- package/src/task/worktree.ts +19 -19
- package/src/tools/ask.ts +8 -9
- package/src/tools/bash-interceptor.ts +1 -5
- package/src/tools/bash.ts +19 -18
- package/src/tools/calculator.ts +12 -12
- package/src/tools/complete.ts +3 -4
- package/src/tools/context.ts +2 -2
- package/src/tools/fetch.ts +23 -26
- package/src/tools/find.ts +15 -16
- package/src/tools/gemini-image.ts +14 -14
- package/src/tools/grep.ts +27 -27
- package/src/tools/index.ts +78 -56
- package/src/tools/list-limit.ts +1 -1
- package/src/tools/ls.ts +7 -7
- package/src/tools/notebook.ts +5 -5
- package/src/tools/output-meta.ts +3 -4
- package/src/tools/output-utils.ts +1 -1
- package/src/tools/path-utils.ts +5 -5
- package/src/tools/python.ts +36 -37
- package/src/tools/read.ts +23 -23
- package/src/tools/render-utils.ts +8 -9
- package/src/tools/renderers.ts +6 -7
- package/src/tools/review.ts +8 -11
- package/src/tools/ssh.ts +31 -30
- package/src/tools/todo-write.ts +13 -13
- package/src/tools/tool-errors.ts +3 -3
- package/src/tools/tool-result.ts +3 -8
- package/src/tools/write.ts +11 -16
- package/src/tui/code-cell.ts +3 -9
- package/src/tui/file-list.ts +3 -4
- package/src/tui/output-block.ts +1 -2
- package/src/tui/status-line.ts +2 -3
- package/src/tui/tree-list.ts +2 -3
- package/src/tui/types.ts +1 -2
- package/src/tui/utils.ts +2 -3
- 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 +4 -9
- 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 +16 -18
- package/scripts/generate-wasm-b64.ts +0 -24
- package/src/commit/map-reduce/.map-phase.ts.kate-swp +0 -0
- package/src/task/.executor.ts.kate-swp +0 -0
- package/src/vendor/photon/photon_rs_bg.wasm.b64.js +0 -1
package/src/task/discovery.ts
CHANGED
|
@@ -11,13 +11,11 @@
|
|
|
11
11
|
*
|
|
12
12
|
* Agent files use markdown with YAML frontmatter.
|
|
13
13
|
*/
|
|
14
|
-
|
|
15
|
-
import * as fs from "node:fs";
|
|
14
|
+
import * as fs from "node:fs/promises";
|
|
16
15
|
import * as path from "node:path";
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import { loadBundledAgents } from "./agents";
|
|
16
|
+
import { logger } from "@oh-my-pi/pi-utils";
|
|
17
|
+
import { findAllNearestProjectConfigDirs, getConfigDirs } from "../config";
|
|
18
|
+
import { loadBundledAgents, parseAgent } from "./agents";
|
|
21
19
|
import type { AgentDefinition, AgentSource } from "./types";
|
|
22
20
|
|
|
23
21
|
/** Result of agent discovery */
|
|
@@ -29,55 +27,23 @@ export interface DiscoveryResult {
|
|
|
29
27
|
/**
|
|
30
28
|
* Load agents from a directory.
|
|
31
29
|
*/
|
|
32
|
-
function loadAgentsFromDir(dir: string, source: AgentSource): AgentDefinition[] {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
for (const entry of entries) {
|
|
47
|
-
if (!entry.name.endsWith(".md")) continue;
|
|
48
|
-
|
|
49
|
-
const filePath = path.resolve(dir, entry.name);
|
|
50
|
-
|
|
51
|
-
// Handle both regular files and symlinks
|
|
52
|
-
try {
|
|
53
|
-
if (!fs.statSync(filePath).isFile()) continue;
|
|
54
|
-
} catch {
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
let content: string;
|
|
59
|
-
try {
|
|
60
|
-
content = fs.readFileSync(filePath, "utf-8");
|
|
61
|
-
} catch {
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const { frontmatter, body } = parseFrontmatter(content, { source: filePath });
|
|
66
|
-
const fields = parseAgentFields(frontmatter);
|
|
67
|
-
|
|
68
|
-
if (!fields) {
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
agents.push({
|
|
73
|
-
...fields,
|
|
74
|
-
systemPrompt: body,
|
|
75
|
-
source,
|
|
76
|
-
filePath,
|
|
30
|
+
async function loadAgentsFromDir(dir: string, source: AgentSource): Promise<AgentDefinition[]> {
|
|
31
|
+
const entries = await fs.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
32
|
+
const files = entries
|
|
33
|
+
.filter(entry => (entry.isFile() || entry.isSymbolicLink()) && entry.name.endsWith(".md"))
|
|
34
|
+
.sort((a, b) => a.name.localeCompare(b.name))
|
|
35
|
+
.map(file => {
|
|
36
|
+
const filePath = path.join(dir, file.name);
|
|
37
|
+
return fs
|
|
38
|
+
.readFile(filePath, "utf-8")
|
|
39
|
+
.then(content => parseAgent(filePath, content, source, "warn"))
|
|
40
|
+
.catch(error => {
|
|
41
|
+
logger.warn("Failed to read agent file", { filePath, error });
|
|
42
|
+
return null;
|
|
43
|
+
});
|
|
77
44
|
});
|
|
78
|
-
}
|
|
79
45
|
|
|
80
|
-
return
|
|
46
|
+
return (await Promise.all(files)).filter(Boolean) as AgentDefinition[];
|
|
81
47
|
}
|
|
82
48
|
|
|
83
49
|
/**
|
|
@@ -89,62 +55,59 @@ function loadAgentsFromDir(dir: string, source: AgentSource): AgentDefinition[]
|
|
|
89
55
|
*/
|
|
90
56
|
export async function discoverAgents(cwd: string): Promise<DiscoveryResult> {
|
|
91
57
|
const resolvedCwd = path.resolve(cwd);
|
|
92
|
-
const agentSources = Array.from(new Set(getConfigDirs("", { project: false }).map(
|
|
58
|
+
const agentSources = Array.from(new Set(getConfigDirs("", { project: false }).map(entry => entry.source)));
|
|
93
59
|
|
|
94
60
|
// Get user directories (priority order: .omp, .pi, .claude, ...)
|
|
95
61
|
const userDirs = getConfigDirs("agents", { project: false })
|
|
96
|
-
.filter(
|
|
97
|
-
.map(
|
|
62
|
+
.filter(entry => agentSources.includes(entry.source))
|
|
63
|
+
.map(entry => ({
|
|
98
64
|
...entry,
|
|
99
65
|
path: path.resolve(entry.path),
|
|
100
66
|
}));
|
|
101
67
|
|
|
102
68
|
// Get project directories by walking up from cwd (priority order)
|
|
103
69
|
const projectDirs = (await findAllNearestProjectConfigDirs("agents", resolvedCwd))
|
|
104
|
-
.filter(
|
|
105
|
-
.map(
|
|
70
|
+
.filter(entry => agentSources.includes(entry.source))
|
|
71
|
+
.map(entry => ({
|
|
106
72
|
...entry,
|
|
107
73
|
path: path.resolve(entry.path),
|
|
108
74
|
}));
|
|
109
75
|
|
|
110
76
|
const orderedSources = agentSources.filter(
|
|
111
|
-
(source) =>
|
|
112
|
-
userDirs.some((entry) => entry.source === source) || projectDirs.some((entry) => entry.source === source),
|
|
77
|
+
source => userDirs.some(entry => entry.source === source) || projectDirs.some(entry => entry.source === source),
|
|
113
78
|
);
|
|
114
79
|
|
|
115
80
|
const orderedDirs: Array<{ dir: string; source: AgentSource }> = [];
|
|
116
81
|
for (const source of orderedSources) {
|
|
117
|
-
const project = projectDirs.find(
|
|
82
|
+
const project = projectDirs.find(entry => entry.source === source);
|
|
118
83
|
if (project) orderedDirs.push({ dir: project.path, source: "project" });
|
|
119
|
-
const user = userDirs.find(
|
|
84
|
+
const user = userDirs.find(entry => entry.source === source);
|
|
120
85
|
if (user) orderedDirs.push({ dir: user.path, source: "user" });
|
|
121
86
|
}
|
|
122
87
|
|
|
123
|
-
const agents: AgentDefinition[] = [];
|
|
124
88
|
const seen = new Set<string>();
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if (seen.has(agent.name))
|
|
129
|
-
agents.push(agent);
|
|
89
|
+
const loadedAgents = (await Promise.all(orderedDirs.map(({ dir, source }) => loadAgentsFromDir(dir, source))))
|
|
90
|
+
.flat()
|
|
91
|
+
.filter(agent => {
|
|
92
|
+
if (seen.has(agent.name)) return false;
|
|
130
93
|
seen.add(agent.name);
|
|
131
|
-
|
|
132
|
-
|
|
94
|
+
return true;
|
|
95
|
+
});
|
|
133
96
|
|
|
134
|
-
|
|
135
|
-
if (seen.has(agent.name))
|
|
136
|
-
agents.push(agent);
|
|
97
|
+
const bundledAgents = loadBundledAgents().filter(agent => {
|
|
98
|
+
if (seen.has(agent.name)) return false;
|
|
137
99
|
seen.add(agent.name);
|
|
138
|
-
|
|
100
|
+
return true;
|
|
101
|
+
});
|
|
139
102
|
|
|
140
103
|
const projectAgentsDir = projectDirs.length > 0 ? projectDirs[0].path : null;
|
|
141
104
|
|
|
142
|
-
return { agents, projectAgentsDir };
|
|
105
|
+
return { agents: [...loadedAgents, ...bundledAgents], projectAgentsDir };
|
|
143
106
|
}
|
|
144
107
|
|
|
145
108
|
/**
|
|
146
109
|
* Get an agent by name from discovered agents.
|
|
147
110
|
*/
|
|
148
111
|
export function getAgent(agents: AgentDefinition[], name: string): AgentDefinition | undefined {
|
|
149
|
-
return agents.find(
|
|
112
|
+
return agents.find(a => a.name === name);
|
|
150
113
|
}
|
package/src/task/executor.ts
CHANGED
|
@@ -3,20 +3,19 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Runs each subagent in a Bun Worker and forwards AgentEvents for progress tracking.
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
6
|
import path from "node:path";
|
|
8
7
|
import type { AgentEvent, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
9
|
-
import type { ModelRegistry } from "@oh-my-pi/pi-coding-agent/config/model-registry";
|
|
10
|
-
import { formatModelString, parseModelPattern } from "@oh-my-pi/pi-coding-agent/config/model-resolver";
|
|
11
|
-
import { checkPythonKernelAvailability } from "@oh-my-pi/pi-coding-agent/ipy/kernel";
|
|
12
|
-
import { LspTool } from "@oh-my-pi/pi-coding-agent/lsp";
|
|
13
|
-
import type { LspParams } from "@oh-my-pi/pi-coding-agent/lsp/types";
|
|
14
|
-
import { callTool } from "@oh-my-pi/pi-coding-agent/mcp/client";
|
|
15
|
-
import type { MCPManager } from "@oh-my-pi/pi-coding-agent/mcp/manager";
|
|
16
|
-
import type { AuthStorage } from "@oh-my-pi/pi-coding-agent/session/auth-storage";
|
|
17
|
-
import { PythonTool, type PythonToolParams } from "@oh-my-pi/pi-coding-agent/tools/python";
|
|
18
|
-
import type { EventBus } from "@oh-my-pi/pi-coding-agent/utils/event-bus";
|
|
19
8
|
import type { ToolSession } from "..";
|
|
9
|
+
import type { ModelRegistry } from "../config/model-registry";
|
|
10
|
+
import { formatModelString, parseModelPattern } from "../config/model-resolver";
|
|
11
|
+
import { checkPythonKernelAvailability } from "../ipy/kernel";
|
|
12
|
+
import { LspTool } from "../lsp";
|
|
13
|
+
import type { LspParams } from "../lsp/types";
|
|
14
|
+
import { callTool } from "../mcp/client";
|
|
15
|
+
import type { MCPManager } from "../mcp/manager";
|
|
16
|
+
import type { AuthStorage } from "../session/auth-storage";
|
|
17
|
+
import { PythonTool, type PythonToolParams } from "../tools/python";
|
|
18
|
+
import type { EventBus } from "../utils/event-bus";
|
|
20
19
|
import { subprocessToolRegistry } from "./subprocess-tool-registry";
|
|
21
20
|
import {
|
|
22
21
|
type AgentDefinition,
|
|
@@ -171,7 +170,7 @@ function getUsageTokens(usage: unknown): number {
|
|
|
171
170
|
* falling back to empty strings if not.
|
|
172
171
|
*/
|
|
173
172
|
function extractMCPToolMetadata(mcpManager: MCPManager): MCPToolMetadata[] {
|
|
174
|
-
return mcpManager.getTools().map(
|
|
173
|
+
return mcpManager.getTools().map(tool => {
|
|
175
174
|
// MCPTool and DeferredMCPTool have these properties
|
|
176
175
|
const mcpTool = tool as { mcpToolName?: string; mcpServerName?: string };
|
|
177
176
|
return {
|
|
@@ -264,7 +263,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
|
|
|
264
263
|
|
|
265
264
|
const pythonToolMode = options.settingsManager?.getPythonToolMode?.() ?? "ipy-only";
|
|
266
265
|
if (toolNames?.includes("exec")) {
|
|
267
|
-
const expanded = toolNames.filter(
|
|
266
|
+
const expanded = toolNames.filter(name => name !== "exec");
|
|
268
267
|
if (pythonToolMode === "bash-only") {
|
|
269
268
|
expanded.push("bash");
|
|
270
269
|
} else if (pythonToolMode === "ipy-only") {
|
|
@@ -706,11 +705,11 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
|
|
|
706
705
|
message: string;
|
|
707
706
|
}
|
|
708
707
|
|
|
709
|
-
const done = await new Promise<Extract<SubagentWorkerResponse, { type: "done" }>>(
|
|
708
|
+
const done = await new Promise<Extract<SubagentWorkerResponse, { type: "done" }>>(resolve => {
|
|
710
709
|
const cleanup = () => {
|
|
711
710
|
listenerController.abort();
|
|
712
711
|
};
|
|
713
|
-
finalize =
|
|
712
|
+
finalize = message => {
|
|
714
713
|
if (resolved) return;
|
|
715
714
|
resolved = true;
|
|
716
715
|
cleanup();
|
package/src/task/index.ts
CHANGED
|
@@ -12,22 +12,23 @@
|
|
|
12
12
|
* - Progress tracking via JSON events
|
|
13
13
|
* - Session artifacts for debugging
|
|
14
14
|
*/
|
|
15
|
-
|
|
16
|
-
import
|
|
17
|
-
import { tmpdir } from "node:os";
|
|
15
|
+
import * as fs from "node:fs/promises";
|
|
16
|
+
import * as os from "node:os";
|
|
18
17
|
import path from "node:path";
|
|
19
18
|
import type { AgentTool, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
|
|
20
19
|
import type { Usage } from "@oh-my-pi/pi-ai";
|
|
21
|
-
import { renderPromptTemplate } from "@oh-my-pi/pi-coding-agent/config/prompt-templates";
|
|
22
|
-
import type { Theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
|
23
|
-
import taskDescriptionTemplate from "@oh-my-pi/pi-coding-agent/prompts/tools/task.md" with { type: "text" };
|
|
24
|
-
import { AgentOutputManager } from "@oh-my-pi/pi-coding-agent/task/output-manager";
|
|
25
|
-
import { formatDuration } from "@oh-my-pi/pi-coding-agent/tools/render-utils";
|
|
26
20
|
import { $ } from "bun";
|
|
27
21
|
import { nanoid } from "nanoid";
|
|
28
22
|
import type { ToolSession } from "..";
|
|
23
|
+
import { renderPromptTemplate } from "../config/prompt-templates";
|
|
24
|
+
import type { Theme } from "../modes/theme/theme";
|
|
25
|
+
import taskDescriptionTemplate from "../prompts/tools/task.md" with { type: "text" };
|
|
26
|
+
import { formatDuration } from "../tools/render-utils";
|
|
27
|
+
// Import review tools for side effects (registers subagent tool handlers)
|
|
28
|
+
import "../tools/review";
|
|
29
29
|
import { discoverAgents, getAgent } from "./discovery";
|
|
30
30
|
import { runSubprocess } from "./executor";
|
|
31
|
+
import { AgentOutputManager } from "./output-manager";
|
|
31
32
|
import { mapWithConcurrencyLimit } from "./parallel";
|
|
32
33
|
import { renderCall, renderResult } from "./render";
|
|
33
34
|
import { renderTemplate } from "./template";
|
|
@@ -49,9 +50,6 @@ import {
|
|
|
49
50
|
getRepoRoot,
|
|
50
51
|
} from "./worktree";
|
|
51
52
|
|
|
52
|
-
// Import review tools for side effects (registers subagent tool handlers)
|
|
53
|
-
import "../tools/review";
|
|
54
|
-
|
|
55
53
|
/** Format byte count for display */
|
|
56
54
|
function formatBytes(bytes: number): string {
|
|
57
55
|
if (bytes < 1024) return `${bytes}B`;
|
|
@@ -174,7 +172,7 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
|
|
|
174
172
|
// Validate agent exists
|
|
175
173
|
const agent = getAgent(agents, agentName);
|
|
176
174
|
if (!agent) {
|
|
177
|
-
const available = agents.map(
|
|
175
|
+
const available = agents.map(a => a.name).join(", ") || "none";
|
|
178
176
|
return {
|
|
179
177
|
content: [
|
|
180
178
|
{
|
|
@@ -268,7 +266,7 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
|
|
|
268
266
|
problems.push(`Missing task ids at indexes: ${missingTaskIndexes.join(", ")}`);
|
|
269
267
|
}
|
|
270
268
|
if (duplicateIds.length > 0) {
|
|
271
|
-
const details = duplicateIds.map(
|
|
269
|
+
const details = duplicateIds.map(entry => `${entry.id} (indexes ${entry.indexes.join(", ")})`).join("; ");
|
|
272
270
|
problems.push(`Duplicate task ids detected (case-insensitive): ${details}`);
|
|
273
271
|
}
|
|
274
272
|
return {
|
|
@@ -308,9 +306,8 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
|
|
|
308
306
|
// Derive artifacts directory
|
|
309
307
|
const sessionFile = this.session.getSessionFile();
|
|
310
308
|
const artifactsDir = sessionFile ? sessionFile.slice(0, -6) : null;
|
|
311
|
-
const tempArtifactsDir = artifactsDir ? null : path.join(tmpdir(), `omp-task-${nanoid()}`);
|
|
309
|
+
const tempArtifactsDir = artifactsDir ? null : path.join(os.tmpdir(), `omp-task-${nanoid()}`);
|
|
312
310
|
const effectiveArtifactsDir = artifactsDir || tempArtifactsDir!;
|
|
313
|
-
await mkdir(effectiveArtifactsDir, { recursive: true });
|
|
314
311
|
|
|
315
312
|
// Initialize progress tracking
|
|
316
313
|
const progressMap = new Map<number, AgentProgress>();
|
|
@@ -349,7 +346,7 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
|
|
|
349
346
|
|
|
350
347
|
// Check spawn restrictions from parent
|
|
351
348
|
const parentSpawns = this.session.getSessionSpawns() ?? "*";
|
|
352
|
-
const allowedSpawns = parentSpawns.split(",").map(
|
|
349
|
+
const allowedSpawns = parentSpawns.split(",").map(s => s.trim());
|
|
353
350
|
const isSpawnAllowed = (): boolean => {
|
|
354
351
|
if (parentSpawns === "") return false; // Empty = deny all
|
|
355
352
|
if (parentSpawns === "*") return true; // Wildcard = allow all
|
|
@@ -372,11 +369,11 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
|
|
|
372
369
|
// Allocate unique IDs across the session to prevent artifact collisions
|
|
373
370
|
const outputManager =
|
|
374
371
|
this.session.agentOutputManager ?? new AgentOutputManager(this.session.getArtifactsDir ?? (() => null));
|
|
375
|
-
const uniqueIds = await outputManager.allocateBatch(tasks.map(
|
|
372
|
+
const uniqueIds = await outputManager.allocateBatch(tasks.map(t => t.id));
|
|
376
373
|
const tasksWithUniqueIds = tasks.map((t, i) => ({ ...t, id: uniqueIds[i] }));
|
|
377
374
|
|
|
378
375
|
// Build full prompts with context prepended
|
|
379
|
-
const tasksWithContext = tasksWithUniqueIds.map(
|
|
376
|
+
const tasksWithContext = tasksWithUniqueIds.map(t => renderTemplate(context, t));
|
|
380
377
|
|
|
381
378
|
// Initialize progress for all tasks
|
|
382
379
|
for (let i = 0; i < tasksWithContext.length; i++) {
|
|
@@ -419,7 +416,7 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
|
|
|
419
416
|
enableLsp: false,
|
|
420
417
|
signal,
|
|
421
418
|
eventBus: undefined,
|
|
422
|
-
onProgress:
|
|
419
|
+
onProgress: progress => {
|
|
423
420
|
progressMap.set(index, {
|
|
424
421
|
...structuredClone(progress),
|
|
425
422
|
args: tasksWithContext[index]?.args,
|
|
@@ -459,7 +456,7 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
|
|
|
459
456
|
enableLsp: false,
|
|
460
457
|
signal,
|
|
461
458
|
eventBus: undefined,
|
|
462
|
-
onProgress:
|
|
459
|
+
onProgress: progress => {
|
|
463
460
|
progressMap.set(index, {
|
|
464
461
|
...structuredClone(progress),
|
|
465
462
|
args: tasksWithContext[index]?.args,
|
|
@@ -565,29 +562,29 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
|
|
|
565
562
|
let patchApplySummary = "";
|
|
566
563
|
let patchesApplied: boolean | null = null;
|
|
567
564
|
if (isIsolated) {
|
|
568
|
-
const patchesInOrder = results.map(
|
|
569
|
-
const missingPatch = results.some(
|
|
565
|
+
const patchesInOrder = results.map(result => result.patchPath).filter(Boolean) as string[];
|
|
566
|
+
const missingPatch = results.some(result => !result.patchPath);
|
|
570
567
|
if (!repoRoot || missingPatch) {
|
|
571
568
|
patchesApplied = false;
|
|
572
569
|
} else {
|
|
573
570
|
const patchStats = await Promise.all(
|
|
574
|
-
patchesInOrder.map(async
|
|
571
|
+
patchesInOrder.map(async patchPath => ({
|
|
575
572
|
patchPath,
|
|
576
|
-
size: (await stat(patchPath)).size,
|
|
573
|
+
size: (await fs.stat(patchPath)).size,
|
|
577
574
|
})),
|
|
578
575
|
);
|
|
579
|
-
const nonEmptyPatches = patchStats.filter(
|
|
576
|
+
const nonEmptyPatches = patchStats.filter(patch => patch.size > 0).map(patch => patch.patchPath);
|
|
580
577
|
if (nonEmptyPatches.length === 0) {
|
|
581
578
|
patchesApplied = true;
|
|
582
579
|
} else {
|
|
583
580
|
const patchTexts = await Promise.all(
|
|
584
|
-
nonEmptyPatches.map(async
|
|
581
|
+
nonEmptyPatches.map(async patchPath => Bun.file(patchPath).text()),
|
|
585
582
|
);
|
|
586
|
-
const combinedPatch = patchTexts.map(
|
|
583
|
+
const combinedPatch = patchTexts.map(text => (text.endsWith("\n") ? text : `${text}\n`)).join("");
|
|
587
584
|
if (!combinedPatch.trim()) {
|
|
588
585
|
patchesApplied = true;
|
|
589
586
|
} else {
|
|
590
|
-
const combinedPatchPath = path.join(tmpdir(), `omp-task-combined-${nanoid()}.patch`);
|
|
587
|
+
const combinedPatchPath = path.join(os.tmpdir(), `omp-task-combined-${nanoid()}.patch`);
|
|
591
588
|
try {
|
|
592
589
|
await Bun.write(combinedPatchPath, combinedPatch);
|
|
593
590
|
const checkResult = await $`git apply --check --binary ${combinedPatchPath}`
|
|
@@ -604,7 +601,7 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
|
|
|
604
601
|
patchesApplied = applyResult.exitCode === 0;
|
|
605
602
|
}
|
|
606
603
|
} finally {
|
|
607
|
-
await rm(combinedPatchPath, { force: true });
|
|
604
|
+
await fs.rm(combinedPatchPath, { force: true });
|
|
608
605
|
}
|
|
609
606
|
}
|
|
610
607
|
}
|
|
@@ -617,18 +614,18 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
|
|
|
617
614
|
"<system-notification>Patches were not applied and must be handled manually.</system-notification>";
|
|
618
615
|
const patchList =
|
|
619
616
|
patchPaths.length > 0
|
|
620
|
-
? `\n\nPatch artifacts:\n${patchPaths.map(
|
|
617
|
+
? `\n\nPatch artifacts:\n${patchPaths.map(patch => `- ${patch}`).join("\n")}`
|
|
621
618
|
: "";
|
|
622
619
|
patchApplySummary = `\n\n${notification}${patchList}`;
|
|
623
620
|
}
|
|
624
621
|
}
|
|
625
622
|
|
|
626
623
|
// Build final output - match plugin format
|
|
627
|
-
const successCount = results.filter(
|
|
628
|
-
const cancelledCount = results.filter(
|
|
624
|
+
const successCount = results.filter(r => r.exitCode === 0).length;
|
|
625
|
+
const cancelledCount = results.filter(r => r.aborted).length;
|
|
629
626
|
const totalDuration = Date.now() - startTime;
|
|
630
627
|
|
|
631
|
-
const summaries = results.map(
|
|
628
|
+
const summaries = results.map(r => {
|
|
632
629
|
const status = r.aborted ? "cancelled" : r.exitCode === 0 ? "completed" : `failed (exit ${r.exitCode})`;
|
|
633
630
|
const output = r.output.trim() || r.stderr.trim() || "(no output)";
|
|
634
631
|
const preview = output.split("\n").slice(0, 5).join("\n");
|
|
@@ -638,10 +635,10 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
|
|
|
638
635
|
return `[${r.agent}] ${status}${meta} ${r.id}\n${preview}`;
|
|
639
636
|
});
|
|
640
637
|
|
|
641
|
-
const outputIds = results.filter(
|
|
638
|
+
const outputIds = results.filter(r => !r.aborted || r.output.trim()).map(r => r.id);
|
|
642
639
|
const outputHint =
|
|
643
640
|
outputIds.length > 0
|
|
644
|
-
? `\n\nUse read with agent:// for full logs: ${outputIds.map(
|
|
641
|
+
? `\n\nUse read with agent:// for full logs: ${outputIds.map(id => `agent://${id}`).join(", ")}`
|
|
645
642
|
: "";
|
|
646
643
|
const schemaNote = schemaOverridden
|
|
647
644
|
? `\n\nNote: Agent '${agentName}' has a fixed output schema; your 'output' parameter was ignored.\nRequired schema: ${JSON.stringify(agent.output)}`
|
|
@@ -655,7 +652,7 @@ export class TaskTool implements AgentTool<typeof taskSchema, TaskToolDetails, T
|
|
|
655
652
|
const shouldCleanupTempArtifacts =
|
|
656
653
|
tempArtifactsDir && (!isIsolated || patchesApplied === true || patchesApplied === null);
|
|
657
654
|
if (shouldCleanupTempArtifacts) {
|
|
658
|
-
await rm(tempArtifactsDir, { recursive: true, force: true });
|
|
655
|
+
await fs.rm(tempArtifactsDir, { recursive: true, force: true });
|
|
659
656
|
}
|
|
660
657
|
|
|
661
658
|
return {
|
|
@@ -6,8 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* This enables reliable agent:// URL resolution and prevents artifact collisions.
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
|
-
import { readdir } from "node:fs/promises";
|
|
9
|
+
import * as fs from "node:fs/promises";
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* Manages agent output ID allocation to ensure uniqueness.
|
|
@@ -37,7 +36,7 @@ export class AgentOutputManager {
|
|
|
37
36
|
|
|
38
37
|
let files: string[];
|
|
39
38
|
try {
|
|
40
|
-
files = await readdir(dir);
|
|
39
|
+
files = await fs.readdir(dir);
|
|
41
40
|
} catch {
|
|
42
41
|
return; // Directory doesn't exist yet
|
|
43
42
|
}
|
|
@@ -73,7 +72,7 @@ export class AgentOutputManager {
|
|
|
73
72
|
*/
|
|
74
73
|
async allocateBatch(ids: string[]): Promise<string[]> {
|
|
75
74
|
await this.#ensureInitialized();
|
|
76
|
-
return ids.map(
|
|
75
|
+
return ids.map(id => `${this.#nextId++}-${id}`);
|
|
77
76
|
}
|
|
78
77
|
|
|
79
78
|
/**
|
package/src/task/parallel.ts
CHANGED
package/src/task/render.ts
CHANGED
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
* Provides renderCall and renderResult functions for displaying
|
|
5
5
|
* task execution in the terminal UI.
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
7
|
import path from "node:path";
|
|
9
|
-
import type {
|
|
10
|
-
import
|
|
8
|
+
import type { Component } from "@oh-my-pi/pi-tui";
|
|
9
|
+
import { Container, Text } from "@oh-my-pi/pi-tui";
|
|
10
|
+
import type { RenderResultOptions } from "../extensibility/custom-tools/types";
|
|
11
|
+
import type { Theme } from "../modes/theme/theme";
|
|
11
12
|
import {
|
|
12
13
|
formatBadge,
|
|
13
14
|
formatDuration,
|
|
@@ -15,17 +16,15 @@ import {
|
|
|
15
16
|
formatStatusIcon,
|
|
16
17
|
formatTokens,
|
|
17
18
|
truncate,
|
|
18
|
-
} from "
|
|
19
|
+
} from "../tools/render-utils";
|
|
19
20
|
import {
|
|
20
21
|
type FindingPriority,
|
|
21
22
|
getPriorityInfo,
|
|
22
23
|
PRIORITY_LABELS,
|
|
23
24
|
type ReportFindingDetails,
|
|
24
25
|
type SubmitReviewDetails,
|
|
25
|
-
} from "
|
|
26
|
-
import { renderStatusLine } from "
|
|
27
|
-
import type { Component } from "@oh-my-pi/pi-tui";
|
|
28
|
-
import { Container, Text } from "@oh-my-pi/pi-tui";
|
|
26
|
+
} from "../tools/review";
|
|
27
|
+
import { renderStatusLine } from "../tui";
|
|
29
28
|
import { subprocessToolRegistry } from "./subprocess-tool-registry";
|
|
30
29
|
import type { AgentProgress, SingleResult, TaskParams, TaskToolDetails } from "./types";
|
|
31
30
|
|
|
@@ -79,7 +78,7 @@ function formatJsonScalar(value: unknown, theme: Theme): string {
|
|
|
79
78
|
}
|
|
80
79
|
|
|
81
80
|
function buildTreePrefix(ancestors: boolean[], theme: Theme): string {
|
|
82
|
-
return ancestors.map(
|
|
81
|
+
return ancestors.map(hasNext => (hasNext ? `${theme.tree.vertical} ` : " ")).join("");
|
|
83
82
|
}
|
|
84
83
|
|
|
85
84
|
function renderJsonTreeLines(
|
|
@@ -295,7 +294,7 @@ function formatArgsInline(args: Record<string, string>, theme: Theme): string {
|
|
|
295
294
|
|
|
296
295
|
/** Convert snake_case or kebab-case to Title Case */
|
|
297
296
|
function humanizeKey(key: string): string {
|
|
298
|
-
return key.replace(/[-_]/g, " ").replace(/\b\w/g,
|
|
297
|
+
return key.replace(/[-_]/g, " ").replace(/\b\w/g, c => c.toUpperCase());
|
|
299
298
|
}
|
|
300
299
|
|
|
301
300
|
function formatScalarInline(value: unknown, maxLen: number, theme: Theme): string {
|
|
@@ -512,8 +511,8 @@ function renderAgentProgress(
|
|
|
512
511
|
const completeData = progress.extractedToolData.complete as Array<{ data: unknown }> | undefined;
|
|
513
512
|
const reportFindingData = progress.extractedToolData.report_finding as ReportFindingDetails[] | undefined;
|
|
514
513
|
const reviewData = completeData
|
|
515
|
-
?.map(
|
|
516
|
-
.filter(
|
|
514
|
+
?.map(c => c.data as SubmitReviewDetails)
|
|
515
|
+
.filter(d => d && typeof d === "object" && "overall_correctness" in d);
|
|
517
516
|
if (reviewData && reviewData.length > 0) {
|
|
518
517
|
const summary = reviewData[reviewData.length - 1];
|
|
519
518
|
const findings = reportFindingData ?? [];
|
|
@@ -697,8 +696,8 @@ function renderAgentResult(result: SingleResult, isLast: boolean, expanded: bool
|
|
|
697
696
|
|
|
698
697
|
// Extract review verdict from complete tool's data field if it matches SubmitReviewDetails
|
|
699
698
|
const reviewData = completeData
|
|
700
|
-
?.map(
|
|
701
|
-
.filter(
|
|
699
|
+
?.map(c => c.data as SubmitReviewDetails)
|
|
700
|
+
.filter(d => d && typeof d === "object" && "overall_correctness" in d);
|
|
702
701
|
const submitReviewData = reviewData && reviewData.length > 0 ? reviewData : undefined;
|
|
703
702
|
|
|
704
703
|
if (submitReviewData && submitReviewData.length > 0) {
|
|
@@ -775,12 +774,12 @@ export function renderResult(
|
|
|
775
774
|
theme: Theme,
|
|
776
775
|
): Component {
|
|
777
776
|
const { expanded, isPartial, spinnerFrame } = options;
|
|
778
|
-
const fallbackText = result.content.find(
|
|
777
|
+
const fallbackText = result.content.find(c => c.type === "text")?.text ?? "";
|
|
779
778
|
const details = result.details;
|
|
780
779
|
|
|
781
780
|
if (!details) {
|
|
782
781
|
// Fallback to simple text
|
|
783
|
-
const text = result.content.find(
|
|
782
|
+
const text = result.content.find(c => c.type === "text")?.text || "";
|
|
784
783
|
return new Text(theme.fg("dim", truncate(text, 100, theme.format.ellipsis)), 0, 0);
|
|
785
784
|
}
|
|
786
785
|
|
|
@@ -800,8 +799,8 @@ export function renderResult(
|
|
|
800
799
|
});
|
|
801
800
|
|
|
802
801
|
// Summary line
|
|
803
|
-
const abortedCount = details.results.filter(
|
|
804
|
-
const successCount = details.results.filter(
|
|
802
|
+
const abortedCount = details.results.filter(r => r.aborted).length;
|
|
803
|
+
const successCount = details.results.filter(r => !r.aborted && r.exitCode === 0).length;
|
|
805
804
|
const failCount = details.results.length - successCount - abortedCount;
|
|
806
805
|
let summary = `${theme.fg("dim", "Total:")} `;
|
|
807
806
|
if (abortedCount > 0) {
|
|
@@ -829,7 +828,7 @@ export function renderResult(
|
|
|
829
828
|
if (fallbackText.trim()) {
|
|
830
829
|
const summaryLines = fallbackText.split("\n");
|
|
831
830
|
const markerIndex = summaryLines.findIndex(
|
|
832
|
-
|
|
831
|
+
line => line.includes("<system-notification>") || line.startsWith("Applied patches:"),
|
|
833
832
|
);
|
|
834
833
|
if (markerIndex >= 0) {
|
|
835
834
|
const extra = summaryLines.slice(markerIndex);
|
|
@@ -840,7 +839,7 @@ export function renderResult(
|
|
|
840
839
|
}
|
|
841
840
|
}
|
|
842
841
|
|
|
843
|
-
const indented = lines.map(
|
|
842
|
+
const indented = lines.map(line => (line.length > 0 ? ` ${line}` : ""));
|
|
844
843
|
return new Text(indented.join("\n"), 0, 0);
|
|
845
844
|
}
|
|
846
845
|
|
|
@@ -6,9 +6,8 @@
|
|
|
6
6
|
* - Trigger subprocess termination on completion
|
|
7
7
|
* - Provide custom rendering for realtime/final display
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
|
-
import type { Theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
|
11
9
|
import type { Component } from "@oh-my-pi/pi-tui";
|
|
10
|
+
import type { Theme } from "../modes/theme/theme";
|
|
12
11
|
|
|
13
12
|
/** Event from subprocess tool execution (parsed from JSONL) */
|
|
14
13
|
export interface SubprocessToolEvent {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AgentEvent, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
2
|
-
import type { SerializedModelRegistry } from "
|
|
3
|
-
import type { Settings } from "
|
|
4
|
-
import type { SerializedAuthStorage } from "
|
|
2
|
+
import type { SerializedModelRegistry } from "../config/model-registry";
|
|
3
|
+
import type { Settings } from "../config/settings-manager";
|
|
4
|
+
import type { SerializedAuthStorage } from "../session/auth-storage";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* MCP tool metadata passed from parent to worker for proxy tool creation.
|