Small models need a bigger runtime.
A frontier model can paper over a sloppy harness. A small local model can't. Mach Agents is built for small and local models: deterministic guarantees where big-model SDKs rely on judgment, and context discipline that treats every token as scarce.
$ npm install @syzygy-ai/agentsRead the docsimport { OpenAICompatibleModel, runAgent } from "@syzygy-ai/agents";
const model = new OpenAICompatibleModel({
slug: "qwen3.6-4b-a1b",
baseUrl: "http://localhost:8080/v1",
requireApiKey: false,
});
const result = await runAgent(
{ id: "assistant", instructions: "Be concise.", model },
"Summarize the release checks."
);Constrain the system, not the model
With a small model, careful has to be enforced. Permission policies reach into tool arguments themselves (headers["X-*"], calls[*], any path) and decide allow, deny, or pause-for-approval deterministically, before anything executes. Paused calls become durable checkpoints a human approves later, and budgets put hard ceilings on tokens, dollars, and wall-clock. The model proposes; the runtime decides.
policy matches inside tool arguments — before anything executes
fs.read("./docs/**") → allow
http.request.headers["X-Admin-Token"] → deny
shell.exec.calls[*] → pause-for-approval
checkpoint saved · run suspended, durable on disk
3h later · approved by dana → resumed at the same step
budgets: { tokens: 200_000, usd: 1.50, wallClock: "10m" } // hard ceilingsEvery token, spent on purpose
Nothing wastes a small context window faster than tool definitions, so Mach Agents never shows the model a full catalog. Toolsets are searched every turn — only the relevant handful enters the prompt, even when an MCP server brings hundreds — and newly discovered tools become callable mid-run. Memory gets the same discipline: compact observations, size-capped working memory, and a relevance filter. That keeps a finite context window focused across longer work.
Mistakes are feedback, not crashes
Small models fumble JSON more often, and the runtime is built for exactly that. Malformed tool arguments become a structured failure the model sees and corrects; structured output is validated with automatic repair rounds; interrupted turns are sealed so the transcript stays valid. The loop bends instead of breaking.
// model returns near-JSON, wrapped in a fence
```json
{ "total": 42, } // trailing comma
```
// → fence stripped, validated against output_model
rejected: "Unexpected token } in JSON"
// → model gets its own error, asked to resubmit
output_repair_attempts: 2 remaining
{ "total": 42 } // ✓ valid on retryIt runs where the model runs
No orchestration server, no cloud dependency. The runtime is in-process TypeScript — the same code inside Mach Studio — and persistence is a single SQLite file on Node's built-in driver. Point it at any OpenAI-compatible endpoint on localhost and streaming, tool calls, and reasoning channels are normalized across local wire dialects. Your agent, your models, your disk.
import { SQLiteStore, OpenAICompatibleModel } from "@syzygy-ai/agents";
const store = new SQLiteStore("./agents.db"); // node:sqlite — zero native builds
const model = new OpenAICompatibleModel({
baseUrl: "http://localhost:8080/v1", // mach · vLLM · anything
requireApiKey: false,
});
// streaming, tool calls, reasoning channels — normalized per dialectBuild agents on the models you own
Mach Agents ships inside Mach Studio, or install it standalone and point it at your own local server.
$ npm install @syzygy-ai/agentsRead the docs