pi-background-tasks 0.7.7 → 1.0.3
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/BACKGROUND-TASKS-INSTRUCTIONS.md +63 -0
- package/PUBLISHING.md +43 -29
- package/README.md +234 -385
- package/TESTING.md +15 -9
- package/TEST_PLAN.md +46 -13
- package/docs/INDEX.md +157 -0
- package/docs/api/eventbus-v1.md +166 -0
- package/docs/assets/architecture.svg +78 -0
- package/docs/assets/footer-dock.svg +47 -0
- package/docs/assets/logo.svg +49 -0
- package/docs/attestations.json +189 -0
- package/docs/choose-a-workflow.md +98 -0
- package/docs/commands/bg-clear.md +70 -0
- package/docs/commands/bg-update.md +82 -0
- package/docs/commands/bg.md +90 -0
- package/docs/commands/fusion-models.md +70 -0
- package/docs/commands/fusion.md +69 -0
- package/docs/commands/jobs.md +74 -0
- package/docs/commands/kill.md +82 -0
- package/docs/commands/logs.md +90 -0
- package/docs/commands/task-manager.md +109 -0
- package/docs/concepts/completion-delivery.md +66 -0
- package/docs/concepts/context-projection-and-budgeting.md +79 -0
- package/docs/getting-started.md +122 -0
- package/docs/manifest.json +1825 -0
- package/docs/operations/configuration.md +110 -0
- package/docs/operations/releasing.md +67 -0
- package/docs/operations/testing.md +101 -0
- package/docs/operations/troubleshooting.md +38 -0
- package/docs/read-before-edit.md +94 -0
- package/docs/reference/runtime-contracts.md +213 -0
- package/docs/reference/shortcuts-and-dock.md +70 -0
- package/docs/subsystems/attested-pi-runs.md +141 -0
- package/docs/subsystems/background-task-runtime.md +85 -0
- package/docs/subsystems/child-launch-durability-and-safety.md +57 -0
- package/docs/subsystems/delegation.md +190 -0
- package/docs/subsystems/docs-freshness-gate.md +26 -0
- package/docs/subsystems/fusion.md +121 -0
- package/docs/subsystems/host-ui-and-telemetry.md +83 -0
- package/docs/tools/bg_delegate.md +193 -0
- package/docs/tools/bg_kill.md +114 -0
- package/docs/tools/bg_logs.md +133 -0
- package/docs/tools/bg_result.md +120 -0
- package/docs/tools/bg_run.md +168 -0
- package/docs/tools/bg_run_pi_attested.md +170 -0
- package/docs/tools/bg_status.md +111 -0
- package/docs/tools/fusion_investigate.md +116 -0
- package/docs/tools/fusion_reason.md +75 -0
- package/docs/tools/fusion_research.md +162 -0
- package/docs/tools/fusion_validate.md +206 -0
- package/logo.png +0 -0
- package/package.json +29 -6
- package/src/core/delegate/budget.ts +1 -1
- package/src/core/delegate/launch.ts +6 -0
- package/src/core/fusion/artifacts.ts +80 -5
- package/src/core/fusion/budget.ts +129 -28
- package/src/core/fusion/child-protocol.ts +82 -0
- package/src/core/fusion/clean-context.ts +91 -0
- package/src/core/fusion/config.ts +124 -35
- package/src/core/fusion/context.ts +33 -6
- package/src/core/fusion/evaluation.ts +392 -15
- package/src/core/fusion/orchestrator.ts +274 -25
- package/src/core/fusion/pi-child.ts +635 -10
- package/src/core/fusion/prompts.ts +167 -6
- package/src/core/fusion/source-policy.ts +257 -0
- package/src/core/fusion/types.ts +232 -5
- package/src/core/fusion/web-fetch.ts +993 -0
- package/src/core/fusion/workflows.ts +184 -0
- package/src/extension.ts +3 -3
- package/src/fusion-child-extension.ts +370 -54
- package/src/fusion-extension.ts +625 -125
- package/src/testing/normalize.ts +0 -22
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
doc_id: subsystems/fusion
|
|
3
|
+
audience: maintainer
|
|
4
|
+
mode: mixed
|
|
5
|
+
review_policy: behavioral
|
|
6
|
+
stability: stable
|
|
7
|
+
covers_surfaces: [renderer:fusion-result, workflow:investigate, workflow:reason, workflow:research, workflow:validate]
|
|
8
|
+
covers_sources: [extensions/fusion-child.ts, src/core/fusion/artifacts.ts, src/core/fusion/budget.ts, src/core/fusion/child-protocol.ts, src/core/fusion/clean-context.ts, src/core/fusion/config.ts, src/core/fusion/context.ts, src/core/fusion/evaluation.ts, src/core/fusion/orchestrator.ts, src/core/fusion/pi-child.ts, src/core/fusion/prompts.ts, src/core/fusion/source-policy.ts, src/core/fusion/types.ts, src/core/fusion/web-fetch.ts, src/core/fusion/workflows.ts, src/fusion-child-extension.ts, src/fusion-extension.ts, src/ui/fusion-model-selector.ts]
|
|
9
|
+
---
|
|
10
|
+
# Fusion subsystem
|
|
11
|
+
|
|
12
|
+
<!-- pi-docs:begin name="fusion-workflows" generator="scripts/docs/generate.mjs" -->
|
|
13
|
+
| Workflow | Tool | Context | Candidate capability | Candidate tools | Evaluator/merger tools | Provenance |
|
|
14
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
15
|
+
| `investigate` | `fusion_investigate` | `clean_task` | `inspect` | `read`, `grep`, `find`, `ls` | none | `src/core/fusion/workflows.ts:80` |
|
|
16
|
+
| `reason` | `fusion_reason` | `session_projection` | `reason` | none | none | `src/core/fusion/workflows.ts:61` |
|
|
17
|
+
| `research` | `fusion_research` | `clean_task` | `research` | `read`, `grep`, `find`, `ls`, `fusion_web_fetch` | none | `src/core/fusion/workflows.ts:99` |
|
|
18
|
+
| `validate` | `fusion_validate` | `clean_task` | `inspect` | `read`, `grep`, `find`, `ls` | none | `src/core/fusion/workflows.ts:118` |
|
|
19
|
+
<!-- pi-docs:end name="fusion-workflows" -->
|
|
20
|
+
|
|
21
|
+
This document is the primary behavioral owner for Fusion's package-owned source files listed in frontmatter. Shared parent-context and token-budget modules are referenced here only as dependencies; their behavior is not owned by this document.
|
|
22
|
+
|
|
23
|
+
## Public v1 surface
|
|
24
|
+
|
|
25
|
+
Fusion v1 exposes exactly two commands and exactly four public tools:
|
|
26
|
+
|
|
27
|
+
- `/fusion` — command shorthand for fixed-purpose `reason`.
|
|
28
|
+
- `/fusion-models` — TUI-only global five-slot model selector.
|
|
29
|
+
- `fusion_reason({prompt})`.
|
|
30
|
+
- `fusion_investigate({objective, background, deliverable, scope?, constraints?})`.
|
|
31
|
+
- `fusion_research({objective, background, deliverable, scope?, constraints?, sources})`.
|
|
32
|
+
- `fusion_validate({objective, background, changeSummary, scope, acceptanceCriteria, verification, knownLimitations?, exclusions?})`.
|
|
33
|
+
|
|
34
|
+
Every public tool schema is closed and has no public capability/mode switch. The retired `fusion_brainstorm` surface is never registered; session start removes it from active tools while preserving rendering of historical completed v4 result messages.
|
|
35
|
+
|
|
36
|
+
## Commands
|
|
37
|
+
|
|
38
|
+
`/fusion <prompt>` trims the command text and runs the reason workflow. `/fusion` with no arguments opens the multiline editor when UI is available; editor cancellation or blank edited text returns without child spawn. TUI mode wraps the run in a cancellable loader. Success sends a hidden `fusion-request` custom message and a visible `fusion-result` custom message containing the merger's exact text; the parent model is not asked to rewrite the result.
|
|
39
|
+
|
|
40
|
+
`/fusion-models` requires TUI mode. It edits five slots (`Candidate 1`, `Candidate 2`, `Candidate 3`, `Evaluator`, `Merger`), allows duplicates, supports `$current`, shows unavailable configured choices, and persists `fusion-models.json` with schema `pi-background-tasks.fusion-models.v1`. Saves are lock-protected, atomic, and revision-safe: if the file changed after load, the selector reports a config conflict instead of overwriting concurrent work.
|
|
41
|
+
|
|
42
|
+
## Context contracts
|
|
43
|
+
|
|
44
|
+
Reason runs (`/fusion` and `fusion_reason`) receive session-projection canonical input (`pi-background-tasks.fusion-input.v5`). Visible user/assistant text is retained verbatim. Assistant thinking, tool calls, tool-result text, and tool-result images are not forwarded; they become deterministic omission receipts plus a local `context-omission-ledger.json`. User image blocks become marker text, and ledger-only image payloads never enter child prompts. Tool calls exclude the active Fusion leaf and sibling calls from the projected branch.
|
|
45
|
+
|
|
46
|
+
Investigate, research, and validate receive clean-task canonical input: exactly `schema_version`, `workflow`, `cwd`, `request`, and `context`. Clean tasks carry no parent system prompt, no conversation projection, no parent transcript, and no omission ledger. Their request text is the canonical JSON serialization of the structured public arguments and is fully authoritative.
|
|
47
|
+
|
|
48
|
+
## Workflow and stage policy
|
|
49
|
+
|
|
50
|
+
All workflows use the same orchestrator shape:
|
|
51
|
+
|
|
52
|
+
1. plan budget and write artifacts before any child exists;
|
|
53
|
+
2. run three candidate children in parallel;
|
|
54
|
+
3. anonymize candidate identities as A/B/C before evaluation;
|
|
55
|
+
4. run a blind no-tool evaluator;
|
|
56
|
+
5. run one no-tool evaluator-repair child only if the first evaluator JSON is invalid or schema-invalid;
|
|
57
|
+
6. run a no-tool merger.
|
|
58
|
+
|
|
59
|
+
Do not describe Fusion as unconditionally exactly five model calls. A completed run may use five or six child invocations, while preflight failures use zero; candidate failures, cancellation, spawn retry, output caps, or invalid repair alter observed attempts.
|
|
60
|
+
|
|
61
|
+
Candidate tool policies are fixed by workflow:
|
|
62
|
+
|
|
63
|
+
| Workflow | Candidate capability | Candidate tools |
|
|
64
|
+
|---|---:|---|
|
|
65
|
+
| reason | `reason` | none (`--no-tools`) |
|
|
66
|
+
| investigate | `inspect` | `read`, `grep`, `find`, `ls` |
|
|
67
|
+
| research | `research` | `read`, `grep`, `find`, `ls`, `fusion_web_fetch` |
|
|
68
|
+
| validate | `inspect` | `read`, `grep`, `find`, `ls` |
|
|
69
|
+
|
|
70
|
+
Evaluator, evaluator-repair, and merger always use capability `reason` and empty tool lists. Tool-enabled children run with built-in tools disabled and an explicit allowlist plus a denylist that includes shell/write/edit, Fusion recursion, and background/delegate tools.
|
|
71
|
+
|
|
72
|
+
## Validation specifics
|
|
73
|
+
|
|
74
|
+
`fusion_validate` enforces a strict public verification contract: `provided` requires non-empty evidence and no reason; `not_run` requires a reason and empty/omitted evidence. Reviewers return closed candidate-report JSON. The host assigns stable finding ids after anonymization, the evaluator must account for every source finding exactly once, and the host renders the final report from validated accounting after the merger. Validation is advisory and read-only: it never edits files, runs tests, gates a release, or replaces builds, linters, scanners, or human review.
|
|
75
|
+
|
|
76
|
+
## Research specifics
|
|
77
|
+
|
|
78
|
+
Research is targeted fetch, not search. The public caller declares exact non-duplicate public `http(s)` URLs and purposes. There is no browser, PDF reader, cache, search provider, page-recrawl loop, or domain allowlist.
|
|
79
|
+
|
|
80
|
+
`fusion_web_fetch` is private to research children and has a closed `{url, extract?}` schema. It rejects credentials, non-http schemes, localhost/known-metadata names, and enumerated private/reserved address classes; vets all DNS answers against that classifier; pins the request to a vetted address; checks the response socket address; follows at most five re-vetted redirects; accepts only HTML/XHTML/plain text/Markdown; caps response bytes at 2 MiB and extracted output at 32 KiB; uses a 60 second deadline; strips script/style/noscript; and extracts text or Markdown. Source-policy admission also rejects literal Azure service address `168.63.129.16`, but the transport classifier does not currently special-case a public DNS/redirect target resolving to that address.
|
|
81
|
+
|
|
82
|
+
Research intentionally combines read-only file tools and network fetch in one child. This supports source-backed synthesis but is security-sensitive: operators must not supply secret-bearing URLs or ask children to put private data in URL strings. The package blocks common SSRF targets and credential URLs, but its deny rules are not an exhaustive network sandbox; fetched content remains untrusted and caller-declared public URLs can still disclose access through remote logs/timing.
|
|
83
|
+
|
|
84
|
+
Inspect/research candidates write sealed tool-call audit logs. The log contains schema version, ordinal, tool name, argument/result byte counts and SHA-256 digests, status, duration, and fetch provenance. Raw arguments, raw results, page content, and rejected raw URLs are not persisted. The parent requires the log and seal, verifies hashes/counts/ordinals/status, enforces the 8 MiB aggregate result-byte cap, and rejects non-allowlisted tools.
|
|
85
|
+
|
|
86
|
+
## Child process isolation
|
|
87
|
+
|
|
88
|
+
Fusion never calls direct completion APIs. It launches direct child `pi --mode text` processes and writes the prompt over stdin. Child argv includes `--no-session`, `--no-extensions`, `--no-skills`, `--no-prompt-templates`, `--no-themes`, and `--no-context-files`; explicit extensions still load, so the package-owned compact metadata extension is always supplied. Anthropic children additionally receive the `@ravshansbox/pi-anthropic-sps` sanitizer extension because discovery is disabled and Claude routes need Pi system-prompt sanitization.
|
|
89
|
+
|
|
90
|
+
Child text mode writes the final full answer to stdout. The private child extension emits compact reasoning-free metadata frames to stderr for finalized assistant messages: provider/model, stop reason, text block byte counts and hashes, aggregate text hash, and the complete Pi `Usage` object. The parent reconstructs and validates stdout against the final metadata, requires final stop reason `stop` and non-final stop reason `toolUse`, verifies model identity, and preserves usage/cost exactly.
|
|
91
|
+
|
|
92
|
+
Fusion child environments strip session/model/provider variables plus metered credential/base-url variables for OpenRouter, OpenAI, Anthropic, Azure OpenAI, and generic Pi API credentials before launch. Frontier model routes are admitted only when the registry reports subscription OAuth for trusted `anthropic` or `openai-codex` endpoints. There is no fallback, model substitution, endpoint override, or metered API-key route.
|
|
93
|
+
|
|
94
|
+
## Budgets and output contracts
|
|
95
|
+
|
|
96
|
+
Budget planning is per route and per stage. Every configured candidate, evaluator, and merger route must have a usable context window. The affine estimator from the shared token-budget layer accounts for byte classes plus a 512-token intercept; backed model-family calibrations are used only where applicable, unknown/unbacked providers are reported in artifacts/result details, and multibyte/dense ASCII diagnostics are preserved.
|
|
97
|
+
|
|
98
|
+
`budget-plan.json` records route capacities, stage forecasts for candidate/evaluation/evaluation-repair/merge, conditional repair reservation, warnings, blockers, empty-request counterfactuals, and remediation. Fatal preflight blockers launch zero children. High utilization or worst-case reservation pressure is a warning when input still fits. Exact rendered prompt checks happen again immediately before candidate, evaluation, repair, and merge launches.
|
|
99
|
+
|
|
100
|
+
Output contracts are checked after durable attempt recording: candidate responses up to 48 KiB JSON-rendered bytes, evaluator up to 64 KiB, merger/final report up to 64 KiB, diagnostics contract 8 KiB, child stdout cap 32 MiB, child stderr cap 4 MiB. Oversized child output fails loudly and preserves evidence; Fusion never clips or silently forwards truncated content.
|
|
101
|
+
|
|
102
|
+
## Artifacts, usage, and lifecycle
|
|
103
|
+
|
|
104
|
+
Run artifacts are private local evidence under `.pi/fusion/<session-id>-<pid>/<run-id>/`. They include `manifest.json`, `canonical-input.json`, `budget-plan.json`, per-attempt prompts/events/stderr/responses, optional partial responses for failed attempts, optional tool-call logs/seals, `blind-candidates.json`, `evaluation.json`, `merged.md`, `error.json`, and workflow-specific context/source-policy artifacts.
|
|
105
|
+
|
|
106
|
+
Artifact writes use durable private temp-file/fsync/rename. Manifests enforce legal state transitions and record config, resolved models, fixed capabilities, context policy, tool policy, anonymous map, attempts, artifact refs, cumulative usage, and errors. Successful, failed, and cancelled observed attempts preserve complete Pi usage/cost components; public tool results clone the same `Usage` shape.
|
|
107
|
+
|
|
108
|
+
Cancellation and shutdown are loud and durable when a run store exists. The extension tracks active runs, links external abort signals, aborts on session shutdown/reload, and waits for settlement. Child processes have a 30 minute wall timeout, 20 minute idle watchdog, SIGTERM grace, SIGKILL wait, process-group kill on POSIX, bounded stdout/stderr, and cleanup-error propagation.
|
|
109
|
+
|
|
110
|
+
## Troubleshooting
|
|
111
|
+
|
|
112
|
+
- `/fusion-models requires Pi TUI mode`: run from the TUI, not RPC/print/JSON.
|
|
113
|
+
- `$current` unavailable or model unavailable: choose explicit available subscription routes with `/fusion-models`.
|
|
114
|
+
- Frontier/API route rejected: use Pi Anthropic or Codex subscription OAuth, not OpenAI/OpenRouter/Azure/API-key routes.
|
|
115
|
+
- `prompt_budget_exceeded_forecast`: inspect `budget-plan.json`; the error says whether shortening the request can help or whether session history/scope/model context window is the blocker.
|
|
116
|
+
- `prompt_budget_exceeded_measured`: an exact rendered prompt exceeded capacity after upstream output was known; split the workflow or choose a larger-context subscription route.
|
|
117
|
+
- `evaluation schema repair failed`: both evaluator attempts failed the closed JSON contract; inspect `evaluation.attempt-*.response.txt` and errors.
|
|
118
|
+
- `tool-call log invalid`: inspect the candidate `*.tool-calls.jsonl` and `*.seal.json`; missing/partial/unsealed logs, non-allowlisted tools, hash/count mismatches, and over-budget tool output fail by design.
|
|
119
|
+
- Research fetch failures are typed and do not retry via other URLs or extraction modes; verify the declared URL is public, reachable, supported content, and within caps.
|
|
120
|
+
|
|
121
|
+
Related user docs: [`../commands/fusion.md`](../commands/fusion.md), [`../commands/fusion-models.md`](../commands/fusion-models.md), [`../tools/fusion_reason.md`](../tools/fusion_reason.md), [`../tools/fusion_investigate.md`](../tools/fusion_investigate.md), [`../tools/fusion_research.md`](../tools/fusion_research.md), [`../tools/fusion_validate.md`](../tools/fusion_validate.md).
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
doc_id: subsystems/host-ui-and-telemetry
|
|
3
|
+
audience: maintainer
|
|
4
|
+
mode: authored
|
|
5
|
+
review_policy: behavioral
|
|
6
|
+
stability: stable
|
|
7
|
+
covers_surfaces: []
|
|
8
|
+
covers_sources: [extensions/background-tasks.ts, src/core/update-check.ts, src/extension.ts, src/ui/background-tasks-manager.ts]
|
|
9
|
+
---
|
|
10
|
+
# Host UI and telemetry
|
|
11
|
+
|
|
12
|
+
This subsystem owns the extension entrypoint, command/tool registration, footer dock, task manager UI, completion renderer, and update-available footer notice. Task lifecycle internals are owned by [background-task-runtime](background-task-runtime.md).
|
|
13
|
+
|
|
14
|
+
## Entrypoint and registration
|
|
15
|
+
|
|
16
|
+
`extensions/background-tasks.ts` re-exports `src/extension.ts`. The extension registers:
|
|
17
|
+
|
|
18
|
+
- commands: `/bg`, `/tasks`, `/bg-tasks`, `/bg-clear`, `/bg-update`, `/jobs`, `/logs`, `/kill`;
|
|
19
|
+
- tools: `bg_run`, `bg_status`, `bg_logs`, `bg_kill` plus package-owned advanced tools documented elsewhere;
|
|
20
|
+
- shortcuts: `shift+down` and `ctrl+alt+c`;
|
|
21
|
+
- renderer: `background-task-notification`.
|
|
22
|
+
|
|
23
|
+
## Footer status
|
|
24
|
+
|
|
25
|
+
The footer widget is updated on task changes and once per second while a session is active. If there are no running tasks and no unseen finished tasks, the background-task footer is cleared unless an update segment is available.
|
|
26
|
+
|
|
27
|
+
When visible, the footer label includes counts in this order:
|
|
28
|
+
|
|
29
|
+
1. running,
|
|
30
|
+
2. failed,
|
|
31
|
+
3. stopped (`killed`),
|
|
32
|
+
4. done (`completed`),
|
|
33
|
+
5. entry hint (`focused` while the dock is open, otherwise `Shift↓`),
|
|
34
|
+
6. `/bg-clear` hint when there are unseen finished tasks **and the dock is closed**,
|
|
35
|
+
7. optional update segment.
|
|
36
|
+
|
|
37
|
+
A finished badge is cleared when that task's detail view is opened, or when `/bg-clear` or its shortcut marks all currently unseen finished tasks as seen. Merely opening the list view or closing the dock does not clear badges.
|
|
38
|
+
|
|
39
|
+
## Task manager UI
|
|
40
|
+
|
|
41
|
+
`/tasks`, `/bg-tasks`, and `Shift+Down` open the same overlay. Non-interactive contexts receive an error notification directing users to `/jobs`, `/logs`, `bg_status`, or `bg_logs`.
|
|
42
|
+
|
|
43
|
+
The list view supports selection, paging, stop, confirmed stop-all, history toggle, rerun, output path, and close. The detail view shows task identity, status, runtime, output path, description, task-owned model/context/tokens/tools when reported, command, error, and an output tail.
|
|
44
|
+
|
|
45
|
+
Detail output semantics:
|
|
46
|
+
|
|
47
|
+
- reads a UI-only tail buffer of 128 KiB;
|
|
48
|
+
- refreshes every second only while following;
|
|
49
|
+
- shows 12 output lines;
|
|
50
|
+
- scrolling up pauses follow and freezes the buffer;
|
|
51
|
+
- reaching the bottom or pressing `r` resumes follow;
|
|
52
|
+
- missing output files and read failures are displayed in the detail box.
|
|
53
|
+
|
|
54
|
+
## Completion rendering
|
|
55
|
+
|
|
56
|
+
`background-task-notification` renders `[bg completed]`, `[bg failed]`, `[bg killed]`, or other status with task name, id, output path, and error. The notification content itself is produced by the runtime and may trigger a follow-up turn depending on task flags.
|
|
57
|
+
|
|
58
|
+
## Update check
|
|
59
|
+
|
|
60
|
+
The update check is one-shot per extension runtime, launched after `session_start` without blocking session startup. It is skipped for `PI_BG_DISABLE_UPDATE_CHECK=1`, `PI_OFFLINE=1`, or missing installed version. The npm registry URL defaults to `https://registry.npmjs.org` and can be overridden by `PI_BG_REGISTRY_URL`. Fetch is time-boxed by `DEFAULT_UPDATE_TIMEOUT_MS` (2000 ms) and every network/status/payload failure resolves to no update segment.
|
|
61
|
+
|
|
62
|
+
When a newer semver is found, the footer segment is `⬆ v<latest> /bg-update`. `/bg-update` prints npm/git install instructions only; it never installs or self-updates.
|
|
63
|
+
|
|
64
|
+
## Telemetry display
|
|
65
|
+
|
|
66
|
+
The host UI displays telemetry only from task snapshots: context, model, token totals, and tool counts. When unavailable, detail rows say `not reported by this background task`. The UI never copies telemetry from the parent session into a task.
|
|
67
|
+
|
|
68
|
+
## Shutdown
|
|
69
|
+
|
|
70
|
+
On session shutdown, the extension marks the registry as shutting down, clears the status interval, kills running tasks with reason `Killed during Pi session shutdown/reload`, reports cleanup failures through the UI when possible, and closes the event service.
|
|
71
|
+
|
|
72
|
+
## Related docs
|
|
73
|
+
|
|
74
|
+
- [Shortcuts and dock](../reference/shortcuts-and-dock.md)
|
|
75
|
+
- [`/tasks` and `/bg-tasks`](../commands/task-manager.md)
|
|
76
|
+
- [`/bg-clear`](../commands/bg-clear.md)
|
|
77
|
+
- [`/bg-update`](../commands/bg-update.md)
|
|
78
|
+
- [Completion delivery](../concepts/completion-delivery.md)
|
|
79
|
+
- [Background task runtime](background-task-runtime.md)
|
|
80
|
+
|
|
81
|
+
## Source ownership/reference
|
|
82
|
+
|
|
83
|
+
Primary source ownership for this document is `extensions/background-tasks.ts`, `src/extension.ts`, `src/core/update-check.ts`, and `src/ui/background-tasks-manager.ts`.
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
---
|
|
2
|
+
doc_id: tools/bg_delegate
|
|
3
|
+
audience: agent
|
|
4
|
+
mode: mixed
|
|
5
|
+
review_policy: contract
|
|
6
|
+
stability: stable
|
|
7
|
+
covers_surfaces: [tool:bg_delegate]
|
|
8
|
+
covers_sources: []
|
|
9
|
+
---
|
|
10
|
+
# `bg_delegate`
|
|
11
|
+
|
|
12
|
+
<!-- pi-docs:begin name="tool-contract-bg_delegate" generator="scripts/docs/generate.mjs" -->
|
|
13
|
+
- Label: **Background Delegate**
|
|
14
|
+
- Source: `src/delegate-extension.ts:265`
|
|
15
|
+
- Description: Launch one background Pi agent seeded with a frozen projection of the current conversation, then return a launch receipt immediately. The child has its own session, a route pinned at launch that is never substituted, and read-only tools. Retrieve its verified answer with bg_result.
|
|
16
|
+
- Root schema: `object`; additionalProperties: `false`
|
|
17
|
+
|
|
18
|
+
| Field | Required | Type | Description | Constraints |
|
|
19
|
+
| --- | --- | --- | --- | --- |
|
|
20
|
+
| `autoDeliver` | no | `string` | Whether the completion notification carries the answer: never \| when_small \| always. Default never; retrieve with bg_result. | |
|
|
21
|
+
| `capability` | no | `string` | Capability profile. Only "inspect" (read/search/list, no shell, no writes, no network, no recursion) is supported. | |
|
|
22
|
+
| `maxToolCalls` | no | `number` | Maximum tool calls. Default 120. | |
|
|
23
|
+
| `maxTurns` | no | `number` | Maximum agent turns. Default 24. | |
|
|
24
|
+
| `name` | yes | `string` | Short human-readable task name shown in the bg footer dock. Use 2-6 words. | |
|
|
25
|
+
| `notifyOnCompletion` | no | `boolean` | Deliver the durable terminal notification. Default true. | |
|
|
26
|
+
| `prompt` | yes | `string` | Authoritative instruction for the delegate. The projected conversation is supporting background only. | |
|
|
27
|
+
| `route` | no | `object` | Explicit route. Defaults to the current model. | additionalProperties: false |
|
|
28
|
+
| `route.model` | yes | `string` | Exact provider-local model id to pin. | |
|
|
29
|
+
| `route.provider` | yes | `string` | Exact provider name to pin. | |
|
|
30
|
+
| `timeoutSeconds` | no | `number` | Wall-clock timeout. Default 1200. | |
|
|
31
|
+
| `triggerOnCompletion` | no | `boolean` | Let that notification start a follow-up turn. Default true. | |
|
|
32
|
+
|
|
33
|
+
<details>
|
|
34
|
+
<summary>Normalized TypeBox contract</summary>
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"additionalProperties": false,
|
|
40
|
+
"properties": {
|
|
41
|
+
"autoDeliver": {
|
|
42
|
+
"description": "Whether the completion notification carries the answer: never | when_small | always. Default never; retrieve with bg_result.",
|
|
43
|
+
"type": "string"
|
|
44
|
+
},
|
|
45
|
+
"capability": {
|
|
46
|
+
"description": "Capability profile. Only \"inspect\" (read/search/list, no shell, no writes, no network, no recursion) is supported.",
|
|
47
|
+
"type": "string"
|
|
48
|
+
},
|
|
49
|
+
"maxToolCalls": {
|
|
50
|
+
"description": "Maximum tool calls. Default 120.",
|
|
51
|
+
"type": "number"
|
|
52
|
+
},
|
|
53
|
+
"maxTurns": {
|
|
54
|
+
"description": "Maximum agent turns. Default 24.",
|
|
55
|
+
"type": "number"
|
|
56
|
+
},
|
|
57
|
+
"name": {
|
|
58
|
+
"description": "Short human-readable task name shown in the bg footer dock. Use 2-6 words.",
|
|
59
|
+
"type": "string"
|
|
60
|
+
},
|
|
61
|
+
"notifyOnCompletion": {
|
|
62
|
+
"description": "Deliver the durable terminal notification. Default true.",
|
|
63
|
+
"type": "boolean"
|
|
64
|
+
},
|
|
65
|
+
"prompt": {
|
|
66
|
+
"description": "Authoritative instruction for the delegate. The projected conversation is supporting background only.",
|
|
67
|
+
"type": "string"
|
|
68
|
+
},
|
|
69
|
+
"route": {
|
|
70
|
+
"additionalProperties": false,
|
|
71
|
+
"description": "Explicit route. Defaults to the current model.",
|
|
72
|
+
"properties": {
|
|
73
|
+
"model": {
|
|
74
|
+
"description": "Exact provider-local model id to pin.",
|
|
75
|
+
"type": "string"
|
|
76
|
+
},
|
|
77
|
+
"provider": {
|
|
78
|
+
"description": "Exact provider name to pin.",
|
|
79
|
+
"type": "string"
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"required": [
|
|
83
|
+
"model",
|
|
84
|
+
"provider"
|
|
85
|
+
],
|
|
86
|
+
"type": "object"
|
|
87
|
+
},
|
|
88
|
+
"timeoutSeconds": {
|
|
89
|
+
"description": "Wall-clock timeout. Default 1200.",
|
|
90
|
+
"type": "number"
|
|
91
|
+
},
|
|
92
|
+
"triggerOnCompletion": {
|
|
93
|
+
"description": "Let that notification start a follow-up turn. Default true.",
|
|
94
|
+
"type": "boolean"
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"required": [
|
|
98
|
+
"name",
|
|
99
|
+
"prompt"
|
|
100
|
+
],
|
|
101
|
+
"type": "object"
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
</details>
|
|
106
|
+
<!-- pi-docs:end name="tool-contract-bg_delegate" -->
|
|
107
|
+
|
|
108
|
+
`bg_delegate` launches one background Pi child for one read-only investigation and returns a launch receipt immediately. Retrieve the answer later with [`bg_result`](bg_result.md).
|
|
109
|
+
|
|
110
|
+
## Public arguments
|
|
111
|
+
|
|
112
|
+
Required:
|
|
113
|
+
|
|
114
|
+
- `name: string` — non-empty after trimming. Used for task display.
|
|
115
|
+
- `prompt: string` — non-blank after trimming. The exact string is preserved as `directive.text` and is authoritative.
|
|
116
|
+
|
|
117
|
+
Optional:
|
|
118
|
+
|
|
119
|
+
- `route: {provider: string, model: string}` — exact route pin. If omitted, the parent session's current `ctx.model.provider` and `ctx.model.id` are used.
|
|
120
|
+
- `capability: "inspect"` — default `"inspect"`; this is the only v1 capability.
|
|
121
|
+
- `maxTurns: positive integer` — default `24`.
|
|
122
|
+
- `maxToolCalls: positive integer` — default `120`.
|
|
123
|
+
- `timeoutSeconds: positive integer` — default `1200`.
|
|
124
|
+
- `autoDeliver: "never" | "when_small" | "always"` — default `"never"`. Current runtime records and reports this setting in launch/task facts; retrieval remains through `bg_result`. The generic terminal notification path does not currently inline delegate answers.
|
|
125
|
+
- `notifyOnCompletion: boolean` — default `true`.
|
|
126
|
+
- `triggerOnCompletion: boolean` — default `true`; only meaningful when notification is enabled.
|
|
127
|
+
|
|
128
|
+
The TypeBox schema is closed (`additionalProperties: false`), and preparation validates required/enum/integer fields before launch.
|
|
129
|
+
|
|
130
|
+
## What the child sees
|
|
131
|
+
|
|
132
|
+
The child receives a frozen delegate seed built from `visible-conversation-ledger-v2`:
|
|
133
|
+
|
|
134
|
+
- user text: verbatim;
|
|
135
|
+
- assistant text: verbatim;
|
|
136
|
+
- user images: marker text only, not raw bytes;
|
|
137
|
+
- assistant thinking, tool-call arguments, tool-result text/images: omitted from visible context and recorded in a hash-accounted omission ledger;
|
|
138
|
+
- unknown block types: loud projection failure;
|
|
139
|
+
- the assistant message containing the active `bg_delegate` call is excluded as a whole, so sibling tool calls in that same message are also excluded.
|
|
140
|
+
|
|
141
|
+
The prompt/directive has explicit authority over projected history. Projected history is supporting, untrusted context. Facts that existed only in omitted parent tool output are not available to the child; restate them in `prompt`.
|
|
142
|
+
|
|
143
|
+
## Isolation and route guarantees
|
|
144
|
+
|
|
145
|
+
The child does not share the parent session. Launch argv gives it a random `--session-id` (`delegate-<32 hex>`) and a task-owned `--session-dir` under the delegate artifact directory.
|
|
146
|
+
|
|
147
|
+
Route resolution is pin-only:
|
|
148
|
+
|
|
149
|
+
- omitted `route` pins the parent current model;
|
|
150
|
+
- explicit `route` must exactly exist in the current model registry;
|
|
151
|
+
- no unavailable route is substituted;
|
|
152
|
+
- no fallback list or retry-on-other-model exists;
|
|
153
|
+
- routes with no declared context window are refused before child creation;
|
|
154
|
+
- the child records provider/model attestations for assistant messages, and a mismatch prevents a successful result commit.
|
|
155
|
+
|
|
156
|
+
## Inspect-only tool boundary
|
|
157
|
+
|
|
158
|
+
The v1 capability is enforced by child argv and Pi's tool registry, not merely by prompt text:
|
|
159
|
+
|
|
160
|
+
- enabled tools: `read`, `grep`, `find`, `ls`, `delegate_read_artifact`;
|
|
161
|
+
- `--no-builtin-tools` is used with the explicit allowlist;
|
|
162
|
+
- forbidden tools include shell/write/background/delegate/Fusion surfaces (`bash`, `edit`, `write`, `bg_run`, `bg_delegate`, `bg_result`, `bg_run_pi_attested`, Fusion tools, etc.);
|
|
163
|
+
- ambient discovery is disabled with `--no-extensions`, `--no-skills`, `--no-prompt-templates`, `--no-themes`, `--no-context-files`;
|
|
164
|
+
- only the package-owned delegate child extension is loaded explicitly.
|
|
165
|
+
|
|
166
|
+
There is no shell, edit/write, network tool, recursive delegation, Fusion, or ambient project resource loading in the child tool set.
|
|
167
|
+
|
|
168
|
+
## Admission, budgets, and artifacts
|
|
169
|
+
|
|
170
|
+
Public admission resolves the route and package-owned child guard extension before entering `preflightDelegateLaunch()`. Within that preflight, the hook contract is checked before capability/limit/seed/budget admission. Every refusal still occurs before child process, child session directory, or artifact root creation, leaving zero child processes and zero delegate artifacts; callers should not depend on a single absolute error-precedence order across route, guard-extension, and hook checks.
|
|
171
|
+
|
|
172
|
+
Budgets and limits:
|
|
173
|
+
|
|
174
|
+
- route capacity is the declared context window minus reserves: `16,384` output, `8,192` framing, `4,096` safety tokens;
|
|
175
|
+
- minimum usable input is `8,192` tokens;
|
|
176
|
+
- launch admission measures the child system prompt plus the exact child prompt bytes that carry the seed;
|
|
177
|
+
- runtime context is measured before each model call;
|
|
178
|
+
- per-tool-result transcript cap: `64 KiB`;
|
|
179
|
+
- aggregate tool-output cap: `64 MiB`;
|
|
180
|
+
- answer capture cap value in the seed: `4 MiB`; current child code carries this limit but does not separately enforce it before packaging;
|
|
181
|
+
- timeout defaults to `1200s`.
|
|
182
|
+
|
|
183
|
+
Artifacts are under `.pi/delegate/<session-id>-<pid>/<task-id>/` and include `seed.json`, `child-prompt.txt`, `context-omission-ledger.json`, `budget-plan.json`, `manifest.json`, `child-session/`, `spill/`, and later `result.json` / `outcome.json` when produced. Child stdout/stderr are captured through the background task output path; the delegate artifact constants include child stream filenames, but current launch/finalize code does not mirror streams into those delegate files.
|
|
184
|
+
|
|
185
|
+
## Spilled tool output
|
|
186
|
+
|
|
187
|
+
Oversized child tool results are written in full to `spill/...` artifacts and replaced in the transcript by receipts carrying path, byte length, SHA-256, tool name, call id, turn sequence, and source call index. The raw oversized payload is not forwarded as a fallback and is not truncated.
|
|
188
|
+
|
|
189
|
+
Inside the child, `delegate_read_artifact({artifact, offset, length})` reads an exact byte range. It refuses path escape, negative/non-integer offsets, non-positive lengths, and reads past EOF rather than returning a short/clamped range.
|
|
190
|
+
|
|
191
|
+
## Completion
|
|
192
|
+
|
|
193
|
+
`bg_delegate` returns a receipt with task id, route, child session id, artifact dir, seed hash/size, budget source, limits, auto-deliver setting, and notification/wake settings. With default notification settings, the parent receives the generic durable `background-task-notification` after terminal state and may then call `bg_result`. Do not poll solely to wait.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
---
|
|
2
|
+
doc_id: tools/bg_kill
|
|
3
|
+
audience: agent
|
|
4
|
+
mode: mixed
|
|
5
|
+
review_policy: contract
|
|
6
|
+
stability: stable
|
|
7
|
+
covers_surfaces: [tool:bg_kill]
|
|
8
|
+
covers_sources: []
|
|
9
|
+
---
|
|
10
|
+
# `bg_kill`
|
|
11
|
+
|
|
12
|
+
<!-- pi-docs:begin name="tool-contract-bg_kill" generator="scripts/docs/generate.mjs" -->
|
|
13
|
+
- Label: **Background Kill**
|
|
14
|
+
- Source: `src/extension.ts:897`
|
|
15
|
+
- Description: Stop a running background task by ID. Fails loudly if the task is unknown or already finished.
|
|
16
|
+
- Root schema: `object`
|
|
17
|
+
|
|
18
|
+
| Field | Required | Type | Description | Constraints |
|
|
19
|
+
| --- | --- | --- | --- | --- |
|
|
20
|
+
| `taskId` | yes | `string` | Task ID or unambiguous prefix to stop | |
|
|
21
|
+
|
|
22
|
+
<details>
|
|
23
|
+
<summary>Normalized TypeBox contract</summary>
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"properties": {
|
|
29
|
+
"taskId": {
|
|
30
|
+
"description": "Task ID or unambiguous prefix to stop",
|
|
31
|
+
"type": "string"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"required": [
|
|
35
|
+
"taskId"
|
|
36
|
+
],
|
|
37
|
+
"type": "object"
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
</details>
|
|
42
|
+
<!-- pi-docs:end name="tool-contract-bg_kill" -->
|
|
43
|
+
|
|
44
|
+
Stop a running background task by id.
|
|
45
|
+
|
|
46
|
+
## Schema
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
Required fields:
|
|
50
|
+
|
|
51
|
+
- `taskId: string` — exact task id or unambiguous prefix.
|
|
52
|
+
|
|
53
|
+
## When to use
|
|
54
|
+
|
|
55
|
+
Use when the user asks to stop a background task or when a `bg_run` command is no longer needed.
|
|
56
|
+
|
|
57
|
+
## Defaults
|
|
58
|
+
|
|
59
|
+
No defaults. The task must be running.
|
|
60
|
+
|
|
61
|
+
## Lifecycle
|
|
62
|
+
|
|
63
|
+
A successful kill sets the task terminal status to `killed`. Killing a completed, failed, or already killed task rejects loudly.
|
|
64
|
+
|
|
65
|
+
## Examples
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{"taskId":"b12345678"}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{"taskId":"b1234"}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Output/result
|
|
76
|
+
|
|
77
|
+
Text result:
|
|
78
|
+
|
|
79
|
+
```text
|
|
80
|
+
Killed background task <name> (<id>). Output: .pi/tasks/.../<id>.output
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Structured details:
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
{ task: BgTaskSnapshot, message: string }
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Errors
|
|
90
|
+
|
|
91
|
+
- Missing/empty id: `Task ID is required`.
|
|
92
|
+
- Unknown id/prefix: `Unknown background task ID: <id>`.
|
|
93
|
+
- Ambiguous prefix: lists matching task ids.
|
|
94
|
+
- Non-running task: `Task <id> is <status>, not running`.
|
|
95
|
+
- Platform-specific process termination failures are loud.
|
|
96
|
+
|
|
97
|
+
## Runtime artifacts
|
|
98
|
+
|
|
99
|
+
Output and metadata remain under `.pi/tasks/...`. Termination diagnostics may be written into the output file and `error` metadata.
|
|
100
|
+
|
|
101
|
+
## Safety boundaries
|
|
102
|
+
|
|
103
|
+
Task control only. POSIX and Windows process-tree semantics differ; Windows force failures report that descendants may have leaked. Shell commands are not sandboxed.
|
|
104
|
+
|
|
105
|
+
## Related docs
|
|
106
|
+
|
|
107
|
+
- [`/kill`](../commands/kill.md)
|
|
108
|
+
- [`bg_status`](bg_status.md)
|
|
109
|
+
- [`bg_logs`](bg_logs.md)
|
|
110
|
+
- [Background task runtime](../subsystems/background-task-runtime.md)
|
|
111
|
+
|
|
112
|
+
## Source ownership/reference
|
|
113
|
+
|
|
114
|
+
Tool registration lives in `src/extension.ts`; task stopping is owned by [background-task-runtime](../subsystems/background-task-runtime.md).
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
---
|
|
2
|
+
doc_id: tools/bg_logs
|
|
3
|
+
audience: agent
|
|
4
|
+
mode: mixed
|
|
5
|
+
review_policy: contract
|
|
6
|
+
stability: stable
|
|
7
|
+
covers_surfaces: [tool:bg_logs]
|
|
8
|
+
covers_sources: []
|
|
9
|
+
---
|
|
10
|
+
# `bg_logs`
|
|
11
|
+
|
|
12
|
+
<!-- pi-docs:begin name="tool-contract-bg_logs" generator="scripts/docs/generate.mjs" -->
|
|
13
|
+
- Label: **Background Logs**
|
|
14
|
+
- Source: `src/extension.ts:852`
|
|
15
|
+
- Description: Read bounded output from a background task for deliberate inspection; this is not a waiting primitive. Output is capped at 50.0KB for model safety and points to the full output file when truncated.
|
|
16
|
+
- Root schema: `object`
|
|
17
|
+
|
|
18
|
+
| Field | Required | Type | Description | Constraints |
|
|
19
|
+
| --- | --- | --- | --- | --- |
|
|
20
|
+
| `maxBytes` | no | `number` | Maximum bytes to return, capped at 50.0KB. Default: 50.0KB. | |
|
|
21
|
+
| `tail` | no | `boolean` | Read the tail of the log when true, head when false. Default: true. | |
|
|
22
|
+
| `taskId` | yes | `string` | Task ID or unambiguous prefix | |
|
|
23
|
+
|
|
24
|
+
<details>
|
|
25
|
+
<summary>Normalized TypeBox contract</summary>
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"properties": {
|
|
31
|
+
"maxBytes": {
|
|
32
|
+
"description": "Maximum bytes to return, capped at 50.0KB. Default: 50.0KB.",
|
|
33
|
+
"type": "number"
|
|
34
|
+
},
|
|
35
|
+
"tail": {
|
|
36
|
+
"description": "Read the tail of the log when true, head when false. Default: true.",
|
|
37
|
+
"type": "boolean"
|
|
38
|
+
},
|
|
39
|
+
"taskId": {
|
|
40
|
+
"description": "Task ID or unambiguous prefix",
|
|
41
|
+
"type": "string"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"required": [
|
|
45
|
+
"taskId"
|
|
46
|
+
],
|
|
47
|
+
"type": "object"
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
</details>
|
|
52
|
+
<!-- pi-docs:end name="tool-contract-bg_logs" -->
|
|
53
|
+
|
|
54
|
+
Read bounded output from a background task.
|
|
55
|
+
|
|
56
|
+
## Schema
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
Required fields:
|
|
60
|
+
|
|
61
|
+
- `taskId: string` — exact task id or unambiguous prefix.
|
|
62
|
+
|
|
63
|
+
Optional fields:
|
|
64
|
+
|
|
65
|
+
- `maxBytes: number` — normalized to `[1, MAX_LOG_BYTES]`, with a current cap of up to 50 KiB.
|
|
66
|
+
- `tail: boolean` — `true` reads the tail; `false` reads the head. Default `true`.
|
|
67
|
+
|
|
68
|
+
## When to use
|
|
69
|
+
|
|
70
|
+
Use only when output bytes are needed: after a terminal notification and you need details, when the user asks for logs, when automatic completion was disabled, or when diagnosing a concrete hang.
|
|
71
|
+
|
|
72
|
+
Do **not** repeatedly call `bg_logs` to wait for completion while a notification is pending.
|
|
73
|
+
|
|
74
|
+
## Defaults
|
|
75
|
+
|
|
76
|
+
- `maxBytes`: default bounded log size, currently up to 50 KiB.
|
|
77
|
+
- `tail`: `true`.
|
|
78
|
+
|
|
79
|
+
## Lifecycle
|
|
80
|
+
|
|
81
|
+
`bg_logs` is a point-in-time file read. Running tasks may append more output later; the tool does not follow or subscribe.
|
|
82
|
+
|
|
83
|
+
## Examples
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{"taskId":"b12345678"}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{"taskId":"b1234","maxBytes":4096,"tail":false}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Output/result
|
|
94
|
+
|
|
95
|
+
Text content is the selected output slice plus a full-output notice. If truncated:
|
|
96
|
+
|
|
97
|
+
- tail reads prepend `[Showing tail ... Full output: <path>]`,
|
|
98
|
+
- head reads append `[Showing head ... Full output: <path>]`.
|
|
99
|
+
|
|
100
|
+
If not truncated, the result appends `[Full output: <path>]`. Structured details:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
{ task: BgTaskSnapshot, path: string, bytesRead: number, truncated: boolean, tail: boolean }
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The `path` is the full output path relative to the task cwd, preserved for opening the complete file.
|
|
107
|
+
|
|
108
|
+
## Errors
|
|
109
|
+
|
|
110
|
+
- Missing/empty id: `Task ID is required`.
|
|
111
|
+
- Unknown id/prefix: `Unknown background task ID: <id>`.
|
|
112
|
+
- Ambiguous prefix: lists matching task ids.
|
|
113
|
+
- Missing output file: `Output file does not exist for <id>: <path>`.
|
|
114
|
+
|
|
115
|
+
## Runtime artifacts
|
|
116
|
+
|
|
117
|
+
Reads `.pi/tasks/<session-id>-<pid>/<task-id>.output`; does not modify output or metadata.
|
|
118
|
+
|
|
119
|
+
## Safety boundaries
|
|
120
|
+
|
|
121
|
+
Read-only, bounded, model-safe inspection. It is not a polling primitive. For the larger interactive tail buffer, use the [`/tasks`](../commands/task-manager.md) detail view.
|
|
122
|
+
|
|
123
|
+
## Related docs
|
|
124
|
+
|
|
125
|
+
- [`/logs`](../commands/logs.md)
|
|
126
|
+
- [`bg_status`](bg_status.md)
|
|
127
|
+
- [`bg_run`](bg_run.md)
|
|
128
|
+
- [Completion delivery](../concepts/completion-delivery.md)
|
|
129
|
+
- [Background task runtime](../subsystems/background-task-runtime.md)
|
|
130
|
+
|
|
131
|
+
## Source ownership/reference
|
|
132
|
+
|
|
133
|
+
Tool registration lives in `src/extension.ts`; bounded log reads are owned by [background-task-runtime](../subsystems/background-task-runtime.md).
|