feat: add Pi provider managed resources
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
# Task: Implement PI-040 provider and managed resources
|
||||
|
||||
## Identity
|
||||
|
||||
- Task ID: 20260822-pi-provider-resources-7c3e91a4
|
||||
- Mode: Feature
|
||||
- Branch: codex/20260822-pi-provider-resources-7c3e91a4-pi-provider-resources
|
||||
- Worktree: D:\Datas\OthersProjects\makelore-pi-provider-resources-7c3e91a4
|
||||
- Base commit: 81d8ad1b6bc0b18859feadfeb9e27cc3f15ffce5
|
||||
- Owner: codex
|
||||
- Status: Completed
|
||||
|
||||
## Scope
|
||||
|
||||
- Implement `PI-040 — Provider and managed resources` from the planner's Pi hard-cutover ticket graph.
|
||||
- Add a Main-owned Provider Account to Pi managed-catalog projection, worker-only credential/header environment projection, Works gateway normalization, and refresh/auth-recovery primitives under `electron/coding-runtime/pi`.
|
||||
- Add managed prompt, Agent manifest, explicit skill-path, directory-layout, and revision/staleness contracts without wiring them into the PI-050 worker pool or Renderer routes yet.
|
||||
- Move bundled coding skills to the vendor-neutral `resources/coding-skills` source and keep the current OpenCode runtime reading that same source until final PI-140 removal.
|
||||
- Add focused provider catalog, redaction, refresh, revision, resource-discovery, packaging, and provider-shaped loopback tests. Real Provider calls and macOS qualification remain explicitly outside this ticket.
|
||||
|
||||
## Intent And Constraints
|
||||
|
||||
- Keep Provider Account identity, credentials, proxy trust, resource selection, and revision state Main-owned. Renderer/API summaries may expose only safe identifiers, model capabilities, header names, revision numbers, and availability state.
|
||||
- Give every account a stable account-derived Pi runtime Provider ID so two accounts for one vendor cannot collide. Map Makelore `openrouter` onto Pi `openai-completions` plus the locked OpenRouter compatibility flags; map the other current protocols directly.
|
||||
- Persist only environment references in Pi `models.json`; API key, OAuth/proxy token, and custom header values enter only the individual worker environment and the worker diagnostic redaction set. They must not enter argv, snapshots, API DTOs, logs, or test snapshots.
|
||||
- Normalize Works gateway roots to exactly one `/v1`, preserve direct custom headers, and treat the current local Host API token as a worker credential rather than as a Provider-account credential revision.
|
||||
- Coalesce concurrent refreshes by account and permit at most one auth refresh plus worker reopen for a failed operation. The contract is generic; PI-050 owns connecting it to worker lifecycle.
|
||||
- A running turn keeps its Provider/resource snapshot. Stale idle workers rebuild before the next prompt; stale running workers rebuild only after settlement. Refresh never interrupts an active run.
|
||||
- Disable all Pi resource auto-discovery and provide only explicit managed prompt/selected skill paths. No project/user `.pi`, `.agents`, `.codex`, or home-directory skill discovery is allowed.
|
||||
- Preserve current OpenCode product behavior during staged implementation by repointing its bundled-skill source to `resources/coding-skills`; do not add a compatibility copy or parallel skill registry.
|
||||
- The user explicitly waived real Provider validation and accepted protocol/account compatibility, real concurrency, credential-isolation, and image-behavior risk. These remain `Accepted Risk`, `realTurnVerified=false`, never `Pass`. macOS validation remains deferred to PI-150.
|
||||
|
||||
## Project Context Loaded
|
||||
|
||||
- `maintain-project-docs` created and verified isolated feature ownership at base `81d8ad1b6bc0b18859feadfeb9e27cc3f15ffce5`; Concurrent Task Gate and Planning Gate passed.
|
||||
- The planner audited `{PI-000, PI-010, PI-020, PI-030}` as Done and identified PI-040 as the unique Ready Frontier ticket. This task follows the locked PI Provider/resource contracts and does not widen into PI-050 worker-pool orchestration or PI-140 cutover removal.
|
||||
- Repository guidance, shared project memory, PI Spec Provider/resource sections, PI-040 ticket, current Provider registry/service/secret store, Works gateway, OpenCode Provider projection, Pi worker boundary, qualification probes, Pi 0.84.2 model/skill documentation, packaging configuration, and all planning peer task records were inspected before planning.
|
||||
- Pi 0.84.2 supports the four locked API shapes (`openai-completions`, `openai-responses`, `anthropic-messages`, `google-generative-ai`), environment interpolation in `models.json` API keys and headers, and repeatable explicit `--skill` paths even with `--no-skills`.
|
||||
- Current Makelore accounts expose three direct Pi API shapes plus `openrouter`; OpenRouter is an application protocol alias mapped to `openai-completions` with `thinkingFormat` and `sessionAffinityFormat` set to `openrouter`. Google accounts currently have no explicit Makelore protocol field and therefore use the registry-derived `google-generative-ai` descriptor.
|
||||
- Built-in coding skills currently live under `.opencode/skills` and are packaged as `course-skills`; PI-040 will make `resources/coding-skills` the single vendor-neutral source while retaining current OpenCode installation behavior through its source resolver.
|
||||
- Other planning peers do not declare writes to the new PI-040 modules or vendor-neutral resource path. `20260820-partner-create-model-parity-c83d` still has undefined scope and is retained as an unknown coordination warning; this task avoids its existing files.
|
||||
- `codebase-design` keeps credential projection, refresh/recovery, revision state, and resource materialization behind small explicit interfaces. The repository prohibition on subagents is honored; no parallel agent was created.
|
||||
|
||||
## Plan
|
||||
|
||||
1. Implement pure Provider Account normalization and Pi catalog projection with stable per-account runtime IDs, protocol/Works semantics, model capability validation, worker-only environment references, and safe summaries.
|
||||
2. Implement per-account refresh single-flight, one-retry auth recovery, and revision/staleness state that defers rebuild until an active run settles.
|
||||
3. Implement the managed Pi directory/resource loader, atomic prompt and Agent-manifest materialization, explicit skill registry/path selection, safe spawn arguments, and negative auto-discovery boundaries.
|
||||
4. Move bundled skills to `resources/coding-skills`, update current packaging/OpenCode source resolution to that single source, and preserve selected-skill behavior.
|
||||
5. Add focused catalog/redaction/refresh/revision/resource/packaging tests plus the packaged provider-shaped loopback; then run typecheck, lint, full tests, build, documentation gates, commit, and planner handoff.
|
||||
|
||||
## Outcome
|
||||
|
||||
- Added the Main-owned Pi Provider boundary. Every enabled current runtime account maps to a stable account-derived `runtimeProviderId`; accounts for the same vendor remain distinct. Makelore `openrouter` maps to Pi `openai-completions` with both locked OpenRouter compatibility flags, Google maps to `google-generative-ai`, and other current protocols map directly.
|
||||
- Added managed `models.json` generation with account/default/imported model selection, image/reasoning/context/output capability projection, Works gateway `/v1` normalization, unavailable-model refusal before atomic replacement, and safe summaries containing only Provider/model/header names and credential-reference state.
|
||||
- API keys, OAuth access tokens, local credentials, Works proxy tokens, and every custom/default Header value now enter only selected-worker environment variables. The catalog stores environment references, worker argv rejects known sensitive values, diagnostics redact all supplied values, and workers inherit an explicit OS/runtime allowlist instead of ambient Provider credentials from Main.
|
||||
- Added secure-store credential resolution, local-proxy preference over stale stored Host tokens, per-account refresh single-flight, at-most-one auth refresh/reopen operation, and separate Provider/resource revision tracking. Idle stale workers rebuild before a prompt; active runs keep their original snapshot and request rebuild only after settlement.
|
||||
- Added the managed `<userData>/coding-runtime/pi/{config,sessions,prompts,extensions,logs,trash}` layout, atomic Prompt plus Agent-manifest materialization, path-segment validation, and explicit bundled Skill ID→`SKILL.md` resolution. Spawn input contains Prompt/Skill paths, never Prompt content, and no project/user `.pi` or other skill roots are inspected.
|
||||
- Moved the four bundled coding Skills from `.opencode/skills` to `resources/coding-skills`, renamed the shared registry to vendor-neutral terminology, and moved the current OpenCode-only Agent Browser plugin to `resources/coding-extensions/opencode`. Existing OpenCode installation now consumes the same vendor-neutral Skill source; generic `resources/` packaging carries both paths.
|
||||
- Extended the controlled packaged Pi probe to execute the four protocol-shaped local Provider contracts. Each protocol completed overlapping two-worker image turns and abort isolation against the packaged runtime. Reports explicitly state `realTurnVerified: false` and `realProviderDecision: explicitly-waived-accepted-risk`.
|
||||
- No PI-050 worker-pool, Host API, Renderer, or current product runtime cutover wiring was added. The real Provider and macOS decisions remain unchanged.
|
||||
|
||||
## Verification
|
||||
|
||||
- `pnpm install --frozen-lockfile`: passed with repository-pinned pnpm 10.33.4.
|
||||
- Core focused suite after final changes: 4 files, 36 tests passed (`pi-provider-config`, Provider/revision state, managed resource loader, Pi RPC foundation). Earlier compatibility-focused run covered 7 files / 79 tests including OpenCode skill install/plugin paths.
|
||||
- `pnpm run typecheck`: passed.
|
||||
- Scoped ESLint over all changed implementation and test files: passed with no findings.
|
||||
- `pnpm run lint:check`: passed with 0 errors and 6 pre-existing warnings outside this task's files.
|
||||
- `pnpm test`: 187 files, 2152 tests passed. The first full run found one stale `.opencode/skills` path in `planning-with-files-skill.test.ts`; after updating it to `resources/coding-skills`, the focused test and full suite passed.
|
||||
- `pnpm run test:electron:windows`: 1 file, 3 Electron-runtime tests passed, including Unicode Skill copy behavior.
|
||||
- `pnpm run build:vite`: passed for Renderer, Main, Preload, and release utility output; existing dynamic-import and chunk-size warnings remain unchanged.
|
||||
- `node scripts/probe-pi-provider-contracts.mjs --timeout-ms 30000`: passed all four local protocol contracts with environment-resolved custom Headers, four image requests per protocol, distinct sessions, overlapping turns, abort isolation, and `realTurnVerified=false`.
|
||||
- `node scripts/probe-pi-packaged-runtime.mjs --timeout-ms 30000`: packaged closure complete (130 expected packages, no missing/relocated packages or assets); all four packaged Provider-shaped loopbacks passed. Runtime result remains intentionally `partial-pass` / `incomplete` because real Provider validation is explicitly waived and macOS remains deferred.
|
||||
- Initial `pnpm run probe:pi-runtime:packaged -- --timeout-ms 30000` invocation stopped before build because pnpm forwarded the separator as an unknown argument; the direct equivalent command above passed twice. Cleanup of generated ignored `release/pi-runtime-probe` was attempted but blocked by the local command policy, so no deletion occurred and the ignored probe output remains outside the commit.
|
||||
- `git diff --check`: passed.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
- `PI-050` owns worker-pool integration. It must write the validated catalog before worker start, pass only `PiWorkerCredentialProjection.env` plus its `sensitiveValues`, use `buildPiManagedInputArgs`, and honor `PiManagedInputRevisionCoordinator` actions around prompt/run settlement.
|
||||
- `PI-050` must connect authentication classification and worker reopening to `PiProviderRefreshCoordinator`; a second authentication failure from the retried operation must surface instead of refreshing again.
|
||||
- `PI-100` may expose only the safe Provider/credential/resource summaries through Host API DTOs. Raw descriptors containing account IDs and raw worker environment projections remain Main-private.
|
||||
- `PI-140` may remove the temporary current-OpenCode consumer and `resources/coding-extensions/opencode` artifact only when cutover is complete. It must keep `resources/coding-skills` as the product-owned Skill source and account for PI-020's temporary legacy migration dependency.
|
||||
- Real Provider authentication, account/protocol variation, rate limiting, true concurrency, credential isolation, abort/session/model/image behavior remain explicitly accepted unverified risk. `realTurnVerified` must stay false and must not be promoted to Pass by local loopbacks. macOS remains deferred to PI-150.
|
||||
|
||||
## Promotion Candidates
|
||||
|
||||
- Target: Pi worker-pool implementation guidance in the architecture/planner task.
|
||||
Proposal: treat catalog/resource revisions as desired Main-owned state; rebuild idle stale workers before prompt and running stale workers only after `agent_settled`, while preserving the run's original revision snapshot.
|
||||
Evidence: focused revision tests prove provider/resource changes do not mutate active-run snapshots and produce distinct pre-prompt versus post-settlement rebuild actions.
|
||||
Future impact: PI-050 and PI-060 can share one deterministic staleness contract without interrupting active turns or adding worker-specific flags.
|
||||
Semantic conflicts: none found.
|
||||
Human confirmation required: no.
|
||||
- Target: Pi credential-isolation guidance in the architecture/planner task.
|
||||
Proposal: persist only `$ENV_VAR` references in managed `models.json`, build a selected-account worker environment from secure-store/Works credentials, pass the same values as the diagnostic redaction set, and inherit only explicit non-Provider OS/runtime variables.
|
||||
Evidence: catalog/redaction/argv/environment tests and the environment-resolved packaged Provider-shaped loopback all pass; ambient OpenAI/Anthropic/custom secret variables are excluded.
|
||||
Future impact: PI-050 must preserve this exact spawn boundary and PI-100 must expose only safe summaries.
|
||||
Semantic conflicts: none found.
|
||||
Human confirmation required: no.
|
||||
Reference in New Issue
Block a user