soev_agents.testing.http
Conformance checks for the threads and public HTTP profiles.
The suite sends HTTP requests to a running deployment and checks the HTTP responses of the threads API:
the event streams, the refusals, the failure and resume, the cancel, the replay and the delete. The deployment runs
ConformanceAgent, so the suite needs no live model. Run it from Python with run_conformance, or from the
command line with python -m soev_agents.testing.http --url <base URL>.
The command expects ConformanceAgent under the name http-conformance (--agent). --mount public checks the
routes of Mount.public(), and --profile public runs the public profile. --auth-provider module:object gives
an AuthProvider.
The agent under test
The deployment serves this scripted agent.
ConformanceAgent
classConformanceAgent()The scripted agent that the HTTP conformance suite runs against. It calls no live model.
Register it in the deployment under the name of ConformanceTarget.agent, and give create_app the argument
models=["scripted"]. The suite checks that the deployment refuses another model with 422. Each fresh input is
one command:
"output": record aconformance_noteevent with the text"é世界", then the output of a scripted model."request": record aRequestof the kindclarificationthat expects an integer. A response continues the turn as"output"does."slow": record nothing and wait until the run is cancelled."fail": raise aTransientError, so that the turn fails. A resume then continues as"output"does.- An integer: continue as
"output"does.
The scripted model gives the text "scripted output é世界" and the reasoning "scripted reasoning". A streamed
call yields both as fragments first. The output names the model of the latest input, or "scripted".
Make the agent, with slow_started clear.
attributeinput= …The input class. It accepts the four commands and any integer.
attributeelement_typesSequence[type[Element]]= ()No element types.
attributeevent_typesSequence[type[Event]]= …The type of the conformance_note event.
attributeslow_startedAn asyncio.Event that is set while a "slow" command waits. A ConformanceSignals can
wait on it in wait_running.
methodbuild(resources, turn, model) -> GraphRunning the suite
A target says where the deployment is and which policies it applies. The report says which checks passed.
run_conformance
functionrun_conformanceasync (target, *, profile='threads') -> ConformanceReportRun the conformance suite against target, and delete each thread that it opened.
The threads profile checks the threads API: the contract and capabilities, history and fork, open requests
and refusals, failure and resume, a running thread and its cancel, replay and delete, the declared policies, and
the OpenAPI document. The public profile adds the tool, model and thread lists, and the task completions, for
each of these routes that target.mount enables. The suite stops at the first check that fails. It skips no
check of an operation that the target enables.
paramtargetConformanceTargetThe deployment and its policies.
Returns
ConformanceReportThe report: the profile, the checks that passed and the number of HTTP requests.
Raises:
ConformanceTarget
dataclassConformanceTarget(base_url, mount, auth, agent, model=None, timeout=10.0, transport=None, unauthorized_status=None, conceal_foreign=False, error_media_type='application/json', signals=None, task_error=None)The deployment that the suite checks, and the policies that it applies.
parambase_urlstrThe base URL of the deployment.
parammountMountThe routes that the deployment serves. The suite checks only the routes that the Mount enables.
Mount.public() gives the routes of the public profile.
paramauthAuthProviderThe provider of the headers of each HTTP request.
paramagentstrThe name under which the deployment serves ConformanceAgent.
parammodelstr | None= NoneThe model that each opened thread names, or None for the deployment's default model.
paramtimeoutfloat= 10.0The seconds that one HTTP request, or one wait for a signal, can take.
paramtransporthttpx.AsyncBaseTransport | None= NoneThe httpx transport, for example an httpx.ASGITransport for an app in the same process, or
None for the network.
paramunauthorized_statusint | None= NoneThe status that the deployment gives an unauthorized open, or None to skip the
admission check.
paramconceal_foreignbool= FalseWhether the deployment returns 404 for a thread of another identity. True adds the
ownership check.
paramerror_media_typestr= 'application/json'The media type of the deployment's error bodies.
paramsignalsConformanceSignals | NoneConformanceReport
dataclassConformanceReport(profile, checks, requests)The result of a conformance run that passed.
paramprofilestrThe profile that ran: "threads" or "public".
paramcheckstuple[str, ...]The name of each group of checks that passed, in run order.
paramrequestsintThe number of HTTP requests that the suite sent, cleanup included.
ConformanceSignals
protocolConformanceSignalsThe readiness signals of a deployment in the same process, which the suite waits on.
The suite needs them when an ASGI transport buffers the event streams. Give them when the deployment runs in the same process as the suite. The suite then waits on these signals, and not on the event stream, before it checks a running thread or deletes a thread during a replay.
methodwait_runningasync (thread_id) -> Nonemethodwait_eventsasync (thread_id, after) -> NoneAuthentication
An auth provider gives the headers of each HTTP request that the suite sends.
AuthProvider
protocolAuthProviderThe source of the authentication headers of each HTTP request that the suite sends.
methodheadersasync (request, *, identity) -> Mapping[str, str]Return the headers that authenticate request as identity.
The suite calls it once for each HTTP request, cleanup included, after the body is serialized. So a provider can sign the exact body. Read secrets from the provider's own environment.
paramrequestTestRequestThe HTTP request that the suite is about to send.
paramidentitystrWho sends it: "owner" for the normal checks, "unauthorized" for the admission check, and
"other" for the ownership check.
Returns
Mapping[str, str]The headers to add to the HTTP request.
NoAuth
classNoAuthThe auth provider of an anonymous deployment: it adds no headers.
methodheadersasync (request, *, identity) -> Mapping[str, str]Return no headers, for any HTTP request and any identity.
paramrequestTestRequestThe HTTP request that the suite is about to send.
paramidentitystrWho sends it.
Returns
Mapping[str, str]An empty mapping.
TestRequest
dataclassTestRequest(operation, method, path, body, thread_id, after=0)One HTTP request that the suite is about to send, as its auth provider sees it.
paramoperationstrWhat the HTTP request does: open, read, inputs, resume, events, fork, cancel,
delete, health, capabilities, openapi, tools, models, list or task.
parammethodstrThe HTTP method.
parampathstrThe path, with its query string, below the base URL.
parambodybytesThe exact body that the suite sends, as JSON bytes. Empty for an HTTP request without a body.
paramthread_idstr | NoneThe thread that the HTTP request is about, or None.
paramafterint= 0The cursor that an events request sends as Last-Event-ID, else 0.