Pillar 5 · Agent core (the loop)
The interpretation engine — where the product thesis (same corpus, per-audience presentation) executes. inference (backend/internal/conversation/inference/) wraps the CloudWego eino ADK loop (Anthropic → native Messages API; Gemini → its own adapter; every other provider → OpenAI-compatible adapter — eino_model.go); the frontend is a thin SSE consumer. Two recent structural moves define this pillar: the launchable core — backend/agentcore/ (deliberately outside internal/) exposes Driver + BuildVisitorAgent(driver, input), making the core independently launchable (bridge.go adapts a Driver onto the loop's internal ports; eval-harness/, a separate Go module, drives the same loop with its own EvalDriver — "eval is just another consumer"); and the entry-agnostic principle — the agent is entry-agnostic: entries fill a neutral _meta.standmeet/session and invoke.
Status (2026-09-07, 36789537d): Bridge/Driver landed, and the earlier fixture deviation is REMEDIATED — no fixtures remain in the core ("the Driver IS the environment"); inject-and-launch still test-only: BuildVisitorAgent has exactly one non-test caller (eval-harness/main.go:164, candidate.go:138) and nothing under backend/internal or backend/cmd imports agentcore. The prod web path builds its agent directly — internal/routes/public/sessions.go → capreg.AssembleVisitorBundle → inference.RunAgentTurn (the runtime promotion is the remaining step).
flowchart LR
subgraph SM["StandMeet — prod box"]
WEB["web visitor entry
(fills neutral _meta session)"] --> ASM["routes/public sessions.go
(capreg AssembleVisitorBundle)"]
IM["im-bridge (Telegram)
via @standmeet/sdk-core"] --> ASM
ASM --> LOOP["eino ADK loop
(anthropic native / gemini / openai-compat)"]
LOOP --> SSE["SSE stream → app (frontend)"]
end
subgraph DEV["dev estate — same repo, separate go.mod"]
EV["eval-harness"] --> ED["EvalDriver
(canned data)"]
end
ED --> BUILD["BuildVisitorAgent(driver, input)
(bridge.go: Driver → loop ports)"]
BUILD --> LOOP
FUT["runtime promotion
(prod through BuildVisitorAgent — not yet)"] -.-> BUILD
One chat turn (sequence)
sequenceDiagram
participant A as app (SSE)
participant R as routes/session
participant L as eino loop
participant T as tool (mcp-server / connector)
A->>R: POST message, SSE opens
R->>L: RunAgentTurn (capreg-assembled tools)
loop until final answer
L-->>A: stream deltas (unbuffered passthrough)
L->>T: tool call (stdio MCP / connector handle)
T-->>L: result (+ ui:// card)
end
L-->>A: final answer
Note over R,L: client disconnect does NOT kill the turn (detached)
L->>R: turn completes → persist messages
Note over R: persist-at-completion — history lands once, whole
L-->>A: done, then optional epilogue frame "ghost" (agent_epilogue.go)
Turn lifecycle (state)
stateDiagram-v2 [*] --> Streaming : turn starts Streaming --> Detached : client disconnects Streaming --> Completed : final answer Detached --> Completed : loop finishes anyway Completed --> Persisted : write messages once Persisted --> [*] : reload recovers from DB
Children
- agent-core-diagram-coverage — class-view coverage index (what is diagrammed, what is debt).
- agent-as-injectable-driver — Bridge/Driver, the launch seam (landed).
- entry-agnostic-agent — entries are consumers; inward/outward symmetry.
- detached-turn-persist-at-completion — turn lifecycle vs persistence.
- force-final-answer — loop termination discipline.
- system-prompt-hash-regression — deterministic assembly → drift instrument.
- unbuffered-sse-passthrough — streaming without buffering.
- eval-harness-on-prod-loop — eval as a Driver consumer of the real loop.
- ghost-steering — built + verified on the real model. One suggested message that bends the conversation: waypoints as soft gates, single-ghost default, momentum/silence/no-repeat, the telemetry loop.