mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-07-09 17:28:45 +00:00
docs(agent): update models phase 9 plan
This commit is contained in:
parent
3e551faf79
commit
c29bbc0958
1 changed files with 16 additions and 14 deletions
|
|
@ -860,20 +860,21 @@ Check items off as they land. Keep this list current; it is the working state fo
|
|||
coding-agent replaces AuthStorage and ModelRegistry's internals with `FileCredentialStore` + a `MutableModels` collection. AgentSession itself stays (AgentHarness adoption is pi 2.0); only its model/auth substrate swaps. Layering is strictly one-directional:
|
||||
|
||||
```txt
|
||||
FileCredentialStore (auth.json, locked) + --api-key overlay + $ENV/!command resolution
|
||||
FileCredentialStore (auth.json, locked, $ENV/!command resolution) + explicit --api-key overlay
|
||||
↑
|
||||
MutableModels: builtin factories (wrapped per models.json config) + custom providers (models.json ∪ extensions)
|
||||
↑
|
||||
ModelRegistry: async facade — reads delegate to the collection; registerProvider/login/logout/status for extensions + UI
|
||||
ModelRegistry: compatibility facade — sync last-known reads delegate to the collection; registerProvider/login/logout/status for extensions + UI
|
||||
↑
|
||||
AgentSession / sdk / interactive-mode (await added; stream via models)
|
||||
AgentSession / sdk / interactive-mode (stream via models; await only auth/refresh paths)
|
||||
```
|
||||
|
||||
Decisions:
|
||||
|
||||
- `AuthStorage` is deleted as a type — it would otherwise depend on provider auth while provider auth depends on its store (circular). Its surface splits: `get`/`set`/`remove` -> `CredentialStore`; `getApiKey` -> `Models.getAuth`; `login`/`logout`/`getAuthStatus` -> ModelRegistry facade methods over `provider.auth.oauth` + the store.
|
||||
- Runtime `--api-key` overrides are a store overlay (an override reads as an ephemeral stored api-key credential, masking stored OAuth — matches today's priority). Every registered provider is guaranteed an `apiKey` auth slot so overrides apply to OAuth-only providers too.
|
||||
- `ModelRegistry.getAll`/`find`/`getAvailable` become async, delegating to the collection (no materialized snapshot, no sync lies; dynamic providers like llama.cpp work). The extension-facing `modelRegistry` surface changes accordingly (breaking, changelogged); extensions also get the collection itself as the forward API.
|
||||
- `FileCredentialStore` is self-contained (path, locking, parse/write, chmod, error buffering) and owns `auth.json` semantics, including `$ENV`/`!command` resolution for stored API-key credentials. Persisted values stay raw; resolution returns copies for auth use.
|
||||
- Runtime `--api-key` overrides are an explicit store overlay (an override reads as an ephemeral stored api-key credential, masking stored OAuth — matches today's priority). Every registered provider is guaranteed an `apiKey` auth slot so overrides apply to OAuth-only providers too.
|
||||
- `ModelRegistry.getAll`/`find`/`getAvailable` stay sync for SDK and extension compatibility, delegating to the collection's last-known sync model lists and fast configured-looking status checks. Dynamic providers update through explicit async `refresh()`, and request auth remains async through `getApiKeyAndHeaders()`/`Models.getAuth()`. Extensions also get the collection itself as the forward API.
|
||||
- models.json keeps FULL feature parity, implemented as provider decoration: builtin factories wrapped so `getModels()` applies provider `baseUrl`/`compat` overlays, `modelOverrides`, and custom-model merges (async-safe); provider `apiKey`/`headers`/`authHeader` configs become that provider's `ApiKeyAuth` (config first, factory auth fallback); parse errors keep `getError()` semantics.
|
||||
- Extension `ProviderConfig` parity: provider-keyed `streamSimple`, old-style `oauth` adapted to `OAuthAuth` (`modifyModels` -> `getModels` wrap + `toAuth`), full model replacement per provider. Legacy `registerApiProvider` writes stay compat-local for consumers that call global `complete()`; they die with compat.
|
||||
- Copilot: stored-credential baseUrl applied in the wrapped `getModels()` (extension-visible models stay correct) plus per-request `toAuth().baseUrl`.
|
||||
|
|
@ -884,14 +885,15 @@ Ordering for new sessions:
|
|||
1. [x] pi-ai rework first: `Provider.getModels()` sync + optional `refreshModels()`; `Models.getModels`/`getModel` sync, `Models.refresh(provider?)` async; `createProvider` takes `models` array + optional `refreshModels` fetcher (in-flight dedupe). Reverses Phase 1's async-listing decision — see "Provider model listing" for rationale (sync-or-async unions breed latent sync assumptions; async-only breaks sync consumer surfaces like extension `find`/`getAll`).
|
||||
2. [x] Cloudflare provider auth in pi-ai factories: Workers AI and AI Gateway validate their required account/gateway env/config and return resolved `baseUrl`, provider-scoped env, and header suppression/override metadata from provider auth.
|
||||
3. [ ] Add `FileCredentialStore` in coding-agent.
|
||||
- Implement the pi-ai `CredentialStore` interface over the existing `auth.json` lock backend (`FileAuthStorageBackend` / `InMemoryAuthStorageBackend` can be reused or renamed).
|
||||
- Implement the pi-ai `CredentialStore` interface as a self-contained `auth.json` store; do not depend on the old `AuthStorageBackend` abstraction, though its lock/retry semantics may be ported.
|
||||
- Preserve the existing file format. `ApiKeyCredential` uses `{ type: "api_key", key?, env? }`, matching today's `auth.json`; do not translate `env` into metadata or rewrite discriminators.
|
||||
- Resolve `$ENV`/`!command` in stored API-key `key` and `env` values out of the box using an injected execution/config environment. `$ENV` lookup should come from that environment, and `!command` should run through the shared shell execution path rather than direct `execSync`.
|
||||
- Persist raw config values; resolved credentials returned for auth use must be copies and must not rewrite `$ENV`/`!command` strings unless a caller explicitly stores new values.
|
||||
- `read(provider)` returns the current credential snapshot and records parse/storage errors for status UI parity.
|
||||
- `modify(provider, fn)` must lock, re-read, run `fn`, merge-write the provider entry, chmod `0600`, and return the post-write credential.
|
||||
- `delete(provider)` must lock and remove only that provider's entry.
|
||||
- Add file-backed and in-memory tests covering lock/RMW behavior, `api_key` reads, OAuth reads, provider `env` preservation, delete, parse errors, and concurrent refresh-style modifications.
|
||||
4. [ ] Add store decorators for coding-agent policy.
|
||||
- `withConfigValues(store, policy)` resolves stored API-key credentials whose `key` or `env` values use `$ENV` or `!command`, using existing `resolve-config-value.ts` semantics. Command execution stays in coding-agent, not pi-ai.
|
||||
- Add file-backed and in-memory tests covering lock/RMW behavior, `api_key` reads with config-value resolution, OAuth reads, provider `env` preservation, delete, parse errors, and concurrent refresh-style modifications.
|
||||
4. [ ] Add runtime override overlay for coding-agent policy.
|
||||
- `withRuntimeOverrides(store, overrides)` implements CLI `--api-key`: read returns an ephemeral `{ type: "api_key", key }` for each overridden provider, masking stored OAuth/API credentials without persisting.
|
||||
- Runtime overrides must apply even to OAuth-capable providers; every provider registered in coding-agent must retain or gain an `apiKey` auth slot so the overlay is meaningful.
|
||||
- Tests cover precedence: runtime override > stored credential > models.json config auth > ambient provider env, with stored credential blocking ambient fallback.
|
||||
|
|
@ -916,21 +918,21 @@ Ordering for new sessions:
|
|||
- Preserve existing extension runtime compatibility through the `/compat` alias until Phase 10.
|
||||
8. [ ] Rebuild coding-agent `ModelRegistry` over `MutableModels`.
|
||||
- It owns a `MutableModels` instance built from decorated built-ins + models.json custom providers + extension providers.
|
||||
- `getAll()`, `find()`, and `getAvailable()` become async and delegate to the collection/status checks. Update extension-facing types and changelog this breaking change.
|
||||
- `refresh()` rebuilds provider layers and calls `models.refresh()` where needed; no global api-registry reset should be part of the new path except compat-only grace behavior.
|
||||
- `getAll()`, `find()`, and `getAvailable()` remain sync compatibility methods over last-known model lists and fast configured-looking auth status. Do not break the extension-facing `modelRegistry` surface for these reads.
|
||||
- `refresh()` is the explicit async freshness boundary: rebuild provider layers and call `models.refresh()` where needed; no global api-registry reset should be part of the new path except compat-only grace behavior.
|
||||
- `registerProvider()`/`unregisterProvider()` mutate provider layers and rebuild the collection.
|
||||
- Facade auth ops (`login`, `logout`, provider status, available OAuth providers) drive `provider.auth.{apiKey,oauth}` and the `CredentialStore`; no `AuthStorage` type remains.
|
||||
- Legacy `registerApiProvider` writes stay only for `/compat` callers and are removed in Phase 10.
|
||||
9. [ ] Rewire consumers.
|
||||
- `AgentSession` stream function resolves through `ModelRegistry`/`Models`, not `getApiKeyAndHeaders()` + compat globals.
|
||||
- SDK options replace `authStorage` with `credentials?: CredentialStore` or an agent-dir-backed default; update `sdk.md` and examples.
|
||||
- `model-resolver`, `--list-models`, model selector, login/logout/status UI, and provider attribution await async model/auth APIs.
|
||||
- `model-resolver`, `--list-models`, model selector, login/logout/status UI, and provider attribution use sync last-known model reads and await only explicit refresh/auth operations.
|
||||
- CLI `--api-key` populates the runtime override decorator instead of mutating `AuthStorage`.
|
||||
- Keep extension loader root-to-compat alias until Phase 10, but expose the new collection/facade as the forward API.
|
||||
10. [ ] Test migration and real-provider validation.
|
||||
- Unit tests for `FileCredentialStore`, config-value decorators, provider decoration, extension OAuth adapter, ModelRegistry async facade, and consumer rewiring.
|
||||
- Unit tests for `FileCredentialStore`, runtime override overlay, provider decoration, extension OAuth adapter, Models-backed ModelRegistry facade, and consumer rewiring.
|
||||
- Regression tests for Cloudflare account/gateway env, Copilot OAuth baseUrl wrapping, runtime `--api-key` precedence, `$ENV`/`!command` resolution, and stored credential blocking ambient fallback.
|
||||
- Update existing tests that assume sync `ModelRegistry.getAll/find/getAvailable`.
|
||||
- Update existing tests for sync last-known `ModelRegistry.getAll/find/getAvailable` plus explicit async refresh behavior.
|
||||
- Run targeted non-e2e suites plus tmux validation of login flows against real providers (Anthropic OAuth/API key, OpenAI Codex OAuth, GitHub Copilot OAuth, Cloudflare AI Gateway, Bedrock if credentials are available).
|
||||
|
||||
### Phase 10 — compat deletion (pi 2.0 era, separate)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue