@selesai/code 0.8.6 → 0.8.8
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 +31 -1
- package/dist/cli/args.d.ts +1 -0
- package/dist/cli/args.js +11 -0
- package/dist/cli/args.test.d.ts +1 -0
- package/dist/cli/args.test.js +24 -0
- package/dist/core/agent-session.d.ts +4 -1
- package/dist/core/agent-session.js +18 -7
- package/dist/core/experimental.d.ts +4 -0
- package/dist/core/experimental.js +4 -0
- package/dist/core/extensions/types.d.ts +6 -0
- package/dist/core/keybindings.d.ts +24 -0
- package/dist/core/model-config.d.ts +5 -0
- package/dist/core/model-config.js +1 -0
- package/dist/core/project-trust.js +2 -2
- package/dist/core/provider-composer.js +17 -4
- package/dist/core/sdk.d.ts +5 -3
- package/dist/core/sdk.js +2 -1
- package/dist/core/session-manager.js +2 -2
- package/dist/core/settings-manager.d.ts +8 -0
- package/dist/core/settings-manager.js +15 -0
- package/dist/core/system-prompt.js +3 -9
- package/dist/core/system-prompt.test.js +6 -0
- package/dist/core/tools/bash.js +2 -0
- package/dist/core/tools/edit.js +2 -0
- package/dist/core/tools/find.js +1 -1
- package/dist/core/tools/grep.js +1 -1
- package/dist/core/tools/index.d.ts +1 -0
- package/dist/core/tools/index.js +1 -0
- package/dist/core/tools/read.js +2 -0
- package/dist/core/tools/schema-prune.d.ts +16 -0
- package/dist/core/tools/schema-prune.js +39 -0
- package/dist/core/tools/schema-prune.test.d.ts +1 -0
- package/dist/core/tools/schema-prune.test.js +111 -0
- package/dist/core/tools/write.js +2 -0
- package/dist/defaults/settings.json +1 -0
- package/dist/extensions/model-prompt-injector/config.json +10 -0
- package/dist/extensions/model-prompt-injector/index.test.ts +112 -0
- package/dist/extensions/model-prompt-injector/index.ts +151 -0
- package/dist/extensions/package.json +1 -0
- package/dist/extensions/pi-subagents/CHANGELOG.md +158 -90
- package/dist/extensions/pi-subagents/UPSTREAM-V0.50-MAPPING.md +172 -0
- package/dist/extensions/pi-subagents/agents/oracle.md +7 -5
- package/dist/extensions/pi-subagents/agents/reviewer.md +2 -2
- package/dist/extensions/pi-subagents/agents/scout.md +1 -1
- package/dist/extensions/pi-subagents/agents/worker.md +1 -1
- package/dist/extensions/pi-subagents/docs/configuration.md +78 -19
- package/dist/extensions/pi-subagents/docs/extension-api.md +36 -0
- package/dist/extensions/pi-subagents/docs/missions.md +5 -3
- package/dist/extensions/pi-subagents/docs/models.md +1 -1
- package/dist/extensions/pi-subagents/docs/observability.md +42 -2
- package/dist/extensions/pi-subagents/docs/tool-reference.md +20 -3
- package/dist/extensions/pi-subagents/docs/workflows.md +5 -5
- package/dist/extensions/pi-subagents/install.mjs +2 -2
- package/dist/extensions/pi-subagents/package-lock.json +1470 -1472
- package/dist/extensions/pi-subagents/package.json +1 -1
- package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +1 -1
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +5 -4
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +15 -14
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +5 -5
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +46 -26
- package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +2 -0
- package/dist/extensions/pi-subagents/src/agents/agents.ts +37 -12
- package/dist/extensions/pi-subagents/src/api/external-runs.ts +174 -84
- package/dist/extensions/pi-subagents/src/api/preflight.ts +13 -7
- package/dist/extensions/pi-subagents/src/extension/config.ts +53 -0
- package/dist/extensions/pi-subagents/src/extension/index.ts +67 -13
- package/dist/extensions/pi-subagents/src/extension/public-execution.ts +34 -6
- package/dist/extensions/pi-subagents/src/extension/rpc.ts +5 -1
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +31 -30
- package/dist/extensions/pi-subagents/src/extension/tool-description.ts +10 -9
- package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +13 -8
- package/dist/extensions/pi-subagents/src/inspectors/herdr/inspector-runner.ts +16 -3
- package/dist/extensions/pi-subagents/src/inspectors/herdr/project-panes.ts +2 -6
- package/dist/extensions/pi-subagents/src/inspectors/herdr/shell-command.ts +16 -0
- package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +5 -4
- package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +19 -42
- package/dist/extensions/pi-subagents/src/missions/goal-driver.ts +3 -1
- package/dist/extensions/pi-subagents/src/missions/store.ts +8 -3
- package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +82 -25
- package/dist/extensions/pi-subagents/src/runs/background/active-run-index.ts +71 -1
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +73 -43
- package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +5 -0
- package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +14 -6
- package/dist/extensions/pi-subagents/src/runs/background/async-status-snapshot.ts +277 -0
- package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +8 -3
- package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +2 -2
- package/dist/extensions/pi-subagents/src/runs/background/completion-replay.ts +11 -1
- package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +21 -6
- package/dist/extensions/pi-subagents/src/runs/background/result-files.ts +437 -0
- package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +187 -41
- package/dist/extensions/pi-subagents/src/runs/background/resume-guidance.ts +27 -7
- package/dist/extensions/pi-subagents/src/runs/background/retained-children.ts +76 -19
- package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +30 -24
- package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +101 -4
- package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +54 -28
- package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +27 -13
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +298 -33
- package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +2 -0
- package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +5 -2
- package/dist/extensions/pi-subagents/src/runs/foreground/async-dismiss-action.ts +2 -1
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +16 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +219 -15
- package/dist/extensions/pi-subagents/src/runs/foreground/prompt-audit.ts +4 -3
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +333 -45
- package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +107 -1
- package/dist/extensions/pi-subagents/src/runs/shared/external-cli-runner.ts +4 -0
- package/dist/extensions/pi-subagents/src/runs/shared/llm-intent-arbiter.ts +39 -23
- package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +16 -2
- package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +66 -62
- package/dist/extensions/pi-subagents/src/runs/shared/orca-progress-tabs.ts +376 -0
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +2 -0
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +15 -0
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +1 -9
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +12 -0
- package/dist/extensions/pi-subagents/src/runs/shared/tool-timeout.ts +95 -0
- package/dist/extensions/pi-subagents/src/shared/agent-stream-options.ts +5 -0
- package/dist/extensions/pi-subagents/src/shared/artifacts.ts +0 -4
- package/dist/extensions/pi-subagents/src/shared/display-text.ts +50 -0
- package/dist/extensions/pi-subagents/src/shared/node-executable.ts +21 -0
- package/dist/extensions/pi-subagents/src/shared/types.ts +50 -4
- package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +34 -25
- package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +4 -0
- package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +160 -45
- package/dist/extensions/pi-subagents/src/tui/fleet-transcript.ts +1 -48
- package/dist/extensions/pi-subagents/src/tui/fleet.ts +128 -16
- package/dist/extensions/pi-subagents/src/tui/render.ts +122 -44
- package/dist/extensions/pi-subagents/src/watchdog/permission-arbiter.ts +2 -1
- package/dist/extensions/pi-subagents/src/watchdog/review.ts +4 -3
- package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +10 -2
- package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +272 -76
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/types.d.ts +2 -0
- package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +68 -9
- package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +27 -1
- package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +49 -0
- package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +1 -0
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +26 -1
- package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +144 -0
- package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +26 -0
- package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +395 -98
- package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +111 -78
- package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +49 -1
- package/dist/extensions/pi-subagents/test/integration/slash-live-state.test.ts +12 -0
- package/dist/extensions/pi-subagents/test/support/node-command.ts +15 -0
- package/dist/extensions/pi-subagents/test/unit/active-async-capacity.test.ts +50 -0
- package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +28 -0
- package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +61 -0
- package/dist/extensions/pi-subagents/test/unit/agent-stream-options.test.ts +14 -0
- package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +76 -0
- package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +2 -0
- package/dist/extensions/pi-subagents/test/unit/async-status-snapshot.test.ts +162 -0
- package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +209 -10
- package/dist/extensions/pi-subagents/test/unit/completion-replay.test.ts +41 -1
- package/dist/extensions/pi-subagents/test/unit/external-runs.test.ts +135 -42
- package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +252 -1
- package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +192 -6
- package/dist/extensions/pi-subagents/test/unit/herdr-inspector-bootstrap.test.ts +32 -0
- package/dist/extensions/pi-subagents/test/unit/herdr-shell-command.test.ts +59 -0
- package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +69 -0
- package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +23 -4
- package/dist/extensions/pi-subagents/test/unit/llm-intent-arbiter.test.ts +56 -1
- package/dist/extensions/pi-subagents/test/unit/mission-goal-driver.test.ts +67 -3
- package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +14 -0
- package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +18 -0
- package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +25 -2
- package/dist/extensions/pi-subagents/test/unit/node-executable.test.ts +26 -0
- package/dist/extensions/pi-subagents/test/unit/notify.test.ts +8 -0
- package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +348 -0
- package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +5 -2
- package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +34 -0
- package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +6 -1
- package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +92 -0
- package/dist/extensions/pi-subagents/test/unit/result-files.test.ts +175 -0
- package/dist/extensions/pi-subagents/test/unit/retained-children.test.ts +127 -17
- package/dist/extensions/pi-subagents/test/unit/run-id-resolver.test.ts +44 -0
- package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +247 -0
- package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +107 -2
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +5 -8
- package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +456 -4
- package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +128 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +28 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +16 -7
- package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +15 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +79 -15
- package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +12 -12
- package/dist/extensions/pi-subagents/test/unit/tool-timeout.test.ts +109 -0
- package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +34 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +94 -1
- package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +42 -2
- package/dist/extensions/question/index.ts +21 -6
- package/dist/extensions/question/question-list.ts +7 -1
- package/dist/extensions/question/row-layout.ts +3 -0
- package/dist/extensions/question/tests/exp.test.ts +70 -0
- package/dist/extensions/question/tests/exp2.test.ts +59 -0
- package/dist/extensions/question/tests/exp3.test.ts +47 -0
- package/dist/extensions/question/tests/helpers.test.ts +7 -0
- package/dist/extensions/question/tests/question-list.test.ts +140 -0
- package/dist/extensions/question/tests/row-layout.test.ts +13 -0
- package/dist/extensions/question/tests/selection-mode.test.ts +54 -0
- package/dist/extensions/question/tests/zz-ig3.test.ts +20 -0
- package/dist/extensions/question/tests/zz-probe.test.ts +29 -0
- package/dist/extensions/tokenin-onboarding.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/main.js +4 -0
- package/dist/modes/interactive/components/model-selector.js +2 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
- package/dist/modes/interactive/components/settings-selector.js +10 -0
- package/dist/modes/interactive/components/tool-execution.js +10 -1
- package/dist/modes/interactive/interactive-mode.d.ts +8 -2
- package/dist/modes/interactive/interactive-mode.js +81 -25
- package/dist/modes/interactive/model-catalog-refresh.d.ts +6 -0
- package/dist/modes/interactive/model-catalog-refresh.js +33 -0
- package/dist/modes/interactive/theme/dark.json +2 -0
- package/dist/modes/interactive/theme/light.json +2 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts +10 -2
- package/dist/modes/interactive/theme/theme-controller.js +25 -11
- package/dist/modes/interactive/theme/theme-schema.json +9 -1
- package/dist/modes/interactive/theme/theme.d.ts +5 -3
- package/dist/modes/interactive/theme/theme.js +12 -2
- package/dist/skills/pi-subagents/SKILL.md +1 -1
- package/dist/skills/pi-subagents/references/constraints-and-recipes.md +5 -4
- package/dist/skills/pi-subagents/references/execution-controls.md +15 -14
- package/dist/skills/pi-subagents/references/management-authoring-rpc.md +5 -5
- package/dist/skills/pi-subagents/references/prompting-and-roles.md +46 -26
- package/dist/utils/abort.d.ts +4 -0
- package/dist/utils/abort.js +47 -0
- package/dist/utils/tools-manager.d.ts +5 -1
- package/dist/utils/tools-manager.js +12 -21
- package/docs/settings.md +6 -0
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@selesai/code` will be documented in this file.
|
|
4
4
|
|
|
5
|
-
## [
|
|
5
|
+
## [0.8.8] - 2026-08-18
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **`--use-theme <name>` CLI flag.** Sets the initial interactive theme for a run; the fullscreen theme controller applies an invocation-level theme before settings load, so the flag wins until you change the theme in `/settings`.
|
|
9
|
+
- **Transcript search highlighting.** The fullscreen TUI now highlights search matches live in the transcript, themeable via new optional `searchMatchBg`/`searchMatchText` colors (falling back to `selectedBg`/`text`).
|
|
10
|
+
- **Fullscreen exit output option.** `/settings` gained a **Fullscreen exit output** entry: exiting fullscreen can print the transcript as before (`"transcript"`) or only a session resume hint (`"resume-hint"`) via the new `fullscreenExitOutput` setting.
|
|
11
|
+
- **`defaultTools` setting.** Seeds the initial built-in tool selection for `createAgentSession`; when set, new sessions start with only the listed tools instead of the `read`/`bash`/`edit`/`write` default.
|
|
12
|
+
- **`sendUserMessage` template expansion.** Extensions can pass `expandPromptTemplates: true` to dispatch extension commands and expand skill commands/prompt templates from a sent user message.
|
|
13
|
+
- **Experimental strict tool sampling.** Under `PI_EXPERIMENTAL=1`, the built-in read/edit/write/bash tools request `json_schema` tool output with `strict: "prefer"`.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- **Managed-tool downloads moved off the startup path.** The TUI mounts and stays responsive while `fd`/`rg` install; download progress and warnings are reported as chat status lines (with an `app.tools.expand` hint) instead of raw `console.log` output, and the interactive startup accepts input (with interrupt/exit/submit feedback) while it completes.
|
|
17
|
+
- **Collapsed large tool output.** Tool components now preview only the first 10 lines with an inline `... (N more lines)` expand hint instead of dumping the whole block.
|
|
18
|
+
- **Shared model-catalog refreshes.** Concurrent interactive all-catalog refreshes reuse one in-flight refresh while keeping each caller's cancellation independent, and refreshes are bounded by a short timeout.
|
|
19
|
+
- **Runtime dependencies updated to Pi 0.84.2.** `@earendil-works/pi-ai`, `@earendil-works/pi-tui`, and `@earendil-works/pi-agent-core` moved to 0.84.2; `openAIResponses` model config gained an optional `supportsAdditionalTools` flag; `exportToHtml` accepts a `themeName` option.
|
|
20
|
+
|
|
21
|
+
## [0.8.7] - 2026-08-17
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
- **Pi Subagents updated through upstream 0.50.0.** The bundled extension advances through upstream 0.49/0.50 (single-child `{ agent, task }` runs, per-tool-call `toolTimeoutMs` with config/env precedence, `debug.run` inspection, builtin role overrides with `tools: "inherit"`, resumable retained-child listings, indexed async result inboxes) with the Selesai fork layers on top: branding, `.selesai` config routing, `SELESAI_SUBAGENT*` env vars, declarative `chain`/`tasks`/`clarify` modes, workflow auto-relaunch wiring, and same-model retry for transient provider errors.
|
|
25
|
+
- **`model-prompt-injector` extension.** Bundled and registered in the extensions manifest, it injects model-specific prompts into the system prompt when the active model matches a configured rule (provider/model globs, bare id/name patterns, first-match-wins, enabled toggle). Modes: `prepend`, `append`, or `replace`.
|
|
26
|
+
- **Wire-level tool schema pruning.** `pruneToolDescriptions` (default `true`) strips every per-field `description` from tool input schemas before they reach the model, keeping one-line tool descriptions. Stripped schemas are memoized and never mutated; UI/docs definitions keep full descriptions; `keepParameterDescriptions` opts a tool out.
|
|
27
|
+
- **Compact subagent tool description by default.** `toolDescriptionMode` now defaults to `"compact"` (~3.2 KB vs ~6.3 KB per model turn), and a missing/invalid custom description file falls back to compact.
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
- **Slimmer default system prompt.** The always-on Pi-docs block shrank from 8 lines to 2 (paths only); docs are still read on demand when the user asks about pi.
|
|
31
|
+
- **Bundled defaults** now set `pruneToolDescriptions: true`.
|
|
32
|
+
- **Test coverage.** `src/extensions` (pi-* excluded) now enforces 100% stmt/branch/func/line coverage via vitest thresholds; `safeMaxTokens()` clamps missing/oversized context-window metadata to a sane default.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
- **Subagent prompt-runtime suite passes inside subagent child environments.** The watchdog-lifecycle test now scrubs the steer env vars (`SELESAI_SUBAGENT_STEER_*`) before registering, so the steering inbox's extra `agent_end` handler cannot skew the handler count.
|
|
6
36
|
|
|
7
37
|
## [0.8.6] - 2026-08-15
|
|
8
38
|
|
package/dist/cli/args.d.ts
CHANGED
package/dist/cli/args.js
CHANGED
|
@@ -142,6 +142,16 @@ export function parseArgs(args) {
|
|
|
142
142
|
else if (arg === "--no-prompt-templates" || arg === "-np") {
|
|
143
143
|
result.noPromptTemplates = true;
|
|
144
144
|
}
|
|
145
|
+
else if (arg === "--use-theme") {
|
|
146
|
+
const themeName = args[i + 1];
|
|
147
|
+
if (themeName === undefined || themeName.startsWith("-")) {
|
|
148
|
+
result.diagnostics.push({ type: "error", message: "--use-theme requires a theme name" });
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
result.useTheme = themeName;
|
|
152
|
+
i++;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
145
155
|
else if (arg === "--no-themes") {
|
|
146
156
|
result.noThemes = true;
|
|
147
157
|
}
|
|
@@ -272,6 +282,7 @@ ${chalk.bold("Options:")}
|
|
|
272
282
|
--prompt-template <path> Load a prompt template file or directory (can be used multiple times)
|
|
273
283
|
--no-prompt-templates, -np Disable prompt template discovery and loading
|
|
274
284
|
--theme <path> Load a theme file or directory (can be used multiple times)
|
|
285
|
+
--use-theme <name[/name]> Set the initial interactive theme for this run
|
|
275
286
|
--no-themes Disable theme discovery and loading
|
|
276
287
|
--no-context-files, -nc Disable AGENTS.md and CLAUDE.md discovery and loading
|
|
277
288
|
--export <file> Export session file to HTML and exit
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import { parseArgs } from "./args.js";
|
|
3
|
+
describe("parseArgs --use-theme", () => {
|
|
4
|
+
test("parses --use-theme with a theme name", () => {
|
|
5
|
+
const result = parseArgs(["--use-theme", "nord-border", "hello"]);
|
|
6
|
+
expect(result.useTheme).toBe("nord-border");
|
|
7
|
+
expect(result.messages).toEqual(["hello"]);
|
|
8
|
+
});
|
|
9
|
+
test("accepts light/dark slash form", () => {
|
|
10
|
+
const result = parseArgs(["--use-theme", "light/dark"]);
|
|
11
|
+
expect(result.useTheme).toBe("light/dark");
|
|
12
|
+
});
|
|
13
|
+
test("reports an error when --use-theme is missing a theme name", () => {
|
|
14
|
+
const result = parseArgs(["--use-theme"]);
|
|
15
|
+
expect(result.useTheme).toBeUndefined();
|
|
16
|
+
expect(result.diagnostics.some((d) => d.type === "error")).toBe(true);
|
|
17
|
+
});
|
|
18
|
+
test("reports an error when --use-theme precedes a flag", () => {
|
|
19
|
+
const result = parseArgs(["--use-theme", "--no-session"]);
|
|
20
|
+
expect(result.useTheme).toBeUndefined();
|
|
21
|
+
expect(result.noSession).toBe(true);
|
|
22
|
+
expect(result.diagnostics.some((d) => d.type === "error")).toBe(true);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -423,6 +423,7 @@ export declare class AgentSession {
|
|
|
423
423
|
*/
|
|
424
424
|
sendUserMessage(content: string | (TextContent | ImageContent)[], options?: {
|
|
425
425
|
deliverAs?: "steer" | "followUp";
|
|
426
|
+
expandPromptTemplates?: boolean;
|
|
426
427
|
}): Promise<void>;
|
|
427
428
|
/**
|
|
428
429
|
* Clear all queued messages and return them.
|
|
@@ -634,7 +635,9 @@ export declare class AgentSession {
|
|
|
634
635
|
* @param outputPath Optional output path (defaults to session directory)
|
|
635
636
|
* @returns Path to exported file
|
|
636
637
|
*/
|
|
637
|
-
exportToHtml(outputPath?: string
|
|
638
|
+
exportToHtml(outputPath?: string, options?: {
|
|
639
|
+
themeName?: string;
|
|
640
|
+
}): Promise<string>;
|
|
638
641
|
/**
|
|
639
642
|
* Export the current session branch to a JSONL file.
|
|
640
643
|
* Writes the session header followed by all entries on the current branch path.
|
|
@@ -35,7 +35,7 @@ import { CURRENT_SESSION_VERSION, getLatestCompactionEntry } from "./session-man
|
|
|
35
35
|
import { createSyntheticSourceInfo } from "./source-info.js";
|
|
36
36
|
import { buildSystemPrompt } from "./system-prompt.js";
|
|
37
37
|
import { createLocalBashOperations } from "./tools/bash.js";
|
|
38
|
-
import { createAllToolDefinitions } from "./tools/index.js";
|
|
38
|
+
import { createAllToolDefinitions, stripToolParameterDescriptions } from "./tools/index.js";
|
|
39
39
|
import { createToolDefinitionFromAgentTool } from "./tools/tool-definition-wrapper.js";
|
|
40
40
|
import { addUsageToTotals, createUsageTotals } from "./usage-totals.js";
|
|
41
41
|
/** Parse consecutive skill blocks at the start of a user message. */
|
|
@@ -1133,7 +1133,7 @@ export class AgentSession {
|
|
|
1133
1133
|
if (options?.deliverAs === "nextTurn") {
|
|
1134
1134
|
this._pendingNextTurnMessages.push(appMessage);
|
|
1135
1135
|
}
|
|
1136
|
-
else if (this.isStreaming) {
|
|
1136
|
+
else if (this.isStreaming && options?.triggerTurn !== false) {
|
|
1137
1137
|
if (options?.deliverAs === "followUp") {
|
|
1138
1138
|
this.agent.followUp(appMessage);
|
|
1139
1139
|
}
|
|
@@ -1180,9 +1180,9 @@ export class AgentSession {
|
|
|
1180
1180
|
if (images.length === 0)
|
|
1181
1181
|
images = undefined;
|
|
1182
1182
|
}
|
|
1183
|
-
// Use prompt() with expandPromptTemplates
|
|
1183
|
+
// Use prompt() with expandPromptTemplates to control command handling and template expansion
|
|
1184
1184
|
await this.prompt(text, {
|
|
1185
|
-
expandPromptTemplates: false,
|
|
1185
|
+
expandPromptTemplates: options?.expandPromptTemplates ?? false,
|
|
1186
1186
|
streamingBehavior: options?.deliverAs,
|
|
1187
1187
|
images,
|
|
1188
1188
|
source: "extension",
|
|
@@ -2056,6 +2056,18 @@ export class AgentSession {
|
|
|
2056
2056
|
toolRegistry.set(tool.name, tool);
|
|
2057
2057
|
}
|
|
2058
2058
|
this._toolRegistry = toolRegistry;
|
|
2059
|
+
if (this.settingsManager.getPruneToolDescriptions()) {
|
|
2060
|
+
const keepDescriptions = new Set();
|
|
2061
|
+
for (const [name, entry] of definitionRegistry) {
|
|
2062
|
+
if (entry.definition.keepParameterDescriptions)
|
|
2063
|
+
keepDescriptions.add(name);
|
|
2064
|
+
}
|
|
2065
|
+
for (const [name, tool] of toolRegistry) {
|
|
2066
|
+
if (!keepDescriptions.has(name)) {
|
|
2067
|
+
toolRegistry.set(name, stripToolParameterDescriptions(tool));
|
|
2068
|
+
}
|
|
2069
|
+
}
|
|
2070
|
+
}
|
|
2059
2071
|
const nextActiveToolNames = (options?.activeToolNames ? [...options.activeToolNames] : [...previousActiveToolNames]).filter((name) => isAllowedTool(name));
|
|
2060
2072
|
if (allowedToolNames) {
|
|
2061
2073
|
for (const toolName of this._toolRegistry.keys()) {
|
|
@@ -2647,9 +2659,8 @@ export class AgentSession {
|
|
|
2647
2659
|
* @param outputPath Optional output path (defaults to session directory)
|
|
2648
2660
|
* @returns Path to exported file
|
|
2649
2661
|
*/
|
|
2650
|
-
async exportToHtml(outputPath) {
|
|
2651
|
-
const
|
|
2652
|
-
const themeName = configuredThemeName && getThemeByName(configuredThemeName) ? configuredThemeName : undefined;
|
|
2662
|
+
async exportToHtml(outputPath, options = {}) {
|
|
2663
|
+
const themeName = [options.themeName, this.settingsManager.getTheme()].find((candidate) => candidate !== undefined && getThemeByName(candidate) !== undefined);
|
|
2653
2664
|
// Create tool renderer if we have an extension runner (for custom tool HTML rendering)
|
|
2654
2665
|
const toolRenderer = createToolHtmlRenderer({
|
|
2655
2666
|
getToolDefinition: (name) => this.getToolDefinition(name),
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
const PREFER_STRICT_TOOL_SAMPLING = { type: "json_schema", strict: "prefer" };
|
|
1
2
|
export function areExperimentalFeaturesEnabled() {
|
|
2
3
|
return process.env.PI_EXPERIMENTAL === "1";
|
|
3
4
|
}
|
|
5
|
+
export function getExperimentalToolSampling() {
|
|
6
|
+
return areExperimentalFeaturesEnabled() ? PREFER_STRICT_TOOL_SAMPLING : undefined;
|
|
7
|
+
}
|
|
@@ -301,6 +301,7 @@ export interface ReplacedSessionContext extends ExtensionCommandContext {
|
|
|
301
301
|
}): Promise<void>;
|
|
302
302
|
sendUserMessage(content: string | (TextContent | ImageContent)[], options?: {
|
|
303
303
|
deliverAs?: "steer" | "followUp";
|
|
304
|
+
expandPromptTemplates?: boolean;
|
|
304
305
|
}): Promise<void>;
|
|
305
306
|
}
|
|
306
307
|
/** Rendering options for tool results */
|
|
@@ -353,6 +354,8 @@ export interface ToolDefinition<TParams extends TSchema = TSchema, TDetails = un
|
|
|
353
354
|
promptGuidelines?: string[];
|
|
354
355
|
/** Parameter schema (TypeBox) */
|
|
355
356
|
parameters: TParams;
|
|
357
|
+
/** When global pruneToolDescriptions is enabled, keep this tool's per-field parameter descriptions on the wire (already pruned by the tool itself). */
|
|
358
|
+
keepParameterDescriptions?: boolean;
|
|
356
359
|
/** Optional provider-side constrained sampling request for this tool. Set false to explicitly disable it, equivalent to leaving it undefined. */
|
|
357
360
|
constrainedSampling?: false | ConstrainedSamplingConfig;
|
|
358
361
|
/** Controls whether ToolExecutionComponent renders the standard colored shell or the tool renders its own framing. */
|
|
@@ -924,9 +927,11 @@ export interface ExtensionAPI {
|
|
|
924
927
|
/**
|
|
925
928
|
* Send a user message to the agent. Always triggers a turn.
|
|
926
929
|
* When the agent is streaming, use deliverAs to specify how to queue the message.
|
|
930
|
+
* Set expandPromptTemplates to dispatch extension commands and expand skill commands and prompt templates.
|
|
927
931
|
*/
|
|
928
932
|
sendUserMessage(content: string | (TextContent | ImageContent)[], options?: {
|
|
929
933
|
deliverAs?: "steer" | "followUp";
|
|
934
|
+
expandPromptTemplates?: boolean;
|
|
930
935
|
}): void;
|
|
931
936
|
/** Append a custom entry to the session for state persistence (not sent to LLM). */
|
|
932
937
|
appendEntry<T = unknown>(customType: string, data?: T): void;
|
|
@@ -1122,6 +1127,7 @@ export type SendMessageHandler = <T = unknown>(message: Pick<CustomMessage<T>, "
|
|
|
1122
1127
|
}) => void;
|
|
1123
1128
|
export type SendUserMessageHandler = (content: string | (TextContent | ImageContent)[], options?: {
|
|
1124
1129
|
deliverAs?: "steer" | "followUp";
|
|
1130
|
+
expandPromptTemplates?: boolean;
|
|
1125
1131
|
}) => void;
|
|
1126
1132
|
export type AppendEntryHandler = <T = unknown>(customType: string, data?: T) => void;
|
|
1127
1133
|
export type SetSessionNameHandler = (name: string) => void;
|
|
@@ -197,6 +197,14 @@ export declare const KEYBINDINGS: {
|
|
|
197
197
|
readonly defaultKeys: [];
|
|
198
198
|
readonly description: "Scroll viewport down half a page";
|
|
199
199
|
};
|
|
200
|
+
readonly "tui.altScreen.lineUp": {
|
|
201
|
+
readonly defaultKeys: [];
|
|
202
|
+
readonly description: "Scroll viewport up one line";
|
|
203
|
+
};
|
|
204
|
+
readonly "tui.altScreen.lineDown": {
|
|
205
|
+
readonly defaultKeys: [];
|
|
206
|
+
readonly description: "Scroll viewport down one line";
|
|
207
|
+
};
|
|
200
208
|
readonly "tui.altScreen.previousPrompt": {
|
|
201
209
|
readonly defaultKeys: "ctrl+shift+up";
|
|
202
210
|
readonly description: "Jump to previous semantic prompt";
|
|
@@ -205,6 +213,22 @@ export declare const KEYBINDINGS: {
|
|
|
205
213
|
readonly defaultKeys: "ctrl+shift+down";
|
|
206
214
|
readonly description: "Jump to next semantic prompt";
|
|
207
215
|
};
|
|
216
|
+
readonly "tui.altScreen.search": {
|
|
217
|
+
readonly defaultKeys: "ctrl+shift+f";
|
|
218
|
+
readonly description: "Search the primary scroll view";
|
|
219
|
+
};
|
|
220
|
+
readonly "tui.altScreen.searchNext": {
|
|
221
|
+
readonly defaultKeys: ["enter", "ctrl+g"];
|
|
222
|
+
readonly description: "Select the next search match";
|
|
223
|
+
};
|
|
224
|
+
readonly "tui.altScreen.searchPrevious": {
|
|
225
|
+
readonly defaultKeys: ["shift+enter", "ctrl+shift+g"];
|
|
226
|
+
readonly description: "Select the previous search match";
|
|
227
|
+
};
|
|
228
|
+
readonly "tui.altScreen.searchClose": {
|
|
229
|
+
readonly defaultKeys: "escape";
|
|
230
|
+
readonly description: "Close transcript search";
|
|
231
|
+
};
|
|
208
232
|
readonly "tui.altScreen.top": {
|
|
209
233
|
readonly defaultKeys: "home";
|
|
210
234
|
readonly description: "Scroll viewport to top";
|
|
@@ -98,6 +98,7 @@ declare const ModelDefinitionSchema: Type.TObject<{
|
|
|
98
98
|
supportsLongCacheRetention: Type.TOptional<Type.TBoolean>;
|
|
99
99
|
supportsStrictMode: Type.TOptional<Type.TBoolean>;
|
|
100
100
|
supportsOpenAIGrammarTools: Type.TOptional<Type.TBoolean>;
|
|
101
|
+
supportsAdditionalTools: Type.TOptional<Type.TBoolean>;
|
|
101
102
|
supportsToolSearch: Type.TOptional<Type.TBoolean>;
|
|
102
103
|
}>, Type.TObject<{
|
|
103
104
|
supportsEagerToolInputStreaming: Type.TOptional<Type.TBoolean>;
|
|
@@ -206,6 +207,7 @@ declare const ModelOverrideSchema: Type.TObject<{
|
|
|
206
207
|
supportsLongCacheRetention: Type.TOptional<Type.TBoolean>;
|
|
207
208
|
supportsStrictMode: Type.TOptional<Type.TBoolean>;
|
|
208
209
|
supportsOpenAIGrammarTools: Type.TOptional<Type.TBoolean>;
|
|
210
|
+
supportsAdditionalTools: Type.TOptional<Type.TBoolean>;
|
|
209
211
|
supportsToolSearch: Type.TOptional<Type.TBoolean>;
|
|
210
212
|
}>, Type.TObject<{
|
|
211
213
|
supportsEagerToolInputStreaming: Type.TOptional<Type.TBoolean>;
|
|
@@ -292,6 +294,7 @@ declare const ProviderConfigSchema: Type.TObject<{
|
|
|
292
294
|
supportsLongCacheRetention: Type.TOptional<Type.TBoolean>;
|
|
293
295
|
supportsStrictMode: Type.TOptional<Type.TBoolean>;
|
|
294
296
|
supportsOpenAIGrammarTools: Type.TOptional<Type.TBoolean>;
|
|
297
|
+
supportsAdditionalTools: Type.TOptional<Type.TBoolean>;
|
|
295
298
|
supportsToolSearch: Type.TOptional<Type.TBoolean>;
|
|
296
299
|
}>, Type.TObject<{
|
|
297
300
|
supportsEagerToolInputStreaming: Type.TOptional<Type.TBoolean>;
|
|
@@ -403,6 +406,7 @@ declare const ProviderConfigSchema: Type.TObject<{
|
|
|
403
406
|
supportsLongCacheRetention: Type.TOptional<Type.TBoolean>;
|
|
404
407
|
supportsStrictMode: Type.TOptional<Type.TBoolean>;
|
|
405
408
|
supportsOpenAIGrammarTools: Type.TOptional<Type.TBoolean>;
|
|
409
|
+
supportsAdditionalTools: Type.TOptional<Type.TBoolean>;
|
|
406
410
|
supportsToolSearch: Type.TOptional<Type.TBoolean>;
|
|
407
411
|
}>, Type.TObject<{
|
|
408
412
|
supportsEagerToolInputStreaming: Type.TOptional<Type.TBoolean>;
|
|
@@ -511,6 +515,7 @@ declare const ProviderConfigSchema: Type.TObject<{
|
|
|
511
515
|
supportsLongCacheRetention: Type.TOptional<Type.TBoolean>;
|
|
512
516
|
supportsStrictMode: Type.TOptional<Type.TBoolean>;
|
|
513
517
|
supportsOpenAIGrammarTools: Type.TOptional<Type.TBoolean>;
|
|
518
|
+
supportsAdditionalTools: Type.TOptional<Type.TBoolean>;
|
|
514
519
|
supportsToolSearch: Type.TOptional<Type.TBoolean>;
|
|
515
520
|
}>, Type.TObject<{
|
|
516
521
|
supportsEagerToolInputStreaming: Type.TOptional<Type.TBoolean>;
|
|
@@ -96,6 +96,7 @@ const OpenAIResponsesCompatSchema = Type.Object({
|
|
|
96
96
|
supportsLongCacheRetention: Type.Optional(Type.Boolean()),
|
|
97
97
|
supportsStrictMode: Type.Optional(Type.Boolean()),
|
|
98
98
|
supportsOpenAIGrammarTools: Type.Optional(Type.Boolean()),
|
|
99
|
+
supportsAdditionalTools: Type.Optional(Type.Boolean()),
|
|
99
100
|
supportsToolSearch: Type.Optional(Type.Boolean()),
|
|
100
101
|
});
|
|
101
102
|
const AnthropicMessagesCompatSchema = Type.Object({
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { CONFIG_DIR_NAME } from "../config.js";
|
|
1
|
+
import { APP_NAME, CONFIG_DIR_NAME } from "../config.js";
|
|
2
2
|
import { emitProjectTrustEvent } from "./extensions/runner.js";
|
|
3
3
|
import { getProjectTrustOptions, hasTrustRequiringProjectResources, } from "./trust-manager.js";
|
|
4
4
|
function formatProjectTrustPrompt(cwd) {
|
|
5
|
-
return `Trust project folder?\n${cwd}\n\nThis allows
|
|
5
|
+
return `Trust project folder?\n${cwd}\n\nThis allows ${APP_NAME} to load ${CONFIG_DIR_NAME} settings and resources, install missing project packages, and execute project extensions.`;
|
|
6
6
|
}
|
|
7
7
|
async function selectProjectTrustOption(cwd, ctx) {
|
|
8
8
|
const options = getProjectTrustOptions(cwd, { includeSessionOnly: true });
|
|
@@ -2,6 +2,17 @@ import { lazyStream, } from "@earendil-works/pi-ai";
|
|
|
2
2
|
import { getApiProvider } from "@earendil-works/pi-ai/compat";
|
|
3
3
|
import { clearConfigValueCache, getConfigValueEnvVarNames, isCommandConfigValue, isConfigValueConfigured, resolveConfigValueOrThrow, resolveHeadersOrThrow, } from "./resolve-config-value.js";
|
|
4
4
|
export const clearApiKeyCache = clearConfigValueCache;
|
|
5
|
+
/** Sane default when a model definition omits maxTokens (kept small so providers never reject it). */
|
|
6
|
+
const DEFAULT_MAX_TOKENS = 16384;
|
|
7
|
+
/**
|
|
8
|
+
* Resolve a safe max output token count. Missing or non-positive values fall back
|
|
9
|
+
* (to a sane default or an inherited value); explicit values are never allowed to
|
|
10
|
+
* exceed the model's context window.
|
|
11
|
+
*/
|
|
12
|
+
function safeMaxTokens(value, contextWindow, fallback = DEFAULT_MAX_TOKENS) {
|
|
13
|
+
const resolved = typeof value === "number" && value > 0 ? value : fallback;
|
|
14
|
+
return Math.min(resolved, Math.max(contextWindow, 1));
|
|
15
|
+
}
|
|
5
16
|
function mergeCompat(base, override) {
|
|
6
17
|
if (!override)
|
|
7
18
|
return base;
|
|
@@ -20,6 +31,7 @@ function mergeCompat(base, override) {
|
|
|
20
31
|
return merged;
|
|
21
32
|
}
|
|
22
33
|
function applyModelOverride(model, override) {
|
|
34
|
+
const contextWindow = override.contextWindow ?? model.contextWindow;
|
|
23
35
|
return {
|
|
24
36
|
...model,
|
|
25
37
|
name: override.name ?? model.name,
|
|
@@ -37,8 +49,8 @@ function applyModelOverride(model, override) {
|
|
|
37
49
|
tiers: override.cost.tiers ?? model.cost.tiers,
|
|
38
50
|
}
|
|
39
51
|
: model.cost,
|
|
40
|
-
contextWindow
|
|
41
|
-
maxTokens: override.maxTokens ?? model.maxTokens,
|
|
52
|
+
contextWindow,
|
|
53
|
+
maxTokens: safeMaxTokens(override.maxTokens ?? model.maxTokens, contextWindow, model.maxTokens),
|
|
42
54
|
compat: mergeCompat(model.compat, override.compat),
|
|
43
55
|
};
|
|
44
56
|
}
|
|
@@ -56,6 +68,7 @@ function modelFromJson(providerId, definition, providerConfig, defaults) {
|
|
|
56
68
|
if (definition.maxTokens !== undefined && definition.maxTokens <= 0) {
|
|
57
69
|
throw new Error(`Provider ${providerId}, model ${definition.id}: invalid maxTokens`);
|
|
58
70
|
}
|
|
71
|
+
const contextWindow = definition.contextWindow ?? 128000;
|
|
59
72
|
return {
|
|
60
73
|
id: definition.id,
|
|
61
74
|
name: definition.name ?? definition.id,
|
|
@@ -66,8 +79,8 @@ function modelFromJson(providerId, definition, providerConfig, defaults) {
|
|
|
66
79
|
thinkingLevelMap: definition.thinkingLevelMap,
|
|
67
80
|
input: (definition.input ?? ["text"]),
|
|
68
81
|
cost: definition.cost ?? { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
69
|
-
contextWindow
|
|
70
|
-
maxTokens: definition.maxTokens
|
|
82
|
+
contextWindow,
|
|
83
|
+
maxTokens: safeMaxTokens(definition.maxTokens, contextWindow),
|
|
71
84
|
headers: undefined,
|
|
72
85
|
compat: mergeCompat(providerConfig.compat, definition.compat),
|
|
73
86
|
};
|
package/dist/core/sdk.d.ts
CHANGED
|
@@ -34,9 +34,11 @@ export interface CreateAgentSessionOptions {
|
|
|
34
34
|
/**
|
|
35
35
|
* Optional allowlist of tool names.
|
|
36
36
|
*
|
|
37
|
-
* When omitted, pi
|
|
38
|
-
*
|
|
39
|
-
*
|
|
37
|
+
* When omitted, pi uses the `defaultTools` setting for the initial built-in
|
|
38
|
+
* selection when configured. Otherwise it enables the default built-in tools
|
|
39
|
+
* (read, bash, edit, write). Extension/custom tools remain enabled unless
|
|
40
|
+
* `noTools` changes that default. When provided, only the listed tool names are
|
|
41
|
+
* enabled.
|
|
40
42
|
*/
|
|
41
43
|
tools?: string[];
|
|
42
44
|
/** Optional denylist of tool names to disable. Applies after `tools` when both are provided. */
|
package/dist/core/sdk.js
CHANGED
|
@@ -130,10 +130,11 @@ export async function createAgentSession(options = {}) {
|
|
|
130
130
|
thinkingLevel = clampThinkingLevel(model, thinkingLevel);
|
|
131
131
|
}
|
|
132
132
|
const defaultActiveToolNames = ["read", "bash", "edit", "write"];
|
|
133
|
+
const configuredDefaultToolNames = settingsManager.getDefaultTools();
|
|
133
134
|
const allowedToolNames = options.tools ?? (options.noTools === "all" ? [] : undefined);
|
|
134
135
|
const excludedToolNames = options.excludeTools;
|
|
135
136
|
const excludedToolNameSet = excludedToolNames ? new Set(excludedToolNames) : undefined;
|
|
136
|
-
const initialActiveToolNames = (options.tools
|
|
137
|
+
const initialActiveToolNames = (options.tools ?? (options.noTools ? [] : (configuredDefaultToolNames ?? defaultActiveToolNames))).filter((name) => !excludedToolNameSet?.has(name));
|
|
137
138
|
let agent;
|
|
138
139
|
// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)
|
|
139
140
|
const convertToLlmWithBlockImages = (messages) => {
|
|
@@ -5,7 +5,7 @@ import { readdir, stat } from "fs/promises";
|
|
|
5
5
|
import { join, resolve } from "path";
|
|
6
6
|
import { createInterface } from "readline";
|
|
7
7
|
import { StringDecoder } from "string_decoder";
|
|
8
|
-
import { getAgentDir as getDefaultAgentDir, getSessionsDir } from "../config.js";
|
|
8
|
+
import { APP_NAME, getAgentDir as getDefaultAgentDir, getSessionsDir } from "../config.js";
|
|
9
9
|
import { normalizePath, resolvePath } from "../utils/paths.js";
|
|
10
10
|
import { createBranchSummaryMessage, createCompactionSummaryMessage, createCustomMessage, } from "./messages.js";
|
|
11
11
|
export const CURRENT_SESSION_VERSION = 3;
|
|
@@ -620,7 +620,7 @@ export class SessionManager {
|
|
|
620
620
|
if (this.fileEntries.length === 0) {
|
|
621
621
|
const explicitPath = this.sessionFile;
|
|
622
622
|
if (statSync(explicitPath).size > 0) {
|
|
623
|
-
throw new Error(`Session file is not a valid
|
|
623
|
+
throw new Error(`Session file is not a valid ${APP_NAME} session: ${explicitPath}`);
|
|
624
624
|
}
|
|
625
625
|
this.newSession();
|
|
626
626
|
this.sessionFile = explicitPath;
|
|
@@ -22,6 +22,7 @@ export interface RetrySettings {
|
|
|
22
22
|
provider?: ProviderRetrySettings;
|
|
23
23
|
}
|
|
24
24
|
export type TuiMode = RendererTuiMode;
|
|
25
|
+
export type FullscreenExitOutput = "transcript" | "resume-hint";
|
|
25
26
|
export interface TerminalSettings {
|
|
26
27
|
showImages?: boolean;
|
|
27
28
|
imageWidthCells?: number;
|
|
@@ -77,6 +78,7 @@ export interface Settings {
|
|
|
77
78
|
branchSummary?: BranchSummarySettings;
|
|
78
79
|
retry?: RetrySettings;
|
|
79
80
|
hideThinkingBlock?: boolean;
|
|
81
|
+
pruneToolDescriptions?: boolean;
|
|
80
82
|
showCacheMissNotices?: boolean;
|
|
81
83
|
externalEditor?: string;
|
|
82
84
|
shellPath?: string;
|
|
@@ -96,6 +98,8 @@ export interface Settings {
|
|
|
96
98
|
agents?: string[];
|
|
97
99
|
terminal?: TerminalSettings;
|
|
98
100
|
tuiMode?: TuiMode;
|
|
101
|
+
defaultTools?: string[];
|
|
102
|
+
fullscreenExitOutput?: FullscreenExitOutput;
|
|
99
103
|
fullscreenScrollbar?: ScrollViewScrollbar;
|
|
100
104
|
images?: ImageSettings;
|
|
101
105
|
enabledModels?: string[];
|
|
@@ -236,6 +240,7 @@ export declare class SettingsManager {
|
|
|
236
240
|
};
|
|
237
241
|
getWebSocketConnectTimeoutMs(): number | undefined;
|
|
238
242
|
getHideThinkingBlock(): boolean;
|
|
243
|
+
getPruneToolDescriptions(): boolean;
|
|
239
244
|
getShowCacheMissNotices(): boolean;
|
|
240
245
|
getExternalEditorCommand(): string;
|
|
241
246
|
setHideThinkingBlock(hide: boolean): void;
|
|
@@ -286,11 +291,14 @@ export declare class SettingsManager {
|
|
|
286
291
|
setTuiMode(mode: TuiMode): void;
|
|
287
292
|
getFullscreenScrollbar(): ScrollViewScrollbar;
|
|
288
293
|
setFullscreenScrollbar(mode: ScrollViewScrollbar): void;
|
|
294
|
+
getFullscreenExitOutput(): FullscreenExitOutput;
|
|
295
|
+
setFullscreenExitOutput(output: FullscreenExitOutput): void;
|
|
289
296
|
getImageAutoResize(): boolean;
|
|
290
297
|
setImageAutoResize(enabled: boolean): void;
|
|
291
298
|
getBlockImages(): boolean;
|
|
292
299
|
setBlockImages(blocked: boolean): void;
|
|
293
300
|
getEnabledModels(): string[] | undefined;
|
|
301
|
+
getDefaultTools(): string[] | undefined;
|
|
294
302
|
setEnabledModels(patterns: string[] | undefined): void;
|
|
295
303
|
getDoubleEscapeAction(): "fork" | "tree" | "none";
|
|
296
304
|
setDoubleEscapeAction(action: "fork" | "tree" | "none"): void;
|
|
@@ -598,6 +598,9 @@ export class SettingsManager {
|
|
|
598
598
|
getHideThinkingBlock() {
|
|
599
599
|
return this.settings.hideThinkingBlock ?? false;
|
|
600
600
|
}
|
|
601
|
+
getPruneToolDescriptions() {
|
|
602
|
+
return this.settings.pruneToolDescriptions ?? true;
|
|
603
|
+
}
|
|
601
604
|
getShowCacheMissNotices() {
|
|
602
605
|
return this.settings.showCacheMissNotices ?? false;
|
|
603
606
|
}
|
|
@@ -834,6 +837,14 @@ export class SettingsManager {
|
|
|
834
837
|
this.markModified("fullscreenScrollbar");
|
|
835
838
|
this.save();
|
|
836
839
|
}
|
|
840
|
+
getFullscreenExitOutput() {
|
|
841
|
+
return this.settings.fullscreenExitOutput === "resume-hint" ? "resume-hint" : "transcript";
|
|
842
|
+
}
|
|
843
|
+
setFullscreenExitOutput(output) {
|
|
844
|
+
this.globalSettings.fullscreenExitOutput = output;
|
|
845
|
+
this.markModified("fullscreenExitOutput");
|
|
846
|
+
this.save();
|
|
847
|
+
}
|
|
837
848
|
getImageAutoResize() {
|
|
838
849
|
return this.settings.images?.autoResize ?? true;
|
|
839
850
|
}
|
|
@@ -859,6 +870,10 @@ export class SettingsManager {
|
|
|
859
870
|
getEnabledModels() {
|
|
860
871
|
return this.settings.enabledModels;
|
|
861
872
|
}
|
|
873
|
+
getDefaultTools() {
|
|
874
|
+
const tools = this.settings.defaultTools;
|
|
875
|
+
return tools ? [...tools] : undefined;
|
|
876
|
+
}
|
|
862
877
|
setEnabledModels(patterns) {
|
|
863
878
|
this.globalSettings.enabledModels = patterns;
|
|
864
879
|
this.markModified("enabledModels");
|
|
@@ -51,7 +51,7 @@ export function buildSystemPrompt(options) {
|
|
|
51
51
|
if (activeGuidelines.length > 0) {
|
|
52
52
|
prompt += `\n\nActive tool guidelines:\n${activeGuidelines.map((guideline) => `- ${guideline}`).join("\n")}`;
|
|
53
53
|
}
|
|
54
|
-
prompt += `\nCurrent working directory: ${promptCwd}`;
|
|
54
|
+
prompt += `\nCurrent working directory: ${promptCwd}\n`;
|
|
55
55
|
return prompt;
|
|
56
56
|
}
|
|
57
57
|
// Get absolute paths to documentation and examples
|
|
@@ -103,14 +103,8 @@ In addition to the tools above, you may have access to other custom tools depend
|
|
|
103
103
|
Guidelines:
|
|
104
104
|
${guidelines}
|
|
105
105
|
|
|
106
|
-
Pi documentation (read only when the user asks about pi itself, its SDK, extensions, themes, skills, or TUI):
|
|
107
|
-
-
|
|
108
|
-
- Additional docs: ${docsPath}
|
|
109
|
-
- Examples: ${examplesPath} (extensions, custom tools, SDK)
|
|
110
|
-
- When reading pi docs or examples, resolve docs/... under Additional docs and examples/... under Examples, not the current working directory
|
|
111
|
-
- When asked about: extensions (docs/extensions.md, examples/extensions/), themes (docs/themes.md), skills (docs/skills.md), prompt templates (docs/prompt-templates.md), TUI components (docs/tui.md), keybindings (docs/keybindings.md), SDK integrations (docs/sdk.md), custom providers (docs/custom-provider.md), adding models (docs/models.md), pi packages (docs/packages.md), environment variables (docs/environment-variables.md)
|
|
112
|
-
- When working on pi topics, read the docs and examples, and follow .md cross-references before implementing
|
|
113
|
-
- Always read pi .md files completely and follow links to related docs (e.g., tui.md for TUI API details)`;
|
|
106
|
+
Pi documentation (read only when the user asks about pi itself, its SDK, extensions, themes, skills, or TUI): main docs ${readmePath}, additional docs ${docsPath}, examples ${examplesPath}.
|
|
107
|
+
When working on pi topics, resolve docs/... and examples/... under those paths (not cwd), read the relevant .md files completely, and follow cross-references before implementing.`;
|
|
114
108
|
if (appendSection) {
|
|
115
109
|
prompt += appendSection;
|
|
116
110
|
}
|
|
@@ -12,6 +12,12 @@ describe("buildSystemPrompt", () => {
|
|
|
12
12
|
expect(prompt).toMatch(/Guidelines:/);
|
|
13
13
|
expect(prompt).toContain("Current working directory: /tmp/project");
|
|
14
14
|
});
|
|
15
|
+
it("keeps the collapsed Pi-docs block without the per-topic filename map", () => {
|
|
16
|
+
const prompt = buildSystemPrompt({ cwd: "/tmp/project" });
|
|
17
|
+
expect(prompt).toContain("Pi documentation");
|
|
18
|
+
expect(prompt).not.toContain("When asked about:");
|
|
19
|
+
expect(prompt).not.toContain("(docs/extensions.md");
|
|
20
|
+
});
|
|
15
21
|
it("keeps the default tool snippets, skills, and agents XML read-gated", () => {
|
|
16
22
|
const skill = {
|
|
17
23
|
name: "test-skill",
|
package/dist/core/tools/bash.js
CHANGED
|
@@ -7,6 +7,7 @@ import { keyHint } from "../../modes/interactive/components/keybinding-hints.js"
|
|
|
7
7
|
import { truncateToVisualLines } from "../../modes/interactive/components/visual-truncate.js";
|
|
8
8
|
import { theme } from "../../modes/interactive/theme/theme.js";
|
|
9
9
|
import { waitForChildProcess } from "../../utils/child-process.js";
|
|
10
|
+
import { getExperimentalToolSampling } from "../experimental.js";
|
|
10
11
|
import { getShellConfig, getShellEnv, killProcessTree, trackDetachedChildPid, untrackDetachedChildPid, } from "../../utils/shell.js";
|
|
11
12
|
import { OutputAccumulator } from "./output-accumulator.js";
|
|
12
13
|
import { getTextOutput, invalidArgText, str } from "./render-utils.js";
|
|
@@ -232,6 +233,7 @@ export function createBashToolDefinition(cwd, options) {
|
|
|
232
233
|
? ["Inspect PI_* environment variables for current model and session details."]
|
|
233
234
|
: undefined,
|
|
234
235
|
parameters: bashSchema,
|
|
236
|
+
constrainedSampling: getExperimentalToolSampling(),
|
|
235
237
|
async execute(_toolCallId, { command, timeout }, signal, onUpdate, ctx) {
|
|
236
238
|
const resolvedCommand = commandPrefix ? `${commandPrefix}\n${command}` : command;
|
|
237
239
|
const spawnContext = resolveSpawnContext(resolvedCommand, cwd, spawnHook, exposeSessionEnvironment, ctx);
|
package/dist/core/tools/edit.js
CHANGED
|
@@ -3,6 +3,7 @@ import { constants } from "fs";
|
|
|
3
3
|
import { access as fsAccess, readFile as fsReadFile, writeFile as fsWriteFile } from "fs/promises";
|
|
4
4
|
import { Type } from "typebox";
|
|
5
5
|
import { renderDiff } from "../../modes/interactive/components/diff.js";
|
|
6
|
+
import { getExperimentalToolSampling } from "../experimental.js";
|
|
6
7
|
import { applyEditsToNormalizedContent, computeEditsDiff, detectLineEnding, generateDiffString, generateUnifiedPatch, normalizeToLF, restoreLineEndings, stripBom, } from "./edit-diff.js";
|
|
7
8
|
import { withFileMutationQueue } from "./file-mutation-queue.js";
|
|
8
9
|
import { resolveToCwd } from "./path-utils.js";
|
|
@@ -169,6 +170,7 @@ export function createEditToolDefinition(cwd, options) {
|
|
|
169
170
|
"Keep edits[].oldText as small as possible while still being unique in the file. Do not pad with large unchanged regions.",
|
|
170
171
|
],
|
|
171
172
|
parameters: editSchema,
|
|
173
|
+
constrainedSampling: getExperimentalToolSampling(),
|
|
172
174
|
renderShell: "self",
|
|
173
175
|
prepareArguments: prepareEditArguments,
|
|
174
176
|
async execute(_toolCallId, input, signal, _onUpdate, _ctx) {
|
package/dist/core/tools/find.js
CHANGED
|
@@ -154,7 +154,7 @@ export function createFindToolDefinition(cwd, options) {
|
|
|
154
154
|
return;
|
|
155
155
|
}
|
|
156
156
|
// Default implementation uses fd.
|
|
157
|
-
const fdPath = await ensureTool("fd"
|
|
157
|
+
const fdPath = await ensureTool("fd");
|
|
158
158
|
if (signal?.aborted) {
|
|
159
159
|
settle(() => reject(new Error("Operation aborted")));
|
|
160
160
|
return;
|
package/dist/core/tools/grep.js
CHANGED
|
@@ -92,7 +92,7 @@ export function createGrepToolDefinition(cwd, options) {
|
|
|
92
92
|
};
|
|
93
93
|
(async () => {
|
|
94
94
|
try {
|
|
95
|
-
const rgPath = await ensureTool("rg"
|
|
95
|
+
const rgPath = await ensureTool("rg");
|
|
96
96
|
if (!rgPath) {
|
|
97
97
|
settle(() => reject(new Error("ripgrep (rg) is not available and could not be downloaded")));
|
|
98
98
|
return;
|
|
@@ -5,6 +5,7 @@ export { createFindTool, createFindToolDefinition, type FindOperations, type Fin
|
|
|
5
5
|
export { createGrepTool, createGrepToolDefinition, type GrepOperations, type GrepToolDetails, type GrepToolInput, type GrepToolOptions, } from "./grep.ts";
|
|
6
6
|
export { createLsTool, createLsToolDefinition, type LsOperations, type LsToolDetails, type LsToolInput, type LsToolOptions, } from "./ls.ts";
|
|
7
7
|
export { createReadTool, createReadToolDefinition, type ReadOperations, type ReadToolDetails, type ReadToolInput, type ReadToolOptions, } from "./read.ts";
|
|
8
|
+
export { stripSchemaDescriptions, stripToolParameterDescriptions, } from "./schema-prune.ts";
|
|
8
9
|
export { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, type TruncationOptions, type TruncationResult, truncateHead, truncateLine, truncateTail, } from "./truncate.ts";
|
|
9
10
|
export { createWriteTool, createWriteToolDefinition, type WriteOperations, type WriteToolInput, type WriteToolOptions, } from "./write.ts";
|
|
10
11
|
import type { AgentTool } from "@earendil-works/pi-agent-core";
|