condensate

Code mode and credits

Let a model make several tool calls in one program, and count every call agents make.

On this page

Let a model make several tool calls in one short program, and count every call it makes.

What code mode is

Code mode lets a model run one short program that calls several tools and returns a concise result. Each tool call is still a normal, metered tool call. The program only avoids a separate model round trip for each intermediate value. Credits are the prepaid balance every metered call debits. The middleware explains the endpoint the calls pass through.

Why you would want it

  • A task needs tool A, then B with A's answer, then C with B's. Without code mode each step costs a model round trip, and each intermediate value lands in the model's context. With it, one program makes the three calls and returns only the part the model needs.
  • You want to know what agents spend. Every call, inside a program or not, debits the same credits, and a failed call is refunded.
  • A caller you have not allowed should see nothing. Only the callers you list see the code-mode tools.

How it works

Without batching:
model → tool A → model → tool B → model → tool C → model

With a code-mode program:
model → program calls A, B, C → selected result → model

This is an execution sketch, not code to paste into the sandbox. The model writes one JavaScript program and hands it to codemode__run. The program runs in a QuickJS sandbox under fixed caps. Inside it, call reaches any aggregated tool, and each such call is checked and metered as if the model had made it. The program ends with return, and only that value goes back to the model.

Try it

Code mode is off by default. To switch it on, set CONDENSATE_CODE_MODE to opt-in or internal (off, or leaving it unset, keeps it off), and list the callers who may use it in CONDENSATE_CODE_MODE_PRINCIPALS as a comma-separated list. Under either value, only the listed callers see the code-mode tools. Other callers see nothing. The two values behave the same today. Any other value stops the backend from booting, so a typo cannot silently switch a rollout off.

You should see three tools under the codemode upstream in tools/list for a listed caller:

ToolWhat it does
codemode__searchFinds tools and namespace methods by words describing the task, best match first. limit runs from 1 to 20, default 8.
codemode__typesReturns TypeScript signatures for the merged tool surface. docs: true adds JSDoc descriptions.
codemode__runRuns one JavaScript program in a QuickJS sandbox. Inside it, await call("<upstream>__<tool>", args) calls any aggregated tool. The program ends with return, and only that value comes back.

What happens when

No caller is listed

With no callers listed, the backend warns at boot and nobody sees the tools.

A program hits a cap

Programs run under fixed caps. Each cap returns a typed error that names it, so nothing is cut off silently. Reference lists the caps.

Two programs run at once

Only one run is allowed at a time per caller.

A program calls a native namespace

Native namespaces, such as agents, canvas and review, are host objects rather than tools. They are bound only when their service URL is configured, and they count toward the namespace-call cap, not the tool-call cap.

A head reads the threads below it

A head is the lead agent, the one that hands tasks to other agents. A head that runs a program in its own thread can read the threads below it without raw HTTP. agents.children and agents.history answer one page at a time and say when more follow. agents.turnStatus and agents.memory.reflect cap their lists and count what they left out. agents.memory.recall answers at most 20 memories. Like every other agents method that takes a thread id, the four thread reads reach only the thread the program runs in, a thread below it, or a thread the program opened. The memory reads take no thread: they read the workspace the aggregator is set to.

MethodWhat it answers
agents.thread(id)The thread's type, title, parent, stage and whether its agent is replying.
agents.children(id?, { after, limit })One page of the live (not archived) direct children, newest first. With no id it lists the calling thread's children. It never lists a sibling or an ancestor.
agents.turnStatus(id)Whether the agent is replying, and which messages wait.
agents.history(id, { after, limit })The log from its first event. It never skips older events in favour of a snapshot.
agents.memory.recall(query, { limit, tags })Memories that match the query, from the aggregator's workspace.
agents.memory.reflect(query)A written answer from that workspace's memory, with its sources.

The memory reads are on only when CONDENSATE_AGENTS_WORKSPACE names a workspace. Without it, they are refused.

You search for a tool

codemode__search ranks every aggregated tool and every method of a namespace in scope, such as agents.spawn or review.pr. A match on more of your words ranks first, so a tool that matches every word comes before one that matches only some. Among matches on the same number of words, a word in the name counts for more than a word in the description. A plural finds its singular, so "threads" finds "thread". When nothing matches, the answer says where to look next.

Credits and metering

When /mcp is on, every tools/call debits prepaid credits. A new caller receives a signup grant. A failed metered call is refunded.

  • CONDENSATE_FREE_SIGNUP_CREDITS sets the signup grant.
  • CONDENSATE_DEFAULT_TOOL_COST sets the cost per call, which is 1 by default.
  • CONDENSATE_TOOL_COSTS overrides the cost for named tools.
  • Balances live in Postgres when CONDENSATE_DATABASE_URL is set. Otherwise they live in a JSONL file at CONDENSATE_CREDITS_PATH. With neither, they stay in memory, the backend logs a warning, and balances reset on restart.

Reference

CapDefault
Wall-clock time per run10 seconds. Some surfaces raise this for a longer run.
Tool calls per run20
Namespace calls per run100
Reply timeout per tool call180 seconds
Returned result size64 KiB of JSON
agents.children page20 threads, at most 50
agents.history page50 events, at most 200
agents.turnStatus queue50 listed; the rest are counted
agents.memory.recall hits8, at most 20
agents.memory.reflect sources and documents20 of each listed; the rest are counted
Search answer fieldWhat it holds
kindtool for an aggregated tool, namespace for a namespace method.
upstreamThe upstream of a tool match. Pass it as upstream to search that upstream only.
namespaceThe namespace of a namespace match, with the method's one-line description. Pass it as upstream to search that namespace only.
hintPresent only when nothing matched. It names codemode__types and the namespaces in scope.

A query is at most 200 characters, and only its first 16 distinct words are scored.

SettingWhat it does
CONDENSATE_CODE_MODEoff (default), opt-in or internal. Any other value stops the boot.
CONDENSATE_CODE_MODE_PRINCIPALSThe comma-separated callers who see the code-mode tools.
CONDENSATE_FREE_SIGNUP_CREDITSThe signup grant for a new caller.
CONDENSATE_DEFAULT_TOOL_COSTThe cost per call. Default 1.
CONDENSATE_TOOL_COSTSThe cost of named tools.
CONDENSATE_DATABASE_URLKeeps balances in Postgres.
CONDENSATE_CREDITS_PATHKeeps balances in a JSONL file when there is no database.
CONDENSATE_AGENTS_WORKSPACEThe workspace whose memory agents.memory reads. Unset, those reads are refused.