Build an agent-backed bound operation
Use this pattern when the application owns identifiers and exact operations, but a bounded semantic choice belongs to the agent. The example uses the keyless test model and a harmless local operation. Keyless does not mean dry-run: capability code executes for real. Never attach destructive or privileged operations to a test-model endpoint.
Complete example
Section titled “Complete example”Install summonpot[serve] and save as agent_summary.py:
from typing import Literal
from pydantic import BaseModel, Fieldfrom summonpot import AgentChoice, Exactly, FromRequest, Operation, Required, Summon
class SummaryRequest(BaseModel): topic: str = Field(min_length=1, max_length=200)
class SummaryResponse(BaseModel): summary: str style: Literal["brief", "detailed"]
def build_summary(topic: str, style: Literal["brief", "detailed"]) -> SummaryResponse: """Build a deterministic local summary candidate.""" limit = 80 if style == "brief" else 240 return SummaryResponse(summary=topic[:limit], style=style)
summary_operation = Operation( build_summary, bind={"topic": FromRequest("topic"), "style": AgentChoice()}, output=SummaryResponse,)
summon = Summon("summary-api")
@summon("/summarize")def summarize( request: SummaryRequest, result=Required(summary_operation, calls=Exactly(1)),) -> SummaryResponse: """Summarize the request topic and choose a brief or detailed style.""" ...
if __name__ == "__main__": summon.serve(host="127.0.0.1", port=8000)Run the local server:
SUMMONPOT_MODEL=test python agent_summary.pyCall the public HTTP route from another terminal:
curl -i -X POST http://127.0.0.1:8000/summarize \ -H 'Content-Type: application/json' \ -d '{"topic":"A concise contract separates trusted request data from bounded choices."}'The test model supplies placeholder agent output, not a useful semantic answer; the operation still runs. The response must validate as SummaryResponse, and Required means the operation must succeed before a successful final output. Do not treat the final text as proof that it reproduces the operation result: local schema validation constrains shape and types, not semantic provenance.
Follow the authority boundary
Section titled “Follow the authority boundary”SummaryRequestvalidates caller input.FromRequest("topic")injects that validated topic; it is absent from the model-visible operation arguments.AgentChoice()is the only model-controlled argument in this declaration. It grants a choice within the registeredbuild_summarycallable, not permission to select another function or trusted customer identity.Required(..., calls=Exactly(1))sets the mandatory operation and call bound. Runtime state enforces the bound; the prompt alone is not enforcement.output=SummaryResponsevalidates operation output before it can count as a successful required call. The endpoint response is separately validated.
Operation outputs and valid-looking final responses do not imply authorization, atomicity, idempotency, exactly-once completion, or a causal link between returned text and operation result. Enforce access control in the operation; design retries and side effects explicitly.
Common mistakes
Section titled “Common mistakes”- Do not make a customer ID an
AgentChoice; bind trusted request fields and authorize them in application code. - Do not expect keyless model output to exercise the semantic behavior of a real provider. This is a wiring check, not quality evaluation.
- Do not expose shell, raw database connections, arbitrary SQL, or broad service objects as capabilities.
- Do not assume a failed output validation undoes an operation that already had side effects.
- Do not switch to
Operation(fn)with missing bindings to get a permissive fallback; unsupported explicit declarations fail at registration.
Limits of the shipped slice
Section titled “Limits of the shipped slice”The runtime-enforced bound-operation slice supports the explicit FromRequest and direct AgentChoice binding vocabulary with compatible receiving types and exact output contracts. The no-model path is stricter and permits no unresolved AgentChoice. Bare callable dependencies remain on the legacy agent path. FromResult, FromContext, after, collection-backed choices, broader graph execution, and multi-operation deterministic compilation are planned/rejected for the current explicit runtime slice. See the reference and roadmap.
For exact model-free execution, use Build a model-free endpoint. For provider/runtime setup and HTTP errors, see Operations and troubleshooting.