4c338ed914
Post-merge validation fixes (upstream v0.3.0 + Ai4Sci fork): - llm/patches.py: restore the two module-level patch calls the merge dropped (_patch_openai_empty_sse_keepalive, _patch_deepagents_extracted_document_text) and make _is_ccproxy_codex accept an explicit base_url/api_key so the invocation plan can classify an endpoint without mutating the process env. - llm/models.py: an explicit per-call plan now wins over EVOSCIENTIST_USE_RESPONSES_API (env is only a default), an explicit caller `reasoning` block survives an explicit use_responses_api=False, and the third-party (openrouter) default effort stays the fork's fixed `medium`. - EvoScientist.py: sub-agent stacks pass NO_OP_SINK as `events` instead of None. - middleware/error_normalization.py: platform-generated diagnostics (ModelOutputTruncatedError) keep their actionable text while provider SDK errors still get the canned redacted message. - pyproject.toml: hold google-genai 1.x (langchain-google-genai>=4.3.7,<4.4) because llm/gemini_interactions.py drives the 1.x Interactions API; this is also what deepagents 0.7.13 requires. - config/settings.py: restore upstream's use_responses_api config field. `reasoning_effort` stays deleted on purpose — Ai4Sci keeps reasoning an invocation-plan parameter, never a deployment-env override. - tests: align upstream tests that encode replaced behaviour (ccproxy responses-api context, reasoning-effort-overrides-env, fingerprint coverage) with the fork's contracts.
Model Runtime Layout
The model runtime has three configuration and execution boundaries.
| Layer | Source | Owns | Must not own |
|---|---|---|---|
| Provider | configuration/provider.py |
Adapter identity, credentials, endpoints, headers, connection defaults | Model capabilities, model token limits, derived tool transport |
| Model | configuration/model.py |
Provider model ID, capabilities, limits, canonical parameters, access, billing | Credentials, base URL, SDK client options, derived tool transport |
| Invocation | invocation/contract.py |
Immutable API mode, output parameter, tool transport, streaming flag, final SDK parameters | Admin persistence, credentials, routing decisions |
Supporting modules have narrower responsibilities:
model_config_v4.pynormalizes and persists the Provider + ModelProfile admin contract, then projects it to the stable runtime schema.model_config.pyparses and validates the runtime schema. It re-exports the provider and model contracts for compatibility with existing integrations.adapter_registry.pydeclares provider/model-family support and converts canonical model parameters into provider SDK parameters.runtime.pyselects a frozen route, asks its adapter to compile parameters, compiles anInvocationPlan, and constructs the provider client from that plan only.
The call chain is fixed:
V4 Provider + ModelProfile
-> normalize and validate
-> V3 runtime projection
-> select provider endpoint and model profile
-> merge canonical model parameters
-> provider adapter compilation
-> immutable InvocationPlan validation
-> provider SDK call
Important invariants:
- Environment variables may provide secrets, proxy settings, and timeouts; they cannot select an API protocol or rewrite a compiled invocation.
tool_call_transportis not administrator configuration. It is derived asnativewhencapabilities.tools=true, otherwisedisabled.- Exactly one provider output-limit parameter is allowed in a compiled plan:
max_output_tokens,max_completion_tokens, ormax_tokens. - Provider-specific parameter names are selected by the adapter. Gateway, frontend, and generic runtime code must not guess them from model names.
- Runtime logs report the final non-secret plan and parameter names. They must never include credentials, authorization headers, or raw secret values.
- Provider input projection removes assistant history that has neither final
text nor a tool call. A newly completed empty response receives one bounded
same-route repair attempt, then fails as
MODEL_PROVIDER_RESPONSE_INVALID.