pi routes the main chat through the registered provider, but sibling
extensions that call streamSimple from @earendil-works/pi-ai/compat with
the active Command Code model resolve model.api through the compat
api-registry, which only knows built-in APIs. On plain pi that failed
with "No API provider registered for api: commandcode-custom".
Register commandcode-custom there and delegate to the transport router.
The registry resolves no credentials for extension providers, so fall
back to the configured Command Code key when the caller passes none.
Closes#68
(cherry picked from commit 7e9659e672771c6a9223b95938e50fb2a051a0a7)
Verify display pricing against the official pricing page and the live
provider model list:
- add claude-fable-5-1 and deepseek/deepseek-v4-flash-fast
- remove minimax/minimax-m3-free and minimax/minimax-m2.7-free, which the
provider no longer lists
- end the claude-sonnet-5 introductory window; the listed rate is unchanged
- google/gemini-3.7-flash returns to list price after the promotion ended
Add an agent skill that walks through a full model catalog refresh: drift
detection, catalog sync, manually reviewed pricing updates, fixture
refresh, and test updates. Its helper scripts run on Windows and Linux:
one snapshots the live model-id list into the test fixture, the other
regenerates the pricing fixture from MODEL_COSTS through prettier so
format:check stays green. Typecheck now covers the skill scripts.
execFile cannot spawn npm's .cmd shim directly on Windows, so the catalog
sync and drift check failed with spawn npm ENOENT. Route npm invocations
through the shell with argument quoting on Windows and keep direct
execFile calls elsewhere.
Align the developer-message fix with the Provider API transport router.
The fix stays scoped to the legacy /alpha/generate converter, and the
OMP advisory compat test now forces the upgrade_required fallback so the
advisory is asserted on the generate request body.
Fetches live account quota from Command Code alpha usage endpoints
(whoami, billing/credits, billing/subscriptions, usage/summary) and
renders a plain-text dashboard via ui.notify.
- Graceful degradation: optional endpoint transport/timeout/parse
failures degrade to null sections instead of aborting; only 401/403
are hard failures. 429 is transient, not fatal.
- Overall deadline bounds the whole command to QUOTA_TIMEOUT_MS
(per-request controllers are chained; post-deadline phases fail fast).
- OMP auth: filter unresolved $COMMANDCODE_API_KEY placeholder and fall
back to the host resolver via pickCommandCodeApiKey.
- ZDR privacy header respected on quota requests.
- Redaction reuses redactCommandCodeErrorText plus JSON-quoted
credential fields; outer-catch errors are redacted too.
- resetAt parsed from seconds, ms, numeric string, or ISO string.
- 21 hermetic unit tests wired into npm test (test:quota).
OMP converts custom and hook messages (advisor notes, todo reminders,
retry nudges) to role "developer" before calling the provider.
messagesToCC() only handled user, assistant, and toolResult, so those
messages were dropped before params.messages was sent to
/alpha/generate. Steering still interrupted pending tools, but the
model never saw the message content.
/alpha/generate has no developer role: the official command-code CLI
(0.32.3) only emits user, assistant, and tool messages plus a separate
params.system. Forward developer messages as user messages with
identical content in the same chronological position. Hoisting them
into params.system would turn a mid-conversation note into a global
top-priority instruction.
Persist the last valid Command Code model catalog and use it when live model discovery fails. Keep first-time offline startup non-fatal, surface clear warnings, and cover cached model selection with unit and pi integration regression tests.
The model fetch at startup throws and blocks pi from starting when
there's no network. Catch the error and register the provider with
an empty model list instead.
Add retry mechanism driven by pi settings.json retry.provider config
(timeoutMs, maxRetries, maxRetryDelayMs).
HTTP-level retries handle 429/5xx with exponential backoff and jitter,
respecting Retry-After headers (seconds and HTTP-date formats).
Stream-level retries handle cases where the API returns 200 OK but
sends an error event in the stream body. Retries only when no content
has been emitted yet.
Per-attempt timeout via AbortController with automatic retry. Clean
abort propagation through the retry loop.