Concepts
Each word below has exactly one meaning: in the Python API, in the files a run writes, in the monitor’s HTTP API, in the web components and in this documentation. No other word is used for the same thing.
“In code” names the code by its name (Task), by its public path where that says
more (contraagent.engine.Run), or by a file. A name a public module exports
(contraagent, contraagent.config, contraagent.backends, contraagent.engine,
contraagent.plugins, contraagent.monitor, contraagent.monitor.api,
contraagent.testing) is found there, and its __module__ names that module; any
other name is implementation, not public (Compatibility), and is
named for whoever works on contraagent itself.
| Word | Means | In code |
|---|---|---|
| coding agent | the CLI program that does the work (claude, omp, opencode, pi, codex) |
agent in config, routes, journal and monitor; Backend is its Python adapter |
| LLM | the language model the coding agent runs on, nothing else | model |
| agent task / Python task | a task a coding agent executes / one this process executes | agent_task, @python_task; Task.executor and on disk executor: "agent" | "python" |
| kind | the class of work (summarize); a Python task’s kind is its own name |
Task.kind |
| unit | what a kind is applied to (alpha): it names a task and its output, and locks nothing |
Task.unit |
| claim / claim capacity | a name a task holds while it runs, its declaration a template (topic:{unit}, topic:{params.topics}: one name per element of a list); one task holds a name at a time / how many running tasks may hold one name instead, given by the name or by an fnmatch pattern that gives each name it matches a capacity of its own: a number, or what one running task that claims the name needs of the host (memory, cores), worked out from the host’s free memory and usable cores each time such a task would start |
agent_task(claims=), @python_task(claims=), Task.claims; plan claims / claim_capacity, [defaults.claim_capacity], PerTask, ClaimCapacity, WorkQueue.capacity |
| service / service address | the long-lived helper a claim name stands for (a worker service, a database, a local server), given by a function of the name that returns a context manager: the first task that claims the name starts it, every task that claims it shares it while it runs, and the run’s end stops it; a task a stub run plays holds none / the string its start gives, by which a task that claims the name reaches it | Pipeline(services=), Service, service_address, CONTRAAGENT_SERVICE_<NAME>; services.jsonl (ServiceEvent); monitor Plan.services (ServiceSpan) |
| task | one kind applied to one unit | Task |
| key | a task’s stable identity: an agent task’s is <kind>-<unit> (<kind> with no unit), a Python task’s python:<kind>-<unit> (python:<kind> with no unit), or the task call’s key=; the n-th task a flow call creates under one key is <key>~n |
Task.key, field key everywhere, monitor URL key; as the name of its files (streams/, contracts/, calls/, inflight/): file_name(key), every character but a letter, a digit, -, _ and . turned into _ |
| params | what a task is given | Task.params, call file params, CONTRAAGENT_PARAMS |
| flow | the plain function that calls the tasks | Pipeline.run(flow, ...) |
| flow call | one run of a generator in a flow: the top flow, or a generator it yields; it waits at each yield for tasks or other flow calls; ids 0, 0.1, 0.1.2, …; a flow that does not yield is flow call 0; its state is running until it returned, raised or was closed |
FlowCall, FlowDriver, FlowCall.state; flow_calls.jsonl (FlowCallRow); monitor Plan.flow_calls, FlowCallNode |
| flow error | an exception a top flow call raised after its first task was queued | RunReport.flow_errors |
| origin | where a flow created a task: its flow path (with each loop’s pass), created from and flow call | Task.origin, Origin; plan flow, created_from, flow_call |
| flow path | the frames of flow code that created a task, outermost first, across flow calls; a flow call’s flow path is its parent’s where the parent yielded it | Origin.flow, Frame; plan and flow call flow, the monitor’s too |
| call site | where a frame of the flow path was when the task was created: function (module.qualname), file and line; a flow call’s site is where its parent yielded it |
Frame.function, .file, .line; FlowCall.site |
| loop | a for or while statement in a generator of flow code, named by its first line; a call site’s loops are those whose pass it is in, outermost first; a comprehension is not a loop |
Loop.line, Frame.loops; flow[].loops[].line |
| pass | one iteration of one loop, numbered from 1 each time the loop is entered; never an attempt, never the ~n of a key |
Loop.pass_, flow[].loops[].pass; max_passes (the passes a while loop may make; a for loop has no limit), @max_passes(n) (the passes each while loop of one generator function may make, in place of the run’s), TooManyPasses |
| created from | the keys whose results a flow call had received when it created a task | Origin.created_from |
| fingerprint | a digest of what defines a task’s work: kind, unit, key, params, its definition (instructions, role file, its plugins’ skills, schemas, validators; a Python task’s source), per task it waits for, that task’s output file when the flow received it, else its fingerprint, and its outside state when it declares one; resume skips a key whose last journal row is ok with the same fingerprint, but not a task declared rerun_on_resume, nor one whose last result was partial or that waits for one |
Task.fingerprint, journal fingerprint; AgentTask.digest, PythonTask.digest |
| outside state | what a task’s work depends on beside its params, its definition and the outputs it reads (a state file the pipeline keeps, files another process wrote), as the JSON value a function of its unit and params returns; called when the task is about to start, its value’s digest is part of the task’s fingerprint, so a resume runs the task again when it changed; a function that raises refuses the task | agent_task(outside_state=), @python_task(outside_state=), OutsideState, Task.outside; journal outside |
| rerun | a task a resume runs again although an earlier attempt of the run finished it, and why: its outside state or another part of its fingerprint changed, its last result was partial, it waits for a task that runs again for that, or its kind is declared rerun_on_resume |
journal rerun, monitor PlanNode.rerun; rerun_reason |
Definition
Section titled “Definition”| Word | Means | In code |
|---|---|---|
| interface | what an agent task takes, produces and may spend | agent_task(params=, output=, max_turns=, ...) |
| implementation | how an agent task is done: a plugin directory, with the skills of the skill plugins it names. One declaration may name several by name, each a kind of its own | agent_task(plugin=), agent_task(implementations=), Plugin |
| base kind | the kind a declaration of several implementations names (review); each implementation is the kind <base kind>-<name> (review-go), takes the base kind’s task table below its own, and is drawn in the base kind’s group; no other declaration may have the base kind or an implementation kind as its kind |
agent_task(implementations=), Implementations, kind_clash, AgentTask.base_kind, Task.base_kind; plan.jsonl and definition base_kind |
| skill plugin | a plugin that holds skills and nothing else that acts; tasks with different plugins load it to share its skills | agent_task(skills_from=), Plugin.skills_only |
| role | a named agent definition in a plugin: its procedure | agents/<role>.md, Launch.role, Claude Code’s --agent |
| instructions | text before the call protocol, for an agent task with no plugin | agent_task(instructions=) |
| hook | a hook inside the coding agent, declared by a plugin; nothing else | hooks.toml, contraagent plugin render |
| MCP servers | the MCP servers an agent task’s coding agent gets: its plugin’s .mcp.json, or what the pipeline’s function returns for the task; never the user’s or the project’s |
.mcp.json, Pipeline(mcp_servers=), McpServers, Launch.mcp_config |
| call file | the params and output contract handed to one agent task | CallFile, runs/<run>/calls/<key>.json |
| changes | the files one attempt created, modified or deleted under the patterns its task declares (but those a ! pattern leaves out), beside its output; the files a failed attempt created are removed, or kept when its kind keeps them |
agent_task(changes=, keep_failed_changes=), TaskAdapter.changes; Changes: TaskResult.changes, journal changes (removed, kept) |
| final message | the agent’s last message of a launch; an agent task whose output is its final message has it written to its output file and checked there | LaunchResult.result_text; agent_task(output_from="message"), call file output.from, OutputContract.from_message |
| unwrap | taking the JSON document out of a final message that wraps it (a sentence before it, a fence around it): the output is the document, the whole message is kept beside it | agent_task(unwrap=True), OutputContract.unwrap, unwrap_json; <output>.message.txt; LaunchResult.unwrapped |
Checking
Section titled “Checking”| Word | Means | In code |
|---|---|---|
| schema | the pydantic class a file is checked against | agent_task(output=), OutputContract.schema |
| rows / row | an output that is a JSON Lines file, each line one instance of a pydantic model, checked line by line (a line that fails names its number) / one such line, the model’s instance (a row of a log, a journal row, is the same: one JSON object on one line); as a value, a list of the rows in the file’s order: what the flow receives, validators are given and a task it is passed to gets | agent_task(output=Rows[Row]), Rows (a list), RowsFile; call file output.format: "jsonl", json_schema that of one row; monitor ContractSpec.format |
| example | the value an output declares for a stub run, by one rule at every part of its JSON Schema: the first entry of that part’s examples (a model’s own, model_config = ConfigDict(json_schema_extra={"examples": [...]}); a field’s, Field(examples=[...]); a text output’s, Annotated[str, Field(examples=[...])]), else the smallest value that part accepts; in each of its strings, {unit}, {key}, {kind} and {params.<name>} are the task call’s, as in a claim; it must pass its own schema. The example of rows is one row, its model’s |
writes_example, contraagent run --stub; contraagent check reports one that fails its schema |
| validator | a check a file must pass beyond its schema; it may also take, by keyword, the task’s params, its call file, its cwd, and before (the file as it was before the task) |
agent_task(validators=), CommandValidator, any (path, value) -> errors; CONTEXT |
| contract | a file plus its schema and validators | OutputContract, InputContract |
| preserve | the parts of an output file a launch must keep as they were before it: JSON pointers (RFC 6901, a segment * for every member), each value they select in the file before the launch equal in it after |
agent_task(preserve=), OutputContract.preserve; call file output.preserve |
| output of | the output file of another kind’s task for the same unit, which an agent task writes in place of a file of its own; the task waits for the latest task created before it that writes that file | agent_task(output_of=), AgentTask.output_of; definition output_of |
| check | what can be found wrong with a flow without a launch | Pipeline.check, CheckReport, contraagent check |
| reachable kind | a kind whose task declaration a generator flow’s code refers to, directly or through the functions, modules, closures, containers, classes of flow code (their methods, static and class methods, properties, bases) and instances of them it refers to; checked, routed and probed before the first launch. A candidate, not a use: of two declarations of one kind, the one whose tasks are created is the kind’s | reachable, CheckReport.later_kinds |
| stub agent | a coding agent that plays scripted replies instead of an LLM, for tests | contraagent.testing.StubAgent |
| stub run | a run in which no coding agent is launched: the stub agent plays its tasks (agent tasks, and Python tasks but the kinds it executes: names or fnmatch patterns, * for every one), or a replay plays its tasks’ recordings (but the Python task kinds it executes); flow code runs as in any run |
Pipeline(stub=), StubAgent(default=, execute=), writes_example, contraagent run --stub --execute PATTERN; run.json stub |
| recording | what one task attempt left behind, kept to be played again: for an agent task, the facts of its last launch, the final contents of its outputs, the files its changes patterns saw created, modified and deleted, and its transcript; for a Python task, how its call ended and its output; and its task’s fingerprint; never the rest of the working directory. A file over the cap is kept by its hash and size only, and its task’s recording cannot be played |
Pipeline(record=, record_max_file_mb=), contraagent run --record DIR --record-max-file-mb N; <DIR>/<kind>/<key>.json (by_hash); Recorder |
| replay | a run whose tasks play their recordings in place of a launch or of a Python task’s function, attempt by attempt, with nothing spent; the Python task kinds it executes (execute, as in a stub run) run their functions. A replay is a stub run: its run.json says stub; with record_missing, a task with no recording launches or runs as in any run and is recorded into the same directory, and the run is no stub run |
Pipeline(replay=, execute=, record_missing=), contraagent run --replay DIR --execute PATTERN --record-missing; Replay, ReplayAgent; run.json replay; a played attempt: TaskResult.replayed, JournalRow.replayed |
| imported recording | a recording made from the run directory of a run that was not recorded: for each task whose last attempt finished ok or partial, one attempt with its output files and changed files as they are now, the facts the journal and the launches recorded, and the fingerprint its journal row holds; a replay plays it only for a task of its own key and that fingerprint, and the import lists the tasks it leaves out | contraagent.import_recording(run_dir, directory), RecordingImport (imported, unfinished, not_imported), contraagent recording import RUN_DIR DIR; the entry’s imported (run, run_uid, imported_at) |
| undeclared change | a path of the working directory a recording run created, modified or deleted that no task’s outputs or changes= patterns cover (.git, __pycache__, the recordings and the run’s own files left out): a replay cannot make it again. Tasks run at once, so it is the run’s, not a task’s |
<DIR>/undeclared.json (run, created, modified, deleted); the warning [record] undeclared change: <path>; Recorder.start, Recorder.finish |
Routing
Section titled “Routing”| Word | Means | In code |
|---|---|---|
| task table | one kind’s [tasks.<kind>] table in the config; an implementation kind’s starts from its base kind’s |
PipelineConfig.task_tables(), resolved_task_tables, TASK_TABLE_KEYS |
| pipeline table | a pipeline’s own table in the config, read by its code; contraagent never checks its keys | [pipeline.<name>]; contraagent.pipeline_table(name) in a run or in flow code a check builds (NoCurrentRun outside both), PipelineConfig.table(name) |
[defaults] |
run-wide routing, including [[defaults.fallbacks]] |
PipelineConfig.defaults(), .fallbacks() |
| routing plan | how each kind is routed (not plan.jsonl) |
RoutingPlan |
KindConfig |
one kind’s resolved routing and budgets | RoutingPlan.configs |
| route | one entry of a kind’s failover chain: a coding agent, a model and a credential, labeled by its place in the chain (hop 2/3 omp/m2) |
Route, Router; journal route (the last hop’s) |
| hop | one launch of an attempt on one route; an attempt that fails over has one hop per route it launched on | Hop: TaskResult.hops, journal hops |
| budget | the turn, time, cost, context and stall caps of a launch | max_turns, timeout_s, context_budget, …; Limits, Launch.limits |
| credential | the identity (and so the account) an agent’s API calls are billed to | [credentials.<name>], Credential (each kind of credential a subclass), Launch.credential; for one task, its call’s credential= (Task.credential, plan credential) |
| trait | a label on a credential that a task may require (zdr) |
traits, agent_task(requires=) |
| pool / gateway | several credentials used as one / your own endpoint (LiteLLM, a proxy) | Pool, Gateway |
| ambient | the built-in credential: the host’s own setup, untouched | AMBIENT |
| quota | a subscription’s utilization of its 5-hour and weekly windows (and a model’s own windows), as the coding agent reports it: account-wide. One reading is a QuotaReading, one window of it a QuotaWindow; the two windows a quota cap names are five_hour and seven_day, each with its words and length in one table |
QuotaReading, QuotaWindow, WINDOWS; LaunchResult.quota, journal quota, Backend.usage_reading |
| quota refusal | a launch refused for its quota (a 429), with the cool-off the provider stated; not a reading | QuotaRefusal (retry_after_s), LaunchResult.quota_refusal, quota_refusal; stop rate_limited |
| account | the billing account a quota reading is of, as a 12-hex-digit digest of its login’s UUID or of the credential’s secret, never the value itself; one credential can stand for two (ambient on two coding agents, a token replaced between runs), and a credential’s rests are judged by the readings of the account a launch as it bills |
QuotaReading.account, Backend.account, account_digest |
| quota cap / quota rule | the utilization past which a credential rests / a domain’s own test of a credential’s latest quota reading | max_five_hour_pct, max_seven_day_pct, QuotaCap (run.json quota_caps, monitor Plan.quota_caps) / Pipeline(quota_rule=) |
| rest | not launched on for a time: a hop or a pool member after a 429, a credential past a quota cap or rule until its window resets; a task takes the next hop; with none left it ends rate_limited after 429s, and is deferred (never launched) when its credentials rest on their quota. A quota rest is recorded as data (Rest: window, reading, cap, or what the rule said, and until when) as it begins and ends |
Router, CredentialPool, QuotaRests, Rest; rests.jsonl (RestEvent); monitor Plan.rests (CredentialRest) |
| preflight / preflight policy | one probe of each distinct route of the reachable kinds before the first launch: a route its coding agent does not list, or whose probe does not complete, is dropped / what happens to a kind with no route left: substitute (it runs on the first route that answered, of its own credential), stop (the run is refused, nothing launches), off (no probe) |
Pipeline(preflight=), [defaults] preflight, contraagent run --preflight, PreflightStopped; run.json preflight and Plan.preflight (PreflightRecord: DroppedRoute, Substitution, KeptKind) |
| skipped hop | a hop an attempt passed over without a launch because its credential rested on its quota; not one of the attempt’s hops, which are launches | SkippedHop: TaskResult.skipped_hops, journal skipped_hops, a deferral’s cause rests |
Running
Section titled “Running”| Word | Means | In code |
|---|---|---|
| engine | the parts underneath Pipeline that run tasks on their own: the runners, the queue, the flow driver, a run’s directory and cursor, the routing |
contraagent.engine (Run, AgentRunner, RetryingRunner, PythonTaskRunner, TaskAdapter, WorkQueue, FlowDriver, CursorStore, RoutingPlan, Router, run_until_valid); RunnerConfig: what WorkQueue reads of a task’s config (max_concurrent) |
| launch | one run of a coding agent, and its result | Launch, Backend.run, LaunchResult |
| light launch | the launch of an agent task declared with no tools: its role’s text (or its instructions) replaces the coding agent’s system prompt, its params and output schema are in the prompt, no plugin, settings or MCP server is loaded, and its final message is its output | agent_task(tools=()), AgentTask.light, KindConfig.light, Backend.light_launch |
| tokens | what API calls took and gave: input, output, cache read, cache write, and the calls; a launch’s calls one by one, and summed over a launch, a hop or an attempt | per call CallUsage, a launch’s calls Usage; summed TokenUsage (Usage.totals(), Hop.usage, JournalRow.usage); per model ModelUsage |
| resident | the whole input of an attempt’s first API call: what the coding agent loads before the task starts | TokenUsage.resident, Usage.resident |
| peak context | the whole input (fresh input, cache read and cache write) of a launch’s largest API call; of an attempt, the largest of its hops’ and rounds’. context_budget stops a launch whose peak context passes it; context_warn_pct warns past that % of it and stops nothing |
LaunchResult.peak_context, Usage.peak_context, TokenUsage.peak_context, ModelUsage.peak_context; JournalRow.context_budget, JournalRow.context_warned; a queue note with context_warned |
| context window | the most input one API call of a model takes, as the coding agent reports it for the model a launch ran on, in its stream or its model catalogue (never inferred from the model’s name); of an attempt, the window of the model its peak context was on. context_pct is the peak context as a percent of it |
LaunchResult.context_window, LaunchResult.context_pct, TokenUsage.context_window, ModelUsage.context_window |
| other model | a model a launch called besides the one it ran on (Claude Code summarizes a fetched page on a smaller model): its cost is in the launch’s, its tokens are not in the launch’s usage, and the models’ spend counts it apart |
OtherModel: LaunchResult.other_models, Hop.other_models |
| round | one launch within a session: the first, or a resume after contract errors; an attempt’s cost counts each round once | rounds, round_costs |
| correction round | a round after the first: the same session resumed with the errors of the output’s checks; the monitor shows it as a “correction”. A kind allows max_corrections of them (3 unless set), then its task ends invalid_output |
agent_task(max_corrections=), [tasks.<kind>] max_corrections, KindConfig.max_corrections, run_until_valid(max_corrections=); TaskResult.rounds, TaskResult.max_corrections, TaskResult.round_errors; journal rounds (each round after the first is one), max_corrections, round_errors; StubLaunch.resumed |
| attempt | one try of a task, numbered from 0: an agent task’s in a fresh session, a Python task’s a call of its function | RetryingRunner, PythonTaskRunner, Task.attempt, journal rows |
| partial | a task’s result whose output is only part of the work: a Python task’s placeholder, returned when a server it needs is unavailable, or what an agent task wrote before the runner stopped its launch for one of its partial_on stops (timeout, stalled), when it was written by the attempt and passes every check; ok, so the flow receives its value and later tasks run on it, and stop partial, so a resume runs it again with the tasks that wait for it; its reason says why (an agent task’s: the launch’s stop); counted apart from passed and failed |
Partial(value, reason=), agent_task(partial_on=), [tasks.<kind>] partial_on, STOP_PARTIAL, RunReport.partial; journal stop: "partial"; monitor plan state partial, TaskCounts.partial, TrendKind.tasks_partial, partial beside ok |
| retries | the fresh attempts a task may make after its first: an agent task’s after one that made no progress, a Python task’s after an exception of a class in its retry_on |
KindConfig.retries; @python_task(retries=, retry_on=), PythonTask.retries, PythonTask.retry_on |
| result | a task’s final result / what Pipeline.run returns |
TaskResult / RunReport |
| run / run group | one runs/<id>/ directory, named by its run id, which is a file name on every operating system / a label grouping runs |
contraagent.engine.Run, Run(run_group=) |
| run format | the version of a run directory’s layout and records, a whole number its run.json records: a release writes one and reads the formats it lists; a run.json without one is of run format 1. Each record has a JSON Schema of its run format |
run.json format; FORMAT, FORMATS, format_of; RunFormatError; contraagent/docs/schemas/*.schema.json, RunInfo, LaunchRow |
| run uid / host id | the id no other run has, on any host, kept when the run is resumed / the host that drives the run | run.json run_uid / host_id (CONTRAAGENT_HOST_ID, else the host name) |
| run records / layout / layout name | what a run writes in its directory apart from its outputs (logs and documents) / the name of each record, written down once / a record’s name relative to the run directory (journal.jsonl, streams/<file>.stream.jsonl) |
the run records layer, layout |
| log / document | a run record of JSON lines, appended whole and never rewritten, read by its complete lines only (a last line without its newline is still being written) / a run record of one JSON value, replaced whole | LOGS, RunSource.logs, RunSource.lines, RunSource.lines_at (from a LogPosition), append_lines, read_lines, parse_rows / RunSource.documents, RunSource.document, write_document |
| run source / liveness | where runs’ records are read from, by the monitor, a relay and the trends / which runs are live and their processes | contraagent.monitor.RunSource (public: DirectorySource; implementation: MemorySource, HubSource) / contraagent.monitor.Liveness (implementation: ProcLiveness, StaticLiveness, HeartbeatLiveness), a snapshot’s shape Liveness.snapshot |
| telemetry line | the first line of an agent task’s prompt, naming its run, kind, unit, key and role; the monitor reads a live process’s role from it | telemetry.line, telemetry.parse, TELEMETRY run=... role=... |
| hub / relay | the server that holds every host’s runs and serves their monitor / the process on a host that ships its runs to a hub (never “agent”, which is the coding agent); a run on a hub is named <run_id>@<host_id> |
contraagent hub, Hub, HubStore, RunRef / contraagent relay, HubClient |
| heartbeat | a relay’s report that its host is up, with its runs’ live processes; a host’s runs are live while its heartbeats keep arriving | Heartbeat; its runs’ liveness: HeartbeatLiveness |
| blob | a file’s content on a hub, named by its SHA-256 | BlobStore |
| segment / open segment | a sealed part of a transcript on a hub: one object of zstd frames with an index of their first lines / the part still being written, a file on the hub’s disk | SegmentedStreamLogs, segment_format, SegmentIndex; --segments / --streams-dir |
| held / durable | the lines of a log a hub holds / those of them that survive the loss of the hub’s disk (sealed segments, the database) | Held, Accepted.logs / Accepted.durable |
| retention / prune | how long a hub keeps a run after its last activity / removing what is older, with everything the hub holds of it | contraagent hub --retain-days, Hub.prune, PruneReport, contraagent hub prune |
| grace period | how long an unreferenced blob is kept before a prune removes it (it may be on its way) | Hub.prune(blob_grace=) |
| active transcript | a transcript whose task is running or whose file grew in the last seconds; a relay ships it between its full passes | Relay.fast_once |
| journal / plan | the finished attempts / the queued tasks | journal.jsonl (JournalRow) / plan.jsonl (PlanRow; monitor PlanNode) |
| wire | what a coding agent prints about a launch as it runs, one event per line: its reader folds it into the launch’s result (unread event: a type the reader does not know), and the monitor renders it through its stream format |
each backend’s wire reader, EventFold, KNOWN_EVENTS, Backend.wire |
| stop | how one launch ended, exactly one, weighed from what its wire said in one order for every coding agent: a limit it was ended on, quota, refused credential, safety refusal, abort, the agent’s own cap, another API error, the agent done, a nonzero exit with no answer, nothing seen, no answer | Stop, LaunchResult.stop; Signals (how an agent words a refusal), classify_stop; journal stop |
| model catalogue | the models a coding agent lists, each with the context window it lists for it; read once per backend | Backend.models, Backend.read_models |
| unread event | an event type a coding agent sent that its reader in this contraagent does not know: a newer coding agent | LaunchResult.unread_events, JournalRow.unread_events |
| web fetch | the coding agent reading a web page by its URL (Claude Code WebFetch, omp read of a URL, opencode webfetch, Codex web_search opening a page) |
a transcript’s tool call web_fetch |
| web search | a search of the web by the coding agent’s own tool (Claude Code WebSearch, omp web_search, opencode websearch, Codex web_search); its query is recorded |
LaunchResult.web_queries, JournalRow.web_queries; a transcript’s tool call web_query |
| tail | the expected wall time of the work a flow creates after a task, not queued when the task is: the median, over tasks with the same flow path’s function names, kind and loop passes (capped) in recent runs and in this one, of the longest complete chain of wall times after them along after and created from |
Task.tail_s, JournalEstimates.tail, TailKey |
| bottom level | a queued task’s estimate plus the longer of its known dependents’ path and its tail: what the queue orders by first, highest first | WorkQueue._blevel |
| priority | a number a task call gives (default 0) that breaks ties in the queue’s order, highest first: between tasks the bottom level, overdue waiting and a time box’s endgame leave equal; not part of the fingerprint | summarize(unit, priority=), Task.priority; plan priority |
| slot | a place for one running task, of which the queue has max_concurrent: every running task takes one, an agent task or a Python task alike; two rate-limited ends in a row halve them for throttle_s |
Pipeline(max_concurrent=), WorkQueue(max_concurrent=), WorkQueue.slots(); run.json max_workers; monitor Procs.max_workers |
| overdue | a queued task startable for longer than overdue_s: it goes before the others, and while it is the first that cannot start, no later task takes the last place it needs on a name it claims or under its kind’s cap (the starvation guard) |
WorkQueue(overdue_s=) |
| slack | the time before the deadline from which the queue orders for the deadline: shortest remaining work first, deferring what cannot finish | WorkQueue(slack_s=) |
| time box | a deadline over part of a run: the run’s own (deadline_s), or a flow call’s, counted from its start, over the tasks it and the flow calls it starts create; past it only its finishing kinds launch, for its grace window; a task is held to every time box it is in |
time_box(flow, deadline_s=, grace_s=, finishing_kinds=, slack_s=), TimeBox, Task.time_boxes; as recorded, with when its flow call started: TimeBoxRecord (flow_calls.jsonl and monitor FlowCallNode.time_box); a deferral’s cause flow_call |
| stream file | the raw transcript of a task’s launches | streams/<file>.stream.jsonl (stream(key)); keep_transcripts |
| stream format | how a stream file is parsed (claude, omp, opencode, pi, codex) |
normalize_stream_line(format, ...) |
| stage | a run phase | cursor stage |
TaskScope |
a function of a task that returns the context manager around one attempt of it: every hop of an agent task; the input check, the call and the output check of a Python task | Pipeline(scopes=), AgentRunner(scopes=), PythonTaskRunner(scopes=) |
ResultEnricher |
what sees a task, agent or Python, before one attempt and its result after, and may return it with a payload added or its verdict (ok, stop) changed; the task and the result it is given are frozen |
Pipeline(enrichers=), AgentRunner(enrichers=), PythonTaskRunner(enrichers=) |
| pipeline log / pipeline document | a pipeline’s own file in its run, written by its flow code and its Python tasks, shipped to a hub and read by panels: rows appended one per line / one JSON value, replaced whole | contraagent.log(name, row) / contraagent.save(name, value); runs/<id>/pipeline/<name>.jsonl / <name>.json; outside a run NoCurrentRun; read with RunRecords.log / .document |
| row extras | a pipeline’s own columns of a journal row, named by the pipeline: what row_extras(result) adds |
Pipeline(row_extras=), Run(row_extras=); monitor RunSummary.row_extras, TaskDetail.row_extras |
The runners: AgentRunner (one agent task, with failover), RetryingRunner,
PythonTaskRunner. Queue callbacks: on_event, on_result, follow_up.
A task not launched by the deadline (of a time box it is in), whose remaining
work cannot finish before it, with every hop on a resting credential, or whose input is the
output of a deferred task, finishes deferred: not launched, nothing spent, and no failure
(RunReport.deferred, never RunReport.failed). deferred.jsonl records why (DeferredRow): a
Deferral, its reason in one line and its cause as data (DeferralCause: deadline,
grace_window, cannot_finish, each with the flow_call whose time box it was,
dependency_not_queued, dependency_deferred with the dependency it reads, rest;
AgentRunner.deferral, Graph.input_deferral); a follow-up task the
queue refuses because its key is in flight finishes duplicate_key. A task a
flow waited for that did not succeed raises TaskFailed at the yield
(TaskDeferred when it was deferred). A text output a flow receives is a
TextOutput, a str.
The Python API
Section titled “The Python API”| Word | Means | In code |
|---|---|---|
| deprecated name | a public name that a later major release removes or renames, still read in its public module until then (from 1.0, for at least two minor releases: compatibility): a moved name warns and gives the object from its new home, a removed name raises AttributeError saying what to use instead |
ContraagentDeprecationWarning; a public module’s __getattr__ = migration(...) |
The monitor
Section titled “The monitor”| Word | Means | In code |
|---|---|---|
| group | a column of the plan: the kinds Monitor(groups=) lists together, the implementation kinds of a base kind it does not list, or one kind |
Monitor(groups=), PlanGroup |
| period | days from..to, both included, in a time zone, over which runs are summed |
contraagent.monitor.Period; /api/trends?from=&to=&tz=; its runs as a trends panel reads them: PeriodRuns (RunRecords for each) |
| trends | what the runs of a period add up to, day by day: cost by kind (or group), each kind’s tasks, success and time, each model’s spend, failures, refused tool calls, utilization, rests, deferrals, run starts; read from each run’s digest, kept in a finished run’s trends.json (RunSource.kept, RunSource.keep) |
Monitor.trends, /api/trends, Trends; Panel(scope="trends") |
| function drawn open | a function node of the pipeline graph drawn as a box holding its own layer, in the layer shown; a chain of functions, each the only function in the layer of the one before, is one box named by its path | FlowBox, compound (@contraagent/ui/adapters), cluster id fx::<place> |
| place | where a function node is across every layer: its layer and its id there | placeKey, <layer>/<id> |
| outline | the pipeline graph’s list of every function of the flow and the loops they are in, as a tree | outlineTree, nav.outline |
| tab | one top-level view (overview, journal, …, panel:<name>); on the Trends page, the trends with the trends panels of no tab, or the trends panels of one tab |
Tab, view route tab; Panel.tab, PanelInfo.tab, view route trendsTab (?page=trends&tab=) |
| panel / panel body | a view a pipeline adds to the monitor: computed per run (scope="run", fn(run) with the run’s RunRecords, a tab of each run) or over the runs of a period (scope="trends", fn(runs, period)) / what it returns: a typed body (tiles, table, columns, lines, heatmap, status_grid, hbars, note, code, tree, blocks of them) the monitor draws, or any other JSON object, shown as a JSON tree |
contraagent.monitor.Panel; contraagent.monitor.PanelBody, PANEL_TYPES; contraagent monitor --panels |
| status grid / note | a panel body of a state per row and column, each named by its label and coloured by its tone (a heatmap is a number per cell, in shades of one colour) / a panel body of text beside the figures, markdown shown escaped |
contraagent.monitor.StatusGridBody, GridCell; contraagent.monitor.NoteBody; the element cae-state-grid |
| code / tree | a panel body of a text shown as code: highlighted by its language, with line numbers, some lines highlighted / a panel body of nodes the reader folds and opens (files and directories), each node holding the code shown beside the tree while it is selected, or a link | contraagent.monitor.CodeBody, LANGUAGES, CODE_LINES; contraagent.monitor.TreeBody, TreeNode, TreeLink; the elements cae-code, cae-tree |
| anchor | the name of a body of a panel, which a tree node’s link leads to | each panel body’s anchor, TreeLink.anchor |
| task view | what the stream tab shows of a task: transcript, input, output, definition |
TaskView, view route view |
| view route | where the reader is in the monitor, kept in the URL (or in the element, with history="memory") |
ViewRoute, ViewRoutePatch, ViewRouter in @contraagent/ui |
| element | a web component: ca-* in @contraagent/ui, cae-* in @contraagent/elements |
CaMonitor, CaTranscript, CaeSegmented, … |
| tone | the status colour a value takes: failed, attention, done, running, muted, neutral | PanelTile.tone and each panel body’s tone, a table row’s _tone; data-tone |
| selection | what is selected: in the pipeline graph’s layer, a node, a loop box or a mark; in a tree body, a node | view route sel, markSel, parseSelection; TreeBody.selected |
| inspector | the card beside the selection in the pipeline graph’s frame (a sheet under the frame on a narrow screen) that shows its facts and where it leads | ca-pipeline-graph (its content), the inspector slot of cae-layered-graph |
| cluster | a box of nodes in a layered graph; a loop box is one | GraphClusterInput, .cluster |
| edge path | the slots a drawn edge passes in a layered graph, from its source to its target: a point on every layer it crosses (not a route) | EdgePath, EdgePathStep, Arrangement.edgePaths in @contraagent/elements |
| series | the id that lines marks up across a layered graph’s nodes; the pipeline graph’s units | GraphInput.series |
| adapter | a function in @contraagent/ui/adapters that turns run data into a generic element’s model |
graphFromPlan, matrixFromPlan, kpiTiles, … |
| wrapper | a ca-* element that feeds a cae-* element through an adapter and turns its cae-* events into ca-* events |
ca-pipeline-graph, ca-kpis, … |
| run start | one start of a run over its directory: the first, or a resume; a task numbers its attempts from 0 in each | run.json started_at (the latest), runStarts |
| view | one thing the monitor answers about a run, by name: the JSON at /api/runs/<run>/<name>, the run feed’s <name> event when its value changes, and an export’s runs/<run>/<name>.json |
VIEWS (View), serialize |
| endpoint | one method and path of an HTTP API: the monitor’s (GET /api/runs, /api/runs/{run}/journal, as its OpenAPI document lists them), the hub’s ingest (POST /ingest/records, …), a coding agent’s provider’s usage endpoint (GET <base>/v1/usage) (not a route) |
server.create_app, createMonitorClient (a method per GET endpoint), contraagent hub --openapi; an export holds a file per GET endpoint |
| base path | the path a reverse proxy serves the monitor under (/monitor), which the proxy takes off before it passes a request on; the page the monitor serves names it in every URL it reads |
contraagent monitor --base-path, contraagent hub --base-path, create_app(base_path=), serve(base_path=); <ca-monitor base-url="/monitor"> |
| export | the monitor’s views of some runs written as files (the page and the JSON the API answers for each view), read with no server; it holds no transcripts and no processes, and this machine’s paths and name are taken out | contraagent monitor export, contraagent.monitor.export (ExportReport), SiteExportFile (a file of no run); Info.export (ExportInfo); createExportClient, openExportFeed, <ca-monitor export="data/"> |
The monitor’s screens show some of these in the words of engineers who use
coding agents (a correction round is a “correction”, a task’s
Outcome its “status”); the words above stay in its tooltips.