Skip to content

Smithers vs the agent platform

It is easy to confuse Smithers with "the agent platform." They overlap. They are not the same thing. This page makes the boundary explicit and explains how each side depends on the other.

Substrate framing: the agent platform (system.agents, system.inference, the provider drivers, system.factotum) is substrate-side infrastructure — the cognitive runtime any vertical can use. Smithers is vertical-side — one specific developer-facing app built on top of that infrastructure. The substrate is general-purpose; the vertical is opinionated.

What "the agent platform" is

The Matrix agent platform (informal name) consists of these actors and packages, none of which Smithers owns:

Actor / packageRole
system.inferenceRoutes inference requests through @open-matrix/inference-catalog. Resolves provider credentials (Codex, Claude, Anthropic API key) without callers ever seeing a key.
system.agentsGeneric session-based agent runtime. Owns session lifecycle, transcript, runtime status. Smithers can dispatch to it; Smithers does not own it.
@open-matrix/codex-agent / @open-matrix/claude-agentSDK worker packages that register themselves as runtimes capable of serving agent sessions. Smithers calls them via system.agents.
@open-matrix/chatThe default, generic chat workbench. A user can talk to any actor through it. Not a Smithers competitor.
system.factotumCredential gatekeeper. The ONE actor that reads/writes credential files (per project Rule 4). Smithers' inference resolution goes through it.

These exist whether or not Smithers is installed. They are general-purpose.

What Smithers adds

Smithers is specifically about constraint-convergence orchestration. It does not:

  • Implement an inference adapter. It uses @open-matrix/inference-catalog and omega-lisp/piai.
  • Own session storage. When dispatching to an SDK worker (SmithersSupervisor._stopSdkWorkerSession, _readAgentSessionState, _appendAgentOutputFromSessionTrace), it reads system.agents session state.
  • Manage credentials. _resolvePiAiConfig in CodingAgent.ts:213-264 resolves credentials by calling into inferenceCatalog.createInferenceConfig which in turn flows through system.inference and Factotum.

Status note: cross-package import boundary. CodingAgent.ts:219 does an in-process await import('@open-matrix/inference-catalog') instead of routing through the bus to system.inference. This is a known intentional design — tracked as P1.6 — and is not yet resolved. It means Smithers' inference path is currently substrate-aware (it knows about inference-catalog as a workspace package) rather than purely substrate-routed (every call through system.inference). Don't pretend this is fully fixed when reading the rest of this page; the bus contract is the target, the in-process import is the present.

Smithers does add:

ResponsibilityWhere in source
Constraint gathering and projectionConstraintGraph (src/actors/ConstraintGraph.ts)
GitHub issue ingestion + parsingGitHubAdapter (src/actors/GitHubAdapter.ts)
Convergence-loop orchestrationSmithersSupervisor.onSmithersStart
Sign-off forcing functionSmithersSupervisor.onSmithersSignOff
Parallel review barrierReviewerAgent (src/actors/ReviewerAgent.ts)
Ratchet of satisfied constraintsRatchetStore (src/actors/RatchetStore.ts)
Issue-actor lifecycleIssueActor (src/actors/IssueActor.ts)
Local CodingAgent fallbackCodingAgent (src/coding-agent/CodingAgent.ts) — used when no SDK worker is registered
Container management for isolated agentsContainerManager (src/actors/ContainerManager.ts)
Workspace UI stateWorkspaceActor (src/actors/WorkspaceActor.ts)
Workstream-request inboxSmithersSupervisor._workstreamRequests

Two execution paths for the coding agent

Smithers' supervisor runs the agent through one of two paths, decided at dispatch time (see SmithersSupervisor.ts around the SDK worker selection logic):

Path A — Local CodingAgent

Smithers spawns its own CodingAgent actor inside the same Node process. It:

  1. Resolves PiAiConfig through inferenceCatalog.createInferenceConfig.
  2. Builds a streamingOracle shell tool (one tool — Unix-native shell) and runs the LLM tool loop in-process.
  3. Streams code.event activity frames; the supervisor subscribes and forwards them to the browser via the activity bus.

This path requires Docker only if container.runtime: 'docker' is configured AND the user explicitly asks for a containerised run; otherwise everything runs on the local filesystem.

Path B — SDK worker (@open-matrix/codex-agent / claude-agent)

When a registered SDK worker is available, Smithers prefers it. It:

  1. Looks up an SdkWorkerRef in system.runtimes.
  2. Creates a session in system.agents and dispatches the constraint-convergence prompt to that session.
  3. Reads transcript and runtime status back through system.agents ops; on completion, extracts evidence with evidence-extraction.ts.

Path B is what the productization story rests on (P2.6-smithers-productize.md):

Spawn container button → real container starts. Send prompt → worker session starts, ActivityFrame events stream to UI. Steer / interrupt / continue all work. Session persistence verified across page reload.

Container manager scope

ContainerManager (src/actors/ContainerManager.ts:81-120) is a Docker control surface used by the SDK worker path. It:

  • Subscribes to a heartbeat subject (mx.discovery.heartbeat) and prunes offline containers every 15s.
  • Tracks WorkerRecord[] per container — each container can host multiple worker actors of kind codex or claude-code.
  • Provides container.spawn, container.stop, container.list, container.remove, container.images ops.

This is not generic Docker tooling. It is specifically the actor that ContainerManager exposes for Smithers to manage worker containers. The wider Matrix platform does not depend on it.

Why the worker-isolation audit gates Smithers

P2.5-worker-isolation-audit.md says:

SDK worker integration merged. prove-sdk-worker-container.ts confirms a container can spawn and workers register. But the security model — what filesystem, what network, what host calls a worker can make — is unaudited.

The required audit areas are filesystem scope (cwd/repo roots), shell permissions, NATS credential isolation, network egress policy, approval policy, and heartbeat anti-spoofing. Until those gates close, Smithers is allowed only as a local-Vite proof; no public Smithers/Codex/Claude demo is possible without the audit.

Quick decision table

If you want toUseNotes
Run an agent on a single one-off tasksystem.agents directly (or chat)No constraint orchestration, no review barrier
Run a one-off task with structured constraintsSmithers (smithers.start)Even single-issue runs benefit from the sign-off and ratchet
Plug in a new LLM provider@open-matrix/inference-catalogSmithers reads from there; do not add a Smithers-specific provider path
Add a new agent runtime (e.g., a third SDK)Add a sibling to codex-agent / claude-agentSmithers will discover it via system.runtimes and use it through system.agents
Audit and harden agent isolationP2.5 audit + ContainerManager + system.factotumThe audit feeds into ContainerManager constraints, not Smithers' app code

See also

Source: WORKSTREAMS/loose-ends/items/P2.6-smithers-productize.md, WORKSTREAMS/loose-ends/items/P2.5-worker-isolation-audit.md, projects/matrix-3/packages/smithers/src/coding-agent/CodingAgent.ts:179-264, projects/matrix-3/packages/smithers/src/actors/ContainerManager.ts:81-120.