KDCube
← Engineering
KDCube Engineering · Deep Dive

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.

2026-07-29Engineering12 minExperienceBlueprint Deck
agent state conversation timeline native vs integrated agent working memory session view compaction timeline is the state how events land

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.

FOLD · QUEUE · EXPIRE followup · steer · other external event — MID-TURN shared conversation event source Redis-backed · appends busy-turn events classify event type and check live turn ownership FOLD into the running turn when the live ReAct turn consumes it QUEUE eligible work schedulable after release EXPIRE stale steer never becomes future work followup → +decision round + iteration credit steer → interrupt generation/tool → bounded finalize followup · domain event · subagent result only work eligible for a later turn event.user.steer targets the turn active on arrival ONE LANE, THREE OUTCOMES — FOLD WHAT IS CONSUMED · QUEUE ELIGIBLE WORK · EXPIRE STALE STEER
Fig. 1 — One lane, three outcomes: fold what the live turn consumes, queue eligible continuation, expire stale steer.

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.

TWO MEMORIES · TWO OWNERS TIMELINE · LAYER 1 — PLATFORM-OWNED ordered blocks: messages inline, external events as URIs read side, any worker: restore | search | hosting | downloads | pull-by-URI NATIVE agent — timeline IS the state session view rendered per round: recent full, older → summaries + URIs, refresh by pull INTEGRATED agent — timeline REFLECTS the state own checkpointer · platform-scoped thread key agent + user + conversation · I/O captured back FOR THE NATIVE AGENT THEY ARE ONE STORE; FOR AN INTEGRATED AGENT THEY ARE TWO
Fig. 2 — One record the platform owns; one working memory the agent owns. For the native agent they are the same store; for an integrated agent they are two.

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 SESSION VIEW · GRADED BY TURN AGE OLDEST → NEWEST TOKEN CEILING [COMPACTED PRIOR CONVERSATION MEMORY] one range-summary checkpoint · kept under the token ceiling older turns → compact working-summary cards each card carries the URIs of what it collapsed recent turns → full blocks large tool results shown as bounded previews preview current turn → live the agent's active context, in full NOW ANNOUNCE TAIL → VOLATILE STATE limits · live turn events · workspace status — regenerated every round, prefix stays cache-pure depth on demand — react.read · react.pull · react.memsearch recover exact collapsed content by its URI when needed IT READS AN AGE-GRADED VIEW AND REFRESHES ITSELF BY URI — NOT RESENT HISTORY, NOT EVERYTHING PULLED
Fig. 3 — The agent does not resend history and does not pull everything by link — it reads an age-graded view and refreshes itself by URI when it needs more.

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.

THE RULE

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:

GainWhere it comes from
Multi-user serving with bound identityeach 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 scalestate keys on the conversation, the agent is rebuilt per turn, so any worker can take the next turn
Any-event ingestiona common request/event context across transports; conversational work enters the lane, while namespaces own block production for domain events
Live follow-up and steerthe 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 runtimesa 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, titlesthe platform timeline and turn recording, framework-neutral
Cross-conversation searchthe same record, searchable under the caller's user boundary
File hosting both waysdurable conv:fi: links: user downloads later, agent code pulls the same bytes into its workspace
Depth on demand over URIssummaries carry refs; read/pull/search recover exact collapsed content
Cheap subagentstimeline fork by value + fenced child runtimes with reduce
Isolated generated codethe split execution fence; tool calls brokered by the trusted supervisor
Accounting that follows the requestthe accounting subject rides supported runtime crossings and attributes integrated model, embedding, search, and participating custom-call paths
Consent-gated capabilitydemand-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.

Dimensionworkspace (native ReAct)ported-langgraph-agents (integrated)
Reasoning coreKDCube ReAct rounds, protocol, action governanceframework/domain-owned LangGraph graphs; deliberate integration changes stay small and documented
Constructionagent built fresh per turn from config.reactsurfaces.as_consumera dispatcher resolves the agent id and builds a fresh graph per turn
Working memorythe 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 rolesource of truth — state and record are onereflection — inputs/outputs captured into the record
Mid-turn eventsfolds followup/steer live at decision boundariesfolds the accepted ingress batch at start; eligible mid-turn messages wait for the next turn, while unconsumed steer expires
ToolsSDK tools + named services + MCP, taught by composed instruction blocksapp @tools + selected SDK wrappers + MCP tools + consent placeholders, mapped by the adapter
Generated codefull exec path with an exported tool catalogrun_python — isolated computation + hosted files
Streamingchannel protocol through the communicatorLangGraph events mapped to chat events by the stream adapters
NATIVE AND INTEGRATED · SIDE BY SIDE workspace — NATIVE ReAct ported-langgraph-agents — INTEGRATED REASONING CORE CONSTRUCTION WORKING MEMORY TIMELINE ROLE MID-TURN TOOLS GENERATED CODE STREAMING ReAct rounds fresh per turn from config session view over the timeline source of truth — state & record are one folds live SDK + named services + MCP full exec catalog channel protocol framework-owned LangGraph graph dispatcher builds fresh graph checkpointer · scoped agent/user/conversation reflection — I/O captured into the record start-batch fold · eligible work queues @tools + wrappers + MCP run_python mapped LangGraph events SAME RUNTIME, TWO RELATIONSHIPS TO THE RECORD — NATIVE: STATE IS THE TIMELINE; INTEGRATED: TIMELINE REFLECTS IT
Fig. 4 — Same runtime, two relationships to the record: the native agent's state IS the timeline; the integrated agent's timeline reflects its captured inputs and outputs.

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.

ONE TURN · END TO END person · webhook · automation · MCP client submit work onto the conversation ingress appends the accepted start batch to the conversation source the lane reserves the accepted batch for ONE turn serialized per conversation — one turn at a time run() bind identity + accounting context · start turn recording execute_core(...) your agent code — the one function you own NATIVE render the session view · enter ReAct rounds PORTED fold accepted start batch · restore checkpointer · run graph declared tool boundaries target enforces authority the communicator peers progress to the initiator recording lands the turn turn.log blocks · timeline artifact · chat events (cost · timing · citations) produced files hosted as conv:fi: links the lane reservation finalizes — eligible pending work may schedule next READ SIDE — LATER, ANY WORKER restore in chat · search across conversations · file download · pull by URI SUPPORTED CROSSINGS USE EXPLICIT CONTRACTS · CONVERSATION OUTPUT BECOMES BLOCKS OR REFS
Fig. 5 — Supported crossings use explicit contracts; conversation-facing output becomes timeline blocks or durable refs.

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.

· Read the implementation contracts

· Continue with the worked stories

KDCube Engineering
№ 2026-07-29 · kdcube.tech