spakky-agent¶
spakky-agent는 Agent workflow를 Spakky 컴포넌트로 모델링하기 위한 계약, 도구, 상태, signal, evidence 타입을 제공합니다.
Agentic Hexagonal Architecture의 core 계약입니다.
설치¶
spakky-agent는 @Agent, AgentExecutionSpec, RunAgentInput, AgentRunner,
AgentEvent, AgentYield, tool dispatch, context compaction, state/signal/evidence
repository port, task store, safety/recovery/delegation 타입 같은 public contract를
소유합니다. 이 패키지는 의도적으로 vLLM, SQLAlchemy, FastAPI, Typer, AG-UI, A2A,
MCP를 import하지 않습니다. 운영에서 durable execution을 사용하려면 provider
contribution의 repository 구현이 필요하며, 운영용 in-memory fallback은 제공하지
않습니다.
Public API¶
Agentic hexagonal architecture contracts for Spakky Framework.
Message = Progress
module-attribute
¶
Backward-compatible progress-yield payload alias.
TextDelta = Token
module-attribute
¶
Backward-compatible token-yield payload alias.
PLUGIN_NAME = Plugin(name='spakky-agent')
module-attribute
¶
Plugin identifier for the Spakky Agent package.
AgentCancellationCleanupCallable = Callable[[AgentCancellationRequest], Awaitable[AgentCancellationCleanupResult]]
¶
Async hook shape invoked for model stream/tool/delegate cancellation cleanup.
AgentEvent = MessageDeltaEvent | ReasoningDeltaEvent | ToolCallStartEvent | ToolCallArgsDeltaEvent | ToolCallEndEvent | ToolCallResultEvent | RunStartedEvent | RunPausedEvent | RunFinishedEvent | StepStartedEvent | StepFinishedEvent | StateSnapshotEvent | StateDeltaEvent | ArtifactEvent
¶
Discriminated union of every protocol-neutral agent event.
Each member exposes a distinct kind literal so adapters dispatch with
match/case exhaustiveness rather than runtime attribute probing.
JsonObject = Mapping[str, JsonValue]
¶
JSON object payload used by public agent contracts.
JsonPrimitive = bool | float | int | str | None
¶
Scalar JSON value accepted by agent public contracts.
JsonValue = JsonPrimitive | Mapping[str, JsonValue] | Sequence[JsonValue]
¶
Recursive JSON-compatible value used at model, signal, and evidence boundaries.
AbstractSpakkyAgentError
¶
AgentBootstrapError
¶
AgentDefinitionError
¶
AgentModelConfigurationError
¶
AgentOutputGuardError
¶
AgentPersistenceConfigurationError
¶
AgentToolBindingError
¶
AgentToolDispatchError
¶
AgentToolDispatcher(target, catalog, runtime_context=None)
dataclass
¶
Resolve and invoke a catalog tool from a model tool call.
The dispatcher binds to a single agent instance whose @agent_tool
methods are described by catalog. Catalog descriptors that own no
instance parameter (such as MCP-normalized external tools) are invoked
without the bound target.
descriptor_for(call)
¶
Resolve the catalog descriptor a model tool call targets.
Source code in core/spakky-agent/src/spakky/agent/dispatcher.py
dispatch(call)
async
¶
Bind a model tool call payload and invoke its catalog callable.
Source code in core/spakky-agent/src/spakky/agent/dispatcher.py
ContextDigest(id, context_identity, source_manifest_ref, digest, derived_from_pack_ids=tuple(), compression_evidence_ref=None, algorithm=None, summary=None, created_at=None, metadata=dict())
dataclass
¶
Derived compression evidence for a context identity.
ContextFreshness
¶
Bases: StrEnum
Freshness classification for context rot and budget decisions.
ContextHealthSignal(id, symptom, manifest_ref=None, pack_id=None, evidence_ref=None, score=None, observed_at=None, metadata=dict())
dataclass
¶
Observed context rot signal used to choose optimization actions.
evidence_payload()
¶
Return JSON-compatible signal metadata for append-only evidence.
Source code in core/spakky-agent/src/spakky/agent/context.py
ContextManifest(id, entries, origin_ref=None, evidence_refs=tuple(), created_at=None, metadata=dict())
dataclass
¶
Auditable composition record for model input context packs.
ContextManifestEntry(pack_id, source, role, origin_ref, evidence_ref=None, digest_ref=None, sensitive_fields=(), metadata=dict())
dataclass
¶
One audited pack entry inside a context manifest.
ContextOptimizationAction(id, kind, signal_refs=tuple(), target_pack_ids=tuple(), manifest_ref=None, digest_ref=None, delegation_ref=None, result_evidence_ref=None, reason=None, metadata=dict())
dataclass
¶
Selected optimization action derived from context health signals.
evidence_payload()
¶
Return JSON-compatible action metadata without raw context contents.
Source code in core/spakky-agent/src/spakky/agent/context.py
ContextOptimizationActionKind
¶
Bases: StrEnum
Optimization actions that can be selected from context health signals.
ContextOptimizationEvidenceStage
¶
Bases: StrEnum
Where an optimization action evidence item sits in the agent flow.
ContextPack(id, content, source, role, freshness=ContextFreshness.UNKNOWN, relevance=None, token_budget=ContextTokenBudget(), sensitivity=ContextSensitivity.INTERNAL, sensitive_fields=(), metadata=dict())
dataclass
¶
LLM-facing context unit derived from state, signal, or evidence.
guarded_content(policy=None)
¶
Return deterministic model-safe content for this context pack.
Source code in core/spakky-agent/src/spakky/agent/context.py
message_metadata(policy=None)
¶
Return non-content metadata for provider-neutral model messages.
Source code in core/spakky-agent/src/spakky/agent/context.py
ContextPackRole
¶
Bases: StrEnum
Semantic role of a context pack inside a model request.
ContextRotSymptom
¶
Bases: StrEnum
Typed context rot symptoms observed before model input assembly.
ContextSensitivity
¶
Bases: StrEnum
Deterministic sensitivity metadata carried before model input.
ContextTokenBudget(max_tokens=None, estimated_tokens=None, reserved_output_tokens=None)
dataclass
¶
Token budget allocated to one context pack.
IAgentContextHandler
¶
Bases: ABC
Select context optimization actions from health signals and manifests.
select_optimization_actions(signals, manifest)
abstractmethod
¶
Return optimization actions without mutating raw evidence.
Source code in core/spakky-agent/src/spakky/agent/context.py
AgentCancellationCleanupReport(state_id, signal_id, outcomes=())
dataclass
¶
Aggregate cleanup evidence for one CANCEL signal.
cleanup_succeeded
property
¶
Return whether all cleanup hooks completed without failure.
failed_outcomes
property
¶
Return the hook outcomes that force FAILED terminal state.
__post_init__()
¶
Reject reports that cannot be attached to state and signal evidence.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
to_payload()
¶
Serialize the report for state metadata and evidence payloads.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
to_evidence_candidate(*, summary=None)
¶
Represent cancellation cleanup as append-only evidence.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
AgentCancellationCleanupResult(target_kind, target_ref, status, reason=None, error_code=None, message=None, metadata=dict())
dataclass
¶
Result returned by one cancellation cleanup hook.
failed_cleanup
property
¶
Return whether this hook prevents a clean CANCELLED terminal state.
__post_init__()
¶
Reject outcomes that cannot be correlated with the cleanup target.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
succeeded(*, target_kind, target_ref, reason=None, metadata=None)
classmethod
¶
Record a cleanup hook that released its target.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
failed(*, target_kind, target_ref, error_code, message, metadata=None)
classmethod
¶
Record a cleanup hook that could not release its target.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
skipped(*, target_kind, target_ref, reason, metadata=None)
classmethod
¶
Record a cleanup target that was already inactive or unavailable.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
to_payload()
¶
Serialize this hook outcome into evidence/state metadata.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
AgentCancellationCleanupStatus
¶
Bases: StrEnum
Outcome of one cancellation cleanup hook.
AgentCancellationCleanupTask(target_kind, target_ref, cleanup, metadata=dict())
dataclass
¶
One cleanup hook registered for a running cancellation target.
__post_init__()
¶
Reject hooks that cannot be identified in cleanup evidence.
run(*, state, signal)
async
¶
Invoke the hook and verify that it reports the same target.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
AgentCancellationRequest(state_id, signal_id, target_kind, target_ref, reason=None, requested_by=None, metadata=dict())
dataclass
¶
Cancellation request passed to a model stream, tool, or delegate hook.
__post_init__()
¶
Reject requests that cannot be traced back to state/signal/target.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
from_signal(*, state, signal, target_kind, target_ref, metadata=None)
classmethod
¶
Build a hook request from the durable CANCEL signal payload.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
to_payload()
¶
Serialize the request into append-only evidence metadata.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
AgentCancellationTargetKind
¶
Bases: StrEnum
Running execution target that can receive a cancellation cleanup hook.
AgentEvidence(id, agent_state_id, kind, payload=dict(), summary=None, digest=None, manifest_ref=None, reference=None, sensitive_fields=(), created_at=None)
dataclass
¶
Append-only artifact captured during an agent execution.
AgentEvidenceCandidate(kind, payload=dict(), summary=None, digest=None, manifest_ref=None, reference=None, sensitive_fields=())
dataclass
¶
Append-only evidence candidate before repository id assignment.
tool_result(*, tool_identity, tool_schema_name, result, capture, sensitive_fields=(), exposure_policy=None, summary=None)
classmethod
¶
Create evidence metadata for a captured tool result.
Source code in core/spakky-agent/src/spakky/agent/evidence.py
model_decision(*, model, decision, summary=None)
classmethod
¶
Create evidence metadata for a model decision.
Source code in core/spakky-agent/src/spakky/agent/evidence.py
tool_decision(*, tool_identity, decision, summary=None)
classmethod
¶
Create evidence metadata for a tool-routing decision.
Source code in core/spakky-agent/src/spakky/agent/evidence.py
context_optimization(*, action, stage, signals=(), summary=None)
classmethod
¶
Create before/after evidence for a context optimization action.
Source code in core/spakky-agent/src/spakky/agent/evidence.py
to_evidence(*, evidence_id, agent_state_id, created_at=None)
¶
Assign repository identity while preserving append-only contents.
Source code in core/spakky-agent/src/spakky/agent/evidence.py
AgentEvidenceKind
¶
Bases: StrEnum
Kinds of append-only evidence captured by agent execution.
AgentEventAttribution(agent_id, run_id, conversation_id, parent_run_id=None)
dataclass
¶
Attribution carried by every protocol-neutral agent event.
parent_run_id is None exactly when the run is a delegation-tree root
(ADR-0013 §3 "parent link" / ADR-0009 parent linkage). The remaining ids are
always present so adapters never have to synthesize linkage.
__post_init__()
¶
Reject attribution that cannot identify an agent, run, or conversation.
Source code in core/spakky-agent/src/spakky/agent/event.py
AgentEventKind
¶
Bases: StrEnum
Protocol-neutral event kinds emitted across an agent run.
The lifecycle kinds (RUN_STARTED … ARTIFACT) generalize ADR-0009's
public AgentYield vocabulary and align 1:1 with the streaming events that
AG-UI and A2A adapters must reproduce (ADR-0013 §3).
ArtifactEvent(attribution, artifact_id, content, name=None, metadata=dict())
dataclass
¶
A produced artifact surfaced by an agent run.
MessageDeltaEvent(attribution, message_id, delta, metadata=dict())
dataclass
¶
Incremental assistant message text produced by the model.
ReasoningDeltaEvent(attribution, reasoning_id, delta, metadata=dict())
dataclass
¶
Incremental model reasoning (thinking) text.
RunFinishedEvent(attribution, error=None, metadata=dict())
dataclass
¶
A run has finished executing.
error is None for a successful run and carries a terminal failure
payload otherwise (A2A failed task / AG-UI RUN_ERROR).
RunPausedEvent(attribution, reason, prompt, state_id, approval_id=None, tool_call_id=None, allowed_decisions=(), metadata=dict())
dataclass
¶
A run has paused without terminal success or failure.
The event is intentionally protocol-neutral: it carries core lifecycle reason plus the input prompt/decision envelope adapters need to project their own input-required or auth-required protocol states.
__post_init__()
¶
Reject pause events that cannot be shown or resumed.
Source code in core/spakky-agent/src/spakky/agent/event.py
RunStartedEvent(attribution, metadata=dict())
dataclass
¶
A run has started executing.
StateDeltaEvent(attribution, patch, metadata=dict())
dataclass
¶
An incremental change to shared run state.
patch is a sequence of JSON-Patch operations (RFC 6902), the same shape
AG-UI STATE_DELTA carries, so adapters relay it without re-deriving a diff.
StateSnapshotEvent(attribution, snapshot, metadata=dict())
dataclass
¶
A full snapshot of shared run state.
StepFinishedEvent(attribution, step_name, metadata=dict())
dataclass
¶
A named step inside a run has finished.
StepStartedEvent(attribution, step_name, metadata=dict())
dataclass
¶
A named step inside a run has started (one model-loop iteration).
ToolCallArgsDeltaEvent(attribution, call_id, args_delta, metadata=dict())
dataclass
¶
Incremental serialized arguments for an in-flight tool call.
ToolCallEndEvent(attribution, call_id, metadata=dict())
dataclass
¶
A tool call has finished streaming its arguments.
ToolCallResultEvent(attribution, call_id, tool_name, message_id, result=None, metadata=dict())
dataclass
¶
The result returned by executing a completed tool call.
message_id identifies the conversation message this tool result belongs
to, so an adapter can attach the result to the right message. AG-UI requires
it as messageId on TOOL_CALL_RESULT; without it the result frame
cannot be reconstructed losslessly.
ToolCallStartEvent(attribution, call_id, tool_name, parent_message_id=None, metadata=dict())
dataclass
¶
A model has begun emitting a tool call with a known name.
parent_message_id links the tool call to the assistant message that
requested it (None when the model emits the call outside any message).
AG-UI projects this as parentMessageId on TOOL_CALL_START.
AgentApprovalBoundaryKind
¶
Bases: StrEnum
Action boundaries where orchestration may require human approval.
AgentApprovalDecisionOutcome(request_id, decision, status, transition, reason=None, modified_payload=dict(), comment=None)
dataclass
¶
Typed result of an approval decision signal.
AgentApprovalPlan(action, request=None, state=None, yield_item=None)
dataclass
¶
Plan for an action boundary before executing it.
requires_approval
property
¶
Return whether orchestration must wait for a HITL decision.
AgentApprovalPlanAction
¶
Bases: StrEnum
Approval plan outcome before an action boundary is executed.
AgentApprovalRequest(id, agent_state_id, boundary, prompt, risk, action_ref, allowed_decisions=DEFAULT_APPROVAL_DECISIONS, metadata=dict())
dataclass
¶
Approval request materialized at a risky action boundary.
__post_init__()
¶
Reject approval requests that cannot be matched by a signal.
Source code in core/spakky-agent/src/spakky/agent/approval.py
from_tool_descriptor(*, approval_id, agent_state_id, descriptor, prompt=None, action_ref=None, call_id=None, metadata=None)
classmethod
¶
Build an approval request from a risky tool descriptor.
Source code in core/spakky-agent/src/spakky/agent/approval.py
to_state(*, agent_type)
¶
Materialize the approval wait as interrupted lifecycle state.
Source code in core/spakky-agent/src/spakky/agent/approval.py
to_yield()
¶
Expose this approval request to an inbound adapter stream.
Source code in core/spakky-agent/src/spakky/agent/approval.py
to_metadata()
¶
Return JSON-compatible metadata for state, yield, and evidence.
Source code in core/spakky-agent/src/spakky/agent/approval.py
AgentActionBoundaryCheckpoint(action_id, action_kind, stage, idempotency=Idempotency.UNKNOWN, metadata=dict())
dataclass
¶
Serializable checkpoint recorded before or after one external action.
__post_init__()
¶
Reject checkpoints that cannot be correlated after restart.
before_model_call(action_id, *, idempotency=Idempotency.UNKNOWN, metadata=None)
classmethod
¶
Create the checkpoint recorded before a model call is attempted.
Source code in core/spakky-agent/src/spakky/agent/recovery.py
after_model_call(action_id, *, idempotency=Idempotency.UNKNOWN, metadata=None)
classmethod
¶
Create the checkpoint recorded after a model call completes.
Source code in core/spakky-agent/src/spakky/agent/recovery.py
before_tool_call(action_id, *, idempotency, metadata=None)
classmethod
¶
Create the checkpoint recorded before a tool call is attempted.
Source code in core/spakky-agent/src/spakky/agent/recovery.py
after_tool_call(action_id, *, idempotency, metadata=None)
classmethod
¶
Create the checkpoint recorded after a tool call completes.
Source code in core/spakky-agent/src/spakky/agent/recovery.py
before_approval_wait(action_id, *, metadata=None)
classmethod
¶
Create the checkpoint recorded before waiting for approval.
Source code in core/spakky-agent/src/spakky/agent/recovery.py
after_approval_wait(action_id, *, metadata=None)
classmethod
¶
Create the checkpoint recorded after an approval wait resolves.
Source code in core/spakky-agent/src/spakky/agent/recovery.py
to_evidence_candidate(*, summary=None)
¶
Represent this checkpoint as append-only evidence.
Source code in core/spakky-agent/src/spakky/agent/recovery.py
AgentActionBoundaryStage
¶
Bases: StrEnum
Checkpoint side recorded around an action boundary.
AgentActionKind
¶
Bases: StrEnum
Recoverable external action classes in an agent execution.
AgentResumeAction
¶
Bases: StrEnum
Orchestration action selected from persisted checkpoint evidence.
AgentResumeBoundary(action_id, action_kind, stage, idempotency, evidence_id)
dataclass
¶
Last action boundary reconstructed from append-only evidence.
AgentResumePlan(state, action, boundary=None, signals=())
dataclass
¶
AgentDelegateTarget(agent_type, agent_name=None, metadata=dict())
dataclass
¶
First-class delegate target represented by another @Agent component.
__post_init__()
¶
Reject delegate targets that cannot identify an agent component.
Source code in core/spakky-agent/src/spakky/agent/delegation.py
DelegationToolResult(summary, output=None, events=(), metadata=dict())
dataclass
¶
Model-facing result plus child neutral events from a teammate call.
__post_init__()
¶
Reject delegated tool results without a model-facing summary.
from_result(result, *, events=())
classmethod
¶
Build a model-facing tool result from a delegation result object.
Source code in core/spakky-agent/src/spakky/agent/delegation.py
DelegationBudget(max_steps=None, max_tokens=None, timeout_seconds=None, deadline_at=None, metadata=dict())
dataclass
¶
Budget metadata attached to a delegation packet.
__post_init__()
¶
Reject delegation budgets that cannot be enforced consistently.
Source code in core/spakky-agent/src/spakky/agent/delegation.py
DelegationContextSlice(summary=None, evidence_refs=(), manifest_ref=None, metadata=dict())
dataclass
¶
Minimal parent context projected for a child agent.
DelegationExpectedOutput(description=None, schema=dict(), metadata=dict())
dataclass
¶
Expected child output description and optional JSON schema.
DelegationPacket(id, parent_agent_state_id, target, task, context=DelegationContextSlice(), constraints=(), expected_output=DelegationExpectedOutput(), budget=DelegationBudget(), allowed_capabilities=(), return_policy=DelegationReturnPolicy.SUMMARY_AND_EVIDENCE, metadata=dict())
dataclass
¶
Task packet passed from a parent agent to a delegate agent.
__post_init__()
¶
Reject delegation packets without parent linkage or task identity.
Source code in core/spakky-agent/src/spakky/agent/delegation.py
DelegationResult(id, packet_id, target, summary, output=None, evidence_refs=(), metadata=dict(), created_at=None)
dataclass
¶
Child agent result projected back to the parent execution.
__post_init__()
¶
Reject delegated results that cannot be linked to a packet.
Source code in core/spakky-agent/src/spakky/agent/delegation.py
to_parent_evidence(*, evidence_id, parent_agent_state_id)
¶
Represent a delegated result as append-only parent evidence.
Source code in core/spakky-agent/src/spakky/agent/delegation.py
to_parent_yield(*, evidence_id, parent_agent_state_id)
¶
Expose the delegated result on the parent's AgentYield stream.
Source code in core/spakky-agent/src/spakky/agent/delegation.py
DelegationReturnPolicy
¶
Bases: StrEnum
How a child agent result should be projected back to the parent.
IAgentDelegate
¶
Bases: ABC
Execution hook that runs a delegation packet against a delegate target.
delegate(packet)
abstractmethod
¶
Execute delegation without prescribing spawn topology or transport.
delegate_tool_result(packet)
async
¶
Execute delegation and collect the terminal result for a tool call.
Source code in core/spakky-agent/src/spakky/agent/delegation.py
ICompactionStrategy
¶
Bases: ABC
Provider-neutral context-compaction transform applied before a request.
A strategy maps a resolved history to a shorter one, reading the running
ModelUsage and backend ModelCapability so it can scale its effect to
how close the run is to the context limit. Implementations are pure transforms
— they never mutate the input — so the runner can apply a declared chain by
threading each strategy's output into the next.
compact(history, usage, capability)
abstractmethod
async
¶
Return a compacted view of history for the next model request.
Source code in core/spakky-agent/src/spakky/agent/compaction.py
KeepRecentMessagesCompactionStrategy(max_messages)
dataclass
¶
Bases: ICompactionStrategy
Sliding-window strategy that keeps only the most recent messages.
The cheapest compaction: drop the oldest messages and keep the last
max_messages. It carries no model dependency, so it is the safe default
tail of a chain that bounds history length regardless of content.
ProviderManagedCompactionStrategy()
dataclass
¶
Bases: ICompactionStrategy
No-op strategy for backends that manage their own context window.
Some providers compact server-side, so the framework must not also trim the transcript. Declaring this strategy makes that hand-off explicit in the spec rather than leaving compaction silently absent.
compact(history, usage, capability)
async
¶
Return the history unchanged — the provider owns compaction.
Source code in core/spakky-agent/src/spakky/agent/compaction.py
SummarizeOldTurnsCompactionStrategy(model, keep_recent, summary_instruction=DEFAULT_SUMMARY_INSTRUCTION)
dataclass
¶
Bases: ICompactionStrategy
Replace older turns with a model-generated summary, keeping recent ones.
The richest compaction: a secondary model call condenses the turns older than
keep_recent into one EVIDENCE summary message that precedes the kept
tail. This preserves earlier context as a briefing instead of dropping it, at
the cost of one extra model round-trip. When the history is already within
keep_recent there is nothing older to summarize, so the call is skipped.
__post_init__()
¶
Reject a window that would leave no recent turns to anchor the summary.
Source code in core/spakky-agent/src/spakky/agent/compaction.py
compact(history, usage, capability)
async
¶
Summarize turns older than keep_recent ahead of the recent tail.
Source code in core/spakky-agent/src/spakky/agent/compaction.py
TrimToolResultsCompactionStrategy(max_characters)
dataclass
¶
Bases: ICompactionStrategy
Truncate verbose tool-result messages while preserving the dialogue.
Tool results (search dumps, file contents) dominate token cost yet rarely
need to be replayed verbatim. This strategy truncates only TOOL role
message content past max_characters and leaves the user/assistant turns
untouched, so the model still sees that a tool ran and a clipped head of its
output.
Agent(spec=AgentExecutionSpec(), *, name='', scope=Scope.SINGLETON)
dataclass
¶
Bases: Pod
UseCase-equivalent Pod stereotype for agentic workflow components.
validate_bootstrap()
¶
Re-run definition validation during application bootstrap.
required_persistence_repository_types()
¶
Return repository ports required by this Agent's durable path.
Source code in core/spakky-agent/src/spakky/agent/execution.py
AgentCompactionPolicy(strategies, trigger_token_threshold)
dataclass
¶
Declared compaction chain plus the token threshold that triggers it.
The strategies form an ordered chain of pluggable ICompactionStrategy
ports applied in sequence once the running token estimate crosses
trigger_token_threshold. The runner threads each strategy's output into
the next, so chain order is the compaction order (ADR-0013 §7).
__post_init__()
¶
Reject compaction policies that cannot be enforced consistently.
Source code in core/spakky-agent/src/spakky/agent/execution.py
AgentExecutionLimits(timeout_seconds=None)
dataclass
¶
Bounded execution limits declared outside infrastructure capabilities.
__post_init__()
¶
Reject limits that would fail later at bootstrap.
AgentExecutionSpec(name=None, objective=None, instructions=None, output_type=None, accepted_signals=(), recovery=RecoveryStrategy.NONE, streaming_exposure_mode=StreamingExposureMode.BALANCED, timeout_seconds=None, limits=AgentExecutionLimits(), teammates=(), compaction=None, delegation_allowed=False, metadata=dict())
dataclass
¶
Declarative execution semantics that cannot be inferred from DI alone.
__post_init__()
¶
Reject execution specs that would fail later at bootstrap.
Source code in core/spakky-agent/src/spakky/agent/execution.py
AgentTeammate(name, pod=None, card_url=None)
dataclass
¶
Declared collaborator an agent may delegate to during execution.
A teammate is resolved either in-process by a local @Agent Pod type or
remotely by an AgentCard endpoint URL. Exactly one binding is declared; the
runtime exposes it as a synthetic teammate delegation tool and dispatches it
through the local runner or an injected IAgentDelegate port.
__post_init__()
¶
Reject teammates that cannot resolve to a single delegate target.
Source code in core/spakky-agent/src/spakky/agent/execution.py
RecoveryStrategy
¶
Bases: StrEnum
Recovery strategy requested by an agent execution contract.
StreamingExposureMode
¶
Bases: StrEnum
Streaming output guard profile exposed by agent execution.
AgentSignalHookCatalog(descriptors=())
dataclass
¶
Deterministic catalog of signal hooks discovered from an Agent class.
__post_init__()
¶
Reject duplicate hook identities so dispatch order stays stable.
Source code in core/spakky-agent/src/spakky/agent/hooks.py
hooks_for(kind)
¶
Return every hook that handles the requested signal kind, in order.
Source code in core/spakky-agent/src/spakky/agent/hooks.py
AgentSignalHookDescriptor(identity, owner, callable, kind)
dataclass
¶
Discovered signal hook bound to an owner class and callable.
AgentSignalHookIdentity(owner_module, owner_qualname, member_name)
dataclass
¶
Hook identity independent from the developer-chosen method name.
key
property
¶
Return a stable key for deterministic ordering and logs.
RunAgentInput(state_id, instruction, conversation_id=None, parent_run_id=None, resume=False, message_history=(), model_selection=None, metadata=dict())
dataclass
¶
Inbound contract for one framework-owned agent run.
effective_conversation_id
property
¶
Return the multi-turn thread id, defaulting to the run id.
ADR-0013 §3 attribution requires a conversation id on every event. A single-turn caller may omit it, in which case the run id identifies the (degenerate) one-turn conversation.
__post_init__()
¶
Reject inbound input that cannot correlate a run or seed a request.
Source code in core/spakky-agent/src/spakky/agent/inbound.py
IAgentModelResolver
¶
Bases: ABC
Resolve the model adapter used for one Agent run.
resolve_model(agent_instance, run_input=None)
abstractmethod
¶
Return a run-specific model, or None to use injected fallback.
AgentRunner(agent, target, model, states=None, signals=None, evidence=None, task_store=None)
dataclass
¶
Framework-owned standard agent loop bound to one agent instance.
Durable repositories are None for a stateless agent (one that declares
no accepted_signals and no action-boundary recovery). In that mode the
runner skips state/evidence/signal handling and runs model -> tool -> final.
for_agent_instance(instance)
classmethod
¶
Resolve runner ports from an agent instance's injected attributes.
ADR-0009 stores constructor-injected ports as instance attributes, so the
runner reads vars(instance) (the typed instance __dict__, not the
banned getattr) and resolves each port by runtime type. Attribute
names are developer-chosen, so resolution is type-driven, not name-driven.
Source code in core/spakky-agent/src/spakky/agent/runner.py
with_model(model)
¶
run(run_input)
async
¶
Run one model-mediated agent loop, yielding the public stream.
Source code in core/spakky-agent/src/spakky/agent/runner.py
run_events(run_input)
async
¶
Run one model-mediated loop, emitting the neutral event taxonomy.
This is the lossless native stream AG-UI/A2A adapters consume (ADR-0013
§3). It shares the run's orchestration with run() — model request,
tool dispatch, durable approval gating, evidence persistence — but emits
distinct AgentEvent members instead of coarse AgentYield items, so
an adapter projects each event one-to-one rather than re-expanding framing.
Source code in core/spakky-agent/src/spakky/agent/runner.py
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | |
AgentRunResult(state_id, status, tool_calls, evidence_count)
dataclass
¶
Neutral terminal summary returned when a spec declares no output type.
AgentRunnerFactory(model_resolver=None)
¶
Bases: IAgentRunnerFactory
Default runner factory using the native framework-owned runner.
Source code in core/spakky-agent/src/spakky/agent/runner_factory.py
open_runner(agent_instance, run_input=None)
async
¶
Yield the native runner for one request.
Source code in core/spakky-agent/src/spakky/agent/runner_factory.py
IAgentRunnerFactory
¶
Bases: ABC
Port for opening a request-scoped runner for one agent instance.
open_runner(agent_instance, run_input=None)
abstractmethod
¶
Yield a runner bound to agent_instance for one adapter request.
Source code in core/spakky-agent/src/spakky/agent/runner_factory.py
IAgentEvidenceRepository
¶
IAgentSignalRepository
¶
IAgentStateRepository
¶
Bases: ABC
Materialized state repository for long-running agent executions.
get(state_id)
abstractmethod
¶
get_or_none(state_id)
abstractmethod
¶
save(state)
abstractmethod
¶
list_by_status(status)
abstractmethod
¶
Return states matching an externally observable lifecycle status.
list_resume_candidates()
abstractmethod
¶
Return active or interrupted states that may resume after restart.
ConversationTurn(role, content, metadata=dict())
dataclass
¶
One persisted exchange in a multi-turn conversation transcript.
A turn is the protocol-neutral unit a TaskStore persists: who spoke
(role) and what was said (content). It is intentionally narrower than
a model-request ModelMessage — the transcript records the user/assistant
dialogue that seeds future turns, not the system or evidence framing the
runner assembles fresh on each request. as_model_message projects a turn
back into the model-request vocabulary when the runner replays history.
__post_init__()
¶
Reject turns that cannot seed a future model request.
Source code in core/spakky-agent/src/spakky/agent/interfaces/task_store.py
as_model_message()
¶
Project this turn into a model-request message for history replay.
ITaskStore
¶
Bases: ABC
Durable conversation-history store keyed by conversation_id.
Persists the running transcript of a server-side session so a later run with
the same conversation_id continues the conversation (ADR-0013 §6). A2A
can map its contextId to this key for transcript replay, while A2A task
snapshots are stored by spakky-a2a's repository bridge.
load_history(conversation_id)
abstractmethod
¶
Return the persisted transcript for a conversation in turn order.
Returns an empty sequence for a conversation that has no persisted turns yet — the first turn of a brand-new conversation.
Source code in core/spakky-agent/src/spakky/agent/interfaces/task_store.py
append_turns(conversation_id, turns)
abstractmethod
¶
Append new turns to a conversation's transcript in order.
IAgentModel
¶
Bases: ABC
Outbound model adapter port owned by spakky-agent core.
capability
abstractmethod
property
¶
Return the backend capability descriptor queryable before a run.
capability_for(selection=None)
¶
Return capability for a run-specific model selection.
Existing fixed-model adapters can ignore the selector and inherit the default. Routing adapters can override this to expose per-model context windows, reasoning support, or token-counting support before a request.
Source code in core/spakky-agent/src/spakky/agent/interfaces/model.py
complete(request)
abstractmethod
async
¶
stream(request)
abstractmethod
¶
JsonSchemaConstraint(schema, strict=True)
dataclass
¶
JSON schema constraint shared by structured output and tool calling.
ModelCapability(supports_reasoning=False, context_window_tokens=None, supports_token_counting=False)
dataclass
¶
Provider-neutral declaration of a model backend's queryable abilities.
The agent runner consults this descriptor before a run to adjust behaviour
without invoking the backend. supports_reasoning gates whether the runner
expects REASONING_DELTA events; when False the adapter omits them rather
than failing (graceful degrade). context_window_tokens is None when the
backend does not declare a fixed limit. supports_token_counting declares
whether the backend can report token accounting for a request before sending it.
ModelError(code, message, retryable=False, metadata=dict())
dataclass
¶
Provider-neutral model failure payload.
ModelMessage(role, content, metadata=dict())
dataclass
¶
Provider-neutral model message.
ModelMessageRole
¶
Bases: StrEnum
Roles accepted by provider-neutral model messages.
ModelRequest(messages, context=tuple(), context_manifest=None, context_digest=None, structured_output=None, tool_calling=None, sampling=SamplingOptions(), streaming=StreamingOptions(), model_selection=None, metadata=dict())
dataclass
¶
Provider-neutral request passed to an agent model adapter.
assemble_messages(policy=None)
¶
Assemble prompt messages from typed context packs without concatenation.
Source code in core/spakky-agent/src/spakky/agent/interfaces/model.py
ModelResponse(content, structured_output=None, tool_calls=tuple(), usage=ModelUsage(), metadata=dict())
dataclass
¶
Provider-neutral non-streaming model response.
guarded(sensitive_fields, policy=None)
¶
Return a copy with sensitive output payloads deterministically guarded.
Source code in core/spakky-agent/src/spakky/agent/interfaces/model.py
ModelSelection(provider=None, model=None, profile=None, metadata=dict())
dataclass
¶
Provider/model selector carried by one Agent run.
A service may let a user choose OpenAI, Anthropic, Vertex, OpenRouter, vLLM, or another provider per run. The selector is intentionally provider-neutral: concrete adapters or routing models decide which values they accept.
__post_init__()
¶
Reject blank selector fields before they reach provider adapters.
Source code in core/spakky-agent/src/spakky/agent/interfaces/model.py
ModelStreamEvent(kind, token_delta=None, message_delta=None, reasoning_delta=None, tool_call=None, tool_call_args_delta=None, structured_output=None, error=None, usage=None, metadata=dict())
dataclass
¶
Provider-neutral model streaming event.
token_delta carries the generic streamed token channel. message_delta
and reasoning_delta distinguish assistant-facing text from model reasoning
so callers can route or suppress reasoning independently. tool_call_args_delta
carries incremental tool-call argument text framed by TOOL_CALL_START and
TOOL_CALL_END boundary events that reference the same tool_call.
guarded(sensitive_fields, policy=None)
¶
Return a copy with sensitive streaming payloads guarded.
Source code in core/spakky-agent/src/spakky/agent/interfaces/model.py
ModelStreamEventKind
¶
Bases: StrEnum
Provider-neutral streaming event kinds emitted by a model adapter.
ModelToolCall(name, arguments, call_id=None, metadata=dict())
dataclass
¶
Tool invocation candidate emitted by a model adapter.
guarded(sensitive_fields, policy=None)
¶
Return a copy with sensitive argument values deterministically guarded.
Source code in core/spakky-agent/src/spakky/agent/interfaces/model.py
ModelToolChoice
¶
Bases: StrEnum
Provider-neutral tool calling strategy requested from a model adapter.
ModelToolSpec(name, parameters, description=None, metadata=dict())
dataclass
¶
LLM-facing tool descriptor normalized by agent tooling.
ModelUsage(input_tokens=None, output_tokens=None, total_tokens=None)
dataclass
¶
Token accounting reported by a model adapter.
SamplingOptions(temperature=None, top_p=None, max_tokens=None)
dataclass
¶
Portable model sampling options.
StreamingOptions(include_usage=True, include_progress=True)
dataclass
¶
Portable model streaming options.
StructuredOutputSpec(constraint, output_type_name=None)
dataclass
¶
Structured output contract requested from a model adapter.
ToolCallingSpec(tools, choice=ModelToolChoice.AUTO)
dataclass
¶
Tool calling contract requested from a model adapter.
AgentSignal(id, agent_state_id, kind, payload=dict(), created_at=None)
dataclass
¶
Inbound stimulus appended for an agent execution.
AgentSignalKind
¶
Bases: StrEnum
Inbound stimulus kinds that an agent may accept while running.
ApprovalDecision
¶
Bases: StrEnum
Human-in-the-loop approval outcomes.
AgentSignalConsumptionBatch(state_id, poll_point, signals)
dataclass
¶
Signals consumed during one non-blocking poll.
consumed_count
property
¶
Return the number of signals consumed by this poll.
AgentSignalPollPoint
¶
Bases: StrEnum
Places where orchestration may poll durable signals without waiting.
ContextExposurePolicy(include_pii_values=False, include_sensitive_values=False, include_sensitive_schema_metadata=False, include_sensitive_context_metadata=False)
dataclass
¶
Policy for LLM-facing context and schema metadata exposure.
can_expose_value(field)
¶
Return whether a sensitive value may cross the model boundary.
Source code in core/spakky-agent/src/spakky/agent/safety.py
CredentialRef(id, provider=None)
dataclass
¶
Reference to a credential outside LLM-facing context.
__post_init__()
¶
Reject blank credential references.
DataSensitivity
¶
Bases: StrEnum
Canonical sensitivity classes carried by descriptors.
EvidenceExposurePolicy(include_pii_values=False, include_sensitive_values=False, include_sensitive_metadata=True)
dataclass
¶
Policy for evidence payload exposure before append-only capture.
can_expose_value(field)
¶
Return whether a sensitive value may be stored in evidence payloads.
Source code in core/spakky-agent/src/spakky/agent/safety.py
MaskingPolicy
¶
Bases: StrEnum
Deterministic text masking strategies for sensitive values.
PII
¶
Bases: StrEnum
PII categories that can be declared with typing.Annotated.
RedactionPolicy
¶
Bases: StrEnum
Boundary action used when a value must not be exposed.
SecretField(redaction=RedactionPolicy.REFERENCE_ONLY, label=None, metadata=dict())
dataclass
¶
typing.Annotated metadata for values that must never be model text.
sensitivity
property
¶
Return the normalized sensitivity class.
__post_init__()
¶
guard_text(value)
¶
to_metadata()
¶
Serialize marker metadata without including the secret value.
Source code in core/spakky-agent/src/spakky/agent/safety.py
SecretRef(id, credential=None)
dataclass
¶
Opaque reference to a secret value stored outside model context.
SensitiveField(category, masking=MaskingPolicy.REDACT, redaction=RedactionPolicy.REDACT, label=None, metadata=dict())
dataclass
¶
typing.Annotated metadata for deterministic sensitive-field handling.
sensitivity
property
¶
Return the normalized sensitivity class.
category_name
property
¶
Return the stable public category name.
__post_init__()
¶
guard_text(value)
¶
Return deterministic model/evidence-safe text for this field.
to_metadata()
¶
Serialize marker metadata without including the sensitive value.
Source code in core/spakky-agent/src/spakky/agent/safety.py
SensitiveFieldDescriptor(path, field)
dataclass
¶
Path-bound sensitive metadata extracted from Annotated types.
to_metadata()
¶
Serialize descriptor metadata without leaking the field value.
StreamingGuardFailureMode
¶
Bases: StrEnum
Final audit behavior when a streaming guard missed a raw candidate.
StreamingRedactionAudit(status, detected_count, redacted_count, missed_matches, buffer_size, emitted_char_count, original_char_count)
dataclass
¶
Final aggregate audit for a bounded streaming redaction session.
missed_count
property
¶
Return the number of raw candidates still present after streaming.
to_evidence_payload()
¶
Serialize audit evidence without raw streamed content.
Source code in core/spakky-agent/src/spakky/agent/safety.py
to_error_payload()
¶
Serialize a typed error payload for stream consumers.
Source code in core/spakky-agent/src/spakky/agent/safety.py
StreamingRedactionAuditStatus
¶
Bases: StrEnum
Final aggregate streaming redaction audit status.
StreamingRedactionMatch(pattern_name, start, end, metadata=dict())
dataclass
¶
Sanitized final-audit match location for a missed redaction candidate.
to_payload()
¶
Serialize a match without the sensitive value itself.
Source code in core/spakky-agent/src/spakky/agent/safety.py
StreamingRedactionPolicy(patterns, buffer_size=64, emit_chunk_size=None, failure_mode=StreamingGuardFailureMode.RAISE)
dataclass
¶
Bounded buffering policy balancing stream latency and redaction correctness.
__post_init__()
¶
Reject policies that would make the guard unbounded or silent.
Source code in core/spakky-agent/src/spakky/agent/safety.py
StreamingRedactionResult(chunks, audit=None, error=None)
dataclass
¶
Output produced by a bounded streaming redaction step.
StreamingRedactionSession(policy)
¶
Stateful bounded redactor for model token streams.
Source code in core/spakky-agent/src/spakky/agent/safety.py
push(chunk)
¶
Redact one token chunk and emit only the safe bounded prefix.
Source code in core/spakky-agent/src/spakky/agent/safety.py
finish()
¶
Flush the remaining buffer and run the mandatory final audit.
Source code in core/spakky-agent/src/spakky/agent/safety.py
StreamingSensitivePattern(name, pattern, replacement=REDACTED_VALUE, metadata=dict())
dataclass
¶
Caller-supplied deterministic pattern used by streaming redaction.
__post_init__()
¶
Reject blank names and invalid pattern syntax before streaming starts.
Source code in core/spakky-agent/src/spakky/agent/safety.py
redact(value)
¶
Return redacted text and the number of replacements applied.
find_matches(value)
¶
Return sanitized match locations without exposing raw text.
Source code in core/spakky-agent/src/spakky/agent/safety.py
AgentState(id, agent_type, status, transition=None, reason=None, current_activity=None, input_ref=None, output_ref=None, pending_signal_count=0, last_event_cursor=None, recovery_marker=None, metadata=dict(), created_at=None, updated_at=None)
dataclass
¶
Materialized state for a long-running agent execution.
__post_init__()
¶
Reject state snapshots that cannot represent a real queue count.
AgentStateReason
¶
Bases: StrEnum
Structured reason that refines an externally observable lifecycle state.
AgentStateTransition
¶
Bases: StrEnum
State transition vocabulary accepted by durable agent orchestration.
AgentStatus
¶
Bases: StrEnum
Externally observable lifecycle states for an agent execution.
AgentToolCatalog(descriptors=())
dataclass
¶
Deterministic catalog of descriptors discovered from an Agent class.
__post_init__()
¶
Reject duplicate identity or schema names before model lookup.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
by_identity(identity)
¶
Lookup a descriptor by typed identity.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
by_schema_name(schema_name)
¶
Lookup a descriptor by model-facing schema name.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
AgentToolApprovalContext(prompt=None, action_ref=None, metadata=dict())
dataclass
¶
Invocation-specific approval display and correlation metadata.
__post_init__()
¶
Reject blank override strings before they enter approval state.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
AgentToolBoundInvocation(args=(), kwargs=dict())
dataclass
¶
Python-call-ready tool invocation arguments.
AgentToolDefinition(name, schema_name, description=None, metadata=AgentToolMetadata())
dataclass
¶
Method-level metadata attached by @agent_tool before owner discovery.
__post_init__()
¶
Reject definitions that would make catalog lookup ambiguous.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
AgentToolDescriptor(identity, owner, callable, schema, description=None, metadata=AgentToolMetadata())
dataclass
¶
Discovered tool descriptor bound to an owner class and callable.
AgentToolIdentity(owner_module, owner_qualname, name)
dataclass
¶
AgentToolMetadata(permissions=(), effects=ToolEffects(), idempotency=Idempotency.UNKNOWN, data_access=DataAccess.NONE, externality=Externality.LOCAL, timeout=TimeoutPolicy(), result_budget=ResultBudget(), evidence=EvidenceCapture.NONE, approval=ToolApprovalRequirement.DERIVED)
dataclass
¶
Typed approval, idempotency, and evidence metadata for a descriptor.
AgentToolRuntimeContext(state_id, conversation_id, call_id, tool_name)
dataclass
¶
Runtime correlation data injected into framework-owned tool callables.
__post_init__()
¶
Reject runtime context that cannot link events and evidence.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
AgentToolSchemaHandle(name, input_schema_name, output_schema_name, input_schema=dict(), output_schema=dict(), input_sensitive_fields=(), output_sensitive_fields=())
dataclass
¶
Stable schema names and generated JSON schemas owned by a descriptor.
__post_init__()
¶
Reject blank schema handles.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
input_schema_for(policy=None)
¶
Return model-facing input schema under the requested exposure policy.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
output_schema_for(policy=None)
¶
Return model-facing output schema under the requested exposure policy.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
DataAccess
¶
Bases: StrEnum
Data access level declared by a tool.
EvidenceCapture
¶
Bases: StrEnum
Evidence capture strategy for tool results.
Externality
¶
Bases: StrEnum
External side-effect boundary declared by a tool.
Idempotency
¶
Bases: StrEnum
Action idempotency declared by a tool.
ResultBudget(max_bytes=None)
dataclass
¶
Optional result-size budget for model-facing tool output.
__post_init__()
¶
Reject result budgets that cannot constrain output.
TimeoutPolicy(seconds=None)
dataclass
¶
Optional timeout boundary for a tool invocation.
__post_init__()
¶
Reject non-positive timeout policies at definition time.
ToolApprovalRequirement
¶
Bases: StrEnum
Human approval requirement at the tool boundary.
ToolEffects(data_access=DataAccess.NONE, externality=Externality.LOCAL, destructive=False, network=False)
dataclass
¶
Typed effect metadata used to derive display risk outside core.
read_only()
classmethod
¶
write_state()
classmethod
¶
external_side_effect()
classmethod
¶
Declare a tool that crosses an external side-effect boundary.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
destructive_action()
classmethod
¶
Declare a tool that may irreversibly mutate local or external state.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
ToolPermission(name)
dataclass
¶
Typed permission marker attached to a tool descriptor.
__post_init__()
¶
Reject permission names that cannot be matched deterministically.
ToolResumeAction
¶
Bases: StrEnum
Resume action allowed by stored tool idempotency metadata.
ToolResumeMetadata(idempotency=Idempotency.UNKNOWN)
dataclass
¶
Stored idempotency metadata used when resuming an incomplete action.
from_metadata(metadata)
classmethod
¶
Build resume metadata from a tool descriptor metadata object.
action_for_completed_boundary()
¶
Return the resume action for an already completed action boundary.
action_for_incomplete_boundary()
¶
Return the resume action for an incomplete action boundary.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
ToolRisk(axes=())
dataclass
¶
Derived typed risk axes for policy and evidence annotations.
requires_approval_candidate
property
¶
Return whether the risk is strong enough to suggest HITL approval.
__post_init__()
¶
Reject duplicate axes so risk comparisons stay deterministic.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
from_metadata(metadata)
classmethod
¶
Derive risk axes from source tool metadata.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
ToolRiskAxis
¶
Bases: StrEnum
Derived risk axes exposed for policy and UI decisions.
AgentYield(kind, payload)
dataclass
¶
Typed stream item returned from an agent execute generator.
AgentYieldKind
¶
Bases: StrEnum
Canonical public vocabulary yielded by agent execution.
Approval(id, prompt, allowed_decisions, metadata)
dataclass
¶
Approval request surfaced to the inbound adapter.
Cancel(reason=None, requested_by=None, metadata=dict())
dataclass
¶
Cancellation acknowledgement surfaced to the caller.
Error(code, message, retryable=False, metadata=dict())
dataclass
¶
Recoverable or terminal execution error surfaced to the caller.
Evidence(evidence, metadata=dict())
dataclass
¶
Evidence item surfaced to the inbound adapter.
Final(output, metadata)
dataclass
¶
Final output carried by a generator stream.
Progress(message, current_step=None, metadata=dict())
dataclass
¶
Agent progress update intended for direct inbound adapter consumption.
Token(text, metadata=dict())
dataclass
¶
Incremental model token intended for streaming clients.
Tool(name, call_id=None, arguments=dict(), result=None, metadata=dict())
dataclass
¶
Tool call or tool result surfaced by agent execution.
begin_agent_cancellation(state, signal)
¶
Materialize receipt of a CANCEL signal as CANCELLING state.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
complete_agent_cancellation(state, report)
¶
Resolve CANCELLING state into CANCELLED or FAILED cleanup outcome.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
run_agent_cancellation_cleanup(*, state, signal, tasks)
async
¶
Invoke model stream/tool/delegate cleanup hooks for a CANCEL signal.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
materialize_agent_approval_decision_state(current, outcome)
¶
Apply a typed approval decision outcome to an existing state snapshot.
Source code in core/spakky-agent/src/spakky/agent/approval.py
parse_agent_approval_decision_signal(signal, *, request=None)
¶
Parse an approval decision signal into a typed workflow outcome.
Source code in core/spakky-agent/src/spakky/agent/approval.py
plan_agent_tool_approval(*, descriptor, approval_id, agent_state_id, agent_type, prompt=None, action_ref=None, call_id=None, metadata=None)
¶
Plan whether a tool invocation should proceed or wait for approval.
Source code in core/spakky-agent/src/spakky/agent/approval.py
plan_agent_resume(state, evidence, signals=())
¶
Restore the next resume action using only persisted state and evidence.
Source code in core/spakky-agent/src/spakky/agent/recovery.py
discover_agent_signal_hooks(owner)
¶
Discover @on_signal methods in deterministic class-definition order.
Source code in core/spakky-agent/src/spakky/agent/hooks.py
on_signal(kind)
¶
Declare a method that reacts to one inbound signal kind.
The decorated method must be an async generator yielding AgentYield
items and accepting exactly one signal: AgentSignal argument besides
self. The runner invokes it when it consumes a signal of kind at a
poll point, and forwards every yielded item into the public stream.
Source code in core/spakky-agent/src/spakky/agent/hooks.py
consume_pending_agent_signals(repository, state_id, *, poll_point=AgentSignalPollPoint.SAFE_BOUNDARY, accepted_signals=None, max_signals=None)
¶
Consume currently pending signals without sleeping or waiting for new input.
The repository remains responsible for durable queue ordering. This helper consumes only the eligible prefix of the pending queue so later signals never overtake an earlier unaccepted signal.
Source code in core/spakky-agent/src/spakky/agent/signal_consumption.py
agent_tool(*, name=None, schema_name=None, description=None, permissions=(), effects=None, idempotency=Idempotency.UNKNOWN, data_access=None, externality=None, timeout=None, result_budget=None, evidence=EvidenceCapture.NONE, approval=ToolApprovalRequirement.DERIVED)
¶
Attach typed agent-tool metadata to a method object.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
bind_agent_tool_invocation(function, payload)
¶
Bind a structured model payload to a tool function signature.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
discover_agent_tools(owner)
¶
Discover @agent_tool methods in deterministic class-definition order.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
실행¶
Agent execution metadata contracts.
REMOTE_AGENT_CARD_SCHEMES = ('http', 'https')
module-attribute
¶
URL schemes accepted for a remote teammate's AgentCard endpoint.
RecoveryStrategy
¶
Bases: StrEnum
Recovery strategy requested by an agent execution contract.
StreamingExposureMode
¶
Bases: StrEnum
Streaming output guard profile exposed by agent execution.
AgentExecutionLimits(timeout_seconds=None)
dataclass
¶
Bounded execution limits declared outside infrastructure capabilities.
__post_init__()
¶
Reject limits that would fail later at bootstrap.
AgentTeammate(name, pod=None, card_url=None)
dataclass
¶
Declared collaborator an agent may delegate to during execution.
A teammate is resolved either in-process by a local @Agent Pod type or
remotely by an AgentCard endpoint URL. Exactly one binding is declared; the
runtime exposes it as a synthetic teammate delegation tool and dispatches it
through the local runner or an injected IAgentDelegate port.
__post_init__()
¶
Reject teammates that cannot resolve to a single delegate target.
Source code in core/spakky-agent/src/spakky/agent/execution.py
AgentCompactionPolicy(strategies, trigger_token_threshold)
dataclass
¶
Declared compaction chain plus the token threshold that triggers it.
The strategies form an ordered chain of pluggable ICompactionStrategy
ports applied in sequence once the running token estimate crosses
trigger_token_threshold. The runner threads each strategy's output into
the next, so chain order is the compaction order (ADR-0013 §7).
__post_init__()
¶
Reject compaction policies that cannot be enforced consistently.
Source code in core/spakky-agent/src/spakky/agent/execution.py
AgentExecutionSpec(name=None, objective=None, instructions=None, output_type=None, accepted_signals=(), recovery=RecoveryStrategy.NONE, streaming_exposure_mode=StreamingExposureMode.BALANCED, timeout_seconds=None, limits=AgentExecutionLimits(), teammates=(), compaction=None, delegation_allowed=False, metadata=dict())
dataclass
¶
Declarative execution semantics that cannot be inferred from DI alone.
__post_init__()
¶
Reject execution specs that would fail later at bootstrap.
Source code in core/spakky-agent/src/spakky/agent/execution.py
Agent(spec=AgentExecutionSpec(), *, name='', scope=Scope.SINGLETON)
dataclass
¶
Bases: Pod
UseCase-equivalent Pod stereotype for agentic workflow components.
validate_bootstrap()
¶
Re-run definition validation during application bootstrap.
required_persistence_repository_types()
¶
Return repository ports required by this Agent's durable path.
Source code in core/spakky-agent/src/spakky/agent/execution.py
Inbound run contract consumed by the framework-owned agent runner.
ADR-0013 §1 hands the execution loop to the framework runner. A caller (an
inbound adapter today, an AG-UI/A2A protocol adapter later) hands the runner a
RunAgentInput describing one run: which durable run to correlate against, the
user instruction that seeds the model request, and whether the run resumes a
paused/interrupted execution (ADR-0013 §5 HITL resume / restart recovery).
A stateless caller may also carry the prior transcript inline through
message_history (ADR-0013 §6 client-injected history, pydantic-ai
message_history precedent). When it is empty and a TaskStore is wired,
the runner instead loads the server-persisted transcript by
effective_conversation_id — the two multi-turn paths are mutually exclusive
per run, never merged.
Approval decisions are not carried here. The unified pause -> approval request -> resume flow (ADR-0013 §5) delivers a decision through the durable signal repository, not through this input, so the runner polls the signal queue non-blockingly rather than reading a decision off the inbound contract.
RunAgentInput(state_id, instruction, conversation_id=None, parent_run_id=None, resume=False, message_history=(), model_selection=None, metadata=dict())
dataclass
¶
Inbound contract for one framework-owned agent run.
effective_conversation_id
property
¶
Return the multi-turn thread id, defaulting to the run id.
ADR-0013 §3 attribution requires a conversation id on every event. A single-turn caller may omit it, in which case the run id identifies the (degenerate) one-turn conversation.
__post_init__()
¶
Reject inbound input that cannot correlate a run or seed a request.
Source code in core/spakky-agent/src/spakky/agent/inbound.py
Framework-owned agent execution loop (ADR-0013 §1).
The runner generalizes the manual model -> tool -> evidence -> terminate loop
that ADR-0009 left in developer execute() bodies. A developer declares an
@Agent spec plus @agent_tool methods; the framework provides the loop.
The runner consumes the provider-neutral model stream (C2), dispatches tool
calls through the discovered catalog (C4), records boundary/evidence (C3 model
contracts), consumes durable signals, drives the unified HITL pause -> approval
request -> resume flow (ADR-0013 §5), and terminates with a typed final output
shaped by spec.output_type.
The runner exposes two streams over the same orchestration. run() yields the
public AgentYield vocabulary that inbound adapters already consume. run_events()
yields the protocol-neutral AgentEvent taxonomy (ADR-0013 §3) that AG-UI (#414)
and A2A (#415) adapters project losslessly: the runner emits message/reasoning
deltas, the tool-call start/args-delta/end/result lifecycle, and
run/step boundaries as distinct events carrying attribution (agent / run / parent /
conversation), rather than collapsing them into coarse AgentYield items that an
adapter would have to re-expand. The fine-grained model-stream channels (C2
ModelStreamEventKind message/reasoning/tool-args deltas) project one-to-one onto
the neutral taxonomy; REASONING_DELTA is omitted when the model declares no
reasoning capability (graceful degrade, ADR-0013 §4).
DEFAULT_SYSTEM_INSTRUCTION = 'Use the declared tools to accomplish the objective.'
module-attribute
¶
Fallback system message when an agent spec declares no instructions.
DEFAULT_SAMPLING = SamplingOptions(temperature=0.0, max_tokens=512)
module-attribute
¶
Deterministic default sampling for the framework-owned model request.
ESTIMATED_CHARACTERS_PER_TOKEN = 4
module-attribute
¶
Provider-neutral characters-per-token ratio for the compaction trigger estimate.
The core cannot call a provider tokenizer (it stays protocol-neutral, ADR-0013 §2), so the compaction trigger estimates token count from transcript length using the widely-used ~4-characters-per-token approximation. The estimate only decides whether the declared chain runs; the strategies themselves bound the result, so an approximate trigger is sufficient.
AgentRunResult(state_id, status, tool_calls, evidence_count)
dataclass
¶
Neutral terminal summary returned when a spec declares no output type.
AgentRunner(agent, target, model, states=None, signals=None, evidence=None, task_store=None)
dataclass
¶
Framework-owned standard agent loop bound to one agent instance.
Durable repositories are None for a stateless agent (one that declares
no accepted_signals and no action-boundary recovery). In that mode the
runner skips state/evidence/signal handling and runs model -> tool -> final.
for_agent_instance(instance)
classmethod
¶
Resolve runner ports from an agent instance's injected attributes.
ADR-0009 stores constructor-injected ports as instance attributes, so the
runner reads vars(instance) (the typed instance __dict__, not the
banned getattr) and resolves each port by runtime type. Attribute
names are developer-chosen, so resolution is type-driven, not name-driven.
Source code in core/spakky-agent/src/spakky/agent/runner.py
with_model(model)
¶
run(run_input)
async
¶
Run one model-mediated agent loop, yielding the public stream.
Source code in core/spakky-agent/src/spakky/agent/runner.py
run_events(run_input)
async
¶
Run one model-mediated loop, emitting the neutral event taxonomy.
This is the lossless native stream AG-UI/A2A adapters consume (ADR-0013
§3). It shares the run's orchestration with run() — model request,
tool dispatch, durable approval gating, evidence persistence — but emits
distinct AgentEvent members instead of coarse AgentYield items, so
an adapter projects each event one-to-one rather than re-expanding framing.
Source code in core/spakky-agent/src/spakky/agent/runner.py
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | |
runner_backed_execute(self, run_input)
async
¶
Framework-provided execute() bound onto a declaration-only @Agent.
@Agent binds this as the agent's execute() when the developer
declares only a spec plus @agent_tool methods (ADR-0013 §1). It builds a
runner from the agent instance's injected ports and replays its stream.
Source code in core/spakky-agent/src/spakky/agent/runner.py
DI entry point for opening agent runners.
Protocol adapters should not construct :class:AgentRunner directly when an
application may load runner-augmenting plugins such as MCP. They ask this
factory port for a runner scoped to one request instead; plugins can then bind
the port to their own implementation while the default remains the native
framework runner.
IAgentRunnerFactory
¶
Bases: ABC
Port for opening a request-scoped runner for one agent instance.
open_runner(agent_instance, run_input=None)
abstractmethod
¶
Yield a runner bound to agent_instance for one adapter request.
Source code in core/spakky-agent/src/spakky/agent/runner_factory.py
AgentRunnerFactory(model_resolver=None)
¶
Bases: IAgentRunnerFactory
Default runner factory using the native framework-owned runner.
Source code in core/spakky-agent/src/spakky/agent/runner_factory.py
open_runner(agent_instance, run_input=None)
async
¶
Yield the native runner for one request.
Source code in core/spakky-agent/src/spakky/agent/runner_factory.py
Event¶
Protocol-neutral agent event taxonomy.
This taxonomy is the single neutral source that AG-UI, A2A, and MCP adapters normalize into their respective protocols. The core stays protocol-neutral (ADR-0013 §2 / §3): no event field is named after, or shaped by, any single external protocol, yet every event carries enough attribution for each adapter to reconstruct that protocol's linkage without loss.
Attribution carried by every event (ADR-0013 §3):
agent_id— which agent emitted the event (team-mode composite attribution).run_id— the run this event belongs to. AG-UI projects this asrunId; A2A projects this as the A2ATaskid.parent_run_id— the parent run in a delegation tree (Nonefor a root run that has no delegating parent). AG-UI projects this asparentRunId; A2A projects this as the parent task in its task hierarchy.conversation_id— the multi-turn conversation this run participates in. AG-UI projects this asthreadId; A2A projects this ascontextId.
AgentEvent = MessageDeltaEvent | ReasoningDeltaEvent | ToolCallStartEvent | ToolCallArgsDeltaEvent | ToolCallEndEvent | ToolCallResultEvent | RunStartedEvent | RunPausedEvent | RunFinishedEvent | StepStartedEvent | StepFinishedEvent | StateSnapshotEvent | StateDeltaEvent | ArtifactEvent
¶
Discriminated union of every protocol-neutral agent event.
Each member exposes a distinct kind literal so adapters dispatch with
match/case exhaustiveness rather than runtime attribute probing.
AgentEventKind
¶
Bases: StrEnum
Protocol-neutral event kinds emitted across an agent run.
The lifecycle kinds (RUN_STARTED … ARTIFACT) generalize ADR-0009's
public AgentYield vocabulary and align 1:1 with the streaming events that
AG-UI and A2A adapters must reproduce (ADR-0013 §3).
AgentEventAttribution(agent_id, run_id, conversation_id, parent_run_id=None)
dataclass
¶
Attribution carried by every protocol-neutral agent event.
parent_run_id is None exactly when the run is a delegation-tree root
(ADR-0013 §3 "parent link" / ADR-0009 parent linkage). The remaining ids are
always present so adapters never have to synthesize linkage.
__post_init__()
¶
Reject attribution that cannot identify an agent, run, or conversation.
Source code in core/spakky-agent/src/spakky/agent/event.py
MessageDeltaEvent(attribution, message_id, delta, metadata=dict())
dataclass
¶
Incremental assistant message text produced by the model.
ReasoningDeltaEvent(attribution, reasoning_id, delta, metadata=dict())
dataclass
¶
Incremental model reasoning (thinking) text.
ToolCallStartEvent(attribution, call_id, tool_name, parent_message_id=None, metadata=dict())
dataclass
¶
A model has begun emitting a tool call with a known name.
parent_message_id links the tool call to the assistant message that
requested it (None when the model emits the call outside any message).
AG-UI projects this as parentMessageId on TOOL_CALL_START.
ToolCallArgsDeltaEvent(attribution, call_id, args_delta, metadata=dict())
dataclass
¶
Incremental serialized arguments for an in-flight tool call.
ToolCallEndEvent(attribution, call_id, metadata=dict())
dataclass
¶
A tool call has finished streaming its arguments.
ToolCallResultEvent(attribution, call_id, tool_name, message_id, result=None, metadata=dict())
dataclass
¶
The result returned by executing a completed tool call.
message_id identifies the conversation message this tool result belongs
to, so an adapter can attach the result to the right message. AG-UI requires
it as messageId on TOOL_CALL_RESULT; without it the result frame
cannot be reconstructed losslessly.
RunStartedEvent(attribution, metadata=dict())
dataclass
¶
A run has started executing.
RunPausedEvent(attribution, reason, prompt, state_id, approval_id=None, tool_call_id=None, allowed_decisions=(), metadata=dict())
dataclass
¶
A run has paused without terminal success or failure.
The event is intentionally protocol-neutral: it carries core lifecycle reason plus the input prompt/decision envelope adapters need to project their own input-required or auth-required protocol states.
__post_init__()
¶
Reject pause events that cannot be shown or resumed.
Source code in core/spakky-agent/src/spakky/agent/event.py
RunFinishedEvent(attribution, error=None, metadata=dict())
dataclass
¶
A run has finished executing.
error is None for a successful run and carries a terminal failure
payload otherwise (A2A failed task / AG-UI RUN_ERROR).
StepStartedEvent(attribution, step_name, metadata=dict())
dataclass
¶
A named step inside a run has started (one model-loop iteration).
StepFinishedEvent(attribution, step_name, metadata=dict())
dataclass
¶
A named step inside a run has finished.
StateSnapshotEvent(attribution, snapshot, metadata=dict())
dataclass
¶
A full snapshot of shared run state.
StateDeltaEvent(attribution, patch, metadata=dict())
dataclass
¶
An incremental change to shared run state.
patch is a sequence of JSON-Patch operations (RFC 6902), the same shape
AG-UI STATE_DELTA carries, so adapters relay it without re-deriving a diff.
ArtifactEvent(attribution, artifact_id, content, name=None, metadata=dict())
dataclass
¶
A produced artifact surfaced by an agent run.
Dispatcher¶
Declarative tool dispatch over a discovered agent tool catalog.
ADR-0013 §1 hands the model-call -> tool-invoke step to the framework runner.
This module removes the developer-written if call.name == ... chain and the
manual payload extraction it implied: a model tool call is resolved against the
catalog, its arguments are bound through the descriptor, and the descriptor's
callable is invoked. External MCP tools (follow-up F1) normalize into the same
AgentToolCatalog and therefore dispatch through this identical path.
AgentToolDispatcher(target, catalog, runtime_context=None)
dataclass
¶
Resolve and invoke a catalog tool from a model tool call.
The dispatcher binds to a single agent instance whose @agent_tool
methods are described by catalog. Catalog descriptors that own no
instance parameter (such as MCP-normalized external tools) are invoked
without the bound target.
descriptor_for(call)
¶
Resolve the catalog descriptor a model tool call targets.
Source code in core/spakky-agent/src/spakky/agent/dispatcher.py
dispatch(call)
async
¶
Bind a model tool call payload and invoke its catalog callable.
Source code in core/spakky-agent/src/spakky/agent/dispatcher.py
State¶
Agent lifecycle state contracts.
AgentStatus
¶
Bases: StrEnum
Externally observable lifecycle states for an agent execution.
AgentStateTransition
¶
Bases: StrEnum
State transition vocabulary accepted by durable agent orchestration.
AgentStateReason
¶
Bases: StrEnum
Structured reason that refines an externally observable lifecycle state.
AgentState(id, agent_type, status, transition=None, reason=None, current_activity=None, input_ref=None, output_ref=None, pending_signal_count=0, last_event_cursor=None, recovery_marker=None, metadata=dict(), created_at=None, updated_at=None)
dataclass
¶
Materialized state for a long-running agent execution.
__post_init__()
¶
Reject state snapshots that cannot represent a real queue count.
Signal¶
Non-blocking consumption helpers for durable agent signals.
AgentSignalPollPoint
¶
Bases: StrEnum
Places where orchestration may poll durable signals without waiting.
AgentSignalConsumptionBatch(state_id, poll_point, signals)
dataclass
¶
Signals consumed during one non-blocking poll.
consumed_count
property
¶
Return the number of signals consumed by this poll.
consume_pending_agent_signals(repository, state_id, *, poll_point=AgentSignalPollPoint.SAFE_BOUNDARY, accepted_signals=None, max_signals=None)
¶
Consume currently pending signals without sleeping or waiting for new input.
The repository remains responsible for durable queue ordering. This helper consumes only the eligible prefix of the pending queue so later signals never overtake an earlier unaccepted signal.
Source code in core/spakky-agent/src/spakky/agent/signal_consumption.py
Evidence¶
Agent evidence contracts.
AgentEvidenceKind
¶
Bases: StrEnum
Kinds of append-only evidence captured by agent execution.
AgentEvidence(id, agent_state_id, kind, payload=dict(), summary=None, digest=None, manifest_ref=None, reference=None, sensitive_fields=(), created_at=None)
dataclass
¶
Append-only artifact captured during an agent execution.
AgentEvidenceCandidate(kind, payload=dict(), summary=None, digest=None, manifest_ref=None, reference=None, sensitive_fields=())
dataclass
¶
Append-only evidence candidate before repository id assignment.
tool_result(*, tool_identity, tool_schema_name, result, capture, sensitive_fields=(), exposure_policy=None, summary=None)
classmethod
¶
Create evidence metadata for a captured tool result.
Source code in core/spakky-agent/src/spakky/agent/evidence.py
model_decision(*, model, decision, summary=None)
classmethod
¶
Create evidence metadata for a model decision.
Source code in core/spakky-agent/src/spakky/agent/evidence.py
tool_decision(*, tool_identity, decision, summary=None)
classmethod
¶
Create evidence metadata for a tool-routing decision.
Source code in core/spakky-agent/src/spakky/agent/evidence.py
context_optimization(*, action, stage, signals=(), summary=None)
classmethod
¶
Create before/after evidence for a context optimization action.
Source code in core/spakky-agent/src/spakky/agent/evidence.py
to_evidence(*, evidence_id, agent_state_id, created_at=None)
¶
Assign repository identity while preserving append-only contents.
Source code in core/spakky-agent/src/spakky/agent/evidence.py
Context¶
Typed context contracts for agent model input assembly.
ContextPackRole
¶
Bases: StrEnum
Semantic role of a context pack inside a model request.
ContextFreshness
¶
Bases: StrEnum
Freshness classification for context rot and budget decisions.
ContextSensitivity
¶
Bases: StrEnum
Deterministic sensitivity metadata carried before model input.
ContextRotSymptom
¶
Bases: StrEnum
Typed context rot symptoms observed before model input assembly.
ContextOptimizationActionKind
¶
Bases: StrEnum
Optimization actions that can be selected from context health signals.
ContextOptimizationEvidenceStage
¶
Bases: StrEnum
Where an optimization action evidence item sits in the agent flow.
ContextTokenBudget(max_tokens=None, estimated_tokens=None, reserved_output_tokens=None)
dataclass
¶
Token budget allocated to one context pack.
ContextHealthSignal(id, symptom, manifest_ref=None, pack_id=None, evidence_ref=None, score=None, observed_at=None, metadata=dict())
dataclass
¶
Observed context rot signal used to choose optimization actions.
evidence_payload()
¶
Return JSON-compatible signal metadata for append-only evidence.
Source code in core/spakky-agent/src/spakky/agent/context.py
ContextOptimizationAction(id, kind, signal_refs=tuple(), target_pack_ids=tuple(), manifest_ref=None, digest_ref=None, delegation_ref=None, result_evidence_ref=None, reason=None, metadata=dict())
dataclass
¶
Selected optimization action derived from context health signals.
evidence_payload()
¶
Return JSON-compatible action metadata without raw context contents.
Source code in core/spakky-agent/src/spakky/agent/context.py
IAgentContextHandler
¶
Bases: ABC
Select context optimization actions from health signals and manifests.
select_optimization_actions(signals, manifest)
abstractmethod
¶
Return optimization actions without mutating raw evidence.
Source code in core/spakky-agent/src/spakky/agent/context.py
ContextPack(id, content, source, role, freshness=ContextFreshness.UNKNOWN, relevance=None, token_budget=ContextTokenBudget(), sensitivity=ContextSensitivity.INTERNAL, sensitive_fields=(), metadata=dict())
dataclass
¶
LLM-facing context unit derived from state, signal, or evidence.
guarded_content(policy=None)
¶
Return deterministic model-safe content for this context pack.
Source code in core/spakky-agent/src/spakky/agent/context.py
message_metadata(policy=None)
¶
Return non-content metadata for provider-neutral model messages.
Source code in core/spakky-agent/src/spakky/agent/context.py
ContextManifestEntry(pack_id, source, role, origin_ref, evidence_ref=None, digest_ref=None, sensitive_fields=(), metadata=dict())
dataclass
¶
One audited pack entry inside a context manifest.
ContextManifest(id, entries, origin_ref=None, evidence_refs=tuple(), created_at=None, metadata=dict())
dataclass
¶
Auditable composition record for model input context packs.
ContextDigest(id, context_identity, source_manifest_ref, digest, derived_from_pack_ids=tuple(), compression_evidence_ref=None, algorithm=None, summary=None, created_at=None, metadata=dict())
dataclass
¶
Derived compression evidence for a context identity.
Compaction¶
Pluggable context-compaction strategies (ADR-0013 §7).
A long conversation eventually outgrows a model backend's context window. The
framework runner owns when to compact (ADR-0013 §1 declarative loop ownership);
this module owns how. ICompactionStrategy is the provider-neutral port a
developer declares in an @Agent spec, and the runner applies the declared
chain to the resolved history before each model request once the running token
estimate crosses the policy threshold.
The port shape follows pydantic-ai's message-history processor / ProcessHistory
capability: a processor receives the message list (plus run context such as token
usage) and returns a transformed list. Here the contextual inputs are made
explicit parameters — the running ModelUsage and the backend ModelCapability
— so a strategy decides how aggressively to compact from the same signals the
runner uses to decide whether to compact. Strategies are pure transforms over
tuple[ModelMessage, ...] and compose by sequential application, so a chain of
strategies is just each applied to the previous one's output.
SUMMARY_MESSAGE_METADATA_KEY = 'compaction'
module-attribute
¶
Metadata flag marking a message the summarize strategy synthesized.
SUMMARY_MESSAGE_METADATA_VALUE = 'summary'
module-attribute
¶
Metadata value identifying a synthesized transcript summary message.
DEFAULT_SUMMARY_INSTRUCTION = 'Summarize the earlier conversation turns below into a concise briefing that preserves decisions, facts, and open questions. Reply with the summary only.'
module-attribute
¶
Fallback instruction for the secondary model that summarizes old turns.
ICompactionStrategy
¶
Bases: ABC
Provider-neutral context-compaction transform applied before a request.
A strategy maps a resolved history to a shorter one, reading the running
ModelUsage and backend ModelCapability so it can scale its effect to
how close the run is to the context limit. Implementations are pure transforms
— they never mutate the input — so the runner can apply a declared chain by
threading each strategy's output into the next.
compact(history, usage, capability)
abstractmethod
async
¶
Return a compacted view of history for the next model request.
Source code in core/spakky-agent/src/spakky/agent/compaction.py
KeepRecentMessagesCompactionStrategy(max_messages)
dataclass
¶
Bases: ICompactionStrategy
Sliding-window strategy that keeps only the most recent messages.
The cheapest compaction: drop the oldest messages and keep the last
max_messages. It carries no model dependency, so it is the safe default
tail of a chain that bounds history length regardless of content.
TrimToolResultsCompactionStrategy(max_characters)
dataclass
¶
Bases: ICompactionStrategy
Truncate verbose tool-result messages while preserving the dialogue.
Tool results (search dumps, file contents) dominate token cost yet rarely
need to be replayed verbatim. This strategy truncates only TOOL role
message content past max_characters and leaves the user/assistant turns
untouched, so the model still sees that a tool ran and a clipped head of its
output.
ProviderManagedCompactionStrategy()
dataclass
¶
Bases: ICompactionStrategy
No-op strategy for backends that manage their own context window.
Some providers compact server-side, so the framework must not also trim the transcript. Declaring this strategy makes that hand-off explicit in the spec rather than leaving compaction silently absent.
compact(history, usage, capability)
async
¶
Return the history unchanged — the provider owns compaction.
Source code in core/spakky-agent/src/spakky/agent/compaction.py
SummarizeOldTurnsCompactionStrategy(model, keep_recent, summary_instruction=DEFAULT_SUMMARY_INSTRUCTION)
dataclass
¶
Bases: ICompactionStrategy
Replace older turns with a model-generated summary, keeping recent ones.
The richest compaction: a secondary model call condenses the turns older than
keep_recent into one EVIDENCE summary message that precedes the kept
tail. This preserves earlier context as a briefing instead of dropping it, at
the cost of one extra model round-trip. When the history is already within
keep_recent there is nothing older to summarize, so the call is skipped.
__post_init__()
¶
Reject a window that would leave no recent turns to anchor the summary.
Source code in core/spakky-agent/src/spakky/agent/compaction.py
compact(history, usage, capability)
async
¶
Summarize turns older than keep_recent ahead of the recent tail.
Source code in core/spakky-agent/src/spakky/agent/compaction.py
Recovery¶
Action-boundary recovery contracts for durable agent execution.
AgentActionKind
¶
Bases: StrEnum
Recoverable external action classes in an agent execution.
AgentActionBoundaryStage
¶
Bases: StrEnum
Checkpoint side recorded around an action boundary.
AgentResumeAction
¶
Bases: StrEnum
Orchestration action selected from persisted checkpoint evidence.
AgentActionBoundaryCheckpoint(action_id, action_kind, stage, idempotency=Idempotency.UNKNOWN, metadata=dict())
dataclass
¶
Serializable checkpoint recorded before or after one external action.
__post_init__()
¶
Reject checkpoints that cannot be correlated after restart.
before_model_call(action_id, *, idempotency=Idempotency.UNKNOWN, metadata=None)
classmethod
¶
Create the checkpoint recorded before a model call is attempted.
Source code in core/spakky-agent/src/spakky/agent/recovery.py
after_model_call(action_id, *, idempotency=Idempotency.UNKNOWN, metadata=None)
classmethod
¶
Create the checkpoint recorded after a model call completes.
Source code in core/spakky-agent/src/spakky/agent/recovery.py
before_tool_call(action_id, *, idempotency, metadata=None)
classmethod
¶
Create the checkpoint recorded before a tool call is attempted.
Source code in core/spakky-agent/src/spakky/agent/recovery.py
after_tool_call(action_id, *, idempotency, metadata=None)
classmethod
¶
Create the checkpoint recorded after a tool call completes.
Source code in core/spakky-agent/src/spakky/agent/recovery.py
before_approval_wait(action_id, *, metadata=None)
classmethod
¶
Create the checkpoint recorded before waiting for approval.
Source code in core/spakky-agent/src/spakky/agent/recovery.py
after_approval_wait(action_id, *, metadata=None)
classmethod
¶
Create the checkpoint recorded after an approval wait resolves.
Source code in core/spakky-agent/src/spakky/agent/recovery.py
to_evidence_candidate(*, summary=None)
¶
Represent this checkpoint as append-only evidence.
Source code in core/spakky-agent/src/spakky/agent/recovery.py
AgentResumeBoundary(action_id, action_kind, stage, idempotency, evidence_id)
dataclass
¶
Last action boundary reconstructed from append-only evidence.
AgentResumePlan(state, action, boundary=None, signals=())
dataclass
¶
plan_agent_resume(state, evidence, signals=())
¶
Restore the next resume action using only persisted state and evidence.
Source code in core/spakky-agent/src/spakky/agent/recovery.py
Approval¶
Human-in-the-loop approval workflow contracts.
AgentApprovalBoundaryKind
¶
Bases: StrEnum
Action boundaries where orchestration may require human approval.
AgentApprovalPlanAction
¶
Bases: StrEnum
Approval plan outcome before an action boundary is executed.
AgentApprovalRequest(id, agent_state_id, boundary, prompt, risk, action_ref, allowed_decisions=DEFAULT_APPROVAL_DECISIONS, metadata=dict())
dataclass
¶
Approval request materialized at a risky action boundary.
__post_init__()
¶
Reject approval requests that cannot be matched by a signal.
Source code in core/spakky-agent/src/spakky/agent/approval.py
from_tool_descriptor(*, approval_id, agent_state_id, descriptor, prompt=None, action_ref=None, call_id=None, metadata=None)
classmethod
¶
Build an approval request from a risky tool descriptor.
Source code in core/spakky-agent/src/spakky/agent/approval.py
to_state(*, agent_type)
¶
Materialize the approval wait as interrupted lifecycle state.
Source code in core/spakky-agent/src/spakky/agent/approval.py
to_yield()
¶
Expose this approval request to an inbound adapter stream.
Source code in core/spakky-agent/src/spakky/agent/approval.py
to_metadata()
¶
Return JSON-compatible metadata for state, yield, and evidence.
Source code in core/spakky-agent/src/spakky/agent/approval.py
AgentApprovalPlan(action, request=None, state=None, yield_item=None)
dataclass
¶
Plan for an action boundary before executing it.
requires_approval
property
¶
Return whether orchestration must wait for a HITL decision.
AgentApprovalDecisionOutcome(request_id, decision, status, transition, reason=None, modified_payload=dict(), comment=None)
dataclass
¶
Typed result of an approval decision signal.
plan_agent_tool_approval(*, descriptor, approval_id, agent_state_id, agent_type, prompt=None, action_ref=None, call_id=None, metadata=None)
¶
Plan whether a tool invocation should proceed or wait for approval.
Source code in core/spakky-agent/src/spakky/agent/approval.py
parse_agent_approval_decision_signal(signal, *, request=None)
¶
Parse an approval decision signal into a typed workflow outcome.
Source code in core/spakky-agent/src/spakky/agent/approval.py
materialize_agent_approval_decision_state(current, outcome)
¶
Apply a typed approval decision outcome to an existing state snapshot.
Source code in core/spakky-agent/src/spakky/agent/approval.py
Cancellation¶
Cancellation lifecycle and cleanup contracts for agent execution.
AgentCancellationCleanupCallable = Callable[[AgentCancellationRequest], Awaitable[AgentCancellationCleanupResult]]
¶
Async hook shape invoked for model stream/tool/delegate cancellation cleanup.
AgentCancellationTargetKind
¶
Bases: StrEnum
Running execution target that can receive a cancellation cleanup hook.
AgentCancellationCleanupStatus
¶
Bases: StrEnum
Outcome of one cancellation cleanup hook.
AgentCancellationRequest(state_id, signal_id, target_kind, target_ref, reason=None, requested_by=None, metadata=dict())
dataclass
¶
Cancellation request passed to a model stream, tool, or delegate hook.
__post_init__()
¶
Reject requests that cannot be traced back to state/signal/target.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
from_signal(*, state, signal, target_kind, target_ref, metadata=None)
classmethod
¶
Build a hook request from the durable CANCEL signal payload.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
to_payload()
¶
Serialize the request into append-only evidence metadata.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
AgentCancellationCleanupResult(target_kind, target_ref, status, reason=None, error_code=None, message=None, metadata=dict())
dataclass
¶
Result returned by one cancellation cleanup hook.
failed_cleanup
property
¶
Return whether this hook prevents a clean CANCELLED terminal state.
__post_init__()
¶
Reject outcomes that cannot be correlated with the cleanup target.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
succeeded(*, target_kind, target_ref, reason=None, metadata=None)
classmethod
¶
Record a cleanup hook that released its target.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
failed(*, target_kind, target_ref, error_code, message, metadata=None)
classmethod
¶
Record a cleanup hook that could not release its target.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
skipped(*, target_kind, target_ref, reason, metadata=None)
classmethod
¶
Record a cleanup target that was already inactive or unavailable.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
to_payload()
¶
Serialize this hook outcome into evidence/state metadata.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
AgentCancellationCleanupTask(target_kind, target_ref, cleanup, metadata=dict())
dataclass
¶
One cleanup hook registered for a running cancellation target.
__post_init__()
¶
Reject hooks that cannot be identified in cleanup evidence.
run(*, state, signal)
async
¶
Invoke the hook and verify that it reports the same target.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
AgentCancellationCleanupReport(state_id, signal_id, outcomes=())
dataclass
¶
Aggregate cleanup evidence for one CANCEL signal.
cleanup_succeeded
property
¶
Return whether all cleanup hooks completed without failure.
failed_outcomes
property
¶
Return the hook outcomes that force FAILED terminal state.
__post_init__()
¶
Reject reports that cannot be attached to state and signal evidence.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
to_payload()
¶
Serialize the report for state metadata and evidence payloads.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
to_evidence_candidate(*, summary=None)
¶
Represent cancellation cleanup as append-only evidence.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
run_agent_cancellation_cleanup(*, state, signal, tasks)
async
¶
Invoke model stream/tool/delegate cleanup hooks for a CANCEL signal.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
begin_agent_cancellation(state, signal)
¶
Materialize receipt of a CANCEL signal as CANCELLING state.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
complete_agent_cancellation(state, report)
¶
Resolve CANCELLING state into CANCELLED or FAILED cleanup outcome.
Source code in core/spakky-agent/src/spakky/agent/cancellation.py
Delegation¶
Agent-to-agent delegation contracts.
DelegationReturnPolicy
¶
Bases: StrEnum
How a child agent result should be projected back to the parent.
AgentDelegateTarget(agent_type, agent_name=None, metadata=dict())
dataclass
¶
First-class delegate target represented by another @Agent component.
__post_init__()
¶
Reject delegate targets that cannot identify an agent component.
Source code in core/spakky-agent/src/spakky/agent/delegation.py
DelegationBudget(max_steps=None, max_tokens=None, timeout_seconds=None, deadline_at=None, metadata=dict())
dataclass
¶
Budget metadata attached to a delegation packet.
__post_init__()
¶
Reject delegation budgets that cannot be enforced consistently.
Source code in core/spakky-agent/src/spakky/agent/delegation.py
DelegationContextSlice(summary=None, evidence_refs=(), manifest_ref=None, metadata=dict())
dataclass
¶
Minimal parent context projected for a child agent.
DelegationExpectedOutput(description=None, schema=dict(), metadata=dict())
dataclass
¶
Expected child output description and optional JSON schema.
DelegationPacket(id, parent_agent_state_id, target, task, context=DelegationContextSlice(), constraints=(), expected_output=DelegationExpectedOutput(), budget=DelegationBudget(), allowed_capabilities=(), return_policy=DelegationReturnPolicy.SUMMARY_AND_EVIDENCE, metadata=dict())
dataclass
¶
Task packet passed from a parent agent to a delegate agent.
__post_init__()
¶
Reject delegation packets without parent linkage or task identity.
Source code in core/spakky-agent/src/spakky/agent/delegation.py
DelegationResult(id, packet_id, target, summary, output=None, evidence_refs=(), metadata=dict(), created_at=None)
dataclass
¶
Child agent result projected back to the parent execution.
__post_init__()
¶
Reject delegated results that cannot be linked to a packet.
Source code in core/spakky-agent/src/spakky/agent/delegation.py
to_parent_evidence(*, evidence_id, parent_agent_state_id)
¶
Represent a delegated result as append-only parent evidence.
Source code in core/spakky-agent/src/spakky/agent/delegation.py
to_parent_yield(*, evidence_id, parent_agent_state_id)
¶
Expose the delegated result on the parent's AgentYield stream.
Source code in core/spakky-agent/src/spakky/agent/delegation.py
DelegationToolResult(summary, output=None, events=(), metadata=dict())
dataclass
¶
Model-facing result plus child neutral events from a teammate call.
__post_init__()
¶
Reject delegated tool results without a model-facing summary.
from_result(result, *, events=())
classmethod
¶
Build a model-facing tool result from a delegation result object.
Source code in core/spakky-agent/src/spakky/agent/delegation.py
IAgentDelegate
¶
Bases: ABC
Execution hook that runs a delegation packet against a delegate target.
delegate(packet)
abstractmethod
¶
Execute delegation without prescribing spawn topology or transport.
delegate_tool_result(packet)
async
¶
Execute delegation and collect the terminal result for a tool call.
Source code in core/spakky-agent/src/spakky/agent/delegation.py
build_teammate_tool_descriptors(owner, teammates)
¶
Build model-callable delegation tools from an @Agent teammate spec.
Source code in core/spakky-agent/src/spakky/agent/delegation.py
Safety¶
Deterministic sensitive-data contracts for agent boundaries.
DataSensitivity
¶
Bases: StrEnum
Canonical sensitivity classes carried by descriptors.
PII
¶
Bases: StrEnum
PII categories that can be declared with typing.Annotated.
MaskingPolicy
¶
Bases: StrEnum
Deterministic text masking strategies for sensitive values.
RedactionPolicy
¶
Bases: StrEnum
Boundary action used when a value must not be exposed.
StreamingGuardFailureMode
¶
Bases: StrEnum
Final audit behavior when a streaming guard missed a raw candidate.
StreamingRedactionAuditStatus
¶
Bases: StrEnum
Final aggregate streaming redaction audit status.
ContextExposurePolicy(include_pii_values=False, include_sensitive_values=False, include_sensitive_schema_metadata=False, include_sensitive_context_metadata=False)
dataclass
¶
Policy for LLM-facing context and schema metadata exposure.
can_expose_value(field)
¶
Return whether a sensitive value may cross the model boundary.
Source code in core/spakky-agent/src/spakky/agent/safety.py
EvidenceExposurePolicy(include_pii_values=False, include_sensitive_values=False, include_sensitive_metadata=True)
dataclass
¶
Policy for evidence payload exposure before append-only capture.
can_expose_value(field)
¶
Return whether a sensitive value may be stored in evidence payloads.
Source code in core/spakky-agent/src/spakky/agent/safety.py
CredentialRef(id, provider=None)
dataclass
¶
Reference to a credential outside LLM-facing context.
__post_init__()
¶
Reject blank credential references.
SecretRef(id, credential=None)
dataclass
¶
Opaque reference to a secret value stored outside model context.
SensitiveField(category, masking=MaskingPolicy.REDACT, redaction=RedactionPolicy.REDACT, label=None, metadata=dict())
dataclass
¶
typing.Annotated metadata for deterministic sensitive-field handling.
sensitivity
property
¶
Return the normalized sensitivity class.
category_name
property
¶
Return the stable public category name.
__post_init__()
¶
guard_text(value)
¶
Return deterministic model/evidence-safe text for this field.
to_metadata()
¶
Serialize marker metadata without including the sensitive value.
Source code in core/spakky-agent/src/spakky/agent/safety.py
SecretField(redaction=RedactionPolicy.REFERENCE_ONLY, label=None, metadata=dict())
dataclass
¶
typing.Annotated metadata for values that must never be model text.
sensitivity
property
¶
Return the normalized sensitivity class.
__post_init__()
¶
guard_text(value)
¶
to_metadata()
¶
Serialize marker metadata without including the secret value.
Source code in core/spakky-agent/src/spakky/agent/safety.py
SensitiveFieldDescriptor(path, field)
dataclass
¶
Path-bound sensitive metadata extracted from Annotated types.
to_metadata()
¶
Serialize descriptor metadata without leaking the field value.
StreamingSensitivePattern(name, pattern, replacement=REDACTED_VALUE, metadata=dict())
dataclass
¶
Caller-supplied deterministic pattern used by streaming redaction.
__post_init__()
¶
Reject blank names and invalid pattern syntax before streaming starts.
Source code in core/spakky-agent/src/spakky/agent/safety.py
redact(value)
¶
Return redacted text and the number of replacements applied.
find_matches(value)
¶
Return sanitized match locations without exposing raw text.
Source code in core/spakky-agent/src/spakky/agent/safety.py
StreamingRedactionPolicy(patterns, buffer_size=64, emit_chunk_size=None, failure_mode=StreamingGuardFailureMode.RAISE)
dataclass
¶
Bounded buffering policy balancing stream latency and redaction correctness.
__post_init__()
¶
Reject policies that would make the guard unbounded or silent.
Source code in core/spakky-agent/src/spakky/agent/safety.py
StreamingRedactionMatch(pattern_name, start, end, metadata=dict())
dataclass
¶
Sanitized final-audit match location for a missed redaction candidate.
to_payload()
¶
Serialize a match without the sensitive value itself.
Source code in core/spakky-agent/src/spakky/agent/safety.py
StreamingRedactionAudit(status, detected_count, redacted_count, missed_matches, buffer_size, emitted_char_count, original_char_count)
dataclass
¶
Final aggregate audit for a bounded streaming redaction session.
missed_count
property
¶
Return the number of raw candidates still present after streaming.
to_evidence_payload()
¶
Serialize audit evidence without raw streamed content.
Source code in core/spakky-agent/src/spakky/agent/safety.py
to_error_payload()
¶
Serialize a typed error payload for stream consumers.
Source code in core/spakky-agent/src/spakky/agent/safety.py
StreamingRedactionResult(chunks, audit=None, error=None)
dataclass
¶
Output produced by a bounded streaming redaction step.
StreamingRedactionSession(policy)
¶
Stateful bounded redactor for model token streams.
Source code in core/spakky-agent/src/spakky/agent/safety.py
push(chunk)
¶
Redact one token chunk and emit only the safe bounded prefix.
Source code in core/spakky-agent/src/spakky/agent/safety.py
finish()
¶
Flush the remaining buffer and run the mandatory final audit.
Source code in core/spakky-agent/src/spakky/agent/safety.py
guard_json_value(value, sensitive_fields, policy)
¶
Redact JSON-compatible values according to path-bound descriptors.
Source code in core/spakky-agent/src/spakky/agent/safety.py
schema_with_sensitive_metadata(schema, sensitive_fields, policy)
¶
Return a JSON schema copy with policy-approved sensitivity extensions.
Source code in core/spakky-agent/src/spakky/agent/safety.py
Tooling¶
Agent tool descriptor discovery contracts.
Idempotency
¶
Bases: StrEnum
Action idempotency declared by a tool.
ToolResumeAction
¶
Bases: StrEnum
Resume action allowed by stored tool idempotency metadata.
DataAccess
¶
Bases: StrEnum
Data access level declared by a tool.
Externality
¶
Bases: StrEnum
External side-effect boundary declared by a tool.
EvidenceCapture
¶
Bases: StrEnum
Evidence capture strategy for tool results.
ToolApprovalRequirement
¶
Bases: StrEnum
Human approval requirement at the tool boundary.
ToolRiskAxis
¶
Bases: StrEnum
Derived risk axes exposed for policy and UI decisions.
ToolPermission(name)
dataclass
¶
Typed permission marker attached to a tool descriptor.
__post_init__()
¶
Reject permission names that cannot be matched deterministically.
ToolEffects(data_access=DataAccess.NONE, externality=Externality.LOCAL, destructive=False, network=False)
dataclass
¶
Typed effect metadata used to derive display risk outside core.
read_only()
classmethod
¶
write_state()
classmethod
¶
external_side_effect()
classmethod
¶
Declare a tool that crosses an external side-effect boundary.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
destructive_action()
classmethod
¶
Declare a tool that may irreversibly mutate local or external state.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
TimeoutPolicy(seconds=None)
dataclass
¶
Optional timeout boundary for a tool invocation.
__post_init__()
¶
Reject non-positive timeout policies at definition time.
ResultBudget(max_bytes=None)
dataclass
¶
Optional result-size budget for model-facing tool output.
__post_init__()
¶
Reject result budgets that cannot constrain output.
ToolResumeMetadata(idempotency=Idempotency.UNKNOWN)
dataclass
¶
Stored idempotency metadata used when resuming an incomplete action.
from_metadata(metadata)
classmethod
¶
Build resume metadata from a tool descriptor metadata object.
action_for_completed_boundary()
¶
Return the resume action for an already completed action boundary.
action_for_incomplete_boundary()
¶
Return the resume action for an incomplete action boundary.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
AgentToolSchemaHandle(name, input_schema_name, output_schema_name, input_schema=dict(), output_schema=dict(), input_sensitive_fields=(), output_sensitive_fields=())
dataclass
¶
Stable schema names and generated JSON schemas owned by a descriptor.
__post_init__()
¶
Reject blank schema handles.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
input_schema_for(policy=None)
¶
Return model-facing input schema under the requested exposure policy.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
output_schema_for(policy=None)
¶
Return model-facing output schema under the requested exposure policy.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
AgentToolIdentity(owner_module, owner_qualname, name)
dataclass
¶
AgentToolMetadata(permissions=(), effects=ToolEffects(), idempotency=Idempotency.UNKNOWN, data_access=DataAccess.NONE, externality=Externality.LOCAL, timeout=TimeoutPolicy(), result_budget=ResultBudget(), evidence=EvidenceCapture.NONE, approval=ToolApprovalRequirement.DERIVED)
dataclass
¶
Typed approval, idempotency, and evidence metadata for a descriptor.
AgentToolApprovalContext(prompt=None, action_ref=None, metadata=dict())
dataclass
¶
Invocation-specific approval display and correlation metadata.
__post_init__()
¶
Reject blank override strings before they enter approval state.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
ToolRisk(axes=())
dataclass
¶
Derived typed risk axes for policy and evidence annotations.
requires_approval_candidate
property
¶
Return whether the risk is strong enough to suggest HITL approval.
__post_init__()
¶
Reject duplicate axes so risk comparisons stay deterministic.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
from_metadata(metadata)
classmethod
¶
Derive risk axes from source tool metadata.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
AgentToolRuntimeContext(state_id, conversation_id, call_id, tool_name)
dataclass
¶
Runtime correlation data injected into framework-owned tool callables.
__post_init__()
¶
Reject runtime context that cannot link events and evidence.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
AgentToolDefinition(name, schema_name, description=None, metadata=AgentToolMetadata())
dataclass
¶
Method-level metadata attached by @agent_tool before owner discovery.
__post_init__()
¶
Reject definitions that would make catalog lookup ambiguous.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
AgentToolDescriptor(identity, owner, callable, schema, description=None, metadata=AgentToolMetadata())
dataclass
¶
Discovered tool descriptor bound to an owner class and callable.
AgentToolBoundInvocation(args=(), kwargs=dict())
dataclass
¶
Python-call-ready tool invocation arguments.
AgentToolCatalog(descriptors=())
dataclass
¶
Deterministic catalog of descriptors discovered from an Agent class.
__post_init__()
¶
Reject duplicate identity or schema names before model lookup.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
by_identity(identity)
¶
Lookup a descriptor by typed identity.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
by_schema_name(schema_name)
¶
Lookup a descriptor by model-facing schema name.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
agent_tool(*, name=None, schema_name=None, description=None, permissions=(), effects=None, idempotency=Idempotency.UNKNOWN, data_access=None, externality=None, timeout=None, result_budget=None, evidence=EvidenceCapture.NONE, approval=ToolApprovalRequirement.DERIVED)
¶
Attach typed agent-tool metadata to a method object.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
discover_agent_tools(owner)
¶
Discover @agent_tool methods in deterministic class-definition order.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
get_agent_tool_definition(function)
¶
Return decorator metadata attached to a function object.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
bind_agent_tool_invocation(function, payload)
¶
Bind a structured model payload to a tool function signature.
Source code in core/spakky-agent/src/spakky/agent/tooling.py
Signal Hooks¶
Declarative signal-hook discovery contracts (ADR-0013 §1).
The framework runner owns the execution loop, but a developer still needs a
declarative seam to react to inbound signals (a steering instruction, an
external event, a user message) and emit their own stream items without writing
a loop body. @on_signal(kind) is that seam: it marks a coroutine generator
method the same way @agent_tool marks a tool method, and the runner invokes
every matching hook when it consumes a signal of that kind at a poll point.
Discovery mirrors discover_agent_tools exactly — an MRO walk reading
vars() (not the banned getattr) so the raw function objects are found
before descriptor binding — so the two declarative seams stay structurally
identical for a reader.
AgentSignalHookDefinition(kind)
dataclass
¶
Method-level metadata attached by @on_signal before owner discovery.
AgentSignalHookIdentity(owner_module, owner_qualname, member_name)
dataclass
¶
Hook identity independent from the developer-chosen method name.
key
property
¶
Return a stable key for deterministic ordering and logs.
AgentSignalHookDescriptor(identity, owner, callable, kind)
dataclass
¶
Discovered signal hook bound to an owner class and callable.
AgentSignalHookCatalog(descriptors=())
dataclass
¶
Deterministic catalog of signal hooks discovered from an Agent class.
__post_init__()
¶
Reject duplicate hook identities so dispatch order stays stable.
Source code in core/spakky-agent/src/spakky/agent/hooks.py
hooks_for(kind)
¶
Return every hook that handles the requested signal kind, in order.
Source code in core/spakky-agent/src/spakky/agent/hooks.py
on_signal(kind)
¶
Declare a method that reacts to one inbound signal kind.
The decorated method must be an async generator yielding AgentYield
items and accepting exactly one signal: AgentSignal argument besides
self. The runner invokes it when it consumes a signal of kind at a
poll point, and forwards every yielded item into the public stream.
Source code in core/spakky-agent/src/spakky/agent/hooks.py
discover_agent_signal_hooks(owner)
¶
Discover @on_signal methods in deterministic class-definition order.
Source code in core/spakky-agent/src/spakky/agent/hooks.py
Yield¶
Agent streaming yield contracts.
TextDelta = Token
module-attribute
¶
Backward-compatible token-yield payload alias.
Message = Progress
module-attribute
¶
Backward-compatible progress-yield payload alias.
AgentYieldKind
¶
Bases: StrEnum
Canonical public vocabulary yielded by agent execution.
AgentYield(kind, payload)
dataclass
¶
Typed stream item returned from an agent execute generator.
Token(text, metadata=dict())
dataclass
¶
Incremental model token intended for streaming clients.
Progress(message, current_step=None, metadata=dict())
dataclass
¶
Agent progress update intended for direct inbound adapter consumption.
Tool(name, call_id=None, arguments=dict(), result=None, metadata=dict())
dataclass
¶
Tool call or tool result surfaced by agent execution.
Evidence(evidence, metadata=dict())
dataclass
¶
Evidence item surfaced to the inbound adapter.
Approval(id, prompt, allowed_decisions, metadata)
dataclass
¶
Approval request surfaced to the inbound adapter.
Error(code, message, retryable=False, metadata=dict())
dataclass
¶
Recoverable or terminal execution error surfaced to the caller.
Cancel(reason=None, requested_by=None, metadata=dict())
dataclass
¶
Cancellation acknowledgement surfaced to the caller.
Final(output, metadata)
dataclass
¶
Final output carried by a generator stream.
Model Interface¶
Agent public interface ports.
ContextDigest(id, context_identity, source_manifest_ref, digest, derived_from_pack_ids=tuple(), compression_evidence_ref=None, algorithm=None, summary=None, created_at=None, metadata=dict())
dataclass
¶
Derived compression evidence for a context identity.
ContextFreshness
¶
Bases: StrEnum
Freshness classification for context rot and budget decisions.
ContextManifest(id, entries, origin_ref=None, evidence_refs=tuple(), created_at=None, metadata=dict())
dataclass
¶
Auditable composition record for model input context packs.
ContextManifestEntry(pack_id, source, role, origin_ref, evidence_ref=None, digest_ref=None, sensitive_fields=(), metadata=dict())
dataclass
¶
One audited pack entry inside a context manifest.
ContextPack(id, content, source, role, freshness=ContextFreshness.UNKNOWN, relevance=None, token_budget=ContextTokenBudget(), sensitivity=ContextSensitivity.INTERNAL, sensitive_fields=(), metadata=dict())
dataclass
¶
LLM-facing context unit derived from state, signal, or evidence.
guarded_content(policy=None)
¶
Return deterministic model-safe content for this context pack.
Source code in core/spakky-agent/src/spakky/agent/context.py
message_metadata(policy=None)
¶
Return non-content metadata for provider-neutral model messages.
Source code in core/spakky-agent/src/spakky/agent/context.py
ContextPackRole
¶
Bases: StrEnum
Semantic role of a context pack inside a model request.
ContextSensitivity
¶
Bases: StrEnum
Deterministic sensitivity metadata carried before model input.
ContextTokenBudget(max_tokens=None, estimated_tokens=None, reserved_output_tokens=None)
dataclass
¶
Token budget allocated to one context pack.
IAgentModel
¶
Bases: ABC
Outbound model adapter port owned by spakky-agent core.
capability
abstractmethod
property
¶
Return the backend capability descriptor queryable before a run.
capability_for(selection=None)
¶
Return capability for a run-specific model selection.
Existing fixed-model adapters can ignore the selector and inherit the default. Routing adapters can override this to expose per-model context windows, reasoning support, or token-counting support before a request.
Source code in core/spakky-agent/src/spakky/agent/interfaces/model.py
complete(request)
abstractmethod
async
¶
stream(request)
abstractmethod
¶
JsonSchemaConstraint(schema, strict=True)
dataclass
¶
JSON schema constraint shared by structured output and tool calling.
ModelCapability(supports_reasoning=False, context_window_tokens=None, supports_token_counting=False)
dataclass
¶
Provider-neutral declaration of a model backend's queryable abilities.
The agent runner consults this descriptor before a run to adjust behaviour
without invoking the backend. supports_reasoning gates whether the runner
expects REASONING_DELTA events; when False the adapter omits them rather
than failing (graceful degrade). context_window_tokens is None when the
backend does not declare a fixed limit. supports_token_counting declares
whether the backend can report token accounting for a request before sending it.
ModelError(code, message, retryable=False, metadata=dict())
dataclass
¶
Provider-neutral model failure payload.
ModelMessage(role, content, metadata=dict())
dataclass
¶
Provider-neutral model message.
ModelMessageRole
¶
Bases: StrEnum
Roles accepted by provider-neutral model messages.
ModelRequest(messages, context=tuple(), context_manifest=None, context_digest=None, structured_output=None, tool_calling=None, sampling=SamplingOptions(), streaming=StreamingOptions(), model_selection=None, metadata=dict())
dataclass
¶
Provider-neutral request passed to an agent model adapter.
assemble_messages(policy=None)
¶
Assemble prompt messages from typed context packs without concatenation.
Source code in core/spakky-agent/src/spakky/agent/interfaces/model.py
ModelResponse(content, structured_output=None, tool_calls=tuple(), usage=ModelUsage(), metadata=dict())
dataclass
¶
Provider-neutral non-streaming model response.
guarded(sensitive_fields, policy=None)
¶
Return a copy with sensitive output payloads deterministically guarded.
Source code in core/spakky-agent/src/spakky/agent/interfaces/model.py
ModelStreamEvent(kind, token_delta=None, message_delta=None, reasoning_delta=None, tool_call=None, tool_call_args_delta=None, structured_output=None, error=None, usage=None, metadata=dict())
dataclass
¶
Provider-neutral model streaming event.
token_delta carries the generic streamed token channel. message_delta
and reasoning_delta distinguish assistant-facing text from model reasoning
so callers can route or suppress reasoning independently. tool_call_args_delta
carries incremental tool-call argument text framed by TOOL_CALL_START and
TOOL_CALL_END boundary events that reference the same tool_call.
guarded(sensitive_fields, policy=None)
¶
Return a copy with sensitive streaming payloads guarded.
Source code in core/spakky-agent/src/spakky/agent/interfaces/model.py
ModelStreamEventKind
¶
Bases: StrEnum
Provider-neutral streaming event kinds emitted by a model adapter.
ModelToolCall(name, arguments, call_id=None, metadata=dict())
dataclass
¶
Tool invocation candidate emitted by a model adapter.
guarded(sensitive_fields, policy=None)
¶
Return a copy with sensitive argument values deterministically guarded.
Source code in core/spakky-agent/src/spakky/agent/interfaces/model.py
ModelToolChoice
¶
Bases: StrEnum
Provider-neutral tool calling strategy requested from a model adapter.
ModelToolSpec(name, parameters, description=None, metadata=dict())
dataclass
¶
LLM-facing tool descriptor normalized by agent tooling.
ModelUsage(input_tokens=None, output_tokens=None, total_tokens=None)
dataclass
¶
Token accounting reported by a model adapter.
SamplingOptions(temperature=None, top_p=None, max_tokens=None)
dataclass
¶
Portable model sampling options.
StreamingOptions(include_usage=True, include_progress=True)
dataclass
¶
Portable model streaming options.
StructuredOutputSpec(constraint, output_type_name=None)
dataclass
¶
Structured output contract requested from a model adapter.
ToolCallingSpec(tools, choice=ModelToolChoice.AUTO)
dataclass
¶
Tool calling contract requested from a model adapter.
IAgentEvidenceRepository
¶
IAgentSignalRepository
¶
IAgentStateRepository
¶
Bases: ABC
Materialized state repository for long-running agent executions.
get(state_id)
abstractmethod
¶
get_or_none(state_id)
abstractmethod
¶
save(state)
abstractmethod
¶
list_by_status(status)
abstractmethod
¶
Return states matching an externally observable lifecycle status.
list_resume_candidates()
abstractmethod
¶
Return active or interrupted states that may resume after restart.
ConversationTurn(role, content, metadata=dict())
dataclass
¶
One persisted exchange in a multi-turn conversation transcript.
A turn is the protocol-neutral unit a TaskStore persists: who spoke
(role) and what was said (content). It is intentionally narrower than
a model-request ModelMessage — the transcript records the user/assistant
dialogue that seeds future turns, not the system or evidence framing the
runner assembles fresh on each request. as_model_message projects a turn
back into the model-request vocabulary when the runner replays history.
__post_init__()
¶
Reject turns that cannot seed a future model request.
Source code in core/spakky-agent/src/spakky/agent/interfaces/task_store.py
as_model_message()
¶
Project this turn into a model-request message for history replay.
ITaskStore
¶
Bases: ABC
Durable conversation-history store keyed by conversation_id.
Persists the running transcript of a server-side session so a later run with
the same conversation_id continues the conversation (ADR-0013 §6). A2A
can map its contextId to this key for transcript replay, while A2A task
snapshots are stored by spakky-a2a's repository bridge.
load_history(conversation_id)
abstractmethod
¶
Return the persisted transcript for a conversation in turn order.
Returns an empty sequence for a conversation that has no persisted turns yet — the first turn of a brand-new conversation.
Source code in core/spakky-agent/src/spakky/agent/interfaces/task_store.py
append_turns(conversation_id, turns)
abstractmethod
¶
Append new turns to a conversation's transcript in order.
Provider-neutral agent model port.
ModelMessageRole
¶
Bases: StrEnum
Roles accepted by provider-neutral model messages.
ModelMessage(role, content, metadata=dict())
dataclass
¶
Provider-neutral model message.
JsonSchemaConstraint(schema, strict=True)
dataclass
¶
JSON schema constraint shared by structured output and tool calling.
StructuredOutputSpec(constraint, output_type_name=None)
dataclass
¶
Structured output contract requested from a model adapter.
ModelToolChoice
¶
Bases: StrEnum
Provider-neutral tool calling strategy requested from a model adapter.
ModelToolSpec(name, parameters, description=None, metadata=dict())
dataclass
¶
LLM-facing tool descriptor normalized by agent tooling.
ToolCallingSpec(tools, choice=ModelToolChoice.AUTO)
dataclass
¶
Tool calling contract requested from a model adapter.
SamplingOptions(temperature=None, top_p=None, max_tokens=None)
dataclass
¶
Portable model sampling options.
StreamingOptions(include_usage=True, include_progress=True)
dataclass
¶
Portable model streaming options.
ModelSelection(provider=None, model=None, profile=None, metadata=dict())
dataclass
¶
Provider/model selector carried by one Agent run.
A service may let a user choose OpenAI, Anthropic, Vertex, OpenRouter, vLLM, or another provider per run. The selector is intentionally provider-neutral: concrete adapters or routing models decide which values they accept.
__post_init__()
¶
Reject blank selector fields before they reach provider adapters.
Source code in core/spakky-agent/src/spakky/agent/interfaces/model.py
ModelRequest(messages, context=tuple(), context_manifest=None, context_digest=None, structured_output=None, tool_calling=None, sampling=SamplingOptions(), streaming=StreamingOptions(), model_selection=None, metadata=dict())
dataclass
¶
Provider-neutral request passed to an agent model adapter.
assemble_messages(policy=None)
¶
Assemble prompt messages from typed context packs without concatenation.
Source code in core/spakky-agent/src/spakky/agent/interfaces/model.py
ModelUsage(input_tokens=None, output_tokens=None, total_tokens=None)
dataclass
¶
Token accounting reported by a model adapter.
ModelToolCall(name, arguments, call_id=None, metadata=dict())
dataclass
¶
Tool invocation candidate emitted by a model adapter.
guarded(sensitive_fields, policy=None)
¶
Return a copy with sensitive argument values deterministically guarded.
Source code in core/spakky-agent/src/spakky/agent/interfaces/model.py
ModelError(code, message, retryable=False, metadata=dict())
dataclass
¶
Provider-neutral model failure payload.
ModelResponse(content, structured_output=None, tool_calls=tuple(), usage=ModelUsage(), metadata=dict())
dataclass
¶
Provider-neutral non-streaming model response.
guarded(sensitive_fields, policy=None)
¶
Return a copy with sensitive output payloads deterministically guarded.
Source code in core/spakky-agent/src/spakky/agent/interfaces/model.py
ModelStreamEventKind
¶
Bases: StrEnum
Provider-neutral streaming event kinds emitted by a model adapter.
ModelStreamEvent(kind, token_delta=None, message_delta=None, reasoning_delta=None, tool_call=None, tool_call_args_delta=None, structured_output=None, error=None, usage=None, metadata=dict())
dataclass
¶
Provider-neutral model streaming event.
token_delta carries the generic streamed token channel. message_delta
and reasoning_delta distinguish assistant-facing text from model reasoning
so callers can route or suppress reasoning independently. tool_call_args_delta
carries incremental tool-call argument text framed by TOOL_CALL_START and
TOOL_CALL_END boundary events that reference the same tool_call.
guarded(sensitive_fields, policy=None)
¶
Return a copy with sensitive streaming payloads guarded.
Source code in core/spakky-agent/src/spakky/agent/interfaces/model.py
ModelCapability(supports_reasoning=False, context_window_tokens=None, supports_token_counting=False)
dataclass
¶
Provider-neutral declaration of a model backend's queryable abilities.
The agent runner consults this descriptor before a run to adjust behaviour
without invoking the backend. supports_reasoning gates whether the runner
expects REASONING_DELTA events; when False the adapter omits them rather
than failing (graceful degrade). context_window_tokens is None when the
backend does not declare a fixed limit. supports_token_counting declares
whether the backend can report token accounting for a request before sending it.
IAgentModel
¶
Bases: ABC
Outbound model adapter port owned by spakky-agent core.
capability
abstractmethod
property
¶
Return the backend capability descriptor queryable before a run.
capability_for(selection=None)
¶
Return capability for a run-specific model selection.
Existing fixed-model adapters can ignore the selector and inherit the default. Routing adapters can override this to expose per-model context windows, reasoning support, or token-counting support before a request.
Source code in core/spakky-agent/src/spakky/agent/interfaces/model.py
complete(request)
abstractmethod
async
¶
stream(request)
abstractmethod
¶
Persistence ports for durable agent state, signal, and evidence.
IAgentStateRepository
¶
Bases: ABC
Materialized state repository for long-running agent executions.
get(state_id)
abstractmethod
¶
get_or_none(state_id)
abstractmethod
¶
save(state)
abstractmethod
¶
list_by_status(status)
abstractmethod
¶
Return states matching an externally observable lifecycle status.
list_resume_candidates()
abstractmethod
¶
Return active or interrupted states that may resume after restart.
IAgentSignalRepository
¶
IAgentEvidenceRepository
¶
Persistence port for multi-turn conversation history (ADR-0013 §6).
ADR-0013 §6 supports multi-turn conversations through two paths that the framework runner reconciles:
- server-side persisted sessions — the framework persists the running
transcript and continues it by
conversation_id. This port is that conversation-history persistence contract. It is protocol-neutral, but it is not the A2A task snapshot repository:spakky-a2aowns A2ATaskstorage through its plugin repository and bridges it toa2a-sdkTaskStore. - client-injected history — a stateless caller passes the prior transcript
on each run (
RunAgentInput.message_history) and no store is consulted.
The conversation_id key is the protocol-neutral thread identifier carried by
every event (AgentEventAttribution.conversation_id) and seeded by
RunAgentInput.effective_conversation_id. AG-UI projects it as threadId
and A2A projects it as contextId when an adapter wants transcript replay;
A2A protocol Task records remain plugin-owned snapshots.
ConversationTurn(role, content, metadata=dict())
dataclass
¶
One persisted exchange in a multi-turn conversation transcript.
A turn is the protocol-neutral unit a TaskStore persists: who spoke
(role) and what was said (content). It is intentionally narrower than
a model-request ModelMessage — the transcript records the user/assistant
dialogue that seeds future turns, not the system or evidence framing the
runner assembles fresh on each request. as_model_message projects a turn
back into the model-request vocabulary when the runner replays history.
__post_init__()
¶
Reject turns that cannot seed a future model request.
Source code in core/spakky-agent/src/spakky/agent/interfaces/task_store.py
as_model_message()
¶
Project this turn into a model-request message for history replay.
ITaskStore
¶
Bases: ABC
Durable conversation-history store keyed by conversation_id.
Persists the running transcript of a server-side session so a later run with
the same conversation_id continues the conversation (ADR-0013 §6). A2A
can map its contextId to this key for transcript replay, while A2A task
snapshots are stored by spakky-a2a's repository bridge.
load_history(conversation_id)
abstractmethod
¶
Return the persisted transcript for a conversation in turn order.
Returns an empty sequence for a conversation that has no persisted turns yet — the first turn of a brand-new conversation.
Source code in core/spakky-agent/src/spakky/agent/interfaces/task_store.py
append_turns(conversation_id, turns)
abstractmethod
¶
Append new turns to a conversation's transcript in order.
Types¶
Shared JSON-compatible type aliases for agent contracts.
JsonPrimitive = bool | float | int | str | None
¶
Scalar JSON value accepted by agent public contracts.
JsonValue = JsonPrimitive | Mapping[str, JsonValue] | Sequence[JsonValue]
¶
Recursive JSON-compatible value used at model, signal, and evidence boundaries.
JsonObject = Mapping[str, JsonValue]
¶
JSON object payload used by public agent contracts.
Plugin¶
Plugin initialization entry point for spakky-agent.
initialize(app)
¶
Initialize spakky-agent core contracts.
The package intentionally registers no persistence implementation; production repositories must arrive through feature contributions.
Source code in core/spakky-agent/src/spakky/agent/main.py
Bootstrap validation for Agent Pod instances.
AgentBootstrapValidationPostProcessor()
¶
Bases: IPostProcessor, IContainerAware
Validate Agent metadata during application bootstrap.
Initialize without assuming application context injection happened.
Source code in core/spakky-agent/src/spakky/agent/post_processor.py
set_container(container)
¶
post_process(pod)
¶
Fail startup when an Agent contract is no longer valid.