Skip to content

Instantly share code, notes, and snippets.

@rcarmo
Created July 16, 2026 22:42
Show Gist options
  • Select an option

  • Save rcarmo/62b41e7204461c998506b5b6caabb5b8 to your computer and use it in GitHub Desktop.

Select an option

Save rcarmo/62b41e7204461c998506b5b6caabb5b8 to your computer and use it in GitHub Desktop.
# Piclaw Earendil 0.80.9 Upgrade Plan

Piclaw Earendil 0.80.9 Upgrade Plan

Prepared: 2026-07-16
Baseline: Piclaw 6f340fd65 on main
Current Earendil: 0.80.7
Target Earendil: 0.80.9
Scope: @earendil-works/pi-agent-core, @earendil-works/pi-ai, @earendil-works/pi-coding-agent, and all Piclaw-private provider/model extensions that register providers, inspect models, or issue auxiliary model requests

1. Executive summary

Upgrade Piclaw to Earendil 0.80.9 as one atomic compatibility PR, organized into separately testable commits. This is not a dependency-only update: Earendil 0.80.8 replaced the SDK model/auth architecture with async ModelRuntime, and 0.80.9 adds Kimi K3 native deferred-tool loading plus smaller provider and session fixes.

The migration should make ModelRuntime Piclaw's process-wide model/auth service while retaining ModelRegistry only as the synchronous extension-compatibility facade. Piclaw must initialize the runtime cache-first with model network access disabled, start the web service without waiting for remote catalogs, and perform bounded background refreshes afterward.

The highest-value outcomes are:

  1. Canonical request auth, headers, provider environment, OAuth refresh, and model discovery.
  2. Dynamic provider catalogs without a process restart.
  3. Removal of direct dependencies on the now-private AuthStorage and OAuth registry APIs.
  4. Upgrade and consolidation of Piclaw's private provider/model extension layer, including Azure OpenAI/Foundry, GitHub Copilot, model-control, compaction, and semantic summarizers.
  5. Simplification of Piclaw's private GitHub Copilot model discovery patch.
  6. Immediate reliability fixes for long OpenAI Codex session IDs.
  7. Native deferred-tool loading for Kimi K3, matching Piclaw's existing list_tools / activate_tools design.

Estimated implementation: 6–8 engineering days plus package publication and a 24-hour microVM soak.
Risk: Medium–high, concentrated in authentication, custom provider composition/streaming, model selection, dynamic providers, auxiliary model requests, and cross-repository add-on compatibility.
Recommended delivery: A coordinated piclaw-addons compatibility PR and core Piclaw upgrade PR, with add-on packages published before the upgraded core is rolled out; no live deployment until both CI surfaces and microVM validation pass.


2. Evidence and current state

2.1 Current dependency versions

package.json currently pins:

{
  "@earendil-works/pi-agent-core": "0.80.7",
  "@earendil-works/pi-ai": "0.80.7",
  "@earendil-works/pi-coding-agent": "0.80.7"
}

Target all three packages at exactly 0.80.9 to prevent cross-package API skew.

2.2 Isolated compatibility trial

An isolated worktree was upgraded to 0.80.9 and typechecked without modifying the live checkout.

Observed results:

  • 11 TypeScript errors before tests.
  • Focused tests failed at module load because removed exports were imported.
  • 24 runtime source files reference affected model/auth APIs.
  • 29 test files reference affected model/auth APIs.
  • Upstream changed 193 files across pi-ai, pi-agent-core, and pi-coding-agent between 0.80.7 and 0.80.9.

Primary breakpoints:

  1. AuthStorage is no longer exported.
  2. ModelRegistry.create() and ModelRegistry.inMemory() are gone.
  3. SDK/session services accept modelRuntime instead of authStorage + modelRegistry.
  4. AgentSession.modelRegistry became AgentSession.modelRuntime.
  5. Canonical request auth moved to ModelRuntime.getAuth().
  6. ModelRegistry.refresh() became asynchronous.
  7. getOAuthProvider() is no longer exported from @earendil-works/pi-ai/oauth.
  8. Piclaw's login and provider-usage code reads raw credential structures directly.

2.3 Private provider/model extension inventory

The upgrade must include Piclaw-private extensions, not merely the central agent pool. The model-sensitive private surface is:

Class Files Required migration
Azure provider registration and streaming runtime/extensions/integrations/azure-openai.ts, runtime/src/extensions/azure-openai-api.ts, runtime/src/runtime/provider-bootstrap.ts Revalidate registerProvider composition, transient token refresh/re-registration, custom API names, custom streamSimple, headers, retries, model caps, and live model replacement
Azure extension variants runtime/extensions/experimental/azure-openai.harness.ts, runtime/extensions/integrations/azure-openai-session/index.ts, runtime/extensions/integrations/azure-openai-images.ts Keep the harness behavior aligned with the primary integration; verify session hooks and image commands against refreshed models
Dynamic GitHub Copilot catalog runtime/src/extensions/github-copilot-dynamic-models.ts Replace private OAuth lookup and boot registry patch with inherited auth plus refreshModels(context), or remove the overlay if upstream now covers the account catalog
Model control tools runtime/src/extensions/model-control.ts Await async refresh, then enumerate/switch using a coherent post-refresh snapshot
Auxiliary model consumers runtime/src/extensions/context-prune/summarizer.ts, runtime/extensions/integrations/context-mode.ts, runtime/src/extensions/smart-compaction/model-request.ts, runtime/src/extensions/smart-compaction/stream-complete.ts Route auth and completion through the shared ModelRuntime or an injected runtime-owned executor; preserve headers, env, base URL, retries, abort, and usage
Provider payload/response compatibility runtime/src/extensions/provider-request-sanitizer.ts, runtime/src/extensions/provider-response-diagnostics.ts, runtime/src/extensions/llm-context-normalizer.ts, runtime/src/extensions/smart-compaction/remote-compaction.ts Re-run hook-order and payload-shape tests under the new Models dispatch path; do not infer capabilities from provider/model names
Model-aware prompt/profile behavior runtime/src/extensions/local-lite-prompt-profile.ts, smart-compaction context/orchestrator files Verify behavior against refreshed canonical model objects and explicit model metadata
Extension registry and injection seam runtime/src/extensions/index.ts, runtime/src/agent-pool/session.ts, runtime/src/extensions/context-mode-api.ts Inject runtime-owned model execution helpers into built-ins where possible; retain the extension compatibility facade only where external extension loading requires it

There are 64 files under runtime/src/extensions and runtime/extensions importing Earendil packages; all must compile, while the table above identifies the subset requiring behavioral migration rather than type-only validation.

2.4 Private add-on provider/model extension inventory

The separate /workspace/piclaw-addons repository also contains runtime extensions that depend on affected model/provider APIs. They require their own PR, package version bumps, catalog regeneration, publication, and installation validation.

Add-on Current sensitive behavior Required migration
@rcarmo/piclaw-addon-cheapskate registers and re-registers a custom rotating provider update the API identifier/config to the 0.80.9 provider contract; prove merge/re-registration semantics, auth resolution, backend rotation, and in-flight safety
@rcarmo/piclaw-addon-codex-conversion overrides openai-codex with a custom streamSimple verify partial built-in provider override preserves upstream OAuth, base URL, catalog filtering, model headers, and new Codex session-ID behavior; test images/web-search and WebSocket cleanup
@rcarmo/piclaw-addon-delegate captures runtime catalog through synchronous modelRegistry.refresh() and getAvailable() await refresh or use a coherent cached snapshot; preserve fallback to CLI model discovery and abort behavior
@rcarmo/piclaw-addon-skill-model-effort resolves models through the extension compatibility facade await refresh before applying skill model metadata when freshness matters; preserve unique model matching and thinking-level mapping
@rcarmo/piclaw-addon-smart-compaction calls getApiKeyAndHeaders() and completeSimple() directly migrate to the runtime-owned execution pattern available to external extensions, or add a small compatibility adapter that preserves full auth/header/env/base-URL behavior and is tested against 0.80.9
@rcarmo/piclaw-addon-autoresearch test fixture stubs registerProvider() update fixtures/types so standalone compatibility tests represent the new extension API

Repository-wide prerequisites:

  • update piclaw-addons development Earendil packages from 0.80.3 to 0.80.9
  • keep Pi core packages as peer dependencies in published add-ons; do not bundle them
  • run standalone-import tests and bunx tsc --noEmit
  • bump every functionally changed add-on version
  • run bun run sync:catalog and bun run check:catalog
  • preserve public GitHub Pages tarball installation URLs

The add-ons checkout already contains unrelated local modifications. Implementation must use a new worktree and must not absorb or overwrite those changes.

2.5 Protected unrelated state

The existing unrelated dirty file must remain untouched:

runtime/extensions/viewers/editor/vendor/codemirror.meta.json

Use a dedicated worktree and verify the main checkout remains unchanged.


3. Target architecture

3.1 Process-wide model service

Piclaw should own one process-wide ModelRuntime and pass it to every main session, side session, compaction request, provider bootstrap, and control surface.

runtime startup
    |
    +-- ModelRuntime.create({ allowModelNetwork: false })
    |       |
    |       +-- auth.json credentials
    |       +-- models.json configuration
    |       +-- models-store.json cached catalogs
    |
    +-- AgentPool
    |       +-- main sessions
    |       +-- side sessions
    |       +-- compaction/summarization requests
    |       +-- model picker/control handlers
    |
    +-- background catalog refresh after listeners are ready

3.2 Compatibility boundary

Use new ModelRegistry(modelRuntime) only where a synchronous extension-facing facade is required. New Piclaw runtime code should use ModelRuntime directly.

Allowed compatibility uses:

  • externally loaded extensions that receive only ExtensionContext.modelRegistry
  • extension tests explicitly exercising the compatibility facade
  • temporary migration adapters with a documented deletion condition

Piclaw-owned built-in extensions should prefer an injected runtime-owned executor over assembling auth and calling completeSimple() directly. The executor should expose only the operation required by the extension (for example completeSimple(model, context, options)) and internally delegate to the shared ModelRuntime. This keeps provider auth, model headers, base URL, environment, OAuth refresh, and request transforms coherent without exposing the full process-wide runtime to every extension.

Disallowed new uses:

  • process-wide model ownership through ModelRegistry
  • direct request-auth assembly through getApiKeyAndHeaders()
  • direct credential mutation through AuthStorage
  • model catalog reads immediately after an unawaited refresh()

3.3 Startup and refresh policy

Do not permit remote catalog refresh to block web startup. Upstream ModelRuntime.create() can wait up to 15 seconds when model networking is enabled.

Required policy:

  1. Create the runtime with allowModelNetwork: false.
  2. Load built-ins, models.json, credentials, and cached models-store.json during startup.
  3. Start web/Pushover channels.
  4. Schedule one bounded background refresh with network access enabled.
  5. Coalesce concurrent refreshes.
  6. Serve the last good snapshot while refresh is running or fails.
  7. Log provider-specific refresh errors without making the instance unhealthy.
  8. Allow an explicit forced refresh for diagnostics/administration.

Suggested defaults:

  • background refresh timeout: 10–15 seconds total
  • per-provider extension timeout: preserve the existing 3.5-second Copilot timeout unless evidence supports changing it
  • refresh cadence: rely on upstream throttling where available; add a Piclaw coalescing guard so repeated model-picker requests do not start duplicate work
  • startup: no network call on the critical path before the web listener is accepting requests

4. Work packages

WP0 — Branch, baseline, and safety fixtures

Estimate: 0.25 day
Risk: Low

Actions

  1. Prune stale worktrees and create a dedicated branch/worktree, for example:

    cd /workspace/piclaw
    git worktree prune
    git worktree add /workspace/piclaw-earendil-0809 -b upgrade/earendil-0.80.9 main
  2. Record baseline versions, current model configuration, and test results.

  3. Preserve the unrelated CodeMirror metadata modification in the main checkout.

  4. Add or retain test fixtures for:

    • file-backed credentials
    • in-memory credentials
    • custom models.json
    • cached dynamic catalogs
    • Codex and Copilot OAuth-shaped credentials
  5. Run baseline focused tests before changing dependencies.

Exit criteria

  • Dedicated worktree exists.
  • Baseline test results are recorded in the PR description or an implementation note.
  • Main checkout only contains the pre-existing protected modification.

WP1 — Dependency bump and async runtime foundation

Estimate: 0.75–1 day
Risk: High

Files

Primary:

  • package.json
  • bun.lock
  • runtime/src/runtime.ts
  • runtime/src/runtime/composition.ts
  • runtime/src/runtime/bootstrap.ts
  • runtime/src/agent-pool.ts
  • runtime/src/agent-pool/contracts.ts
  • runtime/src/agent-pool/service-factory.ts

Supporting tests:

  • runtime composition/bootstrap tests
  • runtime/test/agent-pool/agent-pool.test.ts
  • runtime/test/agent-pool/service-factory.test.ts

Actions

  1. Update all Earendil packages together:

    bun update \
      @earendil-works/pi-agent-core@0.80.9 \
      @earendil-works/pi-ai@0.80.9 \
      @earendil-works/pi-coding-agent@0.80.9
  2. Introduce async construction for the process-wide model runtime. Preferred shape:

    • createRuntimeCoreServices() becomes async, or
    • add an async factory that creates ModelRuntime and then constructs AgentPool.

    Avoid a promise-valued runtime field or hidden lazy initialization inside request handlers.

  3. Construct the runtime with canonical Piclaw paths and cache-first startup:

    const modelRuntime = await ModelRuntime.create({
      authPath: join(getAgentDir(), "auth.json"),
      modelsPath: join(getAgentDir(), "models.json"),
      modelsStorePath: join(getAgentDir(), "models-store.json"),
      allowModelNetwork: false,
    });
  4. Inject ModelRuntime into AgentPool.

  5. If extension compatibility is needed, construct one facade:

    const modelRegistry = new ModelRegistry(modelRuntime);
  6. Add an explicit background refresh coordinator with:

    • a single in-flight promise
    • timeout/abort support
    • last-good snapshot behavior
    • structured logs per provider
  7. Start background refresh only after Piclaw's listener/channel startup succeeds.

Design decision

Prefer a required modelRuntime dependency in the production AgentPool constructor or an async AgentPool.create() factory. Keep test-only convenience construction explicit; do not make production requests wait for first-use initialization.

Tests

  • startup does not perform remote model fetches before the web listener starts
  • multiple refresh requests coalesce
  • refresh failure leaves cached models available
  • offline startup works with and without models-store.json
  • startup diagnostics expose malformed models.json without crashing unrelated channels

Exit criteria

  • Dependencies resolve at 0.80.9.
  • Process-wide runtime is created exactly once.
  • No production path constructs AuthStorage or calls ModelRegistry.create().
  • Startup is cache-first and bounded.

WP2 — Session, model, and auxiliary request migration

Estimate: 1–1.5 days
Risk: High

Files

  • runtime/src/agent-pool/session.ts
  • runtime/src/agent-pool/session-manager.ts
  • runtime/src/agent-pool/runtime-facade.ts
  • runtime/src/agent-pool/side-prompt-runner.ts
  • runtime/src/agent-pool/cache-stats.ts
  • runtime/src/session-rotation.ts
  • runtime/src/utils/model-auth.ts
  • runtime/src/utils/model-utils.ts
  • runtime/src/extensions/context-prune/summarizer.ts
  • runtime/src/extensions/smart-compaction/model-request.ts
  • runtime/src/agent-control/handlers/model.ts
  • runtime/src/agent-control/handlers/info.ts
  • runtime/src/extensions/model-control.ts

Actions

  1. Replace session-service fields:

    authStorage + modelRegistry -> modelRuntime
    
  2. Pass modelRuntime to createAgentSessionFromServices() and every replacement runtime created for:

    • main sessions
    • side sessions
    • session rotation
    • fork/resume/new-session flows
  3. Replace session.modelRegistry reads with session.modelRuntime.

  4. Change request auth helpers to call:

    const resolved = await modelRuntime.getAuth(model);

    Forward:

    • resolved.auth.apiKey
    • resolved.auth.headers, excluding null/deleted entries where required by the downstream type
    • resolved.auth.baseUrl through the runtime/provider path rather than manually modifying models
    • resolved.env
  5. Prefer modelRuntime.streamSimple() for Piclaw-owned auxiliary model calls where practical. This delegates auth/header/base-URL assembly to the canonical runtime and reduces duplicated logic.

  6. Preserve explicit retry/timeout settings used by compaction and side prompts.

  7. Update model enumeration:

    • synchronous display: getAvailableSnapshot()
    • freshness-required path: await getAvailable() or await refresh() followed by a read
    • all models: getModels()
    • exact lookup: getModel(provider, id)
  8. Update cache-stat model lookup to accept a minimal model lookup interface or ModelRuntime, not the extension facade.

  9. Make all refresh-dependent control handlers async and await refresh before immediate reads.

  10. Fix the legacy session-affinity compatibility hook:

    • do not apply immediately after starting an async refresh
    • apply after the refresh resolves
    • preserve JSONC files without destructive rewriting
    • document removal after the compatibility window ends
  11. Remove obsolete automatic-recovery signatures for missing getApiKeyAndHeaders() once all canonical paths are migrated, while retaining meaningful auth-failure patterns.

Focused tests

  • main session creation and resume
  • side-prompt auth forwarding
  • compaction stream auth forwarding
  • custom model headers and provider-scoped environment
  • session rotation preserves provider/model/thinking selection
  • model picker does not hydrate a cold session
  • model refresh is awaited when a fresh result is required
  • current-model restore uses the refreshed canonical model object
  • legacy session-affinity compatibility applies after async reload

Exit criteria

  • No Piclaw request path manually reimplements canonical runtime auth assembly.
  • Main, side, compaction, and summarization calls use the same model runtime.
  • No stale synchronous read follows an unawaited ModelRegistry.refresh().

WP3 — Login, logout, credentials, and provider usage

Estimate: 1–1.5 days
Risk: High

Files

  • runtime/src/agent-control/handlers/login.ts
  • runtime/src/agent-control/provider-defs.ts
  • runtime/src/agent-control/agent-control-handlers.ts
  • runtime/src/agent-pool/provider-usage.ts
  • related agent-control/provider-usage tests

Actions

  1. Replace Piclaw's private AuthStorageLike control path with ModelRuntime methods:
    • getProviders()
    • getProvider()
    • getProviderAuthStatus()
    • checkAuth()
    • login()
    • logout()
    • listCredentials()
  2. Build /login provider options from provider-owned auth capabilities rather than getOAuthProviders().
  3. Adapt the web card flow to upstream's AuthInteraction contract:
    • prompt() maps text, secret, select, and manual-code requests to supported card steps
    • notify() maps info links, auth URLs, device codes, and progress to card content
    • cancellation uses AbortSignal
  4. For API-key login, call modelRuntime.login(providerId, "api_key", interaction) instead of writing auth.json directly.
  5. For OAuth login, call modelRuntime.login(providerId, "oauth", interaction) and preserve the existing non-blocking web flow where needed. Ensure there is one owner for the background login promise and a clear retry/check state.
  6. Use modelRuntime.logout(providerId) for deletion and refresh.
  7. After editing custom-provider configuration in models.json, call await modelRuntime.reloadConfig(); do not mutate registry internals.
  8. Preserve backup behavior for user-edited config files where Piclaw still writes them.
  9. Refactor provider quota lookup:
    • call modelRuntime.getAuth(providerId) first so OAuth refresh remains canonical
    • use the resolved API key for ZAI and other normal request auth
    • use exported readStoredCredential(providerId, authPath) only for supplemental fields unavailable in request auth, such as Codex account ID or Copilot's original GitHub token
    • never instantiate or expose the removed AuthStorage
  10. Keep quota failure non-fatal and preserve stale cached values.

Security requirements

  • Do not log credentials or resolved request headers.
  • Provider lists/status must use non-secret metadata.
  • Preserve auth.json permissions and format.
  • Do not copy secrets into new Piclaw state files.
  • Avoid direct credential-file writes except through canonical upstream login/logout.

Tests

  • provider discovery and display names
  • API-key login, status, and logout
  • device-code OAuth notifications
  • OAuth completion and cancellation
  • expired credential refresh without duplicate refreshes
  • custom provider login and model availability
  • provider quota with refreshed Codex credential
  • provider quota with Copilot supplemental refresh token
  • auth failure leaves the service responsive and returns actionable UI text

Exit criteria

  • No source import of AuthStorage.
  • No source import of getOAuthProvider().
  • Login/logout uses provider-owned runtime APIs.
  • Quota/status code does not own credential refresh.

WP4 — Dynamic catalogs and GitHub Copilot simplification

Estimate: 0.75–1 day
Risk: Medium

Files

  • runtime/src/extensions/github-copilot-dynamic-models.ts
  • runtime/src/runtime/provider-bootstrap.ts
  • runtime/src/runtime/bootstrap.ts
  • runtime/test/extensions/github-copilot-dynamic-models.test.ts
  • provider-bootstrap tests

Current overlap

Earendil 0.80.9 already:

  • owns GitHub Copilot OAuth and refresh
  • derives credential-specific Copilot endpoints
  • fetches account-enabled model IDs during credential refresh
  • filters its substantial built-in catalog by account availability
  • preserves Copilot-specific stream implementations and headers

Piclaw should retain only the incremental capability it still needs: importing valid live model IDs absent from upstream's generated static catalog.

Actions

  1. Remove the getOAuthProvider() import and any extension-owned OAuth registration.
  2. Register a provider overlay that inherits upstream auth and streams and supplies only refreshModels(context).
  3. In refreshModels(context):
    • restore Piclaw's cached extension catalog from context.store first
    • if context.allowNetwork is false, return the cached/known merged catalog
    • require an OAuth credential with a usable Copilot access token for network discovery
    • derive the credential-specific endpoint safely, including enterprise support
    • fetch /models with the shared abort signal and bounded timeout
    • filter embeddings, trajectory helpers, disabled policies, and non-chat entries
    • merge live entries with upstream's known models
    • preserve upstream metadata when a known model exists
    • infer API/limits/vision/reasoning conservatively for unknown models
    • persist the validated merged catalog with context.store.write()
  4. Do not re-register OAuth, base auth, or custom stream handlers.
  5. Remove the current boot-time function that directly manipulates the global registry.
  6. Trigger canonical runtime refresh after channels are ready. Allow the session/model picker to use the cached snapshot immediately.
  7. Keep a feature flag to disable Piclaw's incremental Copilot overlay independently of upstream's built-in provider.

Decision gate

Before preserving the private overlay, compare the live account catalog with upstream 0.80.9's generated catalog. If all selectable account models are already represented, remove the Piclaw overlay entirely and rely on upstream filtering. This is the preferred outcome.

Tests

  • built-in Copilot OAuth remains inherited
  • no private OAuth export is required
  • offline cache restoration
  • unknown valid chat model import
  • embedding/trajectory/disabled model rejection
  • known model metadata preservation
  • enterprise endpoint derivation
  • network timeout leaves cached models intact
  • concurrent refreshes do not duplicate requests

Exit criteria

  • No boot-time registry patch.
  • No extension-owned Copilot OAuth implementation.
  • Account-specific catalog behavior is preserved or proven redundant.

WP5 — Private provider and model extension upgrade

Estimate: 1–1.5 days
Risk: High

This work package covers all Piclaw-owned provider registrations and model-consuming extensions. It is required for the upgrade, not a deferred cleanup.

WP5A — Azure OpenAI and Foundry providers

Files

  • runtime/extensions/integrations/azure-openai.ts
  • runtime/extensions/experimental/azure-openai.harness.ts
  • runtime/src/extensions/azure-openai-api.ts
  • runtime/src/runtime/provider-bootstrap.ts
  • runtime/extensions/integrations/azure-openai-session/index.ts
  • runtime/extensions/integrations/azure-openai-images.ts
  • all runtime/test/extensions/azure-openai-*.test.ts files
  • runtime/test/runtime/provider-bootstrap.test.ts
  • rename/update runtime/test/agent-pool/earendil-0807-provider-regressions.test.ts

Actions

  1. Compile provider configs against the 0.80.9 ProviderConfigInput and ProviderModelConfig contracts. Replace any at the registration boundary with Parameters<ExtensionAPI["registerProvider"]>[1] or the exported provider config type where practical.
  2. Retain private API names only where required to prevent global handler collisions:
    • Azure Responses custom API
    • Foundry completion adapter
    • secondary Azure endpoint API
  3. Verify custom streamSimple dispatch under ModelRuntime composition:
    • extension stream is selected for its declared API
    • built-in provider streams remain available for inherited APIs
    • re-registration does not discard unspecified provider fields
  4. Keep token acquisition inside the Azure integration, but stop embedding each transient bearer token as long-lived model ownership if a runtime-safe resolver can be used. Preferred order:
    • use an extension/provider auth resolver supported by the public contract, if available
    • otherwise preserve bounded re-registration on token refresh and prove that ModelRuntime.registerProvider() atomically updates request auth without dropping models or in-flight sessions
  5. Do not write Azure access tokens to auth.json or models-store.json.
  6. Preserve provider/model-specific headers and ensure canonical runtime request assembly does not duplicate Authorization or api-key headers.
  7. Revalidate custom base-URL normalization, deployment routing, Responses-only guardrails, Foundry routing, request token estimates, retry-after handling, session affinity, image output, and tool-call limits.
  8. Move model-cap discovery into provider refreshModels(context) where that improves cache/offline behavior without coupling credential refresh to model refresh. If token rotation and capability discovery must remain separate, document and test the two lifecycles explicitly.
  9. Make bootstrap non-blocking for the web listener. Azure provider registration may use cached/static model definitions immediately, then refresh token/caps in the background.
  10. Make the process-level provider bootstrap the sole owner of Azure token/model registration and its refresh timer. The session extension (azure-openai-session) should retain only session-scoped context repair and image/Flux commands. Do not load the full azure-openai.ts default extension per session merely to register providers.
  11. Ensure process shutdown stops the sole Azure bootstrap timer; session replacement must not stop or recreate process-level provider registration.
  12. Keep the experimental harness behavior aligned with the production integration or remove duplicated code if the harness is no longer needed. Do not allow the two implementations to diverge in auth, model metadata, or API routing.

Azure tests

  • static API key and managed identity registration
  • token refresh re-registration preserves all provider models
  • no duplicate auth headers
  • multiple Azure endpoints remain isolated
  • Responses-only models never fall through to completions
  • Foundry models use the intended completion adapter
  • model-cap refresh updates context/output limits atomically
  • network/capability failure retains the last good catalog
  • exactly one Azure token-refresh timer exists per process
  • process shutdown clears the provider timer
  • session replacement rebinds context/image hooks without re-registering providers or restarting the process timer
  • payload sanitizer and response diagnostics still observe Azure requests/responses

WP5B — Model-control extension

Files

  • runtime/src/extensions/model-control.ts
  • runtime/test/extensions/extensions-model-control.test.ts
  • web model-state and compose refresh tests

Actions

  1. Change list_models and switch_model to await ctx.modelRegistry.refresh() before reading the synchronous compatibility snapshot.
  2. Prefer one local const registry = ctx.modelRegistry and one coherent post-refresh read; do not mix snapshots across awaits.
  3. Preserve enabled-model scoping and pagination.
  4. Surface refresh errors while continuing to show cached models.
  5. Verify pi.setModel() receives the refreshed canonical model object.
  6. Keep model/thinking status persistence synchronized after refresh and switching.

WP5C — Compaction, context pruning, and semantic summarizers

Files

  • runtime/src/extensions/context-prune/summarizer.ts
  • runtime/extensions/integrations/context-mode.ts
  • runtime/src/extensions/context-mode-api.ts
  • runtime/src/extensions/smart-compaction/model-request.ts
  • runtime/src/extensions/smart-compaction/stream-complete.ts
  • runtime/src/extensions/smart-compaction/model-execution.ts
  • runtime/src/extensions/smart-compaction/orchestrator.ts
  • runtime/src/extensions/smart-compaction/remote-compaction.ts
  • related context-mode, context-prune, smart-compaction, stream-complete, and remote-compaction tests

Actions

  1. Inject a runtime-owned simple-completion executor into Piclaw built-in extensions. The executor must delegate to the shared ModelRuntime and preserve:
    • resolved API key
    • model and configured headers
    • provider-scoped environment
    • credential-specific base URL
    • OAuth refresh
    • abort signal
    • retry/timeouts and usage
  2. Replace direct ctx.modelRegistry.getApiKeyAndHeaders() plus completeSimple() sequences in Piclaw-owned extensions.
  3. Where an externally loaded extension cannot receive the executor, keep a compatibility helper around ctx.modelRegistry, but await async refresh where required and add a deletion note.
  4. Preserve fail-open behavior for semantic tool-output summaries: failure must fall back to preview/storage behavior and must not fail the parent tool call.
  5. Preserve fail-closed behavior where compaction correctness requires a valid model/auth pair.
  6. Keep the model and auth resolution atomic so token budgets and capability decisions are made for the same model used for the request.
  7. Re-run remote-compaction capability tests and retain the rule that support is explicit provider metadata/configuration—not inferred from model names or api: "openai-responses".
  8. Verify provider hooks (before_provider_headers, request sanitizer, response diagnostics) still run for runtime-owned auxiliary requests where intended. If ModelRuntime.streamSimple() bypasses AgentSession extension hooks, preserve the required transforms explicitly through the injected executor and document which hooks do or do not apply.

WP5D — Provider compatibility hooks and model profiles

Files

  • runtime/src/extensions/provider-request-sanitizer.ts
  • runtime/src/extensions/provider-response-diagnostics.ts
  • runtime/src/extensions/llm-context-normalizer.ts
  • runtime/src/extensions/local-lite-prompt-profile.ts
  • related tests

Actions

  1. Revalidate hook order against ModelRuntime final request assembly:
    • auth/model headers assembled
    • before_provider_headers transform applied
    • request payload sanitizer applied
    • provider response diagnostics observe status/headers
  2. Ensure header deletion/null semantics survive conversion between upstream ProviderHeaders and Piclaw records.
  3. Verify local-lite model detection still uses explicit provider/base-URL configuration and does not become a generic model-name heuristic.
  4. Verify refreshed model objects do not lose custom compatibility metadata used by prompt profiles or compaction.

Private-extension exit criteria

  • Every Piclaw-private provider/model extension compiles against 0.80.9.
  • Azure OpenAI, Foundry, secondary Azure, and experimental harness tests pass.
  • Dynamic provider re-registration is atomic and does not lose catalog/auth/stream configuration.
  • Azure provider registration/token refresh has one process-level owner; session extensions do not create competing timers.
  • Model-control awaits refresh and continues to serve cached data on refresh failure.
  • Context-prune, context-mode, and smart-compaction requests use the shared runtime-owned execution seam.
  • Provider sanitizer/diagnostic hooks have explicit tested behavior for both normal AgentSession calls and auxiliary calls.
  • No private extension imports removed Earendil auth/OAuth APIs.

WP6 — Private add-on compatibility and publication

Estimate: 1–1.5 days
Risk: High

Repository: /workspace/piclaw-addons

Actions

  1. Create a dedicated add-ons worktree from a clean branch; preserve unrelated dirty files in the existing checkout.
  2. Update root development dependencies for all Earendil packages to 0.80.9.
  3. Upgrade cheapskate:
    • use an API name accepted by the 0.80.9 provider contract (openai-completions unless a custom API implementation is deliberately registered)
    • type its provider/model configs
    • verify provider re-registration merges only defined fields and updates routing atomically
    • test rate-limit/context-limit rotation while a session remains active
  4. Upgrade codex-conversion:
    • keep its override as a partial overlay on the built-in openai-codex provider
    • do not replace or reimplement upstream OAuth/catalog behavior
    • verify custom streamSimple receives runtime-resolved auth, headers, environment, and credential-specific base URL
    • retain upstream long-session-ID clamp and deferred-tool behavior where applicable
    • test WebSocket cleanup, image-generation activity, and surfaced web-search activity
  5. Upgrade delegate:
    • make runtime catalog capture async when forcing refresh
    • use await ctx.modelRegistry.refresh() followed by one snapshot read, or explicitly choose getAvailable() cached behavior
    • preserve CLI fallback and metadata merge
  6. Upgrade skill-model-effort:
    • refresh once before resolving a requested skill model when the command/read action applies overrides
    • preserve unambiguous matching and restore behavior
    • test model disappearance or refresh failure using the last good snapshot
  7. Upgrade standalone smart-compaction:
    • remove assumptions that auth is only API key + headers
    • preserve provider env and credential-specific base URL
    • prefer an external-extension-safe model execution API; if upstream exposes no such context method, use the ModelRegistry compatibility facade behind one adapter and test the complete ResolvedRequestAuth forwarding contract
    • retain explicit remote-compaction capability rules
  8. Update autoresearch provider fixtures.
  9. Bump changed package versions, regenerate catalog metadata, and pack each changed add-on.
  10. Run clean standalone imports against Piclaw with Earendil 0.80.9.
  11. Open and merge the add-ons PR separately, then allow CI to publish public tarballs.
  12. Verify published tarball URLs return the new versions before core rollout.

Add-on test gates

cd /workspace/piclaw-addons
bun install
bunx tsc --noEmit
bun test \
  addons/cheapskate/index.test.ts \
  addons/codex-conversion/index.test.ts \
  addons/delegate/index.test.ts \
  addons/skill-model-effort/index.test.ts \
  addons/smart-compaction/index.test.ts
bun run sync:catalog
bun run check:catalog

Also run repository standalone-import tests and pack inspection for each changed package. Use the add-on microVM E2E suite for installed-package behavior.

Exit criteria

  • All affected add-ons compile and pass tests against Earendil 0.80.9.
  • Changed packages have version bumps and synchronized catalog entries.
  • Public tarballs are published and downloadable without authentication.
  • A clean Piclaw 0.80.9 test instance imports every installed affected add-on without startup errors.
  • Provider overrides preserve inherited auth/catalog behavior.
  • No changed package bundles Pi core dependencies.

WP7 — Kimi K3 and deferred-tool verification

Estimate: 0.25–0.5 day
Risk: Low

Scope

No dedicated Piclaw feature implementation should be required. Existing additive activation through activate_tools already provides the signal Earendil uses for deferred tool loading.

Actions

  1. Add or adapt a provider-fixture test for a model with:

    compat: { deferredToolsMode: "kimi" }
  2. Verify the sequence:

    • discovery tools active initially
    • target tool registered but inactive
    • activate_tools adds the target without removing active tools
    • the following request includes the newly activated definition at the tool-result position
    • the tool is callable in that same agent run
  3. Confirm fallback behavior remains correct for non-Kimi models.

  4. Audit lazily activated Piclaw tools with promptSnippet or promptGuidelines. These change the system prompt and can invalidate the provider cache prefix even when the schema is deferred.

  5. Do not remove useful prompt metadata globally. Record high-volume candidates for a later optimization PR, based on prompt-cache measurements.

Exit criteria

  • Existing same-turn activation tests pass under 0.80.9.
  • Kimi serialization is covered by at least one focused compatibility test.
  • No provider-name or model-name heuristics are added in Piclaw.

5. Cross-repository delivery and commit structure

Use two coordinated PRs because published add-ons are an independent compatibility surface and some installed packages must be available before the upgraded core is rolled out.

PR A — rcarmo/piclaw-addons

Recommended commits:

  1. chore(deps): test add-ons against Earendil 0.80.9
  2. fix(providers): update private provider extensions for ModelRuntime
  3. fix(models): await refreshed catalogs in model-aware add-ons
  4. test(addons): cover Earendil 0.80.9 compatibility
  5. chore(catalog): publish upgraded add-on packages

Merge and publish PR A first. Do not install into the local live instance yet.

PR B — rcarmo/piclaw

Use one atomic core PR because intermediate dependency/runtime states do not compile independently. Recommended commits:

  1. chore(deps): update Earendil packages to 0.80.9
    • dependency files
    • async runtime foundation
  2. refactor(models): adopt ModelRuntime across sessions and requests
    • main/side/compaction core
  3. refactor(auth): use provider-owned login and credential APIs
    • login/logout/status/quota
  4. refactor(providers): migrate private provider and catalog extensions
    • Azure OpenAI/Foundry with one process-level registration owner
    • Copilot overlay
    • provider bootstrap and refresh
  5. refactor(extensions): route model helpers through shared runtime
    • model-control
    • context-mode/context-prune
    • smart-compaction and diagnostics
  6. test(models): cover Earendil 0.80.9 compatibility
    • focused regressions and fixtures

PR B may be developed in parallel but must use the published PR A package set for its final microVM gate.

Both PR descriptions must include:

  • upstream release links
  • the breaking API summary
  • startup-network policy
  • before/after model/auth architecture
  • exact local test results
  • microVM deployment and UX evidence
  • rollback instructions

Do not merge without user approval.


6. Validation matrix

6.1 Static and repository gates

Run after each meaningful work package:

bun run typecheck
bun run lint
bun run build:web

Final local gate:

make ci-fast

Hosted CI remains authoritative after pushing the PR.

6.2 Focused unit/integration suites

At minimum, run affected tests covering:

Runtime and sessions

  • runtime/test/agent-pool/agent-pool.test.ts
  • runtime/test/agent-pool/service-factory.test.ts
  • runtime/test/agent-pool/session-manager.test.ts
  • runtime/test/agent-pool/session-auto-compaction-control.test.ts
  • runtime/test/agent-pool/session-persistence-sanitizer.test.ts
  • runtime/test/session-rotation.test.ts

Model/auth behavior

  • replace or rename runtime/test/agent-pool/earendil-0807-ambient-auth.test.ts for 0.80.9
  • runtime/test/utils/model-auth.test.ts
  • runtime/test/agent-pool/compaction-stream-auth.test.ts
  • runtime/test/agent-pool/side-prompt-runner.test.ts
  • runtime/test/agent-control/provider-defs.test.ts
  • runtime/test/agent-control/agent-control-handlers.test.ts
  • runtime/test/agent-pool/provider-usage.test.ts

Dynamic tools/providers and private model extensions

Core repository:

  • runtime/test/agent-pool/tool-activation-live-update.test.ts
  • runtime/test/extensions/github-copilot-dynamic-models.test.ts
  • runtime/test/extensions/extensions-model-control.test.ts
  • runtime/test/extensions/smart-compaction.test.ts
  • runtime/test/extensions/context-prune.test.ts
  • runtime/test/extensions/context-mode.test.ts
  • runtime/test/extensions/provider-request-sanitizer.test.ts
  • runtime/test/extensions/provider-response-diagnostics.test.ts
  • runtime/test/runtime/provider-bootstrap.test.ts
  • runtime/test/extensions/azure-openai-api.test.ts
  • runtime/test/extensions/azure-openai-bootstrap.test.ts
  • runtime/test/extensions/azure-openai-harness-bootstrap.test.ts
  • runtime/test/extensions/azure-openai-routing.test.ts
  • runtime/test/extensions/azure-openai-streaming.test.ts
  • runtime/test/extensions/azure-openai-retry-after.test.ts
  • runtime/test/extensions/azure-openai-session.test.ts
  • runtime/test/extensions/azure-openai-image-output.test.ts
  • runtime/test/extensions/azure-openai-tool-call-limit.test.ts
  • renamed/updated runtime/test/agent-pool/earendil-0807-provider-regressions.test.ts

Add-ons repository:

  • addons/cheapskate/index.test.ts
  • addons/codex-conversion/index.test.ts
  • addons/delegate/index.test.ts
  • addons/skill-model-effort/index.test.ts
  • addons/smart-compaction/index.test.ts
  • addons/autoresearch/supervisor.test.ts
  • repository standalone-import tests
  • catalog sync/check and packed-tarball import checks

Web integration

  • runtime/test/channels/web/web-channel.test.ts
  • model-picker endpoint tests
  • login card/action tests
  • agent status/model-state tests

6.3 Required new regression tests

Add tests that prove:

  1. Cache-first runtime construction performs no model network request.
  2. Background refresh does not block channel startup.
  3. Concurrent refreshes coalesce.
  4. A failed refresh preserves the last good catalog.
  5. models.json reload is awaited before a fresh synchronous facade read.
  6. Model headers, provider environment, and custom base URL survive request assembly.
  7. OAuth refresh is serialized across concurrent main/side requests.
  8. Main, side, compaction, and summarizer calls share the same runtime.
  9. Login/logout uses provider-owned methods.
  10. Copilot dynamic refresh inherits upstream OAuth and stream behavior.
  11. Azure token refresh/re-registration preserves provider models, custom streams, headers, and endpoint isolation.
  12. Azure/Foundry model-cap refresh preserves the last good catalog on failure.
  13. Model-control awaits refresh and serves cached models with a concise refresh error.
  14. Context-mode, context-prune, and smart-compaction auxiliary calls preserve headers, env, credential-specific base URL, abort, and usage through the shared runtime executor.
  15. Provider sanitizer and response diagnostics have explicit tested behavior under the new dispatch path.
  16. Cheapskate backend rotation retains its custom provider and active session.
  17. Codex-conversion preserves inherited OAuth/catalog behavior while overriding only streaming.
  18. Delegate and skill-model-effort use coherent post-refresh catalog snapshots.
  19. Standalone smart-compaction forwards complete request auth or uses the supported runtime execution seam.
  20. Kimi additive tool activation remains callable in the same run.
  21. Sessions created before their first assistant response receive the improved clone/fork diagnostic where applicable.

6.4 MicroVM validation

Deploy the PR branch to the dedicated test microVM; do not restart the local instance.

Required scenarios:

  1. Cold start with network available.
  2. Cold start with provider network blocked or DNS failure.
  3. Existing auth.json, models.json, and no models-store.json.
  4. Existing cached models-store.json while offline.
  5. Open model picker immediately after startup; it must render promptly from the snapshot.
  6. Observe background refresh and subsequent updated model list.
  7. Switch among at least:
    • current default openai-codex/gpt-5.4
    • GitHub Copilot model
    • Azure OpenAI or Foundry model using test-safe configuration
    • custom models.json model, if configured in the fixture
  8. Send a normal prompt and one tool-using prompt through each configured private provider.
  9. Run a side prompt/delegate path.
  10. Trigger context-mode semantic summarization and context-prune summarization.
  11. Trigger manual compaction in a test chat and exercise any enabled remote-compaction path only with an explicitly supported provider fixture.
  12. Verify Azure token/model-cap refresh does not interrupt an active session or erase models.
  13. Install and exercise upgraded cheapskate, codex-conversion, delegate, skill-model-effort, and standalone smart-compaction packages.
  14. Verify add-on provider overrides do not remove upstream OAuth/catalog capabilities.
  15. Rotate/fork/resume a persisted session.
  16. Exercise login/logout with test-safe provider fixtures; do not expose real credentials in artifacts.
  17. Verify no secrets appear in logs or web responses.

Collect:

  • service startup duration
  • time until web listener is ready
  • model-picker response time before and after refresh
  • structured refresh logs
  • Playwright report/screenshots where useful

Recommended performance gates:

  • no regression greater than 10% in median listener-ready time
  • model-picker cached response remains under 500 ms on the microVM
  • no request waits for a remote catalog unless it explicitly asks for a forced fresh result

6.5 Soak

Run the microVM for at least 24 hours with:

  • periodic model-picker polling
  • representative scheduled tasks
  • at least two providers
  • repeated main and side prompts
  • one forced provider failure interval

Watch for:

  • repeated refresh loops
  • OAuth refresh storms
  • unhandled promise rejections
  • catalog loss after transient failures
  • session creation latency
  • memory growth from retained runtime/catalog objects

7. Rollout plan

Stage 1 — Add-ons PR and publication

  • Complete add-ons typecheck, focused tests, standalone imports, pack checks, and catalog validation.
  • Push the piclaw-addons branch and open PR A.
  • Hosted add-ons CI must pass.
  • Merge only after explicit user approval.
  • Verify new public tarballs and catalog entries are available.

Stage 2 — Core PR

  • Complete core local static/focused gates using the upgraded add-on package set.
  • Push the Piclaw branch and open PR B.
  • Hosted core CI must pass.

Stage 3 — Test microVM

  • Deploy core PR B plus the published add-ons from PR A to the microVM.
  • Run UX and operational matrix.
  • Complete 24-hour soak.

Stage 4 — Merge core

  • Merge only after explicit user approval.
  • Confirm main CI is green.
  • Remove both feature worktrees and prune registrations.

Stage 5 — Local instance, only with explicit permission

  1. Check active sessions with session_status.

  2. If another session is active, do not restart; report and wait.

  3. Back up:

    • /workspace/.pi/agent/auth.json
    • /workspace/.pi/agent/models.json
    • /workspace/.pi/agent/settings.json
    • existing models-store.json, if present
  4. Install with:

    cd /workspace/piclaw && make local-install
  5. Call exit_process as the final tool action so systemctl --user restarts Piclaw.

  6. Verify health, model list, default model, prompt, tool call, login status, and logs.

Do not perform this stage without explicit permission.

Stage 6 — Broader release

Follow Piclaw's normal prerelease UX tag and final release gates. Do not push a final release tag without the required passing UX prerelease run.


8. Rollback plan

Rollback must be code-first and non-destructive.

Trigger conditions

Rollback if any of these occur:

  • users cannot authenticate with the current default provider
  • persisted sessions cannot restore their model
  • side prompts or compaction lose provider auth/headers
  • startup is blocked by remote catalog networking
  • model catalogs disappear after transient refresh errors
  • OAuth refresh loops or corrupts credentials
  • secrets are exposed in logs/responses

Procedure

  1. Stop rollout. Revert the core PR and, if necessary, the affected add-on package versions through new PRs.
  2. Reinstall the previous known-good Piclaw build and pin/reinstall the prior public add-on tarballs from the previous catalog versions.
  3. Restart only through the approved service-manager flow.
  4. Restore backed-up configuration only if evidence shows it changed incorrectly.
  5. Leave models-store.json in place unless it is proven to cause a problem; 0.80.7 does not depend on it.
  6. Preserve session JSONL and the messages database.
  7. Attach failure logs with secrets redacted.

Data compatibility

  • auth.json remains the canonical credential file in both versions.
  • models.json remains canonical custom-provider configuration.
  • models-store.json is additive cache state.
  • Installed add-on versions/catalog URLs are an independent rollback dimension; record the exact pre-rollout package versions.
  • No destructive data migration is required or permitted.
  • Do not rewrite user JSONC solely to migrate compatibility fields.

9. Risks and mitigations

Risk Severity Mitigation
OAuth/API-key regression High Provider-owned APIs; focused Codex/Copilot tests; microVM login validation
Slow server startup High allowModelNetwork: false; refresh after listeners start
Empty/stale model picker Medium cached snapshots; coalesced background refresh; explicit freshness path
Lost account-specific Copilot models Medium compare live/static catalog; preserve only necessary refreshModels overlay
Azure token refresh drops provider configuration High typed provider configs; atomic re-registration tests; retain last good catalog
Azure auth/header duplication High one auth owner per request; explicit Authorization/api-key header assertions
Private auxiliary model calls bypass request transforms High injected runtime-owned executor; document/test hook behavior
Installed private add-ons fail after core upgrade High separate compatibility PR, version bumps, published tarballs, clean import/E2E gate
Provider override erases inherited auth/catalog High partial-overlay tests for Codex conversion and dynamic providers
Duplicate OAuth refreshes High one shared runtime and upstream serialized credential modification
Quota display regression Medium runtime refresh first; one-off stored credential read only for supplemental metadata
Custom provider/header regression High request-auth integration tests including headers, env, and base URL
Compaction/side prompt auth divergence High same ModelRuntime for all auxiliary requests
Prefix-cache regression from lazy tools Medium additive activation; measure prompt metadata candidates before changing them
Refresh storm from web polling Medium one in-flight refresh coordinator and provider throttling
User config damage High no destructive rewrite; backups before rollout; JSONC compatibility retained
Scope creep into xAI/Kimi UI work Low validate inherited capabilities only; defer unrelated product changes

10. Acceptance criteria

The upgrade is complete only when all criteria below are satisfied.

Architecture

  • All three Earendil packages are pinned to 0.80.9.
  • Piclaw owns one process-wide ModelRuntime.
  • ModelRegistry exists only at documented extension-compatibility boundaries.
  • No runtime source imports AuthStorage.
  • No runtime source imports getOAuthProvider().
  • Main, side, compaction, summarization, and control paths use the shared runtime.
  • No refresh-dependent synchronous read follows an unawaited refresh.

Startup and availability

  • Web startup does not wait for provider catalog network calls.
  • Cached models are available offline.
  • Background refresh is bounded, coalesced, and failure-tolerant.
  • Model-picker requests remain responsive during refresh.

Authentication

  • Existing Codex and Copilot credentials remain usable without manual migration.
  • API-key and OAuth login/logout use provider-owned runtime APIs.
  • Concurrent OAuth use does not duplicate refreshes.
  • Quota/status functionality works without owning credential refresh.
  • No secrets appear in logs, status payloads, or test artifacts.

Providers, private extensions, and tools

  • Custom models.json providers retain headers, environment, auth, and endpoints.
  • Copilot account-specific model behavior is preserved or the private overlay is proven unnecessary and removed.
  • Azure OpenAI, Foundry, secondary Azure, and experimental harness configurations compile and pass focused tests.
  • Azure token/model-cap refresh preserves last-good models and does not duplicate auth headers.
  • Exactly one process-level Azure provider registration/refresh owner exists; session replacement does not duplicate timers or providers.
  • Model-control tools await refresh and fall back to cached snapshots on failure.
  • Context-mode, context-prune, and smart-compaction use the shared runtime-owned model execution seam.
  • Provider request sanitizer and response diagnostics have explicit tested behavior for normal and auxiliary model calls.
  • Upgraded cheapskate, codex-conversion, delegate, skill-model-effort, and standalone smart-compaction packages pass clean import and focused tests.
  • Add-on provider overrides preserve inherited upstream OAuth, catalog, headers, and endpoints.
  • Existing same-turn activate_tools behavior passes.
  • Kimi deferred-tool serialization has focused coverage.
  • No provider capability is inferred from model-name heuristics in Piclaw.

Validation and operations

  • bun run typecheck passes.
  • bun run lint passes.
  • bun run build:web passes.
  • Focused affected tests pass.
  • make ci-fast passes.
  • Add-ons PR CI, standalone imports, package packing, and catalog validation pass.
  • Updated add-on tarballs are publicly downloadable and installed in the microVM fixture.
  • Core PR CI passes.
  • MicroVM UX/operational matrix passes with the upgraded private add-ons.
  • 24-hour microVM soak shows no refresh/auth/session regressions.
  • Rollback has been rehearsed or verified from artifacts/config compatibility.
  • Live install/restart is performed only after explicit permission and active-session check.

11. Deferred follow-ups

Keep these out of the initial compatibility PR unless required to pass the acceptance criteria:

  1. A user-facing “refresh model catalogs” control.
  2. New xAI/Grok subscription UI beyond inherited provider-owned login support.
  3. Kimi-specific provider onboarding.
  4. Broad removal of promptSnippet / promptGuidelines from lazily activated tools.
  5. Removal of legacy session-affinity compatibility before its support window ends.
  6. General model-control redesign unrelated to the upstream API migration.
  7. Provider quota API expansion.

The private Azure, Copilot, model-control, context-mode/context-prune, smart-compaction, and provider-diagnostics migrations are explicitly not deferred; they are part of WP4/WP5 and must pass before the core PR merges. The affected piclaw-addons packages in WP6 are also mandatory and must be published before rollout.

Create separate issues after the migration if measurements or user demand justify them.


12. Recommended first implementation step

Start two clean worktrees:

  1. Core Piclaw WP0/WP1: establish the shared cache-first ModelRuntime, compile the runtime foundation, and add startup/refresh tests before migrating login or dynamic providers.
  2. Add-ons WP6 preparation: update development dependencies to 0.80.9, run a compile-only compatibility pass, and turn each failure into the focused package changes listed above.

Develop both tracks in parallel, but publish/verify the add-ons PR before the final core microVM gate and live rollout. This exposes architectural and cross-package incompatibilities early without modifying either dirty primary checkout.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment