Engine & harness
This page explains how agent-service runs an agent internally. As an integrator you usually don’t need these details — you only face the SSE stream — but understanding it helps you interpret events, debug, and replay.
DeepAgents: the single engine
The engine layer does no upper abstraction. DeepAgents is the one and only engine (Mastra has been fully removed), so there’s no AGENT_ENGINE token, no AgentEngine interface, and no binding shell — runtime / llm / workflows inject the concrete DeepAgentsEngineService directly.
The implementation sits flat under engine/:
| Part | Responsibility |
|---|---|
engine.service | Three entry points (chat / prompt / workflow) all run one streamWithAgent |
harness.factory | Assembles the LangGraph harness (loop + default tools / middleware) |
event.mapper | LangChain streamEvents v2 → AgentSseEvent (defensive mapping) |
model/ | ChatOpenAI factory (injects a circuit-broken fetch + maxRetries) |
filesystem/ | The per-run virtual workspace (VFS) |
prompts/ | Orchestrator system prompt |
The underlying model is any OpenAI-compatible endpoint (@langchain/openai), configured via OPENAI_API_KEY / LLM_BASE_URL.
Virtual workspace (VFS)
Each run’s state lives in an ephemeral virtual filesystem, not the database:
- A writable
StateBackend— drafts and intermediate artifacts within the run. - A read-only
FilesystemBackend— mounts the skills directory (AGENT_SKILLS_DIR).
Skills are offered to the agent as skills-as-tools: skills in the directory are resolved into callable tools. Engine-side state is not persisted to Prisma — it’s discarded when the run ends. What does get persisted is the harness below.
Harness: persisting every run
Engine state is ephemeral, but every run is persisted by the harness for observability and replay, recorded as a three-level structure:
AgentRun ─┬─ AgentStep ─┬─ AgentEvent
│ └─ AgentEvent
└─ AgentStep ─── AgentEventAgentRun— one run (carries the durablerunIdhandle).AgentStep— a step / tool call within the run.AgentEvent— an individual event (the SSE frame that streamed out).
That’s why GET /api/agent/runs/:runId and .../events can replay a run after the fact. See the “Runs, steps & events” section of the Agent Service overview.
LLM resilience
Outbound calls to the model go through a circuit-broken fetch (LlmResilienceService, built on opossum) injected into the @langchain/openai model factory, with a tunable maxRetries.
Streaming-safe: fetch resolves as soon as the response headers arrive, so the breaker only judges “was the connection established”. The response body streams normally and is never retried mid-stream — which would otherwise tear the SSE stream apart.