keelgate.tools¶
Stability of each symbol (stable or provisional) is listed in the API contract. Narrative and semantics are in the integration contract.
Tool registry and declaration, with each tool tagged by side effect.
CallContext
dataclass
¶
Per-call facts, split by trust.
tenant_id and policy_context come from the harness and are trusted:
they feed the policy engine. rationale, sources, confidence and
verifier_flags come from the model or its tooling and are only ever shown
to a human approver; they never influence a decision.
Claim
dataclass
¶
The outcome of claiming an idempotency key.
state says whether the caller may run the call, must replay the stored output, or is
looking at a call that is still in flight or of unknown outcome.
ClaimState
¶
Bases: StrEnum
Where an idempotency key stands when a caller tries to claim it.
NEW may run; DONE replays the stored result; IN_FLIGHT is running now;
UNKNOWN died mid-flight and must never be retried automatically; CONFLICT means the
key was reused for different arguments.
DirectInvocationError
¶
Bases: RuntimeError
A tool was called without going through the gateway.
ErrorCode
¶
Bases: StrEnum
Why the gateway refused or failed a call.
Stable machine-readable codes, safe to show a model: they never carry model-supplied text.
IdempotencyStore
¶
Bases: Protocol
Where idempotency keys and stored results live.
Implement this to share them across processes. claim must be atomic, and a key left in
flight by a process that died must read as UNKNOWN.
InMemoryIdempotencyStore
¶
Process-local idempotency store.
Fine for tests and single-process use. It is lost on restart, so use SqliteIdempotencyStore
(or your own IdempotencyStore) when a WRITE must never run twice across restarts.
OutcomeStatus
¶
Bases: StrEnum
The four things a gateway call can end as.
OK, DENIED (policy or authority said no), APPROVAL_REQUIRED (parked for a human)
and ERROR.
RegistryFrozenError
¶
Bases: RuntimeError
A tool was registered after the registry was frozen.
SideEffect
¶
Bases: StrEnum
What a tool can do to the world. This is what the policy gate keys off.
SqliteIdempotencyStore
¶
Durable idempotency, safe to share between processes on one host.
This is what makes resume safe. If a process dies after a WRITE completed but
before the loop checkpointed it, the key is DONE and the retry replays the
stored result. If it dies during the WRITE, the key is still IN_FLIGHT, which
a retry reads as outcome-unknown and refuses to repeat: a possibly-executed money
movement is never run twice automatically.
release
¶
Forget a claim that provably did not execute, so a retry is allowed.
Tool
¶
A declared tool. Not callable: execute it through the gateway.
ToolDefinitionError
¶
Bases: ValueError
The tool is declared unsafely or inconsistently. Raised at import time.
ToolError
¶
Bases: BaseModel
A refusal or failure a model can act on: a code, fixed-wording message and hint, and whether a retry could help.
ToolGateway
¶
The single choke point every tool call passes through.
Grant, tenant, tool, capability, side-effect ceiling, paper-only mode, argument validation, budget, idempotency, policy, approval, then execution. A refusal is returned as a result, never raised, and the audit record is written before any side effect.
call
async
¶
call(
*,
tool_name: str,
arguments: Mapping[str, Any],
grant_token: str,
context: CallContext,
) -> ToolOutcome
Run one proposed tool call through every gate. Never raises for a refusal.
ToolOutcome
dataclass
¶
The structured result of one gateway call.
A status, the (untrusted) output or a model-actionable error, and for a parked call the approval to wait for.
for_model
¶
The control-plane part of the result, safe to show a model.
Deliberately excludes output: that is untrusted data, and the caller
must decide explicitly how to present it.
ToolRefusedError
¶
Bases: Exception
Raised by a tool body to say: I did not do anything, so a retry is safe.
Any other exception from a WRITE tool is treated as possibly-partial, and the call is never retried automatically.
ToolRegistry
¶
The set of tools an agent may be offered.
A gateway freezes its registry on construction, so a tool cannot appear mid-run.
describe
¶
Tool schemas to offer a model. Omits capabilities and policy details.
ToolSpec
dataclass
¶
Everything the gateway knows about a tool.
Its schemas, capability, side effect, timeout, cost estimate, and the functions that derive its idempotency key and the facts policy needs.
Untrusted
¶
Bases: Generic[T]
Marks data that came from outside the harness.
Tool output, retrieved documents and web content may contain text written by
an attacker. Wrapping it makes the trust boundary visible in the types: code
must call :meth:unwrap_untrusted by name to read it, and a reviewer can grep
for every place that does.
tool
¶
tool(
*,
capability: str,
side_effect: SideEffect,
name: str | None = None,
description: str | None = None,
timeout_s: float = 10.0,
cost_estimate: float = 0.0,
idempotency_key: IdempotencyKeyFn | None = None,
resource: ResourceFn | None = None,
) -> Callable[[Callable[..., Any]], Tool]
Declare a tool.
The function takes exactly one argument, a Pydantic model, and returns a
Pydantic model; both annotations are required and become the input and
output schemas. resource maps the validated input to the facts the policy
needs ({"symbol": ..., "notional": ...}) so policy packs stay generic.
A WRITE tool must supply idempotency_key.