KDCube

One agent orchestrates a conversation well. Some assignments deserve more than it can give — deeper reasoning, broader knowledge, research that has to be conducted rather than recalled — or simply deserve their own pair of hands while the main thread keeps moving.

The design goal was to make delegation native to the timeline, with the same event vocabulary the agent already lives in — and to make every choice about it (who may delegate, to whom, at what spend) land with the party it belongs to: the admin shapes, the user decides, the runtime enforces.

ONE DELEGATION, END TO END Main conversation the user's chat · parent agent react.delegate(charter, agent_alias) returns at once · fork marker on the timeline parent keeps working contributions fold into the live turn turn may finish, helpers still running nothing waits · no idle rounds follow-up turn delivers the outcome turn total X, of which helpers Y Helper conversation its own scheduled turn · same queue as any turn opens on a fork of the parent context summaries + in-progress turn · charter = assignment works with the parent's tools & skills streams into the chat as a thread persists timeline & workspace every contributed ref resolves reports converged (or failed) published only after persistence kickoff = schedule contribution converged
One delegation, end to end — kickoff is scheduling; reports ride the timeline.

Kickoff, never a pinned context

react.delegate takes one argument that matters: the charter — a single self-contained assignment prompt stating the goal and what to send back. The call returns immediately with the child conversation ref, and the parent keeps working; it may finish its turn with helpers still running. There is no waiting primitive, because a reasoning loop has no good way to wait — it would burn rounds idling.

What happens at the moment of delegation is deliberately small and durable:

react.delegate(charter, agent_alias?, agent_title?)
  ├─ fork projection ──▶ persisted as the child conversation's opening timeline
  │                      (working summaries + the in-progress turn, refs carrying
  │                       their home conversation id)
  ├─ fork record     ──▶ parent turn's stored record: forks += {child, caption}
  └─ charter event   ──▶ child's event lane, carrying a task payload
                         = the kickoff IS the promotion: the child turn is
                           scheduled on the cluster like any other turn

The child is a first-class scheduled turn — same queue, same fairness, same admission and backpressure as every user turn. A user who fans out five helpers is five turns on the queue, fairly interleaved with everyone else's. If the queue declines the kickoff, the delegate call fails loudly and cleans up after itself; nothing half-spawned lingers.

The child opens with a fork of the parent's visible context: the conversation's working summaries plus the turn in progress, every conversation-scoped ref qualified with its home conversation id — so the helper reads its inheritance and can pull any artifact it names. The charter folds in as its assignment. From there it is an agent like its parent: same tools, same skills, its own round budget from configuration.

Reports ride the timeline

The helper speaks back through the parent conversation's event lane, in three event kinds:

  • subagent.contribution — milestones along the way: a short report plus refs, pullable with react.pull exactly as written.
  • subagent.converged — the final report, published only after the child's end-of-turn persistence, so every ref it carries already resolves.
  • subagent.failed — failures are authored, never silent; a helper that dies before starting (including an economics denial) still reports why.

A live parent turn folds these into its current round — the agent sees the contribution and can act on it immediately. A parent that already finished is not left waiting: the completion event carries a task payload, so it starts a follow-up turn whose whole job is to fold the outcome, pull the deliverables, and speak to the user. Exactly-once discipline guards the seam: an event a live turn already consumed is never promoted into a second turn.

Threads in the chat

With visibility set to thread, the helper's stream arrives in the same chat the user is watching — every emission stamped with its origin (child conversation, forked-from turn, charter caption, helper name) and delivered on the parent conversation's channel. The chat client multiplexes the stamp into a collapsible thread anchored under the turn that forked it: collapsed, it shows the helper's name, the charter caption, a live status, and contribution milestones; expanded, the full child stream rendered by the same pipeline as the main lane — its searches, its code, its files, all folded in by the child's own conversation identity. Several helpers under one turn — fan-out — each get their own thread.

Reload reconstructs the same picture from the store: each turn's record carries its forks, the child conversation carries its forked_from backref, and the child fetches through the same conversation endpoint as any other. Live and reload agree because both render the same source.

The default visibility is silent — deployed chat surfaces that render no threads receive no interleaved child traffic; the parent timeline still shows the marker, the contributions, and the outcome.

A named participant, not "you"

The delegating agent names its helper — the optional agent_title on the call ("Science news researcher", "Pricing analyst"). That one name then carries the helper's identity through every place the user meets it: the thread header, the in-flight row of the announce block, and the handoff. The agent that chose the name recognizes its own helper in each of those places without decoding conversation ids.

The subtle part is the reactive handoff. When a helper converges after the parent has already finished, its completion starts a follow-up turn — and that turn was not initiated by the user. So it is attributed to the helper, as a participant in the conversation: where a user turn shows "You" and the message you typed, this turn shows the helper's name and what it said — "Science news researcher said: I compiled the two stories into an Excel with the trend charts." The line the helper speaks is its own react.contribute report — its message to the delegating agent, not a slice of the deliverable. A conversation can now have more than one voice, and each turn says plainly whose voice it is.

Aliases, and where identity lives

The tool document the agent reads is static — identical for every user, free of model names, part of the byte-stable cached instruction. It frames when to delegate by capability need:

Delegate when the assignment needs more capability than yours — deeper reasoning, broader knowledge, work whose quality depends on conducting real research (forming queries, recognizing incomplete results, re-querying, critically analyzing, compiling) — or when a sizable self-contained piece can genuinely run alongside your own work. Do quick work yourself: a delegation costs like a full agent of the chosen strength.

Everything situational renders in the per-round announce block, in one vocabulary:

[DELEGATION]
  you are: fast_agent [regular]
  helper aliases (react.delegate agent_alias):
    - fast_agent [regular]: quick focused work
    - strong_agent [strong] (default): deep reasoning and synthesis
  delegations in this conversation:
    - Vendor-landscape researcher — Research the vendor landscape. — strong_agent [strong] — contributed 1

The helper is chosen by agent_alias — an enum, never a model string. Admins map aliases to models per agent (fast_agent and strong_agent ship as defaults); an alias nobody configured resolves to the smartest configured one. The agent knows itself by the same alias vocabulary, matched from its effective decision model — so "would a helper be stronger than me?" is a direct comparison, recomputed when the user changes their model pick. Live delegations render while they run; a completed one shows once, in the turn its outcome folded, then lives on as ordinary timeline history.

STATIC TOOL DOC · SITUATIONAL ANNOUNCE Tool doc — cached instruction identical for every user · byte-stable "Hand a self-contained assignment to a separate agent similar to you… Delegate when the assignment needs more capability than yours." plain language capability framing 100% cache hit [DELEGATION] — per-round announce the situation now · re-rendered every round you are: fast_agent [regular] - fast_agent [regular]: quick focused work - strong_agent [strong] (default): deep reasoning - Research the vendor landscape. — contributed 1 one alias vocabulary terminal rows expire after their turn admin config: aliases → models · default · captions user: Helper agents toggle · model pick sets "you are"
Static tool doc, situational announce — one contract, two surfaces.

The user pays, the user decides

Delegation raises quality and raises spend, so it follows the platform's capability model:

  • The admin's per-agent config offers it (subagents.allowed) and sets the default; the capability picker then shows a Helper agents toggle to every user, on by default, with the trade-off stated plainly: helpers can raise the quality of hard tasks; each helper runs on its own model calls, billed to your account.
  • A user who turns it off gets turns where the concept simply is not present — the tool leaves the catalog, the guidance leaves the instructions.
  • The helper's turn passes the same economic boundary as the user's own turns — identical subject, budgets, admission; a denial fails the helper loudly back to the parent.
  • Spend stays attributable: helper usage books under the child conversation with a first-class backref to the delegating turn, and when the outcome reaches the user, the usage line reads turn total X, of which helpers Y.

What made it honest

  • Completions publish after persistence. The converged event is authored only when the child's timeline and workspace are saved — every ref in the final report resolves at the moment the parent (or the follow-up turn) reads it.
  • No event buys iteration credit. Helper events inform a live turn; they never extend it and never start anything inside it. Promotion happens only when no turn is live — one event, one consumer, provably once.
  • The catalog is the authority. Delegation is opt-in, so its tool appears only where it is on — and the instruction set now says so generically: configuration can add reactive tools beyond the core set, and every catalog section opens with a derived roster (count + ids) the model verifies completeness against.
KDCube Deep · 12.07.2026