Files
EvoScientist-Multi/EvoScientist/llm
m4 4c338ed914 fix(merge): resolve integration gaps found by running the v0.3.0 test suite
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.
2026-09-13 16:57:03 +08:00
..

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.py normalizes and persists the Provider + ModelProfile admin contract, then projects it to the stable runtime schema.
  • model_config.py parses and validates the runtime schema. It re-exports the provider and model contracts for compatibility with existing integrations.
  • adapter_registry.py declares provider/model-family support and converts canonical model parameters into provider SDK parameters.
  • runtime.py selects a frozen route, asks its adapter to compile parameters, compiles an InvocationPlan, 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:

  1. Environment variables may provide secrets, proxy settings, and timeouts; they cannot select an API protocol or rewrite a compiled invocation.
  2. tool_call_transport is not administrator configuration. It is derived as native when capabilities.tools=true, otherwise disabled.
  3. Exactly one provider output-limit parameter is allowed in a compiled plan: max_output_tokens, max_completion_tokens, or max_tokens.
  4. Provider-specific parameter names are selected by the adapter. Gateway, frontend, and generic runtime code must not guess them from model names.
  5. Runtime logs report the final non-secret plan and parameter names. They must never include credentials, authorization headers, or raw secret values.
  6. 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.