pi-ai's getModel/getModels does not know about the Fireworks providers
(fireworks, fireworks-firepass); both live under our local model-resolver
because Fireworks speaks the Anthropic-compat endpoint with Bearer auth
at https://api.fireworks.ai/inference, not pi-ai's built-in catalog.
Three call sites were still hitting pi-ai directly and failing silently
for Fireworks:
1. connector-model-policy.ts — listProviderModels() caught the pi-ai
throw and returned []. The "Fire Pass (CEO runtime)" card in the
Team Models onboarding step therefore showed "暂无模型 / 已启用 0/0",
blocking users on Fire Pass from continuing onboarding.
2. worker/worker-runner.ts — getModel() threw mid-run when the selected
connector was Fireworks, so the worker could never actually execute
an agent turn against Fire Pass or the curated Fireworks model set.
Now uses resolveModel() + the Fireworks-specific Bearer header from
resolveExtraStreamHeaders() so streamSimple hits the correct endpoint
with the correct auth.
3. agent-runtime/cost-writer.ts — cost observation silently wrote
amount_usd=null for Fireworks runs because getModel() threw inside
the try/catch. Now resolves via resolveModel() so the Fireworks
curated contextWindow/maxTokens are visible to calculateCost().
Verification: pnpm typecheck 0 / pnpm lint 0-0 / pnpm build:verify 0-0
/ pnpm test:unit 508/508.
The `registerCredentialIpcHandlers` and `registerOAuthIpcHandlers`
entry points existed in `ipc-credentials-handlers.ts` and
`ipc-oauth-handlers.ts` but were never called — `registerHandlers()`
in `main-runtime-support.ts` only wired `registerCoreHandlers` and
`registerDomainHandlers`. The result: every renderer call to
`credentials:list` / `credentials:save` / `credentials:remove` /
`credentials:test` / `oauth:start` / `oauth:cancel` /
`oauth:prompt-response` / `oauth:manual-code-response` crashed
with "No handler registered".
Wire both handler families against the PiRuntimeServices container
(credentialStore, credentialResolver, oauthLoginService) already
exposed via `serviceGraph.getPiRuntime()`. The refreshConnectorHealth
callback reuses the existing connectorHealthService so status
badges flip between `ready` and `auth_required` immediately after
a save/login.
typecheck 0 / lint 0-0 / build 0-0 / test:unit 508/508 preserved.
Rewrites the utility-process worker to drive pi-agent-core's Agent class
against pi-ai models and pi-coding-agent tools. The entry file keeps the
queue and cancellation state, delegates runs to WorkerRunner, and routes
RPC responses through WorkerRpcClient so beforeToolCall/afterToolCall
approvals and prepareRun credential resolution travel back to main's
RuntimeBridge. Worker message schema gains `agent-event` + `rpc-request`
envelopes, and run-finished no longer depends on the deleted sessionCodec.
Bootstraps CredentialStore/Resolver, OAuthLoginService, and RuntimeBridge
inside service-graph via the existing pi-runtime factory, and exposes the
bridge to worker-service for agent-event + rpc-request routing. Adds a
`prepareRun` RPC that resolves credentials, loads prior messages, and
registers the active run context in a single call. Session rotation drops
the adapter nativeContextManagement branch; run payloads now carry the
taskSessionId and executionMode the worker needs to drive pi-agent-core.
Drops every `definition.module.*` call and legacy id hardcode (claude_local,
codex_local, gemini_local, claude_compat_*) from the connector services.
Health checks now evaluate stored credentials against the declarative auth
descriptor, model policy reads provider models via pi-ai, matching keys off
provider ids, and hire-hook logs activity without invoking an adapter hook.
Introduces a local normalizeCommandValue helper to replace the deleted
@agentcompany/adapter-utils/server-utils import.
ProvidersPanel reads all 26 CONNECTOR_CATALOG entries and groups them by
auth kind (OAuth / API key / Azure / AWS / Vertex). ProviderRow
dispatches to the matching dedicated form component per auth kind. AWS,
Azure, Vertex forms rewritten with Tailwind classes and a shared field
style module so the Settings pane renders with the same aesthetic as the
rest of the app.
Onboarding ProvidersStep now reads the 26-entry CONNECTOR_CATALOG and
renders featured connectors (claude-pro, openai-codex, anthropic, openai,
amazon-bedrock) up front with a collapsible advanced list for the
remaining 21. Each auth kind gets a dedicated card component: OAuth
button flow, inline API-key form, and a cloud deep-link to Settings.
Delete legacy Claude/Codex/Gemini hardcoded cards and the compatible-API
slot rotation. Swap ModelManagement Settings panel for the new
ProvidersPanel driven by credentialsList IPC.
Add @shared/connector-catalog.ts mirroring the 26-entry pi-mono catalog
from src/main/connector-definitions so renderer can drive provider UI
without importing main-process modules. Widen connectorInputSchema to
accept the new ConnectorId union (5 OAuth + 18 API key + 3 cloud).
Pi-mono's ConnectorDefinition no longer carries defaultCommand,
configurationDoc, capabilityMatrix, or listModels. Synthesise sane
defaults for the legacy ConnectorRecord fields:
- command defaults to empty (pi-mono has no CLI entrypoint)
- capabilityMatrix collapses to a uniform pi-mono baseline
- configurationDoc is generated from the auth descriptor using the
existing buildOAuthDoc / buildApiKeyDoc / buildCloudDoc helpers
These columns stay in the schema so the UI surfaces that still read
them continue to function; the worker and resolver no longer branch on
capability flags since pi-mono handles dispatch uniformly.
Strips adapter module, defaultCommand, listModels, configurationDoc,
capabilityMatrix, and notes fields from the ConnectorDefinition type.
What remains is the declarative pi-mono shape: id, provider, label,
description, defaultModel, auth descriptor, onboardingFeatured, notes.
The three data files are imported and spread into the CONNECTORS array.
findConnectorDefinition + listFeaturedOnboardingConnectors stay in the
lookup module unchanged. Docs builders still provide buildOAuthDoc /
buildApiKeyDoc / buildCloudDoc for the Settings panel and are consumed
by connectors.ts when synthesising per-row configuration docs.
ConnectorAuth now uses `type` as the discriminator (legacy `kind` alias
removed — credential-resolver and ipc-credentials-handlers already keyed
off `type`).
Pure-data declaration of the 26 pi-mono connectors split across three
files so each stays under the 400-line cap:
- connector-definitions-data-oauth.ts (5 OAuth providers)
- connector-definitions-data-apikey.ts (18 API-key providers)
- connector-definitions-data-cloud.ts (3 Cloud providers)
Each entry carries pi-ai provider id, default model, auth descriptor,
onboarding flag, and notes. Fireworks + Fire Pass are marked as locally
resolved (no pi-ai catalog entry) and share FIREWORKS_API_KEY.
Replaces the 13 adapter-slot ids with the five OAuth / eighteen API-key /
three cloud ids that the pi-mono-driven catalog advertises. Downstream
worker, resolver, and database modules will be updated by follow-on
agents; this commit only redefines the type.
- App.tsx: replace per-field ui.navItems/ui.paletteQuery with the ui
object so the memo captures every accessed field.
- ConsoleView.tsx: add eslint-disable for the logRevision dep; it is
intentionally tracked to force ref re-evaluation.
The any type is load-bearing here: callers destructure arbitrary SQL
columns. Add an inline eslint-disable with justification instead of
propagating a typing change across all DB modules.
Migration 28 (add_snapshot_hot_path_indexes) referenced task_comments,
documents, meetings, sprints, agent_messages, activity — all tables
created by ensureOptionalColumns() which runs AFTER runMigrations() on
a fresh DB. Converted from sql-string migration to fn-based so each
index is gated by tableExists(); safe on both fresh and migrated DBs.
Also updated tests/unit/selective-ipc.test.ts exhaustive switch to
include the 7 new DesktopEvent variants added in ef90a58.
- credential-resolver.resolve: throw explicit CREDENTIAL_INVALID when
the connector has no auth schema, and add a default branch so the
switch has a definitive return path for every auth kind
- credential-resolver api_key branch: guard definition.provider being
unset before calling pi-ai's getEnvApiKey
- cost-writer: only attempt cost lookup when definition.provider is
defined; adapter-only connectors still write an unattributed row
- oauth-login-service.start: require definition.auth to be present and
oauth kind before dispatching; captures oauthId in a local so the rest
of the flow does not re-assert the nullable chain
- ipc-credentials-handlers save: reject connectors without an auth
schema instead of crashing on property access
- ipc-credentials-handlers test: require provider and defaultModel to be
set before calling into pi-ai, returning a diagnostic result otherwise
- Expose buildSessionEntryMethods and buildCredentialMethods on
AppDatabaseBase as public readonly members so agent-runtime and
credential-store can access them via db.sessionEntries /
db.credentialsTable
- Add idempotent schema migration v32 creating session_entries and
credentials tables plus supporting indexes; uses CREATE TABLE IF NOT
EXISTS so existing profile DBs upgrade safely without destructive ops
- Add PiOAuthProviderId literal type covering pi-ai's built-in OAuth
providers (anthropic, openai-codex, github-copilot, gemini-cli,
antigravity)
- Add optional ConnectorDefinition fields: provider (pi-ai provider id),
auth (ConnectorAuth with kind/type/provider/oauthId/envKey), and
onboardingFeatured
- Decorate built-in CONNECTORS (codex_local, claude_local, gemini_local,
claude-compat slots) with their pi-ai provider id, auth schema, and
onboarding flag so credential-resolver and oauth-login-service can
dispatch without changing execute/module wiring
- Re-export CONNECTORS, findConnectorDefinition, and
listFeaturedOnboardingConnectors from main/connectors so consumers
(including tests) import from a single module
- Add IPC_CHANNELS entries for credentials list/save/remove/test and
oauth start/cancel/prompt/manual-code
- Extend DesktopEvent union with oauth:*, credentials-changed, and
agent-event variants used by pi-mono runtime and settings UI
- Extend DesktopApi CredentialsApi with listCredentials / saveCredential
/ removeCredential / testCredential and OAuth submit helpers
Adds ~40 automation.ruleEditor.* and automation.workflowEditor.* keys
to en.ts + zh.ts (labels, placeholders, error messages, action labels).
RuleFormModal and WorkflowFormModal now route every hardcoded English
string through useT(), including validation errors and modal titles.
Closes remaining Z-B i18n work after the prompt-builder locale
dispatch (cf92e0c), dept-keywords typing (a78bdb9), and sidebar/
formatters/notification/skills i18n landed earlier.
Replaces Record<string, string[]> with Record<DepartmentId, string[]>
so future edits to the department taxonomy trigger TS errors for any
keyword map that drifts. Cast at the lookup site reflects the fact
that agent.department is a free-form string column that may hold
legacy or custom values.
Split each prompt section into parallel .en.md/.zh.md bundles (sops, api-docs,
ceo-modes, department-guidelines) and mirrored messages/{operating,system}-{en,zh}.ts
modules for the inline identity/culture/rules text that had stayed as hard-coded
English template literals. Every loader now resolves a locale via a single
shared helper so CEO and IC prompts come out fully Chinese when locale=zh and
fully English otherwise, removing the need for the trailing "请记住:全程使用中文"
language reminder.
- New src/main/prompt-builder/wake-reasons/en.ts: WAKE_REASONS record of
{ title, steps(vars) } entries + renderWakeReason() formatter that
numbers the steps and composes the final block
- buildTaskPrompt in prompt-builder/index.ts collapses 100-line inline
reasonMap into a single renderWakeReason call
- index.ts shrinks from 161 to 77 lines; each wake reason's semantic
content (title text + numbered action steps + embedded curl hints)
preserved verbatim
Create src/renderer/components/ui/icons.ts as the single re-export point
for every Phosphor icon the renderer touches, then rewrite the 95 files
that previously imported directly from "@phosphor-icons/react" to pull
from the relative-path-to-barrel instead. The TitleBar commit earlier
in this series already used ui/icons; this commit extends the pattern
to the rest of the renderer.
Benefits now wired in:
- one location where bundle tree-shaking can be reasoned about,
- typos like Briefcase vs BriefCase show up against a finite list,
- re-theming or swapping icon sets is a one-file edit,
- a lint rule that flags raw @phosphor-icons/react imports can be
added later without mass-rewriting call sites.
The barrel also re-exports the `Icon` type so call sites that type
icon props against the Phosphor component type work unchanged.
Test count stays at 363 passing; typecheck stays at 156 errors.
- operating-instructions.ts buildDepartmentSection: replace 120-line
if/else chain with a department-to-markdown lookup table
- New src/main/prompt-builder/department-guidelines/ contains:
engineering, finance, hr, marketing, sales, customer_support, operations
- Each file uses {{companyId}} placeholder, substituted at render time
- operating-instructions.ts trimmed from 384 to 285 lines while
preserving every guideline verbatim
SkillsSection had nine hardcoded English strings (header, filter
placeholder/aria-label, empty-state copy, button labels). Move them to
skills.* keys in en.ts/zh.ts and swap the component to useT().
Moves skill, budget-enforcement, and session-management service
construction to the top of service-graph init(), so the three
getOrCreate* getters are pure readers that throw if called before
init. This also fixes a duplicate-allocation bug in the orchestration
listRuntimeSkillEntries closure, which was building a second
SkillService instance instead of reusing the shared one.
The outer getOrCreate* API surface stays intact for
main-runtime-support.ts callers. The teardown setTimeout(app.exit,
3000) is left in place because worker CLI child processes keep the
event loop alive; replacing it needs a full Disposable chain refactor
that conflicts with in-progress pi-runtime integration work.
- Split 366-line api-section.ts into 11 category markdown files under
src/main/prompt-builder/api-docs/ (header, agent-control, tasks,
goals-projects, approvals, messages, files, knowledge, meetings,
agents, sprints)
- api-section.ts reduced to ~45 lines: imports each section via ?raw,
substitutes {{apiUrl}}/{{companyId}}/{{agentId}}/{{runId}}/{{connectorIds}},
joins sections and appends social media addendum
- Every endpoint signature, body schema, and curl example preserved
verbatim so LLM instruction surface is unchanged
Splits the 391-line bootstrapApplication god function into a thin
orchestrator plus 7 focused modules under src/main/bootstrap/:
prepare-logger, prepare-database, prepare-services (service graph +
ipc wiring), wire-api-server (14-callback dictionary), recover-
scheduled-posts, run-startup-health-checks, recover-interrupted-tasks
(crash notification + clean-shutdown task resumption). Original
startup order, before-quit cleanup, and error handling are preserved;
the entry file drops to 153 lines.
BudgetBar and ConfirmDelete were only sitting in organization/helpers.tsx
but have no organization-specific behaviour. Move them under
components/ui/ and keep the old exports as re-exports so existing
importers continue to resolve. HeartbeatSection stays in helpers.tsx
because it owns agent-specific heartbeat IPC.
RunCenter had three useEffects juggling log-chunk loading, tailing, and
older-chunk fetches. Move the whole lifecycle into useRunLogs, which
uses a single effect + AbortController to scope every IPC call to the
current run and pauses polling while document.hidden.
Changes the AppDatabaseBase module slots (tasks, agents, runs, ...)
from protected to public readonly so new call sites can reach them
directly as db.tasks.x / db.agents.x. The 156 pass-through methods on
AppDatabase remain untouched, so all existing callers keep working;
this is the first step of a two-part migration to eventually drop
the pass-through layer.
P3-56 (renderer): the maximized-state button used a custom 3-rect SVG to
render the 'restored window' glyph while the minimize and close buttons
used Phosphor icons. Swap the SVG for Phosphor's Copy icon so all three
titlebar buttons share the same icon family and weight, and the visual
bundle no longer carries a one-off raster-like SVG block.
Split the flat 134-method DesktopApi interface into 12 domain
sub-interfaces (companies, agents, tasks, runs, approvals,
communication, threads, credentials, skills, budget, automation,
window) under src/shared/contracts/desktop-api/. desktop-api.ts
now intersects them to preserve the exact external flat shape;
window.agentCompany consumers and preload wiring are untouched.
Adds an inline comment partition and typed PROFILE_LEVEL_KEYS /
COMPANY_SCOPED_KEYS constants on ProfileSnapshot so callers can
reason about which fields survive a company switch. Shape is
unchanged; renderer consumption is unaffected.
Break the 281-line kitchen-sink schemas-misc.ts into 12 domain modules
(badges, automation, budget, wakeup, config-revisions, run-events,
agent-permissions, heartbeat, runtime-state, threads, participants,
subscriptions). schemas-misc.ts now re-exports the domain barrel so
existing imports keep working. Adds direct exports to contracts.ts for
new code to pull from the narrower modules.
P3-56: three call sites repeated the same 'lookup → fall back to
new → set if missing' dance for session stores. The duplication hid the
fact that the fallback allocation in the second and third sites could
be wasted when the entry already existed. Extract a single
getOrCreateStore helper that does one map lookup, one conditional
construction, and always returns the cached instance.
Introduce goal-form/ and project-form/ directories each holding a
single shared shell that handles both create and edit modes via a
discriminated mode prop. The existing GoalCreator/GoalEditor and
ProjectCreator/ProjectEditor become thin wrappers that forward props
to the shared shell, eliminating duplicated state, JSX, and save/
delete handlers across the four files.
- P3-52: replace 5-deep if-chain in deriveEscalationWakeTrigger with two
lookup maps (status takes precedence over rule trigger), which removes
the cognitive overhead of reading the chain and makes the two inputs'
roles explicit.
- P3-53: rewrite the Windows-only curl warning as platform-neutral
guidance that matches the surrounding examples. The old text said
'prefer fetch on Windows' while the doc showed curl POSTs everywhere;
the new text recommends fetch universally and explains when the curl
temp-file pattern is needed.