Skip to Content
Agent ServiceOverview

Agent Service

agent-service is the heavy AI service. It runs the DeepAgents engine (a LangGraph loop over an OpenAI-compatible model via @langchain/openai) and streams results as Server-Sent Events (SSE). It also handles PDF parsing, translation, and realtime interview.

  • Base URL (dev): http://localhost:3112
  • Global prefix: /api
  • Swagger UI: /api/docs

Sections

Runtime architecture

Internally agent-service is organized into flat modules:

  • runtime — the HTTP entry core (chat / agent / graph controllers) + run lifecycle, SSE writing, per-user daily token budget, trace persistence.
  • engine — the DeepAgents engine (the single engine, a LangGraph loop over @langchain/openai); no upper abstraction — runtime / llm / workflows inject the concrete implementation directly.
  • llm — assembles prompts → engine streaming, with circuit-breaking / retry (LLM resilience).
  • workflows — analyze / research / rewrite workflows + multi-persona analysis.
  • interview · translation · document — interview (incl. realtime WebSocket), translation, PDF.

How the engine and harness work (the LangGraph loop, virtual workspace, skills-as-tools, AgentRun→Step→Event persistence) is covered in Engine & harness.

Streaming model

Most agent endpoints respond with Content-Type: text/event-stream. The body is a sequence of frames separated by a blank line; each frame is a single data: line carrying one JSON event:

data: {"type":"run_started","runId":"clx..."} data: {"type":"message_chunk","content":"Hello","runId":"clx...","stepId":"stp..."} data: {"type":"done","runId":"clx..."}

Every emitted event carries runId and stepId. The catalog of type values and the parsing rules are in SSE events.

Use curl -N (no buffering) to watch a stream, or a streaming HTTP client in code. Don’t await res.json() on these endpoints — they never return a single JSON body.

Runs, steps & events (the harness)

Every streamed run is persisted for observability and replay. A run is recorded as AgentRunAgentStepAgentEvent. You can fetch a past run after the fact:

ActionMethod & path
Get a runGET /api/agent/runs/:runId
Get a run’s eventsGET /api/agent/runs/:runId/events

This means the runId you see in the stream is a durable handle — store it to later replay or audit what the agent did.

Endpoint map

CapabilityEndpointShape
ChatPOST /api/chatSSE
Agent run (generic task)POST /api/agent/runsSSE
Fetch run / eventsGET /api/agent/runs/:runId[/events]JSON
Research workflowPOST /api/graph/researchSSE
Analyze workflowPOST /api/graph/analyze (alias /api/graph/analyze-resume)SSE
Rewrite workflowPOST /api/graph/rewriteSSE
Multi-persona analysisPOST /api/graph/analyze-resume-multiJSON
PDF parsePOST /api/pdf/parseJSON
TranslatePOST /api/translate/textJSON
Translate (stream)POST /api/translate/streamSSE
Interview start / chatPOST /api/interview/start, POST /api/interview/chatJSON
Interview delete sessionDELETE /api/interview/session/:sessionIdJSON
Realtime interviewWS /api/interview/realtime/:sessionIdWebSocket
HealthGET /api/healthJSON

Agent-service controllers are not Clerk-guarded at the controller level — they expect to sit behind the gateway. If you expose them publicly, enforce auth and rate limiting at your proxy.

Last updated on