5a581c78a2
Build / build (push) Has been cancelled
Docker / build (push) Has been cancelled
Lint / ruff (push) Has been cancelled
Test / pytest (ubuntu-latest, 3.11) (push) Has been cancelled
Test / pytest (ubuntu-latest, 3.12) (push) Has been cancelled
Test / pytest (windows-latest, 3.11) (push) Has been cancelled
Test / pytest (windows-latest, 3.12) (push) Has been cancelled
Introduce provider, model, and invocation contracts with encrypted configuration persistence. Add web runtime fencing, route fallback, recovery middleware, workspace scoping, and comprehensive tests.
134 lines
4.5 KiB
Python
134 lines
4.5 KiB
Python
"""Pure invocation contract shared by configuration and runtime.
|
|
|
|
Provider configuration owns connection/authentication and adapter selection.
|
|
Model configuration owns capabilities, limits, and canonical parameters. This
|
|
module is the only layer that derives the effective wire invocation from those
|
|
inputs; the derived fields are runtime state, not administrator configuration.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
from collections.abc import Mapping
|
|
from dataclasses import dataclass
|
|
from types import MappingProxyType
|
|
from typing import Any, Literal
|
|
|
|
from ..contracts import EvoRuntimeError
|
|
from ..crypto import canonical_json_v1
|
|
|
|
ToolCallTransport = Literal["native", "disabled"]
|
|
|
|
|
|
def derive_tool_call_transport(
|
|
capabilities: Mapping[str, Any],
|
|
) -> ToolCallTransport:
|
|
"""Derive the wire transport from the authoritative tools capability."""
|
|
|
|
return "native" if bool(capabilities.get("tools", False)) else "disabled"
|
|
|
|
|
|
def derive_runtime_invocation(
|
|
api_mode: str,
|
|
capabilities: Mapping[str, Any],
|
|
) -> dict[str, str]:
|
|
"""Build the internal invocation projection for a normalized model."""
|
|
|
|
return {
|
|
"api_mode": str(api_mode),
|
|
"tool_call_transport": derive_tool_call_transport(capabilities),
|
|
}
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class InvocationPlan:
|
|
"""Complete, immutable, non-secret wire contract for one model call."""
|
|
|
|
api_mode: str
|
|
output_token_parameter: str
|
|
output_token_limit: int
|
|
tool_call_transport: ToolCallTransport
|
|
reasoning_effort: str
|
|
streaming: bool
|
|
sdk_params: Mapping[str, Any]
|
|
plan_hash: str
|
|
|
|
def model_kwargs(self) -> dict[str, Any]:
|
|
return dict(self.sdk_params)
|
|
|
|
def projection(self) -> dict[str, Any]:
|
|
return {
|
|
"api_mode": self.api_mode,
|
|
"output_token_parameter": self.output_token_parameter,
|
|
"output_token_limit": self.output_token_limit,
|
|
"tool_call_transport": self.tool_call_transport,
|
|
"reasoning_effort": self.reasoning_effort,
|
|
"streaming": self.streaming,
|
|
"sdk_params": dict(self.sdk_params),
|
|
"plan_hash": self.plan_hash,
|
|
}
|
|
|
|
|
|
def compile_invocation_plan(
|
|
*,
|
|
api_mode: str,
|
|
declared_tool_call_transport: str,
|
|
supports_tools: bool,
|
|
purpose: str,
|
|
output_token_limit: int,
|
|
reasoning_effort: str,
|
|
runtime_provider: str,
|
|
sdk_params: Mapping[str, Any],
|
|
) -> InvocationPlan:
|
|
"""Validate and freeze adapter output before constructing a provider SDK."""
|
|
|
|
params = dict(sdk_params)
|
|
streaming = purpose == "main_agent"
|
|
params["streaming"] = streaming
|
|
if runtime_provider == "openai" and streaming:
|
|
params["stream_usage"] = True
|
|
token_fields = tuple(
|
|
key
|
|
for key in ("max_output_tokens", "max_completion_tokens", "max_tokens")
|
|
if key in params
|
|
)
|
|
if len(token_fields) != 1 or params[token_fields[0]] != output_token_limit:
|
|
raise EvoRuntimeError("MODEL_ADAPTER_COMPILE_FAILED")
|
|
output_token_parameter = token_fields[0]
|
|
if api_mode == "responses" and output_token_parameter != "max_output_tokens":
|
|
raise EvoRuntimeError("MODEL_ADAPTER_COMPILE_FAILED")
|
|
if api_mode == "chat_completions" and output_token_parameter == "max_output_tokens":
|
|
raise EvoRuntimeError("MODEL_ADAPTER_COMPILE_FAILED")
|
|
if runtime_provider == "openai" and api_mode in {
|
|
"responses",
|
|
"chat_completions",
|
|
}:
|
|
if params.get("use_responses_api") is not (api_mode == "responses"):
|
|
raise EvoRuntimeError("MODEL_ADAPTER_COMPILE_FAILED")
|
|
|
|
tool_call_transport: ToolCallTransport = (
|
|
"native" if supports_tools else "disabled"
|
|
)
|
|
if declared_tool_call_transport != tool_call_transport:
|
|
raise EvoRuntimeError("MODEL_ADAPTER_COMPILE_FAILED")
|
|
|
|
plan_payload = {
|
|
"api_mode": api_mode,
|
|
"output_token_parameter": output_token_parameter,
|
|
"output_token_limit": output_token_limit,
|
|
"tool_call_transport": tool_call_transport,
|
|
"reasoning_effort": reasoning_effort,
|
|
"streaming": streaming,
|
|
"sdk_params": params,
|
|
}
|
|
return InvocationPlan(
|
|
api_mode=api_mode,
|
|
output_token_parameter=output_token_parameter,
|
|
output_token_limit=output_token_limit,
|
|
tool_call_transport=tool_call_transport,
|
|
reasoning_effort=reasoning_effort,
|
|
streaming=streaming,
|
|
sdk_params=MappingProxyType(params),
|
|
plan_hash=hashlib.sha256(canonical_json_v1(plan_payload)).hexdigest(),
|
|
)
|