An Agent Living in the Runtimes: Native and Integrated, Side by Side
A hosted agent does not carry a session, restore a conversation, keep a file, or survive a worker restart on its own. Two different memories do that for it — one the platform owns, one the agent owns — and the line between them is the whole story.
A companion article maps the KDCube runtimes and the fences between them. This one turns the map around and stands inside a single agent: how it is fed from any surface, what state exists for it and who owns each layer, and — the part that decides everything else — how a native agent and an integrated framework end up with genuinely different relationships to the same conversation record.
Two shipped apps ground every claim:
workspacethe native path. Its main agent is the KDCube ReAct adapter, constructed fresh per turn from the app descriptor.ported-langgraph-agentsthe integrated path. Two LangGraph agents behind one execute_core: a dispatcher resolves the agent, builds a fresh graph bound to the turn's identity, and routes the graph's own working store onto KDCube's Postgres.(In literal source, the deployable unit is still a bundle; in prose it is an app.)
01 Any surface, one lane
An agent never binds to a transport. Chat over SSE/Socket.IO, REST, public webhooks, MCP, Data Bus handlers, and scheduled work keep their own payload and lifecycle contracts. Each entry establishes the request or execution context available on that path. A public route does not require a platform session; the app or integration may still carry or resolve an actor and apply its own authorization. The serving runtime then splits two ways: an app's direct surfaces answer in place, and supported entries can submit conversational work; work for the agent lands on the conversation event lane — the ordered work lane for one conversation. It reserves one accepted start batch for one turn; that batch may contain same-ingress siblings such as a prompt and its attachments. Same-conversation turns serialize across workers while different conversations run in parallel.
What makes the lane an agent concept rather than plumbing is what happens when events arrive while a turn is running. Ingress appends busy-turn events — followup, steer, other external events — into one shared, Redis-backed conversation event source. The active turn holds a fenced owner lease on that source and listens live.
The two apps split exactly here. The native workspace agent opens the live lane handler and folds mid-turn events at decision boundaries. The LangGraph app takes the safe default: it folds the turn's ingress batch before reading inputs — attachments ride sibling lane events of the prompt, so a run-to-completion door must fold the batch or the agent sees the prompt alone — then runs the graph start to finish. Eligible mid-turn messages wait for the next turn. An unconsumed steer expires. The adapter declares what it actually supports; a composer never offers live steer to a graph that cannot consume it.
02 Two memories, two owners
State for a hosted agent is two distinct layers with two distinct owners. Both must reflect the same conversation; neither substitutes for the other.
Layer 1 — the platform timeline
The platform owns the timeline: an ordered event log per conversation. User and assistant messages sit inline as blocks; external events — tool results, files, anything the runtime ingests — are captured as blocks whose payloads live behind URIs (conv:fi:, conv:ar:, conv:tc:, …). The turn log is the single source of truth for reconstructing a turn.
It feeds everything downstream of the agent: conversation restore (reload rebuilds bubbles, attachment and file cards, citations, cost, and timing from the recorded blocks); cross-conversation search (the same turn logs power the search engine); file hosting, both directions — a user downloads uploads and agent-produced files later, and the agent's own generated code pulls those same files into its execution workspace; and forking — a subagent's conversation is seeded with a projection copy of the parent's, by value.
The timeline is progressive and portable: because the platform owns it as neutral blocks, the harness can pull it on any supported trusted worker or runtime, prune and compact it, and render blocks at different levels of detail by age and by consuming surface. It is keyed to the conversation, never to a process.
Layer 2 — the agent's working memory
The second layer is what the model actually receives on a turn, and its owner depends on the agent kind.
Native. For the KDCube ReAct agent the timeline is not only the record — it is the source of truth for the working memory too. Each round the harness renders a session view from the timeline:
The agent does not resend the whole history, and it does not pull everything by link. It reads a rendered, age-graded view, and it refreshes itself — retrieving exact collapsed data by its URI (⚙ react.read, react.pull) or finding it when no path is known (⚙ react.memsearch). Volatile per-round state — limits, live turn events, workspace status — rides the regenerated ANNOUNCE tail so the stable prefix stays cache-pure.
Integrated. A ported framework keeps its own working memory in its own store. The LangGraph app opens a durable checkpointer per agent (AsyncPostgresSaver routed onto KDCube's Postgres). Its thread_id is a platform-derived key containing tenant, project, active agent, user, and conversation identity — never the browser session id, which changes per session and would open an empty thread on reload. An in-memory saver is not sufficient for scaled serving: a later turn can land on another worker or follow a restart. The alternative is equally valid — reconstruct prior turns from the platform record each turn and feed them in, the record as the single source of truth at the cost of a reconstruction step. What is unsafe is treating client-submitted history or process memory as durable.
In one sentence: for the native agent the timeline IS the state; for an integrated agent the timeline REFLECTS the state — the runtime captures the agent's inputs and outputs into the record, so restore, search, hosting, and title work identically while the framework's own memory stays framework-native.
03 Blocks are owned by their namespace
The timeline is not a fixed schema. Event sources register per-namespace resolvers, and each namespace owns how its events become blocks and how those blocks present everywhere: block production (a task: provider produces and may patch only the timeline blocks it owns — an integrity boundary, not a rendering convenience), rehosting (when the agent pulls an owner ref, the namespace rehoster mirrors the owner's content into the conversation's artifact space and returns concrete paths — external owner refs are opaque until pulled), and cross-surface presentation (the same owner shapes how its event renders in the agent's context, in the chat UI on reload, in the compact external timeline served to MCP consumers, and in a scene).
For the agent this means the timeline can absorb any kind of event — a provider app ships its namespace resolver and its events become first-class timeline citizens with correct presentation and pull behavior, with no change to any agent framework.
04 What the fusion gives an agent
Living inside the runtimes, native or integrated, an agent receives:
| Gain | Where it comes from |
|---|---|
| Multi-user serving with bound identity | each execution uses the actor and authority context established by its entry path; a public route does not require a platform session, while an app or integration may still carry or resolve identity; platform storage helpers apply tenant/project/user scope and trusted app code must preserve those owner keys |
| Horizontal scale | state keys on the conversation, the agent is rebuilt per turn, so any worker can take the next turn |
| Any-event ingestion | a common request/event context across transports; conversational work enters the lane, while namespaces own block production for domain events |
| Live follow-up and steer | the shared event source + owner lease; a live ReAct turn can fold both, eligible continuations can queue, and an unconsumed steer expires |
| Live streaming to the initiator, across communicator-enabled runtimes | a comm spec crosses with supported work and the far side rebuilds it; selected recordable events and durable turn blocks later hydrate the conversation view |
| Durable history, restore, titles | the platform timeline and turn recording, framework-neutral |
| Cross-conversation search | the same record, searchable under the caller's user boundary |
| File hosting both ways | durable conv:fi: links: user downloads later, agent code pulls the same bytes into its workspace |
| Depth on demand over URIs | summaries carry refs; read/pull/search recover exact collapsed content |
| Cheap subagents | timeline fork by value + fenced child runtimes with reduce |
| Isolated generated code | the split execution fence; tool calls brokered by the trusted supervisor |
| Accounting that follows the request | the accounting subject rides supported runtime crossings and attributes integrated model, embedding, search, and participating custom-call paths |
| Consent-gated capability | demand-driven claims at tool-attempt time; grants per user, per agent, revocable |
None of it is automatic exposure: the app descriptor declares what exists, the per-agent inventory narrows it, and the user narrows it further.
05 Native and integrated, side by side
The two apps make the difference concrete.
| Dimension | workspace (native ReAct) | ported-langgraph-agents (integrated) |
|---|---|---|
| Reasoning core | KDCube ReAct rounds, protocol, action governance | framework/domain-owned LangGraph graphs; deliberate integration changes stay small and documented |
| Construction | agent built fresh per turn from config.react ⊕ surfaces.as_consumer | a dispatcher resolves the agent id and builds a fresh graph per turn |
| Working memory | the rendered session view over the timeline (age-graded, refresh-by-URI) | the framework checkpointer on KDCube Postgres, keyed by platform-scoped agent + user + conversation identity |
| Timeline role | source of truth — state and record are one | reflection — inputs/outputs captured into the record |
| Mid-turn events | folds followup/steer live at decision boundaries | folds the accepted ingress batch at start; eligible mid-turn messages wait for the next turn, while unconsumed steer expires |
| Tools | SDK tools + named services + MCP, taught by composed instruction blocks | app @tools + selected SDK wrappers + MCP tools + consent placeholders, mapped by the adapter |
| Generated code | full exec path with an exported tool catalog | run_python — isolated computation + hosted files |
| Streaming | channel protocol through the communicator | LangGraph events mapped to chat events by the stream adapters |
What the worked integrated agent gains without changing its reasoning core is the common layer its adapter actually wires: hosting, restore, search, ordered start-batch handling, horizontal serving, accounting on integrated paths, consent-gated tools, the same workspace grammar (fresh per turn, refs in, produced files hosted out), and the same pull-over-URI primitives the native agent uses (⚙ pull_refs_into_dir; the ReAct tools are one adapter over them, and the ported app binds the same helpers). Framework-specific behavior, such as live event folding or an execution tool catalog, still requires adapter support.
One integrated nuance deserves its own note: Claude Code. Hosted Claude Code keeps continuity through its own session substrate (--session-id/--resume with a deterministic id from user + conversation + agent), not through the platform record; KDCube makes that substrate durable across workers with a git-backed session store, one branch per conversation boundary. It is the clearest illustration that the platform record and a framework's working memory are genuinely different layers: the record is still captured and serves restore and search, while the framework's continuity lives in its own files.
06 One turn, end to end
The whole fusion in a single pass — the native agent shown; the integrated path differs only where marked.
Every supported runtime crossing follows one of the boundary contracts from the companion map. Conversation-facing durable output on the read side becomes timeline blocks or durable refs; framework checkpoints and app-domain state remain in their own stores. That is the fusion: one agent, any declared surface in, several runtimes underneath, one platform-owned conversation record out.