@zihanw/pi-forge 0.4.0-beta.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -1
- package/PUBLIC_API.md +3 -26
- package/README.md +90 -601
- package/README.zh-CN.md +86 -585
- package/SUBAGENT_ADAPTER_CONTRACT.md +3 -197
- package/dist/forge-config.d.ts +80 -0
- package/dist/forge-config.d.ts.map +1 -1
- package/dist/forge-config.js +268 -18
- package/dist/forge-config.js.map +1 -1
- package/dist/index.d.ts +1 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -4
- package/dist/index.js.map +1 -1
- package/dist/lifecycle.js +1 -1
- package/dist/profile-service.d.ts +1 -1
- package/dist/profile-service.d.ts.map +1 -1
- package/dist/profile-service.js +10 -5
- package/dist/profile-service.js.map +1 -1
- package/dist/runtime/subagent-runtime.d.ts +23 -8
- package/dist/runtime/subagent-runtime.d.ts.map +1 -1
- package/dist/runtime/subagent-runtime.js +283 -62
- package/dist/runtime/subagent-runtime.js.map +1 -1
- package/dist/storage.d.ts +1 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +15 -1
- package/dist/storage.js.map +1 -1
- package/dist/subagent/canonical.d.ts +19 -7
- package/dist/subagent/canonical.d.ts.map +1 -1
- package/dist/subagent/canonical.js +19 -47
- package/dist/subagent/canonical.js.map +1 -1
- package/dist/subagent/contract.d.ts +1 -2
- package/dist/subagent/contract.d.ts.map +1 -1
- package/dist/subagent/contract.js +1 -2
- package/dist/subagent/contract.js.map +1 -1
- package/dist/subagent/index.d.ts +4 -3
- package/dist/subagent/index.d.ts.map +1 -1
- package/dist/subagent/index.js +4 -3
- package/dist/subagent/index.js.map +1 -1
- package/dist/subagent/plan.d.ts +5 -1
- package/dist/subagent/plan.d.ts.map +1 -1
- package/dist/subagent/plan.js +28 -31
- package/dist/subagent/plan.js.map +1 -1
- package/dist/subagent/types.d.ts +62 -178
- package/dist/subagent/types.d.ts.map +1 -1
- package/dist/subagent/types.js +1 -1
- package/dist/subagent/types.js.map +1 -1
- package/dist/subagent/validation.d.ts +14 -14
- package/dist/subagent/validation.d.ts.map +1 -1
- package/dist/subagent/validation.js +52 -238
- package/dist/subagent/validation.js.map +1 -1
- package/dist/subagent-command.d.ts.map +1 -1
- package/dist/subagent-command.js +109 -16
- package/dist/subagent-command.js.map +1 -1
- package/dist/subagent-host.d.ts.map +1 -1
- package/dist/subagent-host.js +1 -0
- package/dist/subagent-host.js.map +1 -1
- package/dist/subagent-profile-tool.d.ts +25 -2
- package/dist/subagent-profile-tool.d.ts.map +1 -1
- package/dist/subagent-profile-tool.js +39 -8
- package/dist/subagent-profile-tool.js.map +1 -1
- package/dist/subagent-tool.d.ts +6 -3
- package/dist/subagent-tool.d.ts.map +1 -1
- package/dist/subagent-tool.js +85 -14
- package/dist/subagent-tool.js.map +1 -1
- package/dist/web-editor/client-script.generated.d.ts +1 -1
- package/dist/web-editor/client-script.generated.d.ts.map +1 -1
- package/dist/web-editor/client-script.generated.js +1 -1
- package/dist/web-editor/client-script.generated.js.map +1 -1
- package/dist/web-editor/client-styles.d.ts +2 -0
- package/dist/web-editor/client-styles.d.ts.map +1 -0
- package/dist/web-editor/client-styles.generated.d.ts +2 -0
- package/dist/web-editor/client-styles.generated.d.ts.map +1 -0
- package/dist/web-editor/client-styles.generated.js +3 -0
- package/dist/web-editor/client-styles.generated.js.map +1 -0
- package/dist/web-editor/client-styles.js +2 -0
- package/dist/web-editor/client-styles.js.map +1 -0
- package/dist/web-editor/page.d.ts +2 -0
- package/dist/web-editor/page.d.ts.map +1 -1
- package/dist/web-editor/page.js +11 -73
- package/dist/web-editor/page.js.map +1 -1
- package/dist/web-editor/server.d.ts.map +1 -1
- package/dist/web-editor/server.js +148 -0
- package/dist/web-editor/server.js.map +1 -1
- package/dist/web-editor/styles.d.ts.map +1 -1
- package/dist/web-editor/styles.js +60 -3
- package/dist/web-editor/styles.js.map +1 -1
- package/dist/web-editor/types.d.ts +79 -0
- package/dist/web-editor/types.d.ts.map +1 -1
- package/dist/web-host.d.ts +13 -2
- package/dist/web-host.d.ts.map +1 -1
- package/dist/web-host.js +301 -0
- package/dist/web-host.js.map +1 -1
- package/docs/README.md +41 -0
- package/docs/concepts/agent-profiles.md +60 -0
- package/docs/concepts/prompt-stacks.md +90 -0
- package/docs/design/README.md +17 -0
- package/docs/design/roadmap-0.4-archive.md +216 -0
- package/docs/design/subagents/design-review.md +220 -0
- package/docs/design/subagents/interface-design.md +274 -0
- package/docs/design/subagents/sdk-spike-findings.md +117 -0
- package/docs/development/complexity-review.md +86 -0
- package/docs/development/release.md +31 -0
- package/docs/development/roadmap.md +42 -0
- package/docs/development/setup.md +75 -0
- package/docs/getting-started.md +93 -0
- package/docs/guides/custom-macros-and-slots.md +68 -0
- package/docs/guides/debugging.md +39 -0
- package/docs/guides/delegation.md +99 -0
- package/docs/guides/sillytavern-import.md +47 -0
- package/docs/guides/use-cases.md +65 -0
- package/docs/guides/web-editor.md +75 -0
- package/docs/reference/commands.md +60 -0
- package/docs/reference/configuration.md +64 -0
- package/docs/reference/features.md +279 -0
- package/docs/reference/macros-and-slots.md +82 -0
- package/docs/reference/public-api.md +28 -0
- package/docs/reference/stack-schema.md +167 -0
- package/docs/reference/subagent-adapter.md +204 -0
- package/docs/zh-CN/README.md +37 -0
- package/docs/zh-CN/concepts/agent-profiles.md +44 -0
- package/docs/zh-CN/concepts/prompt-stacks.md +40 -0
- package/docs/zh-CN/getting-started.md +79 -0
- package/docs/zh-CN/guides/delegation.md +66 -0
- package/docs/zh-CN/guides/web-editor.md +45 -0
- package/docs/zh-CN/reference/commands.md +58 -0
- package/package.json +28 -14
- package/dist/subagent/backend-registry.d.ts +0 -75
- package/dist/subagent/backend-registry.d.ts.map +0 -1
- package/dist/subagent/backend-registry.js +0 -463
- package/dist/subagent/backend-registry.js.map +0 -1
- package/dist/subagent/diagnostics.d.ts +0 -3
- package/dist/subagent/diagnostics.d.ts.map +0 -1
- package/dist/subagent/diagnostics.js +0 -5
- package/dist/subagent/diagnostics.js.map +0 -1
- package/dist/subagent/pi-model-runtime.d.ts +0 -8
- package/dist/subagent/pi-model-runtime.d.ts.map +0 -1
- package/dist/subagent/pi-model-runtime.js +0 -22
- package/dist/subagent/pi-model-runtime.js.map +0 -1
- package/dist/subagent/pi-sdk-backend.d.ts +0 -23
- package/dist/subagent/pi-sdk-backend.d.ts.map +0 -1
- package/dist/subagent/pi-sdk-backend.js +0 -383
- package/dist/subagent/pi-sdk-backend.js.map +0 -1
- package/dist/subagent/pi-subprocess-backend.d.ts +0 -72
- package/dist/subagent/pi-subprocess-backend.d.ts.map +0 -1
- package/dist/subagent/pi-subprocess-backend.js +0 -756
- package/dist/subagent/pi-subprocess-backend.js.map +0 -1
- package/dist/subagent/subprocess-bridge.d.ts +0 -21
- package/dist/subagent/subprocess-bridge.d.ts.map +0 -1
- package/dist/subagent/subprocess-bridge.js +0 -87
- package/dist/subagent/subprocess-bridge.js.map +0 -1
- package/dist/subagent/subprocess-report.d.ts +0 -4
- package/dist/subagent/subprocess-report.d.ts.map +0 -1
- package/dist/subagent/subprocess-report.js +0 -55
- package/dist/subagent/subprocess-report.js.map +0 -1
- package/dist/subagent-contract.d.ts +0 -8
- package/dist/subagent-contract.d.ts.map +0 -1
- package/dist/subagent-contract.js +0 -8
- package/dist/subagent-contract.js.map +0 -1
- package/dist/web-editor/client/api.d.ts +0 -9
- package/dist/web-editor/client/api.d.ts.map +0 -1
- package/dist/web-editor/client/api.js +0 -26
- package/dist/web-editor/client/api.js.map +0 -1
- package/dist/web-editor/client/dom.d.ts +0 -13
- package/dist/web-editor/client/dom.d.ts.map +0 -1
- package/dist/web-editor/client/dom.js +0 -30
- package/dist/web-editor/client/dom.js.map +0 -1
- package/dist/web-editor/client/inspector.d.ts +0 -22
- package/dist/web-editor/client/inspector.d.ts.map +0 -1
- package/dist/web-editor/client/inspector.js +0 -226
- package/dist/web-editor/client/inspector.js.map +0 -1
- package/dist/web-editor/client/main.d.ts +0 -2
- package/dist/web-editor/client/main.d.ts.map +0 -1
- package/dist/web-editor/client/main.js +0 -1468
- package/dist/web-editor/client/main.js.map +0 -1
- package/dist/web-editor/client/policy-editor.d.ts +0 -16
- package/dist/web-editor/client/policy-editor.d.ts.map +0 -1
- package/dist/web-editor/client/policy-editor.js +0 -330
- package/dist/web-editor/client/policy-editor.js.map +0 -1
- package/dist/web-editor/client/regex-editor.d.ts +0 -19
- package/dist/web-editor/client/regex-editor.d.ts.map +0 -1
- package/dist/web-editor/client/regex-editor.js +0 -281
- package/dist/web-editor/client/regex-editor.js.map +0 -1
- package/dist/web-editor/client/types.d.ts +0 -60
- package/dist/web-editor/client/types.d.ts.map +0 -1
- package/dist/web-editor/client/types.js +0 -2
- package/dist/web-editor/client/types.js.map +0 -1
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# Subagent request/response design
|
|
2
|
+
|
|
3
|
+
Status: historical design and implementation record for the completed 0.4 path. Execution ownership (backend registry, preflight binding, plan sealing, conversation/execution fingerprints, lifecycle, and the fresh-process `pi-subprocess-readonly`/`pi-rpc-readonly` backends) lives in `@zihanw/pi-subagent-runtime`; the former in-package registry and `pi-sdk-isolated` compatibility backend were removed in that migration. The broader Pi SDK spike is recorded in the [SDK spike findings](sdk-spike-findings.md) (harness since removed), and the concrete exported semantics are documented in the [subagent adapter contract](../../reference/subagent-adapter.md).
|
|
4
|
+
|
|
5
|
+
## Goals
|
|
6
|
+
|
|
7
|
+
- Make pi-forge profiles usable by native, subprocess, package-provided, or remote backends without requiring every backend to reproduce the parent Pi runtime.
|
|
8
|
+
- Start every subagent with a clean conversational context while allowing explicit, bounded context seeding.
|
|
9
|
+
- Keep prompt stacks as the profile-level source of prompt layout, visible-tool policy, and model-visible skills.
|
|
10
|
+
- Keep access, limits, cancellation, trace storage, and result reporting outside reusable profiles.
|
|
11
|
+
- Return a compact parent-visible tool result while retaining normalized execution history for authorized inspection.
|
|
12
|
+
- Export the demonstrated request/resolution/preflight/plan/response boundary while keeping a full owned runner, orchestration, and automatic delegation out of the package surface.
|
|
13
|
+
|
|
14
|
+
## Execution Flow
|
|
15
|
+
|
|
16
|
+
The portable caller request is not itself executable. Execution has five stages:
|
|
17
|
+
|
|
18
|
+
```text
|
|
19
|
+
AgentRequest
|
|
20
|
+
-> host profile/stack/dependency resolution
|
|
21
|
+
-> backend discovery and preflight
|
|
22
|
+
-> backend-assisted host plan preparation
|
|
23
|
+
-> backend execution
|
|
24
|
+
-> AgentResponse
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### 1. AgentRequest
|
|
28
|
+
|
|
29
|
+
The parent supplies intent: profile selection, task/media, explicit selected context, access requirements, limits, and parent-depth provenance. It does not contain parent runtime model objects, loaded files, credentials, raw session entries, or a compiled prompt.
|
|
30
|
+
|
|
31
|
+
### 2. Host resolution
|
|
32
|
+
|
|
33
|
+
pi-forge validates profile syntax, resolves the referenced prompt stack, identifies required custom macro/slot registrations, resolves selected parent-context references, and creates immutable declarative provenance. This stage does not claim that the target backend has the model, credentials, tools, isolation, or limit support needed to execute it.
|
|
34
|
+
|
|
35
|
+
Current parent-runtime resolution used by `/profile use` remains valid for applying profiles to the parent. Subagent host resolution must be a separate operation rather than reusing parent model/auth diagnostics as backend truth.
|
|
36
|
+
|
|
37
|
+
### 3. Backend discovery and preflight
|
|
38
|
+
|
|
39
|
+
Before prompt compilation, the selected backend reports:
|
|
40
|
+
|
|
41
|
+
- Model availability, authentication, thinking-level support, and media support.
|
|
42
|
+
- A stable tool catalog with backend tool IDs, policy-facing names, prompt snippets, and optional adapter mappings.
|
|
43
|
+
- Prompt-runtime inputs needed for Pi-compatible base prompts, tool guidance, skills, and context resources.
|
|
44
|
+
- Workspace/mount materialization support and granular access enforcement.
|
|
45
|
+
- Supported hard limits, cancellation behavior, trace support, and artifact behavior.
|
|
46
|
+
- Remote data-egress requirements.
|
|
47
|
+
|
|
48
|
+
The host applies the prompt stack's tool policy to the backend catalog. An allow pattern that matches nothing remains a warning unless separate dependency metadata marks that tool or capability as required.
|
|
49
|
+
|
|
50
|
+
### 4. Backend-assisted plan preparation and AgentExecutionPlan
|
|
51
|
+
|
|
52
|
+
The host combines the resolved profile, backend preflight receipt, selected context, and prompt-stack compiler into an immutable execution plan. The plan contains prepared system text/messages, exact model and thinking level, effective backend tool IDs, materialized workspace handles, enforced limits, diagnostics, provenance, and a stable execution fingerprint.
|
|
53
|
+
|
|
54
|
+
Some backends cannot expose exact prompt-runtime inputs during passive preflight. Pi SDK 0.80.6, for example, exposes its exact base prompt, tool snippets, skills, and context options through `before_agent_start`, immediately before provider execution. Such an adapter may supply those inputs to a trusted host preparation callback after accepting the prompt, provided it blocks provider transport until host compilation, protected-task validation, limit checks, and plan finalization succeed. A partial dry preflight must declare its prompt-runtime fidelity and cannot masquerade as the exact execution plan.
|
|
55
|
+
|
|
56
|
+
Custom macros and slots execute during plan preparation in the trusted host. Backends receive their rendered result and dependency receipt, not executable registration code. A raw `PromptStack` remains snapshot provenance and is not treated as an executable backend artifact.
|
|
57
|
+
|
|
58
|
+
For a null stack or append/prepend stack mode, the backend preflight must provide the base-prompt inputs required by the selected adapter. If the host cannot reproduce the intended base prompt, plan preparation fails.
|
|
59
|
+
|
|
60
|
+
### 5. AgentResponse
|
|
61
|
+
|
|
62
|
+
The backend returns normalized terminal status, output, enforcement receipts, effective tools/limits, artifacts, usage, and a routed trace handle. A separate projection determines what enters the parent model's context.
|
|
63
|
+
|
|
64
|
+
## Responsibility Boundaries
|
|
65
|
+
|
|
66
|
+
Effective permissions are the intersection of:
|
|
67
|
+
|
|
68
|
+
1. Profile prompt-stack tool selection.
|
|
69
|
+
2. Request access and limit requirements.
|
|
70
|
+
3. Backend-advertised capabilities and enforcement.
|
|
71
|
+
|
|
72
|
+
A backend must reject a required policy it cannot enforce. Prompt tool filtering is not a filesystem, process, or network sandbox.
|
|
73
|
+
|
|
74
|
+
pi-forge owns profile/stack resolution, trusted prompt compilation, context selection, plan creation, stable fingerprints, diagnostics, and parent-visible response projection. Backends own target-runtime preflight, execution, cancellation, backend-namespace canonicalization, enforcement receipts, usage collection, artifacts, and normalized traces.
|
|
75
|
+
|
|
76
|
+
## Context Model and Task Preservation
|
|
77
|
+
|
|
78
|
+
Subagents inherit no parent conversation automatically. Their prepared context contains:
|
|
79
|
+
|
|
80
|
+
1. System instructions compiled from the resolved profile and backend prompt inputs.
|
|
81
|
+
2. Optional parent-selected context rendered as quoted background evidence with provenance.
|
|
82
|
+
3. A protected final user task containing all request text and media.
|
|
83
|
+
|
|
84
|
+
Selected context may contain a provenance-bearing summary, visible user/assistant excerpts, quoted tool-result excerpts, and resource/artifact references. It never automatically contains the parent system prompt, full chat history, hidden reasoning, raw provider payloads, secrets, or environment variables.
|
|
85
|
+
|
|
86
|
+
Tool-result excerpts are background content, not native tool-result messages, because they do not have matching tool calls in the clean subagent history. Delimiters communicate instruction priority but are not a prompt-injection security boundary.
|
|
87
|
+
|
|
88
|
+
The delegated task is appended as a protected final user message after unrestricted prompt-stack message layout has been compiled. A backend adapter may combine adjacent user messages for provider compatibility, but it must preserve the delegated-context/task boundary and all structured media parts. Subagent preparation fails if the final normalized plan does not contain the complete task.
|
|
89
|
+
|
|
90
|
+
Context budgeting uses a required character/byte ceiling in v1. Any optional token estimate records the estimator/tokenizer name and version. Truncation removes optional context before required context and never truncates the final task or required media.
|
|
91
|
+
|
|
92
|
+
## Contract Artifacts
|
|
93
|
+
|
|
94
|
+
The TypeScript shapes and pure validators for the following artifacts are exported. Backend registration, explicit backend selection, and execution lifecycle are owned by `@zihanw/pi-subagent-runtime`; the extension composition root registers local `forge_subagent_profiles` discovery and drives the runtime's `pi-subprocess-readonly` (default) and `pi-rpc-readonly` backends for `forge_subagent` and `/forge-agent`.
|
|
95
|
+
|
|
96
|
+
### AgentRequest
|
|
97
|
+
|
|
98
|
+
- Schema version and host-generated request ID.
|
|
99
|
+
- Profile ID plus an optional expected source fingerprint for optimistic consistency.
|
|
100
|
+
- Structured text/media input.
|
|
101
|
+
- Optional selected-context summary/items with provenance and a character budget.
|
|
102
|
+
- Access requirements expressed through opaque workspace/resource handles, not backend-specific absolute paths.
|
|
103
|
+
- Hard execution limits and a separate parent-result projection limit.
|
|
104
|
+
- Parent run/session provenance and bounded delegation depth.
|
|
105
|
+
- Explicit remote-egress consent when a backend would transmit local project data.
|
|
106
|
+
|
|
107
|
+
### AgentProfileSnapshot
|
|
108
|
+
|
|
109
|
+
- Normalized profile fields and canonical source-profile digest.
|
|
110
|
+
- Normalized prompt-stack definition and canonical stack digest, or null.
|
|
111
|
+
- Required custom macro/slot dependency identities when available.
|
|
112
|
+
- No model-registry object, credential/auth result, loaded file path, diagnostics, session state, or secret.
|
|
113
|
+
|
|
114
|
+
This snapshot is immutable provenance. It is not sent to a backend as a promise that the profile is executable there.
|
|
115
|
+
|
|
116
|
+
### BackendPreflightResult
|
|
117
|
+
|
|
118
|
+
- Accepted/rejected state with structured diagnostics.
|
|
119
|
+
- Resolved target model and thinking level.
|
|
120
|
+
- Stable tool catalog and adapter mappings.
|
|
121
|
+
- Prompt-runtime/base-prompt inputs.
|
|
122
|
+
- Workspace materialization/mount mappings in the backend namespace.
|
|
123
|
+
- Granular enforcement capabilities and accepted hard limits.
|
|
124
|
+
- Media, cancellation, trace, artifact, and remote-egress behavior.
|
|
125
|
+
|
|
126
|
+
### AgentExecutionPlan
|
|
127
|
+
|
|
128
|
+
- Host-generated run ID, request ID, and backend ID.
|
|
129
|
+
- Prepared system prompt and normalized initial messages.
|
|
130
|
+
- Exact model, thinking level, effective backend tool IDs, and unmatched policy diagnostics.
|
|
131
|
+
- Materialized workspace handles, relative working directory, network policy, and enforcement requirements.
|
|
132
|
+
- Enforced execution limits and separate result-projection limits.
|
|
133
|
+
- Profile/stack provenance, dependency receipt, and backend preflight receipt.
|
|
134
|
+
- Canonical execution fingerprint covering all behavior-affecting prepared inputs.
|
|
135
|
+
|
|
136
|
+
The run ID exists before backend execution begins so cancellation and trace correlation do not depend on a remote backend first returning its own ID.
|
|
137
|
+
|
|
138
|
+
### AgentResponse
|
|
139
|
+
|
|
140
|
+
Response status is a discriminated union:
|
|
141
|
+
|
|
142
|
+
- `completed`: no error; output may be empty.
|
|
143
|
+
- `failed`: structured error required; optional partial output must be marked partial.
|
|
144
|
+
- `cancelled`: cancellation reason required; output is absent or explicitly partial.
|
|
145
|
+
- `timed-out`: timeout reason and enforced timeout required; output is absent or explicitly partial.
|
|
146
|
+
- `limit-reached`: the reached hard limit is required; output is absent or explicitly partial.
|
|
147
|
+
|
|
148
|
+
Every response includes request/run/backend correlation, model/profile/execution fingerprints, backend-produced enforcement receipt, effective tools and limits, duration, and artifact/trace routing metadata. `effectiveAccess` is never a request echo.
|
|
149
|
+
|
|
150
|
+
Token usage records tokenizer/model provenance when known. Cost uses an amount plus ISO currency code rather than an unqualified number. Artifact/change paths live in a named workspace namespace and include authorization, lifetime, and cleanup metadata.
|
|
151
|
+
|
|
152
|
+
Opaque backend trace IDs are registered behind host trace handles. Inspection authorizes the caller and routes through the backend/host trace registry. Hidden provider reasoning remains excluded by default.
|
|
153
|
+
|
|
154
|
+
Hard execution limits are distinct from response projection truncation. A backend that cannot enforce a required timeout, turn, token, output, filesystem, or network constraint rejects preflight.
|
|
155
|
+
|
|
156
|
+
## Access and Data-Egress Model
|
|
157
|
+
|
|
158
|
+
Requests identify host resources with opaque workspace/resource handles. Backend preflight maps them into backend-visible mounts or uploaded resources. The execution plan uses mount IDs plus normalized relative paths rather than assuming host absolute paths exist remotely.
|
|
159
|
+
|
|
160
|
+
- `none` permits no filesystem mounts and no filesystem working directory.
|
|
161
|
+
- `read-only` permits only read-only mounts.
|
|
162
|
+
- `workspace-write` permits explicitly identified read-write mounts; all other mounts remain read-only or absent.
|
|
163
|
+
- An access receipt distinguishes an `isolated` execution boundary from an explicitly unsafe `shared-user` process. At the shared-user boundary, access levels describe the model-visible tool policy rather than the child process's operating-system permissions.
|
|
164
|
+
- A working directory, when present, must be contained within an accepted mount.
|
|
165
|
+
- The backend canonicalizes and checks paths in its own namespace immediately before access and must enforce containment against symlink races.
|
|
166
|
+
- Model/provider transport is distinct from agent-accessible network tools.
|
|
167
|
+
- Sending project content to a remote backend requires an explicit egress decision; project trust alone is insufficient consent.
|
|
168
|
+
|
|
169
|
+
Capabilities are granular claims such as read-only mount isolation, read-write mount isolation, symlink-safe containment, agent-network isolation, timeout enforcement, turn enforcement, token-budget enforcement, output enforcement, cancellation, media transport, artifact retention, and trace inspection. Broad booleans are insufficient.
|
|
170
|
+
|
|
171
|
+
## Fingerprints and Compatibility
|
|
172
|
+
|
|
173
|
+
New portable fingerprints use canonical serialization and a named algorithm/version such as `sha256:v1:<digest>`.
|
|
174
|
+
|
|
175
|
+
- Source-profile fingerprint: normalized declarative profile.
|
|
176
|
+
- Prompt-stack fingerprint: normalized declarative stack.
|
|
177
|
+
- Execution fingerprint: compiled system/messages, exact model/thinking, effective tool IDs/mappings, relevant prompt-runtime inputs, selected-context/resource digests, dependency receipt, materialized access policy, enforced limits, and adapter/preflight version.
|
|
178
|
+
|
|
179
|
+
The existing `agentProfileFingerprint()` JSON string remains unchanged for stored branch provenance and drift compatibility. Portable snapshot/execution digests are new fields with separate semantics.
|
|
180
|
+
|
|
181
|
+
## Parent-Visible Result
|
|
182
|
+
|
|
183
|
+
The complete response is control-plane data. The main agent receives a bounded tool-result projection containing run ID, terminal status, output, and compact errors/warnings when applicable.
|
|
184
|
+
|
|
185
|
+
The human can expand the same tool result to inspect the plan summary, approval receipt, diagnostics, usage, normalized response, and complete captured subprocess transcript/tool events. Those details stay out of the normal model-visible projection. The full prepared prompt is shown only on demand before approval and is not persisted in result details by default. `/tree` changes the active conversation branch; it cannot undo provider egress, billing, or external effects. Contract trace inspection, artifacts, and resumable sessions remain separate and deferred.
|
|
186
|
+
|
|
187
|
+
## Revised Implementation Plan
|
|
188
|
+
|
|
189
|
+
### Integration checkpoint: require a user-visible walking skeleton
|
|
190
|
+
|
|
191
|
+
Fake-backend conformance proves contract and registry behavior, while the standalone SDK spike proved broader Pi provider behavior. The shipped walking skeleton sends a human-requested task through the complete profile-resolution, runtime-preflight, prompt-preparation, plan-validation, provider-execution, and response-projection path.
|
|
192
|
+
|
|
193
|
+
The first concrete integration was a pi-forge-owned `pi-sdk-isolated` adapter plus a human-operated plan/run command. The current integration drives the runtime package's foreground `pi-subprocess-readonly` (default) and `pi-rpc-readonly` backends for the command and model-callable tool. It exposes only stack-filtered read/list/search tools, declares a shared-user boundary rather than filesystem isolation, requires explicit approval of an immutable plan bound to runtime-issued fingerprints, and returns bounded output plus expandable reports.
|
|
194
|
+
|
|
195
|
+
This integration also exposed a contract seam hidden by the fake backend: backend-assisted preparation cannot require the caller to fabricate the prompt runtime that the backend is responsible for discovering. The backend must supply complete, canonical compiler inputs; the host must compile from them; and the registry must return the exact runtime/preparation pair used for execution-plan construction.
|
|
196
|
+
|
|
197
|
+
### Iteration 1: Shared profile service
|
|
198
|
+
|
|
199
|
+
- Extract shared typed profile repository operations for load, capture, save/update, and delete.
|
|
200
|
+
- Extract profile application and rollback from command rendering.
|
|
201
|
+
- Extract typed resolution preview and runtime/provenance drift status.
|
|
202
|
+
- Refactor commands to use the service without changing current CLI behavior.
|
|
203
|
+
- Add service-level tests so profile UI and subagent preparation share one implementation.
|
|
204
|
+
|
|
205
|
+
### Iteration 2: Internal real-backend spike (completed)
|
|
206
|
+
|
|
207
|
+
- Prototype one in-memory Pi SDK backend using a fresh `SessionManager`, explicit model/thinking, a controlled tool baseline, cancellation, and compact output.
|
|
208
|
+
- Exercise a real profile, restrictive prompt stack, custom macro/slot dependency, media input, and current local provider.
|
|
209
|
+
- Record actual SDK/runtime requirements and failure points.
|
|
210
|
+
- Keep all spike types internal and expose no run tool.
|
|
211
|
+
|
|
212
|
+
Implemented as the opt-in `scripts/subagent-sdk-spike.ts` (removed in the 0.4 cleanup after its findings were productized in the runtime's shared preparation gate); results and limitations are recorded in `SUBAGENT_SDK_SPIKE_FINDINGS.md`.
|
|
213
|
+
|
|
214
|
+
### Iteration 3: Resolve/preflight/plan boundary (completed)
|
|
215
|
+
|
|
216
|
+
- Split parent application resolution from backend-independent host resolution.
|
|
217
|
+
- Define internal request, backend descriptor/preflight, backend-assisted preparation callback, execution-plan, response, enforcement-receipt, and diagnostic types based on the spike.
|
|
218
|
+
- Implement protected task/context preparation and tool negotiation.
|
|
219
|
+
- Validate null/replace/append/prepend stacks and missing custom dependencies.
|
|
220
|
+
|
|
221
|
+
Implemented in `src/subagent-host.ts` and focused modules under `src/subagent/`, with `src/subagent-contract.ts` retained as a compatibility barrel. The SDK spike consumes the shared protected-task and host-resolution helpers.
|
|
222
|
+
|
|
223
|
+
### Iteration 4: Stable validation and fingerprints (completed)
|
|
224
|
+
|
|
225
|
+
- Add canonical snapshot/stack/execution digests without changing legacy provenance fingerprints.
|
|
226
|
+
- Add pure validators and the full status/error/access/limit matrices.
|
|
227
|
+
- Add deterministic context budgeting and artifact/trace namespace validation.
|
|
228
|
+
- Export only the portions demonstrated by the real spike.
|
|
229
|
+
|
|
230
|
+
Implemented with canonical `sha256:v1` fingerprints, deterministic UTF-8 context budgeting, access/limit/status matrices, artifact/trace validation, and package-root exports. Legacy profile provenance fingerprints are unchanged.
|
|
231
|
+
|
|
232
|
+
### Iteration 5: Backend registration and conformance (completed)
|
|
233
|
+
|
|
234
|
+
- Added an optional backend registry/dispatcher with validated descriptor discovery and granular capability negotiation.
|
|
235
|
+
- Added a deterministic fake backend and reusable conformance fixtures shaped by the real spike.
|
|
236
|
+
- Normalized cancellation races, host-abort timeouts, provider failures, malformed responses, enforcement receipts, and authorization-scoped trace routing.
|
|
237
|
+
- pi-forge remains fully functional with no registered backend; the registry starts empty.
|
|
238
|
+
|
|
239
|
+
### Iteration 6: Concrete Pi SDK walking skeleton (completed)
|
|
240
|
+
|
|
241
|
+
- Correct backend-assisted prompt-runtime ownership and add complete compiler-input validation/fingerprints.
|
|
242
|
+
- Extract an access-none, no-tool, in-memory Pi SDK backend from the completed spike.
|
|
243
|
+
- Add human-operated backend discovery, dry plan, and explicit real-run commands through the registry.
|
|
244
|
+
- Cover pre-transport refusal, provider failure, host timeout, cancellation, response normalization, and cleanup without live provider calls in ordinary tests.
|
|
245
|
+
|
|
246
|
+
Implemented as the exported experimental `PiSdkIsolatedBackend` and `/forge-agent backends|plan|run` command path. Ordinary tests use Pi's faux provider through a real in-memory `AgentSession`, proving provider gating and final context without network traffic.
|
|
247
|
+
|
|
248
|
+
### Iteration 7: Foreground parent integration (completed)
|
|
249
|
+
|
|
250
|
+
- Added no-egress `forge_subagent_profiles` discovery so the main agent can select only from profile IDs explicitly enabled by trusted-project delegation policy rather than guessing.
|
|
251
|
+
- Added the sequential `forge_subagent` tool on the shared command/runtime path rather than creating a second runner.
|
|
252
|
+
- Added project-only `subagents.profiles.<id>` policy so ordinary profiles remain portable and independently usable while delegation eligibility, backend, and timeout are resolved per profile; global config remains limited to general defaults until global profile and stack storage have explicit scope semantics.
|
|
253
|
+
- Resolve the profile and prepare the exact immutable plan before asking for interactive approval or permitting provider transport.
|
|
254
|
+
- Show a compact default review, with full prompt inspection on demand, and bind approval to the execution fingerprint.
|
|
255
|
+
- Insert only bounded response text into parent context while retaining complete transcript/tool-event details for expanded human inspection.
|
|
256
|
+
- Keep execution text-only, foreground, clean-context, read-only, and shared-user; cancellation, rejection, provider failure, and missing-UI cases fail closed.
|
|
257
|
+
|
|
258
|
+
### Iteration 8: Sandbox and staged-write decision
|
|
259
|
+
|
|
260
|
+
- Evaluate an optional bubblewrap-style backend that can honestly enforce allowed roots, network policy, and subprocess restrictions without changing the portable contract.
|
|
261
|
+
- Design writes as a separately approved staged patch/change set with clear inspection and undo semantics; do not simply add `write`, `edit`, or shell to the shared-user child.
|
|
262
|
+
- Continue deferring resumable agents, retries, queues, chains, pipelines, background work, and concurrency orchestration until concrete demand exists.
|
|
263
|
+
|
|
264
|
+
Profile UI can proceed independently on the completed Iteration 1 service; it does not need to block parent integration or a concrete adapter decision. Each iteration remains independently reviewable and revertible.
|
|
265
|
+
|
|
266
|
+
## Deferred Decisions
|
|
267
|
+
|
|
268
|
+
- Whether the experimental Pi SDK backend remains built in, becomes separately configurable, or moves to an optional integration after 0.4 feedback.
|
|
269
|
+
- Trace/artifact storage location, retention defaults, redaction, and cleanup implementation.
|
|
270
|
+
- Resumable sessions and continuation references.
|
|
271
|
+
- Automatic retries, fallbacks, priorities, queues, and concurrency.
|
|
272
|
+
- Secret/environment injection.
|
|
273
|
+
- Structured JSON-schema output.
|
|
274
|
+
- Automatic parent-context selection beyond explicit summaries and references.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Historical Pi SDK subagent spike findings
|
|
2
|
+
|
|
3
|
+
Status: completed internal spike against `@earendil-works/pi-coding-agent` 0.80.6 on 2026-07-12. Its contract findings are productized in `@zihanw/pi-subagent-runtime`'s shared SDK preparation gate, which both fresh-process backends use. The spike harness (`scripts/subagent-sdk-spike*.ts`) was removed in the 0.4 cleanup; with it went the only live media-transport and trusted-extension preparation diagnostic, to be re-established when delegated media tasks are productized. The 0.80.6 observations and terminology below remain a historical record.
|
|
4
|
+
|
|
5
|
+
## Deliverable
|
|
6
|
+
|
|
7
|
+
The spike was available through `npm run spike:subagent -- --cwd /path/to/project --profile PROFILE_ID` before its removal in the 0.4 cleanup.
|
|
8
|
+
|
|
9
|
+
Dry-run is the default. A provider call requires `--execute`; that explicit flag is also the spike's consent to transmit the supplied task/media to the selected provider. The other spike-only flags are:
|
|
10
|
+
|
|
11
|
+
- `--task TEXT`
|
|
12
|
+
- `--timeout MILLISECONDS`
|
|
13
|
+
- `--access none|read-only|workspace-write`
|
|
14
|
+
- `--image PATH` (repeatable)
|
|
15
|
+
- `--load-forge-extensions` to execute trusted global/project pi-forge registration code
|
|
16
|
+
|
|
17
|
+
The command emits a JSON preflight/execution report. It creates an in-memory `SessionManager`, uses an isolated SDK resource directory and working directory for `access=none`, loads only the inline compiler bridge, does not write a Pi session file, and disposes the session and trusted registrations when finished.
|
|
18
|
+
|
|
19
|
+
Execution currently rejects `read-only` and `workspace-write`. The SDK can filter tools, but this adapter cannot produce an allowed-root, symlink-safe filesystem/process/network isolation receipt. `access=none` is enforceable by setting the active tool set to empty.
|
|
20
|
+
|
|
21
|
+
## Validated Behavior
|
|
22
|
+
|
|
23
|
+
### Real profile, model, auth, and stack
|
|
24
|
+
|
|
25
|
+
The dry and execute paths resolved `/home/bruhw/programming`'s `default` profile to:
|
|
26
|
+
|
|
27
|
+
- Model: `opencode-go/glm-5.2`
|
|
28
|
+
- Thinking: `high`
|
|
29
|
+
- Stack: `qiqi-assistant`
|
|
30
|
+
- Auth: configured through Pi's real `AuthStorage` and `ModelRegistry`
|
|
31
|
+
|
|
32
|
+
The SDK session used those exact values, remained in memory, and exposed no session file. A real no-tool turn completed with `SPIKE_OK`.
|
|
33
|
+
|
|
34
|
+
### Tool discovery and policy
|
|
35
|
+
|
|
36
|
+
The isolated Pi 0.80.6 SDK session advertised seven built-ins: `read`, `bash`, `edit`, `write`, `grep`, `find`, and `ls`. This confirms that adapter discovery must be dynamic; neither pi-forge nor the contract should hard-code the interactive UI's historical four-tool baseline.
|
|
37
|
+
|
|
38
|
+
The spike computes:
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
backend catalog ∩ prompt-stack policy ∩ request access
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
It records the backend catalog, stack-selected names, effective names, unmatched allow patterns, and whether the requested access can actually be enforced. Tool selection worked for dry preflight, and `access=none` produced an empty effective set in real execution.
|
|
45
|
+
|
|
46
|
+
Pi's public `ToolInfo` includes names, descriptions, parameter schemas, prompt guidelines, and source metadata, but not the one-line `toolSnippets` used by the base prompt. Those snippets are available in `before_agent_start.systemPromptOptions`. A dry plan built only from the public catalog is therefore intentionally marked `partial-dry-run`.
|
|
47
|
+
|
|
48
|
+
### Exact prompt preparation and protected task
|
|
49
|
+
|
|
50
|
+
The inline SDK extension receives the exact base system prompt and `BuildSystemPromptOptions` in `before_agent_start`, then calls the existing pi-forge compiler. On the first `context` event it:
|
|
51
|
+
|
|
52
|
+
1. Removes the delegated task from unrestricted history compilation.
|
|
53
|
+
2. Compiles optional history and synthetic prompt-stack messages.
|
|
54
|
+
3. Appends a structured clone of the delegated text and media as the protected final user message.
|
|
55
|
+
|
|
56
|
+
This preserved the task through `qiqi-assistant` and `image-viewer`, including layouts that add synthetic user messages. Offline tests also cover a `chat-history` slot configured to omit the latest user message and prove that it cannot remove the protected task.
|
|
57
|
+
|
|
58
|
+
The exact `BuildSystemPromptOptions` are not publicly obtainable during passive SDK preflight. For a Pi SDK adapter, exact plan preparation must therefore be backend-assisted inside the accepted prompt lifecycle, after capability preflight but before the provider request. The adapter must fail the turn before transport if compilation or task-preservation validation fails.
|
|
59
|
+
|
|
60
|
+
### Trusted custom macros and slots
|
|
61
|
+
|
|
62
|
+
`--load-forge-extensions` explicitly loads trusted global/project pi-forge registration modules in the host. A dry fixture using `examples/custom-system-status-extension` validated that:
|
|
63
|
+
|
|
64
|
+
- The extension module was discovered and registered.
|
|
65
|
+
- Prompt stacks were reloaded and revalidated after registration.
|
|
66
|
+
- The `cpuLoad` macro and `machine-status` slot compiled without stale unsupported-slot diagnostics.
|
|
67
|
+
- Registrations were unloaded during cleanup.
|
|
68
|
+
|
|
69
|
+
This supports keeping executable dependencies in the trusted host. It also confirms that host resolution must load required registrations before final stack validation. Dependency identity and missing-dependency receipts remain future work.
|
|
70
|
+
|
|
71
|
+
### Media
|
|
72
|
+
|
|
73
|
+
A real `opencode-go/qwen3.7-plus` turn used the `image-viewer` profile and a 1.6 MB PNG. The model received the image, completed successfully, and identified the visible Pi symbol. The final structured task and image were preserved by the prompt-stack layout.
|
|
74
|
+
|
|
75
|
+
Preflight rejects image input when the selected model does not advertise `image` support. File paths are converted to SDK `ImageContent` only for explicitly supplied `--image` references.
|
|
76
|
+
|
|
77
|
+
### Timeout, cancellation, response, and trace
|
|
78
|
+
|
|
79
|
+
A real `glm-5.2` turn with a 1 ms host deadline called `session.abort()`, settled in roughly 70 ms, reported `timed-out`, and recorded zero provider tokens/cost. A normal run reported completion, output, duration, session statistics, and a compact normalized lifecycle trace.
|
|
80
|
+
|
|
81
|
+
The SDK does not enforce hard turn, token, or output limits through `createAgentSession`. Its statistics report numeric cost without a currency code. Future response normalization must mark those limits unsupported and treat cost currency as unknown unless the adapter can supply it.
|
|
82
|
+
|
|
83
|
+
The spike trace includes lifecycle and tool start/end metadata only. It excludes streaming content, provider payloads, credentials, and hidden reasoning.
|
|
84
|
+
|
|
85
|
+
## Contract Revisions Implemented
|
|
86
|
+
|
|
87
|
+
1. Split backend work into discovery/preflight, backend-assisted plan preparation, and execution. Preparation may occur inside an adapter-controlled pre-provider hook when the backend cannot expose exact prompt-runtime inputs earlier.
|
|
88
|
+
2. Keep the host responsible for profile/stack resolution, trusted compiler execution, protected-task assembly, diagnostics, and plan validation, even when the adapter supplies runtime inputs through a callback.
|
|
89
|
+
3. Do not require a passive dry preflight to reproduce the exact prompt when the backend cannot expose all inputs. Record prompt-runtime fidelity and reject execution if exact preparation cannot be completed before provider transport.
|
|
90
|
+
4. Make tool discovery dynamic and include a separate prompt-runtime receipt; `ToolInfo` alone is insufficient to recreate Pi's prompt.
|
|
91
|
+
5. Treat tool filtering and access isolation as separate receipts. The current Pi SDK adapter supports only `access=none` honestly.
|
|
92
|
+
6. Distinguish backend-native limits from host best-effort controls. The observed timeout uses host abort and is not proof of process-level hard isolation.
|
|
93
|
+
7. Load trusted macro/slot registrations before final stack validation and later add explicit dependency identities/fingerprints.
|
|
94
|
+
8. Normalize assistant error/aborted stop reasons because `session.prompt()` may settle with a terminal assistant message rather than throw.
|
|
95
|
+
|
|
96
|
+
## Remaining Concrete-Adapter Gaps
|
|
97
|
+
|
|
98
|
+
- No allowed-root filesystem, subprocess, or agent-network isolation.
|
|
99
|
+
- No hard turn, token, or output-byte enforcement.
|
|
100
|
+
- The retained SDK adapter exposes an empty tool catalog. The default subprocess adapter adds only stack-filtered `read`, `grep`, `find`, and `ls`, under an explicit shared-user rather than sandboxed boundary.
|
|
101
|
+
- The registry, model-callable foreground tool, and text-only subprocess backend now exist, but there is still no artifact store, contract trace storage, media resolution in the shipped path, sandbox enforcement, or staged write workflow.
|
|
102
|
+
- Custom dependency scanning records macro/slot names and registration sources, but it cannot fingerprint executable registration code.
|
|
103
|
+
- The command/tool is foreground-only and does not expose a separate cancel command; Pi/host abort signals and host timeouts terminate the active SDK session or subprocess on a best-effort basis.
|
|
104
|
+
|
|
105
|
+
These gaps do not block the approval-gated read-only foreground workflow. They do require the UI and receipts to keep saying shared-user, and they rule out adding direct write/shell tools until stronger sandboxing or a separately approved staged-change design exists.
|
|
106
|
+
|
|
107
|
+
## Verification Evidence
|
|
108
|
+
|
|
109
|
+
- Offline suite covers the contract matrix, fake-backend conformance, command consent/dry-plan behavior, and concrete SDK execution through Pi's faux provider and a real in-memory `AgentSession` without network traffic.
|
|
110
|
+
- TypeScript typecheck: passed.
|
|
111
|
+
- Real profile dry preflight: passed.
|
|
112
|
+
- Real `glm-5.2` no-tool completion: passed.
|
|
113
|
+
- Real host-timeout/abort case: passed.
|
|
114
|
+
- Real `qwen3.7-plus` PNG input: passed.
|
|
115
|
+
- Trusted custom macro/slot dry fixture: passed.
|
|
116
|
+
|
|
117
|
+
The generated reports were inspected during the spike and were not committed because they contain machine-specific paths, run IDs, timing, and provider usage.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Complexity review
|
|
2
|
+
|
|
3
|
+
> **Historical snapshot:** This review records the repository structure at the end of the 0.4 implementation cycle. File counts and hotspot rankings may age; use it as refactoring context, not current user guidance.
|
|
4
|
+
|
|
5
|
+
Date: 2026-07-18
|
|
6
|
+
|
|
7
|
+
## Executive Summary
|
|
8
|
+
|
|
9
|
+
The structural refactor recommended by the original 2026-07-12 review is complete:
|
|
10
|
+
|
|
11
|
+
- The browser editor is authored as typed modules and bundled only for distribution.
|
|
12
|
+
- The subagent contract is split into focused modules behind compatibility barrels.
|
|
13
|
+
- `src/index.ts` is a small composition root over dedicated runtime services.
|
|
14
|
+
- Package contents and stable, experimental, and compatibility exports are explicitly classified.
|
|
15
|
+
|
|
16
|
+
pi-forge is still a reasonable size for its feature set. The main engineering risk has moved from a few monolithic files to the safety and lifecycle seams of the experimental subagent backend. The narrow parent-agent integration is now complete; the next iteration should harden the shared-user boundary and evaluate an optional sandbox without adding orchestration breadth.
|
|
17
|
+
|
|
18
|
+
## Current Size
|
|
19
|
+
|
|
20
|
+
Measured from the current `feature/0.4-subagents-prep` working tree:
|
|
21
|
+
|
|
22
|
+
| Area | Files | Lines of TypeScript |
|
|
23
|
+
|---|---:|---:|
|
|
24
|
+
| Production source (`src`) | 72 | 16,355 |
|
|
25
|
+
| Core tests and helpers (`tests`) | 23 | 7,271 |
|
|
26
|
+
| Browser tests (`tests-browser`) | 1 | 139 |
|
|
27
|
+
| Internal TypeScript scripts (`scripts`) | 2 | 628 |
|
|
28
|
+
|
|
29
|
+
Additional observations:
|
|
30
|
+
|
|
31
|
+
- `dist/` is generated output and is about 2.1 MB; verification rejects stale generated files.
|
|
32
|
+
- Runtime dependency count remains low.
|
|
33
|
+
- The implementation checkpoint passes 184 core tests, one browser test, TypeScript typecheck, generated-client and `dist` consistency, and npm package-layout checks.
|
|
34
|
+
- The npm package resolves both entry points to compiled output and contains no physical `src/` files.
|
|
35
|
+
|
|
36
|
+
## Completed Structural Work
|
|
37
|
+
|
|
38
|
+
### Typed browser client
|
|
39
|
+
|
|
40
|
+
The previous 2,253-line embedded browser script is now a generated one-line compatibility wrapper. Typed source modules under `src/web-editor/client/` own API transport, DOM access, policy editing, regex editing, inspection, and orchestration. `src/web-editor/client/main.ts` is still large, but it is type-checked and can be split incrementally as profile UI introduces clear component boundaries.
|
|
41
|
+
|
|
42
|
+
### Modular subagent contract
|
|
43
|
+
|
|
44
|
+
The previous 1,373-line `src/subagent-contract.ts` implementation is now a seven-line compatibility barrel. Types, canonicalization, request validation, preflight, tools, context, plans, response handling, and validation live in focused `src/subagent/` modules with import-surface tests preserving the experimental API.
|
|
45
|
+
|
|
46
|
+
### Small composition root
|
|
47
|
+
|
|
48
|
+
`src/index.ts` remains a small composition root and primarily wires prompt-stack, profile, tool-policy, web-editor, lifecycle, subagent runtime, command, and tool registration. Operational behavior lives in dedicated modules.
|
|
49
|
+
|
|
50
|
+
### Package and API boundaries
|
|
51
|
+
|
|
52
|
+
The [public API policy](../reference/public-api.md) classifies stable, experimental, and compatibility surfaces. `@zihanw/pi-forge/subagent` is the preferred experimental integration entry point, while legacy `src/*` aliases resolve to compiled modules without publishing source files.
|
|
53
|
+
|
|
54
|
+
## Current Complexity Hotspots
|
|
55
|
+
|
|
56
|
+
| File | Lines | Current assessment |
|
|
57
|
+
|---|---:|---|
|
|
58
|
+
| `src/web-editor/client/main.ts` | 1,491 | Largest remaining orchestration module; split along profile UI boundaries when that work begins |
|
|
59
|
+
| `src/web-editor/styles.ts` | 995 | Large but mostly presentation logic |
|
|
60
|
+
| `src/compiler.ts` | 578 | Mature core compiler; change cautiously |
|
|
61
|
+
| `src/subagent/backend-registry.ts` | 575 | Highest semantic risk: dispatch, cancellation, timeout, binding, and trace routing |
|
|
62
|
+
| `src/subagent/pi-subprocess-backend.ts` | 773 | Foreground child lifecycle, exact bridge inputs, sanitized report transport, cancellation, and cleanup |
|
|
63
|
+
| `src/subagent-tool.ts` | 453 | Approval UX, bounded model projection, and expandable human report rendering |
|
|
64
|
+
| `src/loader.ts` | 518 | Broad input normalization and validation surface |
|
|
65
|
+
| `src/regex.ts` | 500 | Mature transformation engine with focused tests |
|
|
66
|
+
| `src/subagent/pi-sdk-backend.ts` | 450 | Experimental provider/session lifecycle boundary |
|
|
67
|
+
|
|
68
|
+
The registry, subprocess backend, and approval tool are not concerning solely by line count, but they carry the strongest correctness and egress guarantees. Prefer focused helpers and end-to-end lifecycle tests over broad rewrites.
|
|
69
|
+
|
|
70
|
+
## Near-Term Priorities
|
|
71
|
+
|
|
72
|
+
1. Keep provider egress fail-closed in interactive, non-UI, cancelled, and timed-out paths.
|
|
73
|
+
2. Dogfood the model-callable foreground path without creating a second runner or allowing a tool call to grant its own egress consent.
|
|
74
|
+
3. Preserve read-only defaults, bounded result projection, no automatic parent-history export, and honest shared-user receipts while evaluating bubblewrap-style isolation.
|
|
75
|
+
4. Add profile UI by reusing the existing profile repository/application services and splitting browser orchestration only where the new UI creates stable boundaries.
|
|
76
|
+
5. Re-run the complete verification suite for every release candidate and keep generated output synchronized.
|
|
77
|
+
|
|
78
|
+
## Guardrails
|
|
79
|
+
|
|
80
|
+
Do not remove strict validation, immutable preparation binding, task preservation, access/limit receipts, rollback, provenance, or drift reporting merely to reduce line count. These mechanisms make the experimental runtime's behavior inspectable and enforceable.
|
|
81
|
+
|
|
82
|
+
Avoid building retries, queues, chains, background execution, direct write/shell access, media routing, or artifact/trace storage into the 0.4 foreground path. Evaluate sandbox and external orchestration packages behind the existing backend contract before expanding pi-forge into a general runner.
|
|
83
|
+
|
|
84
|
+
## Final Assessment
|
|
85
|
+
|
|
86
|
+
The original concentration problems and narrow parent-agent integration are addressed. Future complexity control should be incremental: isolate lifecycle-sensitive backend logic, split the browser client along real product boundaries, and resist turning pi-forge into a general orchestration framework without demonstrated need.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Release process
|
|
2
|
+
|
|
3
|
+
[Documentation](../README.md)
|
|
4
|
+
|
|
5
|
+
## Before release
|
|
6
|
+
|
|
7
|
+
1. Confirm the changelog and user documentation describe the intended version and experimental surfaces accurately.
|
|
8
|
+
2. Publish and smoke-test any required `@zihanw/pi-subagent-runtime` version first.
|
|
9
|
+
3. Install dependencies from the lockfile and run `npm run verify`.
|
|
10
|
+
4. Test a packed installation against the documented minimum and current Pi versions.
|
|
11
|
+
5. Exercise ordinary stack/profile use independently of delegation.
|
|
12
|
+
6. Exercise both configured foreground backends and confirm unsupported host capabilities fail closed before provider transport.
|
|
13
|
+
7. Inspect `npm pack --dry-run` for package size and unexpected or missing files.
|
|
14
|
+
|
|
15
|
+
## Dependency policy
|
|
16
|
+
|
|
17
|
+
Published manifests use wildcard peer dependencies for Pi-host-provided SDK packages. Exact versions belong in development dependencies and the lockfile so tests are reproducible without restricting compatible host releases.
|
|
18
|
+
|
|
19
|
+
`pi-subagent-runtime` remains a normal exact dependency until its compatibility policy says otherwise. Its own host-facing Pi dependencies must follow the same host-provided peer model.
|
|
20
|
+
|
|
21
|
+
## Package contents
|
|
22
|
+
|
|
23
|
+
The tarball must include compiled `dist/`, examples, the English and Chinese landing pages, changelog, license, and user/reference documentation. It must not include physical `src/` files. Both the default extension entry and experimental subagent entry must resolve to compiled output.
|
|
24
|
+
|
|
25
|
+
The root `PUBLIC_API.md` and `SUBAGENT_ADAPTER_CONTRACT.md` files are compatibility pointers; authoritative content lives under `docs/reference/`.
|
|
26
|
+
|
|
27
|
+
## Publish and verify
|
|
28
|
+
|
|
29
|
+
Publish the intended version/tag, then install it through Pi in a clean project. Verify `/preset`, `/profile`, `/preset ui`, and—when deliberately enabled—delegation. Restart Pi after installation to avoid testing a stale extension instance.
|
|
30
|
+
|
|
31
|
+
For a stable release, ensure npm `latest` points to the new version and any prerelease channel no longer leaves users on an incompatible older build.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Roadmap
|
|
2
|
+
|
|
3
|
+
[Documentation](../README.md)
|
|
4
|
+
|
|
5
|
+
This file contains forward-looking product work only. Completed capability belongs in the [feature inventory](../reference/features.md), release history in the root [changelog](../../CHANGELOG.md), and completed investigation in the [design archive](../design/README.md).
|
|
6
|
+
|
|
7
|
+
## 0.4 release
|
|
8
|
+
|
|
9
|
+
The profile UI, foreground-delegation dogfooding, dependency compatibility work, and documentation reorganization are complete. Runtime beta.2 is published and the packed extension passes the full verification surface against the documented Pi versions. The 0.4.0 release commit is ready; remaining release work is intentionally small:
|
|
10
|
+
|
|
11
|
+
- merge the release commit to `main`;
|
|
12
|
+
- publish 0.4.0 with delegation explicitly labelled experimental;
|
|
13
|
+
- install the published package through Pi and complete the post-publish smoke check.
|
|
14
|
+
|
|
15
|
+
Stable 0.4 does not imply that the subagent adapter or runtime has become stable. Prompt stacks and ordinary profile use remain independent of delegation.
|
|
16
|
+
|
|
17
|
+
## Near-term candidates
|
|
18
|
+
|
|
19
|
+
### Scoped global profiles and stacks
|
|
20
|
+
|
|
21
|
+
If cross-project presets are added, introduce global profiles and stacks together. Preserve source scope, let same-ID project resources shadow global resources, and apply delegation policy only within the matching scope. Define discovery, auto-activation, reference, and editor behavior before implementation.
|
|
22
|
+
|
|
23
|
+
### Sandbox and staged writes
|
|
24
|
+
|
|
25
|
+
Evaluate an optional backend that can honestly enforce roots, process behavior, symlink containment, and requested network policy. Keep shared-user as an explicit compatibility boundary. Design writes as a separately approved staged patch/change set; do not add write/edit/shell tools directly to the shared-user child.
|
|
26
|
+
|
|
27
|
+
### Import, history, and prompt diagnostics
|
|
28
|
+
|
|
29
|
+
Add SillyTavern fidelity only from real unsupported fixtures. Candidate history controls need concrete use cases and dangling tool-pair tests. Provider-payload rewriting and display-only streaming regex remain deferred until a stable, previewable lifecycle hook exists.
|
|
30
|
+
|
|
31
|
+
## Product guardrails
|
|
32
|
+
|
|
33
|
+
- Prompt-stack JSON stays declarative; executable customization stays in trusted extensions/packages.
|
|
34
|
+
- Profiles remain one-shot presets, not continuous runtime owners.
|
|
35
|
+
- Tool and skill policy stays in prompt stacks, not profiles.
|
|
36
|
+
- Skill filtering is model-visible prompt filtering, not an invocation or security boundary.
|
|
37
|
+
- Delegation remains opt-in, foreground, clean-context, and fail-closed on missing capabilities.
|
|
38
|
+
- Do not report shared-user read-only policy as an OS sandbox.
|
|
39
|
+
- New editor workflows require real-browser coverage.
|
|
40
|
+
- Run the full verification and package checks before release.
|
|
41
|
+
|
|
42
|
+
The detailed completed 0.4 plan is retained in the [historical roadmap](../design/roadmap-0.4-archive.md).
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Development setup
|
|
2
|
+
|
|
3
|
+
[Documentation](../README.md)
|
|
4
|
+
|
|
5
|
+
## Build from source
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/MacroSony/pi-forge.git
|
|
9
|
+
cd pi-forge
|
|
10
|
+
npm install
|
|
11
|
+
npm run build
|
|
12
|
+
pi
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Trust the project in Pi and use `/reload` when needed.
|
|
16
|
+
|
|
17
|
+
The npm package loads compiled `dist/index.js` and intentionally omits physical `src/` files. Clone or fork the repository to inspect or modify source; do not edit generated files in `node_modules`.
|
|
18
|
+
|
|
19
|
+
## Load the extension
|
|
20
|
+
|
|
21
|
+
For release-like local testing, register the cloned package directory in Pi settings:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"packages": ["../pi-forge"]
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
For live source development, remove that package entry and load the TypeScript extension directly:
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"extensions": ["../pi-forge/src/index.ts"]
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
You can also run `pi -e ../pi-forge/src/index.ts` for a one-off smoke test. Never load both package and source entries simultaneously; pi-forge would initialize twice.
|
|
38
|
+
|
|
39
|
+
Browser-client source changes require `npm run build:client` because the editor serves a generated embedded bundle.
|
|
40
|
+
|
|
41
|
+
## Verification
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm test # core Node test suite
|
|
45
|
+
npm run test:browser # real-browser editor characterization
|
|
46
|
+
npm run typecheck # TypeScript and Vue
|
|
47
|
+
npm run build # client bundle and dist output
|
|
48
|
+
npm run verify # all tests plus generated/package consistency
|
|
49
|
+
npm pack --dry-run # inspect the publishable tarball
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Set `CHROME_PATH` when Chrome/Chromium is outside a standard location. CI runs the full verification. When source changes generated output, commit matching generated client and `dist` files.
|
|
53
|
+
|
|
54
|
+
## Pi compatibility
|
|
55
|
+
|
|
56
|
+
Published pi-forge treats Pi-owned SDK packages (`pi-agent-core`, `pi-ai`, `pi-coding-agent`, `pi-tui`, and `typebox`) as host-provided wildcard peers. The running Pi host supplies one coherent SDK instance, avoiding duplicate packages and avoiding an install-time lock to Pi's frequent release cadence.
|
|
57
|
+
|
|
58
|
+
The repository keeps exact SDK versions as development/test fixtures for reproducibility. Exact fixtures do not constrain which Pi version may load the published extension.
|
|
59
|
+
|
|
60
|
+
Release validation should test:
|
|
61
|
+
|
|
62
|
+
- the documented minimum supported Pi version;
|
|
63
|
+
- the current Pi version at release time;
|
|
64
|
+
- an automated or scheduled probe of npm `latest`.
|
|
65
|
+
|
|
66
|
+
Document the tested range separately from peer constraints. Pi-coupled experimental subagent capabilities must preflight against the actual host and fail closed with a precise compatibility diagnostic when required APIs are unavailable; ordinary stacks and profiles should remain usable.
|
|
67
|
+
|
|
68
|
+
## Package boundaries
|
|
69
|
+
|
|
70
|
+
- `@zihanw/pi-forge` is the Pi extension and stable macro/slot registration surface.
|
|
71
|
+
- `@zihanw/pi-forge/subagent` is the preferred experimental host-contract entry point.
|
|
72
|
+
- `@zihanw/pi-subagent-runtime` owns execution lifecycle and fresh-process backends.
|
|
73
|
+
- Legacy `@zihanw/pi-forge/src/*` aliases resolve to compiled compatibility modules and are not a promise that internals are public.
|
|
74
|
+
|
|
75
|
+
See the [public API policy](../reference/public-api.md).
|