Fireworks rolled out the kimi-k2p6-turbo router as the new Fire Pass
target; the k2p5-turbo route will start refusing Fire-Pass-only
callers. Bump the router id and display name in connector-catalog,
apikey connector definition, model-resolver, and capability-seed so
the desktop catalog, the renderer's onboarding rail, the capability
matrix, and the runtime model resolver all point at the same model.
Pi-ai ships $0 pricing for github-copilot (25 models), google-gemini-cli
(6 models), zai (13 models), and kimi-coding (2 models). This made cost
tracking produce $0 for every run through these providers, rendering
budget enforcement useless.
Added resolveModelCostFallback() in model-resolver.ts with two strategies:
1. Cross-provider lookup: subscription providers (github-copilot,
google-gemini-cli) use the same models as their API counterparts.
Look up the model in anthropic/openai/google/xai catalogs using
normalized ID matching (dots→hyphens) to find real pricing.
2. Per-provider fallback: API-key providers with no cross-provider
equivalent (zai, kimi-coding) get a static per-provider cost.
CostWriter now calls resolveModelCostFallback after resolveModel, so
all consumers get patched pricing without touching the pi-ai library.
Three fixes for the non-functional budget system:
1. Fireworks models hardcoded cost {input: 0, output: 0}, making all
Fireworks/Fire Pass runs report $0 and budget enforcement useless.
Added per-model pricing to FIREWORKS_CURATED_MODELS with a fallback
for unknown models. Pi-ai known providers (Anthropic, OpenAI, etc.)
already had correct per-model pricing via getModels().
2. saveAgent IPC handler passed the form's submitted status through
without checking whether the agent was budget-paused and the new
budget exceeds spent. Now auto-resolves paused → idle when the user
raises budget_monthly_usd above spent_monthly_usd.
3. checkAutoResolve in budget-enforcement-service resolved policy
incidents but never touched agents.status. Added
unpauseBudgetBlockedAgents() that scans for paused agents whose
legacy budget now has headroom and flips them to idle.
The previous pass "aligned" model-resolver.ts to
accounts/fireworks/models/kimi-k2.5-turbo — the per-token model path —
to match the connector catalog's default. That was the wrong direction:
Fire Pass subscription traffic routes exclusively through
accounts/fireworks/routers/kimi-k2p5-turbo (see docs.fireworks.ai/firepass),
and the entitlement does not attach to the per-token id. Existing agent
rows already pointed at the router id, so validateConnectorModelSelection
rejected every dispatch with "does not allow model
'accounts/fireworks/routers/kimi-k2p5-turbo'" and the CEO stopped running
entirely.
Put the router id back in model-resolver.ts (the enabled-pool source of
truth), and bring the two catalog defaults in line so a freshly-seeded
Fire Pass connector also ends up on the router id. The per-token
`fireworks` connector keeps the `models/...` default since that path
bills per token and genuinely targets the per-model endpoint.
The shim resolved Fireworks models as api="anthropic-messages" pointed
at Fireworks' /inference baseUrl. That forced pi-ai's Anthropic
provider path, which unconditionally ships Claude-proprietary beta
headers (fine-grained-tool-streaming-2025-05-14,
anthropic-dangerous-direct-browser-access, claude-code identity on the
OAuth branch). Fireworks' Anthropic-compat endpoint accepts the call
but routinely returns a stream that closes with zero tokens emitted —
pi's agent loop interprets the empty stream as a successful run with no
assistant output, runs complete "succeeded" with no tool calls, no
text, no error, and the operator sees the CEO "do nothing" on every
heartbeat.
Fireworks ships a proper OpenAI-compatible endpoint at
https://api.fireworks.ai/inference/v1. pi-ai's streamSimpleOpenAICompletions
already handles arbitrary baseUrl + Bearer auth through the OpenAI
SDK — no beta-header games, no Claude identity spoofing, no auth
header duplication. Switch the resolved Model to
api="openai-completions" with the /v1 baseUrl and let the OpenAI path
do its job. resolveExtraStreamHeaders now returns undefined for every
caller (the OpenAI SDK sets Authorization from apiKey natively).
Also correct the Fire Pass model id from the routers alias to the
canonical `accounts/fireworks/models/kimi-k2.5-turbo` so it matches
the connector-definitions default and the model selection validator
accepts it without an explicit override.
The earlier sweep cleaned the hot path (worker/runtime/automation/api-
server/ipc core — 59 sites). This pass finishes the deferred long tail:
main/* services, database/* CRUD modules, api-server/* routes, ipc-*
handlers, thread-integration, automation helpers, browser, skills.
Default strategy: catch (error) { logger.warn("[module] context:", ...) }
— preserve current behavior, make the failure visible instead of
silently hidden. Widened 3 logger interface signatures to include warn
where callers only passed info/error previously (thread-helpers,
host-environment-service, ipc-domain-common).
Legitimate boundaries left intact: JSON.parse on untrusted input, DNS
resolver no-records paths, explicit safe* helpers (safeJson, parseJson,
parseTriggerDetail), URL-parse predicates, and `<unserialisable>`
fallbacks inside the prompt-builder summarisers. Each kept catch now
either has a reason in context or is a documented safe* helper.
Tests adjusted only where test-constructed no-op loggers needed a warn
stub (message-dispatch, company-mode-switch, ipc-agent-graph-handlers).
With the earlier pass, AgentCompany no longer has silently-swallowing
catch blocks in main-process or renderer business code.