Repository navigation
Document decision models served over the System One API in common.ai - #74266
Merged
Merged
Conversation
pydantic-ai 2.53.0 added SystemOneModel, which runs any decision model behind the POST /v1/systemone API Jev uses (Ollama, Strands Decider, Kev and others). PydanticAIHook already builds it from a pydanticai connection through its generic provider path, so this is docs and examples only. Rename the "Classifier models" page to "Decision models" with a redirect, cover both the typesafe: and system-one: backends in setup, and make the decision-model examples read a decision_default connection with every option described, so they run unchanged on either backend. Co-Authored-By: Claude <noreply@anthropic.com>
phanikumv
approved these changes
Oct 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
pydantic-ai 2.53.0 added
SystemOneModel(pydantic/pydantic-ai#8942), which runs any decision model served over the samePOST /v1/systemoneAPI as TypeSafe's Jev: decision models in Ollama 0.35+, AWS's Strands Decider, Kev, CLM, Laya. The Common AI docs still said Jev was the only decision model pydantic-ai supports.This needs no code change.
PydanticAIHookresolves an unknown prefix through its generic path,infer_provider_class(prefix)(api_key=conn.password, base_url=conn.host), andSystemOneProvidertakes exactly those two arguments. Apydanticaiconnection with the server URL in Host andsystem-one:<model>as its Model is the whole integration. The end-to-end run below confirms it.So this PR is docs and examples:
classifier_models.rstbecomesdecision_models.rst(redirect added). "Decision model" is the term pydantic-ai, Strands and Cloudflare all use now, and the operators already call the gatedecision_policy. Setup covers both backends,typesafe:andsystem-one:.example_classifier_model.pybecomesexample_decision_model.py, and its Dags becomeexample_decision_model_branch/example_decision_model_confidence. These Dags,example_llm_branch_decision_policyand the decision-model retry policies now read adecision_defaultconnection and take the model from it rather than hard-codingmodel_id="typesafe:jev-1.13.0", so the same Dag runs on either backend.Design rationale
The examples now describe every option. The first end-to-end run failed with a 422: for an option with no description, pydantic-ai sends
criteria: {option: null}, and Strands Decider 0.1.0 accepts only string criteria. It also requires question text, which an operator with the default emptysystem_promptdoes not send. The branch example now passesbranches=, and the classify example uses anEnumwithUseEnumMemberDocstringsinstead of a bareLiteral. The decision models page documents both requirements, since they are the first thing a Strands Decider user would hit, and thebranchesdocstring onLLMBranchOperatorsays the same.A
system-one:model's option cap is the server's. pydantic-ai refuses a question over Jev's cap before sending it. A model reached through a connection carries noDecisionModelProfile, so a question over a System One server's cap (Ollama's is 26) comes back as an HTTP error instead. The page says so.Cloudflare's Clef is not named. Its changelog says it "follows the System One API", but Workers AI serves it at
/ai/run. I have not confirmed thatSystemOneModelcan reach it, so the docs don't claim it.Gotchas
example_decision_model.pyimportsUseEnumMemberDocstrings, which shipped in pydantic-ai-slim 2.46. The provider floor stays at 2.33. The example-Dag import test already skips under lowest dependencies, and the page and the example state the versions needed (2.46 for the examples, 2.53 forsystem-one:). On an older pydantic-ai, asystem-one:connection fails with the hook's existing "is not a provider pydantic-ai recognizes" error.jev_defaulttodecision_default). The retry-policy example keeps its note that its confidence bars were calibrated onjev-1.13.0and need measuring again for another model.End-to-end run
Airflow
mainunder breeze, sqlite, pydantic-ai-slim 2.53.0. Strands Decider 2B (StrandsAgents/strands-decider-2B-hobson-v19) served locally bystrands-decider serve. The three Dags ran unmodified from the provider's example-Dag bundle. The classify step was re-run throughPydanticAIHookafter the example'sEnumgot its class docstring: stillresource, confidence 0.61.example_llm_branch_decision_policyrerunat confidence 0.74, above the 0.6 bar.page_oncallandignoreskippedexample_decision_model_branchgrant_bucket_write.restore_deleted_bucketandwait_and_retryskippedexample_decision_model_confidenceresourceat 0.63, andactfiled it for review (0.5 to 0.8 band)The connection, with the server URL in Host and the
system-one:model:The
decisionXCom fromexample_llm_branch_decision_policy, with the model, confidence and probabilities Strands Decider returned:example_decision_model_confidence. The red runs in the grid are the earlier attempts: the previous example's undescribed options (the 422 above), plus a crash of the local model server.Follow-ups
ToolCallJudge(pydantic-ai-harness 0.53) is a natural fit for unattended agents, but it builds its judge model when the Dag file is parsed, so today its credentials can only come from environment variables, not an Airflow connection. That gets its own PR.