Agent ABC + its neutral streamed-event vocabulary.
Re-exports the Agent interface (and its PresetSpec / SubAgentSpec
inputs and AgentInterruptedError error) alongside the StreamEvent types an
agent’s astream yields and run drains.
Agent
tai42_contract.agent.base.Agent
run; override astream only when the agent produces real per-step
events.
Subclasses declare three class attributes that drive auto-tool generation:
tool_name— the registered name (also the auto-generated tool name);tool_description— the LLM-facing description (carried, not lost);ToolInput— a JSON-able pydantic model of the tool params. Livetools=is deliberately NOT inToolInput(API-only viaastream); a non-JSON field fails loudly atmodel_json_schema()time.
spec_runnable is a capability marker (default False):
spec_runnable = True declares that this agent’s ToolInput advertises
EXACTLY the composable fields its runtime honors — no more, no less. This lets
a generic UI gate authoring controls on the input schema’s fields: it renders a
control only for an advertised (honored) field, and baking an un-advertised
field is rejected at author time. The declaration is the implementation’s — it
is never inferred, and no agent name is ever hardcoded. Because every
ToolInput field of a spec_runnable agent is honored, all of them are
preset-bakeable; preset_bakeable_fields covers the other case.
preset_bakeable_fields names the ToolInput fields whose baked
(preset fixed_kwargs) value the runtime honors on an agent that is NOT
UI-composable — declaring a field here implies no UI control at all, only that
a hidden baked value is passed through and acted on. A field is preset-bakeable
iff the agent is spec_runnable (all fields, above) OR the field is listed
here. Like spec_runnable it is the implementation’s own declaration, never
inferred; every listed name must be a real ToolInput field. The empty
default means nothing is bakeable unless the agent is spec_runnable.
Attributes
Members
from_tool_input
tai42_contract.agent.base.Agent.from_tool_input
ToolInput instance to run kwargs.
Passes through every set field with nested pydantic values (presets,
subagents, inline_skills) kept as model instances, since run
and the resolvers it calls read them by attribute. model_dump is
deliberately NOT used — it would flatten those nested models to dicts.
Agents whose JSON tool-face shape differs from their run signature
override this.
Any error an override raises must be a constant, hand-authored message and
must NOT interpolate input values: the agent run routes surface these
messages verbatim to the caller, and the baked input can carry credentials
the caller is not entitled to see.
Parameters
run
tai42_contract.agent.base.Agent.run
tools/tool_names/presets) are uniform only for
tools-agent-shaped agents; role-specific agents (voting/vqa/refine) read
their own params off **kwargs. response_format is
typed Any because the deep path passes a JSON-Schema dict while
the tools-agent path passes a pydantic class. resume_checkpoint_id
forks past an aborted turn, distinct from resume (the interrupt
answer).
Parameters
astream
tai42_contract.agent.base.Agent.astream
str becomes a
MessageFinal (plain-text answer), any other value a
StructuredFinal (the structured response_format object).
Streaming agents override this with the real per-step projection and
implement run by draining their own astream via
_drain.
Parameters
append_thread_messages
tai42_contract.agent.base.Agent.append_thread_messages
messages to thread_id’s stored history WITHOUT running the agent.
Each item is {"role": "user"|"assistant", "content": str}. The conversation
bridge calls this to record a manual-mode inbound and an operator’s outbound reply
into the thread’s memory, so a later agent turn reads them as prior context. An
agent with no thread memory raises NotImplementedError.
Parameters
AgentInterruptedError
tai42_contract.agent.base.AgentInterruptedError
run/_drain when a non-streaming caller drains a run that paused on an interrupt.
A non-streaming caller cannot act on an interrupt, so it surfaces loudly rather than
returning a partial. interrupts is the list of InterruptFinal events the run
emitted.
Attributes
AsksFinal
tai42_contract.agent.events.AsksFinal
to="caller" ask is addressed to the run’s own caller — here the SSE client driving the
stream — so the run cannot proceed until the caller answers it, unlike a to="user" park
(SuspendedFinal) whose answer arrives out of band. asks carries the full parked
entries the caller must answer (id, question, answer format, and the rest of the parked-entry
shape); the vocabulary is generic — it names no driver, engine, or resume state.
Attributes
InterruptFinal
tai42_contract.agent.events.InterruptFinal
interrupt_id is the graph interrupt id (echoed back when resuming);
payload is the interrupt value the agent raised (e.g. the option set);
reason is an optional human-facing label. This event is emitted verbatim
as one SSE frame (type: "interrupt_final"); a consumer reads
interrupt_id, payload and reason off it — do NOT rename payload
or drop reason.
Attributes
MessageDelta
tai42_contract.agent.events.MessageDelta
MessageFinal
tai42_contract.agent.events.MessageFinal
PresetSpec
tai42_contract.agent.base.PresetSpec
StructuredTool at run time.
See resolve_tools. A base tool that interprets its fixed kwargs as a nested document
carries that document opaquely here.
Attributes
ReasoningStep
tai42_contract.agent.events.ReasoningStep
RunUsage
tai42_contract.agent.events.RunUsage
None.
Attributes
StreamEvent
tai42_contract.agent.events.StreamEvent
Agent streams.
type is a stable discriminator; final marks a terminal event (see the terminal
rule in Agent._drain).
Attributes
StructuredFinal
tai42_contract.agent.events.StructuredFinal
data is the object the agent produced — typically the validated response_format
instance. A plain-text answer is carried by MessageFinal instead. Terminal.
Attributes
SubAgentSpec
tai42_contract.agent.base.SubAgentSpec
inline_skills items are plain dicts
({"name", "content"}). JSON callers use the richer DeepSubAgentSpec
(full field set) instead of this type.
tools is list[Any] in the contract (live StructuredTool objects in
the impl) — a vendor type cannot be a runtime pydantic field here.
response_format is a live pydantic class (in-process), the TemplatedText | dict
authored-schema union (a JSON caller’s forced-output schema — inline, or named by stored
id and rendered/parsed to its schema at the point of use), or unset.
Attributes
SuspendedFinal
tai42_contract.agent.events.SuspendedFinal
ask questions and will resume out
of band when their answers (or expiries) arrive — it did NOT fail and did NOT
stop for a live decision, so a non-streaming drain returns a suspended RECEIPT
for it rather than raising AgentInterruptedError.
interaction_ids are the parked questions the resume converges on;
caller_interaction_ids is the subset of them addressed to the CALLER
(to="caller"), empty for a park of only user asks — the two id lists let the
platform’s visit normalise a caller-ask park inside an agent into its
caller/user partition; expiry_at is the earliest park deadline (ISO-8601, or
None when no park carried one); thread_id is the parked run’s thread. The
vocabulary is generic — it names no driver, engine, or resume state, only the parked
interaction ids the flow-blind platform already holds.
Attributes
ToolCallStep
tai42_contract.agent.events.ToolCallStep
call_id is the model-assigned id the matching ToolResultStep carries.
Attributes
ToolResultStep
tai42_contract.agent.events.ToolResultStep
ToolCallStep by call_id.
result is passed through untouched.
Attributes
agent_session_thread
tai42_contract.agent.session_thread.agent_session_thread
thread_id as the ambient session thread for the wrapped block.
The deposit is reset in a finally. A task created inside the block inherits it on a
copy. Absent this wrap the deposit stays None and a run mints its own fresh thread.
Parameters
final_event_for_value
tai42_contract.agent.events.final_event_for_value
str is a plain-text answer (MessageFinal); any other value is structured output
(StructuredFinal, its data). The single rule both the non-streaming astream
default and a resumed run’s plain terminal map a raw value through, so every path surfaces the
same final shape.
Parameters
get_agent_session_thread
tai42_contract.agent.session_thread.get_agent_session_thread
None when none is set.
reset_agent_session_thread
tai42_contract.agent.session_thread.reset_agent_session_thread
token.
token is the return value of the matching set_agent_session_thread call.
Parameters
set_agent_session_thread
tai42_contract.agent.session_thread.set_agent_session_thread
thread_id as the current run’s session thread.
Pass the returned token to reset_agent_session_thread to restore the previous value.
Parameters

