feat: support exact Gemini 0.9.13 credit source variants

This commit is contained in:
Yansong Zhang committed 2026-11-10 21:28:36 +08:00
1 parent c9d28519b8
commit 49c41b3af1
11 files changed
+1526 -32

No files matched your search

@@ -0,0 +1,159 @@
"""Closed V8 Gemini source shapes, separate from immutable V6 declarations.
This DTO validates declaration shape only. A syntactically valid digest is not
reviewed source, SDK/runtime, installed package or target capability evidence.
No registry dispatch, factory, credential, SYSTEM/BYOK or upgrade authority is
added here. Real 0913 contracts must be reviewed before this family is wired.
"""
from dataclasses import dataclass
from typing import Annotated, Literal, Self
from pydantic import Field, model_validator
from services.entities.model_billing_gemini_mapping import (
GEMINI_SOURCE_UID,
GeminiMappingSource,
GeminiMappingTarget,
GeminiSourceSettings,
gemini_source_operations,
)
from services.entities.model_billing_mapping import _StrictModel
GEMINI_0913_SOURCE_UID = "langgenius/gemini:0.9.13@4378187cfc50d4253573f4d96baa13228d8ed2eb746ac3bae492a8eaee2da458"
type GeminiV8SourceUID = Literal[
"langgenius/gemini:0.9.12@9bb9eff3f9c99a8f1f87bdd5e0f178d5493918939dd0e02825ae8383bd0fd7ed",
"langgenius/gemini:0.9.13@4378187cfc50d4253573f4d96baa13228d8ed2eb746ac3bae492a8eaee2da458",
]
class GeminiV8SourceAdapter(_StrictModel):
id: Literal["gemini_credit_source_v1", "gemini_credit_source_v2"]
revision: Literal["1"]
rules_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$")
class GeminiV8SourceVariant(_StrictModel):
variant_id: str = Field(min_length=1)
source_plugin_uid: GeminiV8SourceUID
source_settings: GeminiSourceSettings
source_schema_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$")
source_runtime_schema_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$")
source_profile_id: str = Field(min_length=1)
parameter_adapter: GeminiV8SourceAdapter
target: GeminiMappingTarget
operations: list[str] = Field(min_length=3, max_length=4)
conformance_fixture_ids: list[Annotated[str, Field(min_length=1)]] = Field(min_length=1)
@model_validator(mode="after")
def closed_capability(self) -> Self:
prefix, adapter = (
("gemini0912-native-v1:", "gemini_credit_source_v1")
if self.source_plugin_uid == GEMINI_SOURCE_UID
else ("gemini0913-native-v1:", "gemini_credit_source_v2")
)
if (
self.source_profile_id != prefix + self.target.model
or self.parameter_adapter.id != adapter
or not self.source_settings.matches_model_type(self.target.model_type)
or set(self.operations) != gemini_source_operations(self.target.model)
or len(set(self.operations)) != len(self.operations)
or len(set(self.conformance_fixture_ids)) != len(self.conformance_fixture_ids)
):
raise ValueError("Invalid bounded V8 Gemini source capability")
return self
class SourceGeminiV8VariantMapping(_StrictModel):
schema_version: Literal[8]
mapping_revision: str = Field(min_length=1)
source: GeminiMappingSource
settlement_owner: Literal["shared_credit_pool"]
pool_types: list[Literal["paid", "trial"]] = Field(min_length=1)
variants: list[GeminiV8SourceVariant] = Field(min_length=1, max_length=2)
@model_validator(mode="before")
@classmethod
def exact_version(cls, value: object) -> object:
if type(value) is not dict or type(value.get("schema_version")) is not int or value["schema_version"] != 8:
raise ValueError("Gemini schema version must be integer 8")
return value
@model_validator(mode="after")
def finite_exact_sources(self) -> Self:
if len(set(self.pool_types)) != len(self.pool_types):
raise ValueError("Duplicate V8 Gemini pools")
if len({item.variant_id for item in self.variants}) != len(self.variants):
raise ValueError("Duplicate V8 Gemini variant identity")
selectors = {(item.source_plugin_uid, item.source_settings.model_dump_json()) for item in self.variants}
if len(selectors) != len(self.variants):
raise ValueError("Ambiguous V8 Gemini source selector")
if any(
item.target.model != self.source.model or item.target.model_type is not self.source.model_type
for item in self.variants
):
raise ValueError("V8 Gemini source/target identity changed")
return self
class SourceGeminiV8VariantSelection(_StrictModel):
schema_version: Literal[8]
variant_id: str = Field(min_length=1)
source_plugin_uid: GeminiV8SourceUID
source_settings: GeminiSourceSettings
source_schema_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$")
source_runtime_schema_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$")
registry_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$")
@model_validator(mode="before")
@classmethod
def exact_version(cls, value: object) -> object:
if type(value) is not dict or type(value.get("schema_version")) is not int or value["schema_version"] != 8:
raise ValueError("Gemini schema version must be integer 8")
return value
@dataclass(frozen=True, slots=True)
class SelectedGeminiV8SourceVariant:
"""Future registry-selected wrapper; constructing it grants no authority."""
envelope: SourceGeminiV8VariantMapping
variant: GeminiV8SourceVariant
registry_digest: str
@property
def mapping_revision(self) -> str:
return self.envelope.mapping_revision
@property
def source(self) -> GeminiMappingSource:
return self.envelope.source
@property
def settlement_owner(self) -> Literal["shared_credit_pool"]:
return self.envelope.settlement_owner
@property
def pool_types(self) -> list[Literal["paid", "trial"]]:
return self.envelope.pool_types
@property
def source_schema_digest(self) -> str:
return self.variant.source_schema_digest
@property
def parameter_adapter(self) -> GeminiV8SourceAdapter:
return self.variant.parameter_adapter
@property
def target(self) -> GeminiMappingTarget:
return self.variant.target
@property
def operations(self) -> list[str]:
return self.variant.operations
@property
def conformance_fixture_ids(self) -> list[str]:
return self.variant.conformance_fixture_ids
@@ -0,0 +1,317 @@
"""Pure exact Gemini0913 source factory, separate from immutable0912/V6.
Pins bind the frozen v2 packet fd9d7680 / raw8c32f42e to the actual Source
catalog/runtime Core entities. They prove no installed target, current SDK,
network, credential, migration, billing or release authority. None runtime
schema remains frozen/prospective restoration, never observed RPC evidence.
"""
from __future__ import annotations
import hmac
import re
from dataclasses import dataclass
from typing import Never
from graphon.model_runtime.entities.model_entities import AIModelEntity, ModelPropertyKey, ModelType
from services.entities.model_billing_gemini_mapping import (
GeminiSourceSettings,
gemini_source_model_type,
)
from services.entities.model_billing_gemini_v8_mapping import GEMINI_0913_SOURCE_UID
from services.entities.model_billing_mapping import SourceParameterContract, model_schema_digest
GEMINI_CREDIT_SOURCE_ADAPTER_ID = "gemini_credit_source_v2"
GEMINI_CREDIT_SOURCE_ADAPTER_REVISION = "1"
GEMINI_CREDIT_SOURCE_PROVIDER = "langgenius/gemini/google"
class GeminiCreditSourceV2AdapterError(ValueError):
"""Fixed safe denial; unknown settings/schema never authorize a route."""
@dataclass(frozen=True, slots=True)
class GeminiCreditSourceV2Contract(SourceParameterContract):
"""An exact immutable reviewed profile, not a routing authorization."""
_REVIEWED_CONTRACTS = (
GeminiCreditSourceV2Contract(
profile_id="gemini0913-native-v1:gemini-2.5-flash",
source_plugin_unique_identifier="langgenius/gemini:0.9.13@4378187cfc50d4253573f4d96baa13228d8ed2eb746ac3bae492a8eaee2da458",
source_model="gemini-2.5-flash",
source_schema_digest="sha256:9dfef26ae8e27359f74312f87ca295e08ec59f187c889d4fc5eed747f22682ef",
source_runtime_schema_digest="sha256:e3a9e5a6146b14480e5f9948993afeab62e640b1559bd953fea98651ee1d5a21",
target_model="gemini-2.5-flash",
rules_digest="sha256:13ca4eb8ba52db4537a9177114d1b41f5a468ee79ecbdbc65b6ad940979d79ce",
adapter_id="gemini_credit_source_v2",
algorithm_revision="1",
),
GeminiCreditSourceV2Contract(
profile_id="gemini0913-native-v1:gemini-3.1-flash-lite",
source_plugin_unique_identifier="langgenius/gemini:0.9.13@4378187cfc50d4253573f4d96baa13228d8ed2eb746ac3bae492a8eaee2da458",
source_model="gemini-3.1-flash-lite",
source_schema_digest="sha256:26dc99d59bdab5b1ff139aad894dae0fc15c9baf06777af67b9462f113193504",
source_runtime_schema_digest="sha256:0ee6cea0716356f3d3951066ec994ba34b50cf48fecf8d07c9e9611861e627a4",
target_model="gemini-3.1-flash-lite",
rules_digest="sha256:53574a2d8920b48b3152f97fccc70217e831dfba10d60c97690f9862ac2123ce",
adapter_id="gemini_credit_source_v2",
algorithm_revision="1",
),
GeminiCreditSourceV2Contract(
profile_id="gemini0913-native-v1:gemini-3.1-pro-preview",
source_plugin_unique_identifier="langgenius/gemini:0.9.13@4378187cfc50d4253573f4d96baa13228d8ed2eb746ac3bae492a8eaee2da458",
source_model="gemini-3.1-pro-preview",
source_schema_digest="sha256:9aceca99ac88649944f9d78102241853c8144d1a11f4c086bb5f27bc38766e34",
source_runtime_schema_digest="sha256:3a2ce7dce3477bd042314941826492a5496aeb8bdb047285514a305d810e918e",
target_model="gemini-3.1-pro-preview",
rules_digest="sha256:8fb951c69113cc92eedb5e564817c897804b151f089851e783b0fd2dcc68a3eb",
adapter_id="gemini_credit_source_v2",
algorithm_revision="1",
),
GeminiCreditSourceV2Contract(
profile_id="gemini0913-native-v1:gemini-3.5-flash",
source_plugin_unique_identifier="langgenius/gemini:0.9.13@4378187cfc50d4253573f4d96baa13228d8ed2eb746ac3bae492a8eaee2da458",
source_model="gemini-3.5-flash",
source_schema_digest="sha256:fa5fbdb6fa5ef69496f62f6dc2f4ead6b34d82f26cb6fc793fabf25577b667aa",
source_runtime_schema_digest="sha256:54aefc309ce57ff15f93ee606bb0919f1eb9649d057957cb6ea1fb2b60a3ab44",
target_model="gemini-3.5-flash",
rules_digest="sha256:cd75ed07076e1eebc099e93ada8110754bfd95767f05b1099b688f54db61b1b3",
adapter_id="gemini_credit_source_v2",
algorithm_revision="1",
),
GeminiCreditSourceV2Contract(
profile_id="gemini0913-native-v1:gemini-3.5-flash-lite",
source_plugin_unique_identifier="langgenius/gemini:0.9.13@4378187cfc50d4253573f4d96baa13228d8ed2eb746ac3bae492a8eaee2da458",
source_model="gemini-3.5-flash-lite",
source_schema_digest="sha256:230f022992a7882a800fc31d4b754ca51032a2342a4644ce250f58abc4bf07c9",
source_runtime_schema_digest="sha256:613acb7a29a51dffcf3ffd506f306ba6002599d5765a1baffb66d3ade9257355",
target_model="gemini-3.5-flash-lite",
rules_digest="sha256:601f024ab221e97fc8a80381e068ec3cd948704c57d88d722363ae59a22aad6f",
adapter_id="gemini_credit_source_v2",
algorithm_revision="1",
),
GeminiCreditSourceV2Contract(
profile_id="gemini0913-native-v1:gemini-3.7-flash",
source_plugin_unique_identifier="langgenius/gemini:0.9.13@4378187cfc50d4253573f4d96baa13228d8ed2eb746ac3bae492a8eaee2da458",
source_model="gemini-3.7-flash",
source_schema_digest="sha256:c718fa257170b98e87fd7a0c00c56613cb611d4d18ad1256dd375c9eaf908676",
source_runtime_schema_digest="sha256:7b1cd0a9ea9fbe14386d8458a6bec68833343cdbf4383c460bf0ac2a20f68189",
target_model="gemini-3.7-flash",
rules_digest="sha256:48ea4bb566bf12eb497eea6e23c8360c1fc3635b9ba9582a829a82c2ed5cfe70",
adapter_id="gemini_credit_source_v2",
algorithm_revision="1",
),
GeminiCreditSourceV2Contract(
profile_id="gemini0913-native-v1:gemini-3-flash-preview",
source_plugin_unique_identifier="langgenius/gemini:0.9.13@4378187cfc50d4253573f4d96baa13228d8ed2eb746ac3bae492a8eaee2da458",
source_model="gemini-3-flash-preview",
source_schema_digest="sha256:7a0371459f73f0ba41d20f0ef274923e131032931fb55c9865c7478b42a10f2b",
source_runtime_schema_digest="sha256:ccaa15b0d9e20840ab62d077c5c0a62fd9f5339d04f4d4ab0a978962ac83dab1",
target_model="gemini-3-flash-preview",
rules_digest="sha256:1d608a9072491a4e052a54b3447fce10cd0d6b1083a49fa70e37925736e20a28",
adapter_id="gemini_credit_source_v2",
algorithm_revision="1",
),
GeminiCreditSourceV2Contract(
profile_id="gemini0913-native-v1:gemini-embedding-001",
source_plugin_unique_identifier="langgenius/gemini:0.9.13@4378187cfc50d4253573f4d96baa13228d8ed2eb746ac3bae492a8eaee2da458",
source_model="gemini-embedding-001",
source_schema_digest="sha256:470e3397c5097df3b54673901fc321ce298e6081369bc731432e042daa04fb5d",
source_runtime_schema_digest="sha256:470e3397c5097df3b54673901fc321ce298e6081369bc731432e042daa04fb5d",
target_model="gemini-embedding-001",
rules_digest="sha256:c2d37d9c263af1eeedce8e2c94cb648f995bf1c0c83cd9c7d69baf70bab05d4e",
adapter_id="gemini_credit_source_v2",
algorithm_revision="1",
),
GeminiCreditSourceV2Contract(
profile_id="gemini0913-native-v1:gemini-embedding-2-preview",
source_plugin_unique_identifier="langgenius/gemini:0.9.13@4378187cfc50d4253573f4d96baa13228d8ed2eb746ac3bae492a8eaee2da458",
source_model="gemini-embedding-2-preview",
source_schema_digest="sha256:b16129e398a864dd0baee0c957c4c42573ef888b785c6aaec9d78ac2785e063b",
source_runtime_schema_digest="sha256:b16129e398a864dd0baee0c957c4c42573ef888b785c6aaec9d78ac2785e063b",
target_model="gemini-embedding-2-preview",
rules_digest="sha256:e13153f791fe3f15ea8cf2c7e71df72a76e2046e876d37c66e0e3fe2785a540a",
adapter_id="gemini_credit_source_v2",
algorithm_revision="1",
),
)
_MARKER_FIELDS = frozenset(
{
"schema_version",
"profile_id",
"source_plugin_uid",
"source_model",
"source_schema_digest",
"rules_digest",
}
)
def _deny() -> Never:
raise GeminiCreditSourceV2AdapterError("Gemini source evidence is not reviewed")
def _digest(value: object) -> bool:
return type(value) is str and re.fullmatch(r"sha256:[0-9a-f]{64}", value) is not None
def validate_gemini_credit_source_identity(
*,
source_provider: str,
source_model: str,
source_plugin_unique_identifier: str,
model_type: ModelType,
target_model: str,
) -> None:
if (
type(source_provider) is not str
or source_provider != GEMINI_CREDIT_SOURCE_PROVIDER
or type(source_plugin_unique_identifier) is not str
or source_plugin_unique_identifier != GEMINI_0913_SOURCE_UID
or type(source_model) is not str
or type(target_model) is not str
or source_model != target_model
):
_deny()
try:
expected = gemini_source_model_type(source_model)
except ValueError:
_deny()
else:
if model_type is not expected:
_deny()
def _settings(settings: GeminiSourceSettings, model: str) -> None:
if type(settings) is not GeminiSourceSettings or not settings.matches_model_type(gemini_source_model_type(model)):
_deny()
def _schema_digest(schema: AIModelEntity, model: str) -> str:
if (
not isinstance(schema, AIModelEntity)
or schema.model != model
or schema.model_type is not gemini_source_model_type(model)
or schema.model_type is ModelType.LLM
and schema.model_properties.get(ModelPropertyKey.MODE) != "chat"
):
_deny()
return model_schema_digest(schema)
def _runtime_pin(contract: GeminiCreditSourceV2Contract, expected: str, observed: AIModelEntity | None) -> None:
if not _digest(expected) or not hmac.compare_digest(expected, contract.source_runtime_schema_digest or ""):
_deny()
# None is frozen/prospective restoration, NEVER observed runtime evidence.
if observed is not None and not hmac.compare_digest(_schema_digest(observed, contract.source_model), expected):
_deny()
def gemini_credit_source_marker(
contract: GeminiCreditSourceV2Contract,
*,
source_provider: str,
source_model: str,
model_type: ModelType,
target_model: str,
) -> dict[str, object]:
if type(contract) is not GeminiCreditSourceV2Contract or contract not in _REVIEWED_CONTRACTS:
_deny()
validate_gemini_credit_source_identity(
source_provider=source_provider,
source_model=source_model,
source_plugin_unique_identifier=contract.source_plugin_unique_identifier,
model_type=model_type,
target_model=target_model,
)
if source_model != contract.source_model or target_model != contract.target_model:
_deny()
return {
"schema_version": 1,
"profile_id": contract.profile_id,
"source_plugin_uid": contract.source_plugin_unique_identifier,
"source_model": contract.source_model,
"source_schema_digest": contract.source_schema_digest,
"rules_digest": contract.rules_digest,
}
def build_gemini_credit_source_contract(
*,
adapter_id: str,
adapter_revision: str,
expected_rules_digest: str,
source_provider: str,
source_model: str,
source_plugin_unique_identifier: str,
source_schema: AIModelEntity,
expected_source_schema_digest: str,
expected_source_runtime_schema_digest: str,
target_model: str,
source_settings: GeminiSourceSettings,
source_runtime_schema: AIModelEntity | None = None,
) -> GeminiCreditSourceV2Contract:
if not isinstance(source_schema, AIModelEntity):
_deny()
validate_gemini_credit_source_identity(
source_provider=source_provider,
source_model=source_model,
source_plugin_unique_identifier=source_plugin_unique_identifier,
model_type=source_schema.model_type,
target_model=target_model,
)
_settings(source_settings, source_model)
actual = _schema_digest(source_schema, source_model)
contract = next((row for row in _REVIEWED_CONTRACTS if row.source_model == source_model), None)
if (
contract is None
or type(adapter_id) is not str
or adapter_id != GEMINI_CREDIT_SOURCE_ADAPTER_ID
or type(adapter_revision) is not str
or adapter_revision != GEMINI_CREDIT_SOURCE_ADAPTER_REVISION
or not _digest(expected_rules_digest)
or not _digest(expected_source_schema_digest)
or not hmac.compare_digest(expected_rules_digest, contract.rules_digest)
or not hmac.compare_digest(expected_source_schema_digest, actual)
or not hmac.compare_digest(actual, contract.source_schema_digest)
):
_deny()
_runtime_pin(contract, expected_source_runtime_schema_digest, source_runtime_schema)
return contract
def restore_gemini_credit_source_contract(
marker: object,
*,
source_provider: str,
source_model: str,
model_type: ModelType,
target_model: str,
source_settings: GeminiSourceSettings,
expected_source_runtime_schema_digest: str,
source_runtime_schema: AIModelEntity | None = None,
) -> GeminiCreditSourceV2Contract:
if (
type(marker) is not dict
or set(marker) != _MARKER_FIELDS
or type(marker.get("schema_version")) is not int
or marker.get("schema_version") != 1
or any(type(value) is not str for key, value in marker.items() if key != "schema_version")
):
_deny()
contract = next((row for row in _REVIEWED_CONTRACTS if row.profile_id == marker["profile_id"]), None)
if contract is None:
_deny()
expected = gemini_credit_source_marker(
contract,
source_provider=source_provider,
source_model=source_model,
model_type=model_type,
target_model=target_model,
)
if marker != expected:
_deny()
_settings(source_settings, source_model)
_runtime_pin(contract, expected_source_runtime_schema_digest, source_runtime_schema)
return contract
+93 -3
View File
@@ -43,6 +43,10 @@ from services.entities.model_billing_gemini_mapping import (
gemini_source_operations,
)
from services.entities.model_billing_gemini_mapping import SelectedGeminiSourceVariant as SelectedGeminiSourceVariant # noqa: PLC0414
from services.entities.model_billing_gemini_v8_mapping import GEMINI_0913_SOURCE_UID, SourceGeminiV8VariantMapping
from services.entities.model_billing_gemini_v8_mapping import (
SelectedGeminiV8SourceVariant as SelectedGeminiV8SourceVariant, # noqa: PLC0414
)
from services.entities.model_billing_mapping import ModelMapping, SourceVariantSettings
from services.entities.model_billing_mapping import SelectedSourceVariant as SelectedSourceVariant # noqa: PLC0414
from services.entities.model_billing_mapping import SourceParameterContract as SourceParameterContract # noqa: PLC0414
@@ -69,6 +73,16 @@ from services.model_billing_gemini_credit_source_adapter import (
gemini_credit_source_marker,
restore_gemini_credit_source_contract,
)
from services.model_billing_gemini_credit_source_v2_adapter import GeminiCreditSourceV2Contract
from services.model_billing_gemini_credit_source_v2_adapter import (
build_gemini_credit_source_contract as build_gemini_credit_v2_source_contract,
)
from services.model_billing_gemini_credit_source_v2_adapter import (
gemini_credit_source_marker as gemini_credit_v2_source_marker,
)
from services.model_billing_gemini_credit_source_v2_adapter import (
restore_gemini_credit_source_contract as restore_gemini_credit_v2_source_contract,
)
from services.model_billing_migration_inventory import saved_dependency_inventory_policy
from services.model_billing_openai_audio_adapter import (
OPENAI_AUDIO_SOURCE_UIDS,
@@ -134,6 +148,7 @@ from services.model_billing_source_variants import (
AudioSourceVariantContext,
EmbeddingSourceVariantContext,
GeminiSourceVariantContext,
GeminiV8SourceVariantContext,
MappingDeclaration,
ModelMappingRevision,
SelectedModelMapping,
@@ -215,6 +230,22 @@ def build_source_adapter_contract(
if tongyi_contract != restore_variant_source_contract(mapping):
raise ValueError("Tongyi source variant evidence changed")
return tongyi_contract
if isinstance(mapping, SelectedGeminiV8SourceVariant):
build_gemini_v8 = (
build_gemini_credit_v2_source_contract
if mapping.variant.source_plugin_uid == GEMINI_0913_SOURCE_UID
else build_gemini_credit_source_contract
)
gemini_v8_contract = build_gemini_v8(
**arguments,
source_schema=source_schema,
expected_source_runtime_schema_digest=mapping.variant.source_runtime_schema_digest,
target_model=mapping.target.model,
source_settings=mapping.variant.source_settings,
)
if gemini_v8_contract != restore_variant_source_contract(mapping):
raise ValueError("V8 Gemini source variant evidence changed")
return gemini_v8_contract
if isinstance(mapping, SelectedGeminiSourceVariant):
gemini_contract = build_gemini_credit_source_contract(
**arguments,
@@ -348,6 +379,8 @@ def source_parameter_marker(
}
if isinstance(contract, TongyiCreditSourceContract):
return tongyi_credit_source_marker(contract, **arguments, model_type=model_type)
if isinstance(contract, GeminiCreditSourceV2Contract):
return gemini_credit_v2_source_marker(contract, **arguments, model_type=model_type)
if isinstance(contract, GeminiCreditSourceContract):
return gemini_credit_source_marker(contract, **arguments, model_type=model_type)
if isinstance(contract, OpenAIAudioSourceContract):
@@ -639,7 +672,7 @@ def mapped_dynamic_source_candidates(
def mapping_has_required_operations(mapping: SelectedModelMapping) -> bool:
if isinstance(mapping, SelectedTongyiSourceVariant):
return set(mapping.operations) == tongyi_source_operations(mapping.source.model)
if isinstance(mapping, SelectedGeminiSourceVariant):
if isinstance(mapping, (SelectedGeminiSourceVariant, SelectedGeminiV8SourceVariant)):
return set(mapping.operations) == gemini_source_operations(mapping.source.model)
required = {"model/schema", f"{mapping.source.model_type.value}/invoke"}
if mapping.source.model_type == ModelType.LLM:
@@ -1197,13 +1230,13 @@ def hosted_gemini_source_fact(
) -> HostedGeminiSourceFact | None:
"""Capture actual SYSTEM dictionary classifications, before substitution.
Source0912 LLMs use only the reviewed None/exact Google-root base,
Source0912/0913 LLMs use only the reviewed None/exact Google-root base,
None/disabled metadata and None/empty file prefix. Embeddings do not consume
these three fields. Nothing retains a key, raw URL or credential dictionary.
"""
if (
str(ModelProviderID(provider)) != "langgenius/gemini/google"
or source_uid != GEMINI_SOURCE_UID
or source_uid not in {GEMINI_SOURCE_UID, GEMINI_0913_SOURCE_UID}
or type(credentials) is not dict
):
return None
@@ -1273,6 +1306,47 @@ def gemini_source_variant_context(
return GeminiSourceVariantContext(source_uid, settings)
def gemini_v8_source_variant_context(
fact: HostedGeminiSourceFact | None,
*,
provider: str,
source_uid: str,
model_type: ModelType,
schema: AIModelEntity | None = None,
) -> GeminiV8SourceVariantContext | None:
if (
type(fact) is not HostedGeminiSourceFact
or fact.provider != str(ModelProviderID(provider))
or fact.plugin_unique_identifier != source_uid
or source_uid not in {GEMINI_SOURCE_UID, GEMINI_0913_SOURCE_UID}
or model_type not in {ModelType.LLM, ModelType.TEXT_EMBEDDING}
):
return None
if schema is not None and [
digest
for kind, model, digest in fact.catalog_schema_digests
if (kind, model) == (schema.model_type, schema.model)
] != [model_schema_digest(schema)]:
return None
if model_type is ModelType.LLM:
if (fact.llm_source_base_policy, fact.llm_request_metadata_policy, fact.llm_file_url_policy) != (
"unset_or_exact_google_root",
"system_false_only",
"actual_system_absent_or_empty_only",
):
return None
settings = GeminiSourceSettings(
source_base_policy="unset_or_exact_google_root",
request_metadata_policy="system_false_only",
file_url_policy="actual_system_absent_or_empty_only",
)
else:
settings = GeminiSourceSettings(
source_base_policy="not_used", request_metadata_policy="not_used", file_url_policy="not_used"
)
return GeminiV8SourceVariantContext(source_uid, settings)
def hosted_source_variant_fact(
*, provider: str, source_uid: str, models: Sequence[AIModelEntity], credentials: object
) -> HostedSourceVariantFact | None:
@@ -1370,6 +1444,18 @@ def restore_variant_source_contract(
source_settings=mapping.variant.source_settings,
expected_source_runtime_schema_digest=variant.source_runtime_schema_digest,
)
if isinstance(mapping, SelectedGeminiV8SourceVariant):
restore_gemini_v8 = (
restore_gemini_credit_v2_source_contract
if mapping.variant.source_plugin_uid == GEMINI_0913_SOURCE_UID
else restore_gemini_credit_source_contract
)
return restore_gemini_v8(
marker,
**arguments,
source_settings=mapping.variant.source_settings,
expected_source_runtime_schema_digest=variant.source_runtime_schema_digest,
)
if isinstance(mapping, SelectedGeminiSourceVariant):
return restore_gemini_credit_source_contract(
marker,
@@ -1552,6 +1638,10 @@ def resolve_source_mapping(
context = tongyi_source_variant_context(
tongyi_fact, provider=identity[0], source_uid=source_uid, model_type=identity[1], schema=schema
)
elif isinstance(declaration, SourceGeminiV8VariantMapping):
context = gemini_v8_source_variant_context(
gemini_fact, provider=identity[0], source_uid=source_uid, model_type=identity[1], schema=schema
)
elif isinstance(declaration, SourceGeminiVariantMapping):
context = gemini_source_variant_context(
gemini_fact, provider=identity[0], source_uid=source_uid, model_type=identity[1], schema=schema
@@ -36,11 +36,12 @@ from core.plugin.entities.plugin_daemon import PluginInstallTaskStatus
from core.plugin.impl.model import PluginModelClient
from core.plugin.impl.plugin import PluginInstaller
from extensions import ext_hosting_provider
from graphon.model_runtime.entities.model_entities import ModelPropertyKey, ModelType
from graphon.model_runtime.entities.model_entities import AIModelEntity, ModelPropertyKey, ModelType
from models.provider_ids import ModelProviderID
from repositories.model_billing_dependency_repository import ModelBillingDependencyRepository
from services.entities.model_billing_embedding_mapping import SelectedEmbeddingSourceVariant
from services.entities.model_billing_gemini_mapping import SelectedGeminiSourceVariant
from services.entities.model_billing_gemini_v8_mapping import SelectedGeminiV8SourceVariant
from services.entities.model_billing_mapping import SourceParameterContract
from services.entities.model_billing_tongyi_mapping import SelectedTongyiSourceVariant
from services.model_billing_dependency_inventory import DependencyInventoryPolicy, SavedModelReference
@@ -73,7 +74,7 @@ from services.model_billing_mapping_service import (
source_parameter_public_settings,
)
from services.model_billing_migration_inventory import RequiredSavedCreditModel, SavedDependencySourceEvidence
from services.model_billing_source_variants import selection_payload
from services.model_billing_source_variants import SelectedModelMapping, selection_payload
class RedirectCapabilities(BaseModel):
@@ -574,21 +575,7 @@ class SavedDependencyMigrationEvidenceGateway:
)
if schema is None or schema.model_type != kind:
raise ModelRouteUnmapped
if (
isinstance(
mapping,
(
SelectedAudioSourceVariant,
SelectedXAISourceVariant,
SelectedGeminiSourceVariant,
SelectedTongyiSourceVariant,
),
)
and schema.model != mapping.target.model
):
# These closed families have no alias exception. Do not erase
# an unexpected target identity by normalizing the hash below.
raise ModelRouteUnmapped
_assert_target_source_identity(mapping, schema)
if mapping.parameter_adapter.id == "openai_credit_llm_source_v2" and schema.model not in {
mapping.source.model,
mapping.target.model,
@@ -612,21 +599,62 @@ class SavedDependencyMigrationEvidenceGateway:
# Its exact versioned runtime schema was checked above; selected
# source rows still retain the original dimension-contract check.
# Neither path maps or infers a vector width from a model name.
if (
kind == ModelType.TEXT_EMBEDDING
and not (
isinstance(
mapping,
(SelectedEmbeddingSourceVariant, SelectedGeminiSourceVariant, SelectedTongyiSourceVariant),
)
and prospective_only
)
and source["embedding_dimensions"] != embedding_dimensions_contract(schema)
):
raise ModelRouteUnmapped
_assert_target_embedding_dimensions(
mapping=mapping,
kind=kind,
prospective_only=prospective_only,
source=source,
schema=schema,
)
return expected
def _assert_target_source_identity(mapping: SelectedModelMapping, schema: AIModelEntity) -> None:
"""Closed families have no alias exception; never normalize a wrong target."""
if (
isinstance(
mapping,
(
SelectedAudioSourceVariant,
SelectedXAISourceVariant,
SelectedGeminiSourceVariant,
SelectedGeminiV8SourceVariant,
SelectedTongyiSourceVariant,
),
)
and schema.model != mapping.target.model
):
raise ModelRouteUnmapped
def _assert_target_embedding_dimensions(
*,
mapping: SelectedModelMapping,
kind: ModelType,
prospective_only: bool,
source: Mapping[str, object],
schema: AIModelEntity,
) -> None:
"""Only prospective closed declarations omit the installed-source dimension fact."""
if (
kind == ModelType.TEXT_EMBEDDING
and not (
isinstance(
mapping,
(
SelectedEmbeddingSourceVariant,
SelectedGeminiSourceVariant,
SelectedGeminiV8SourceVariant,
SelectedTongyiSourceVariant,
),
)
and prospective_only
)
and source["embedding_dimensions"] != embedding_dimensions_contract(schema)
):
raise ModelRouteUnmapped
def _name(plugin_id: str, provider: str) -> str:
return str(ModelProviderID(provider if provider.count("/") == 2 else plugin_id + "/" + provider))
@@ -41,6 +41,11 @@ from services.entities.model_billing_gemini_mapping import (
SourceGeminiVariantMapping,
SourceGeminiVariantSelection,
)
from services.entities.model_billing_gemini_v8_mapping import (
SelectedGeminiV8SourceVariant,
SourceGeminiV8VariantMapping,
SourceGeminiV8VariantSelection,
)
from services.entities.model_billing_mapping import (
ModelMapping,
SelectedSourceVariant,
@@ -70,6 +75,7 @@ type MappingDeclaration = (
| SourceAudioVariantMapping
| SourceXAIVariantMapping
| SourceGeminiVariantMapping
| SourceGeminiV8VariantMapping
| SourceTongyiVariantMapping
)
type SelectedSourceVariantMapping = (
@@ -78,6 +84,7 @@ type SelectedSourceVariantMapping = (
| SelectedAudioSourceVariant
| SelectedXAISourceVariant
| SelectedGeminiSourceVariant
| SelectedGeminiV8SourceVariant
| SelectedTongyiSourceVariant
)
type SelectedModelMapping = ModelMapping | SelectedSourceVariantMapping
@@ -87,6 +94,7 @@ type SourceVariantSelectionPayload = (
| SourceAudioVariantSelection
| SourceXAIVariantSelection
| SourceGeminiVariantSelection
| SourceGeminiV8VariantSelection
| SourceTongyiVariantSelection
)
@@ -96,6 +104,7 @@ SOURCE_VARIANT_DECLARATION_TYPES = (
SourceAudioVariantMapping,
SourceXAIVariantMapping,
SourceGeminiVariantMapping,
SourceGeminiV8VariantMapping,
SourceTongyiVariantMapping,
)
SELECTED_SOURCE_VARIANT_TYPES = (
@@ -104,6 +113,7 @@ SELECTED_SOURCE_VARIANT_TYPES = (
SelectedAudioSourceVariant,
SelectedXAISourceVariant,
SelectedGeminiSourceVariant,
SelectedGeminiV8SourceVariant,
SelectedTongyiSourceVariant,
)
@@ -162,6 +172,14 @@ class GeminiSourceVariantContext:
settings: GeminiSourceSettings
@dataclass(frozen=True, slots=True)
class GeminiV8SourceVariantContext:
"""Exact V8 facts; never accepted by the immutable V6 selector."""
source_plugin_uid: str
settings: GeminiSourceSettings
@dataclass(frozen=True, slots=True)
class TongyiSourceVariantContext:
source_plugin_uid: str
@@ -174,6 +192,7 @@ type SourceContext = (
| AudioSourceVariantContext
| XAISourceVariantContext
| GeminiSourceVariantContext
| GeminiV8SourceVariantContext
| TongyiSourceVariantContext
)
@@ -233,6 +252,17 @@ class ModelMappingRevision:
if len(tongyi_matches) != 1:
raise ValueError("Unknown or ambiguous Tongyi source variant")
selected = SelectedTongyiSourceVariant(declaration, tongyi_matches[0], self.digest)
elif isinstance(declaration, SourceGeminiV8VariantMapping):
if type(context) is not GeminiV8SourceVariantContext:
raise ValueError("Source V8 Gemini fact family changed")
gemini_v8_matches = [
item
for item in declaration.variants
if item.source_plugin_uid == context.source_plugin_uid and item.source_settings == context.settings
]
if len(gemini_v8_matches) != 1:
raise ValueError("Unknown or ambiguous V8 Gemini source variant")
selected = SelectedGeminiV8SourceVariant(declaration, gemini_v8_matches[0], self.digest)
elif isinstance(declaration, SourceGeminiVariantMapping):
if type(context) is not GeminiSourceVariantContext:
raise ValueError("Source Gemini fact family changed")
@@ -305,6 +335,11 @@ class ModelMappingRevision:
SelectedTongyiSourceVariant(declaration, variant, self.digest)
for variant in sorted(declaration.variants, key=lambda item: item.variant_id)
)
elif isinstance(declaration, SourceGeminiV8VariantMapping):
result.extend(
SelectedGeminiV8SourceVariant(declaration, variant, self.digest)
for variant in sorted(declaration.variants, key=lambda item: item.variant_id)
)
elif isinstance(declaration, SourceGeminiVariantMapping):
result.extend(
SelectedGeminiSourceVariant(declaration, variant, self.digest)
@@ -344,6 +379,11 @@ class ModelMappingRevision:
selected = self.resolve(
identity, context=TongyiSourceVariantContext(record.source_plugin_uid, record.source_settings)
)
elif isinstance(declaration, SourceGeminiV8VariantMapping):
record = SourceGeminiV8VariantSelection.model_validate(payload)
selected = self.resolve(
identity, context=GeminiV8SourceVariantContext(record.source_plugin_uid, record.source_settings)
)
elif isinstance(declaration, SourceGeminiVariantMapping):
record = SourceGeminiVariantSelection.model_validate(payload)
selected = self.resolve(
@@ -390,6 +430,16 @@ def selection_payload(
source_runtime_schema_digest=selected.variant.source_runtime_schema_digest,
registry_digest=selected.registry_digest,
)
if isinstance(selected, SelectedGeminiV8SourceVariant):
return SourceGeminiV8VariantSelection(
schema_version=8,
variant_id=selected.variant.variant_id,
source_plugin_uid=selected.variant.source_plugin_uid,
source_settings=selected.variant.source_settings,
source_schema_digest=selected.variant.source_schema_digest,
source_runtime_schema_digest=selected.variant.source_runtime_schema_digest,
registry_digest=selected.registry_digest,
)
if isinstance(selected, SelectedGeminiSourceVariant):
return SourceGeminiVariantSelection(
schema_version=6,
@@ -456,6 +506,7 @@ def source_mapping_revision(
| SourceAudioVariantMapping
| SourceXAIVariantMapping
| SourceGeminiVariantMapping
| SourceGeminiV8VariantMapping
| SourceTongyiVariantMapping,
Field(discriminator="schema_version"),
]
@@ -0,0 +1,104 @@
"""Real frozen Source profiles; target/revision strings are unit-only, never release authority."""
import base64
import gzip
import hashlib
import json
from itertools import starmap
from pathlib import Path
from typing import Any, cast
from graphon.model_runtime.entities.model_entities import AIModelEntity, ModelType
from services.entities.model_billing_gemini_mapping import GEMINI_SOURCE_UID, gemini_source_operations
from services.entities.model_billing_gemini_v8_mapping import GEMINI_0913_SOURCE_UID
from tests.helpers.unit.model_billing_gemini_profiles import GeminiProfile
from tests.helpers.unit.model_billing_gemini_profiles import profiles as profiles0912
SOURCE_PROVIDER = "langgenius/gemini/google"
REVISION = "offline-gemini-v8-never-published"
SOURCE_UIDS = (GEMINI_SOURCE_UID, GEMINI_0913_SOURCE_UID)
def profiles(source_uid: str) -> list[GeminiProfile]:
if source_uid == GEMINI_SOURCE_UID:
return profiles0912()
if source_uid != GEMINI_0913_SOURCE_UID:
raise ValueError("Unknown exact source UID")
path = Path(__file__).resolve().parents[2] / "unit_tests/services/fixtures/gemini0913_source_profiles.packed.json"
blob = path.read_bytes()
if hashlib.sha256(blob).hexdigest() != "fd9d76809e7b973da9a1f5081db4880321e88514618ad262459942afef079f81":
raise ValueError("Frozen0913 packet changed")
packed = json.loads(blob)
raw = gzip.decompress(base64.b64decode(packed["payload_base64"], validate=True))
if hashlib.sha256(raw).hexdigest() != packed["raw_sha256"] or packed["raw_sha256"] != (
"8c32f42e9a623fae60f0da32633425938fb6557c4c93ea6975b7f9714dfb3dd7"
):
raise ValueError("Frozen0913 raw profile changed")
rows = cast(list[GeminiProfile], json.loads(raw)["profiles"])
if len(rows) != 9 or any(row["adapter_id"] != "gemini_credit_source_v2" for row in rows):
raise ValueError("Frozen0913 profile set changed")
return rows
def schema(row: GeminiProfile, *, runtime: bool = False) -> AIModelEntity:
return AIModelEntity.model_validate(row["source_daemon_schema" if runtime else "source_catalog_schema"])
def profile_digest(row: GeminiProfile) -> str:
return (
"sha256:"
+ hashlib.sha256(
json.dumps(row, sort_keys=True, separators=(",", ":"), ensure_ascii=False).encode()
).hexdigest()
)
def variant_record(row: GeminiProfile, source_uid: str) -> dict[str, Any]:
kind = ModelType(row["model_type"])
return {
"variant_id": row["profile_id"],
"source_plugin_uid": source_uid,
"source_settings": row["source_settings"],
"source_schema_digest": row["source_schema_digest"],
"source_runtime_schema_digest": row["source_runtime_schema_digest"],
"source_profile_id": row["profile_id"],
"parameter_adapter": {
"id": row["adapter_id"],
"revision": row["adapter_revision"],
"rules_digest": profile_digest(row),
},
"target": {
"plugin_id": "langgenius/tokener",
"provider": "tokener",
"model_type": kind.value,
"model": row["target_model"],
"catalog_revision": "unit-only-no-target-release",
"minimum_plugin_version": "999.0.0.dev1",
},
"operations": sorted(gemini_source_operations(row["source_model"])),
"conformance_fixture_ids": ["core-unit-source-profile:" + row["profile_id"]],
}
def mapping_record(model: str, source_uids: tuple[str, ...] = SOURCE_UIDS) -> dict[str, Any]:
rows = [next(row for row in profiles(uid) if row["source_model"] == model) for uid in source_uids]
if not rows:
raise ValueError("Source profiles required")
kind = ModelType(rows[0]["model_type"])
return {
"schema_version": 8,
"mapping_revision": REVISION,
"source": {
"provider_id": SOURCE_PROVIDER,
"model_type": kind.value,
"model": model,
"mode": "chat" if kind is ModelType.LLM else "text-embedding",
},
"settlement_owner": "shared_credit_pool",
"pool_types": ["paid", "trial"],
"variants": list(starmap(variant_record, zip(rows, source_uids, strict=True))),
}
def registry(source_uids: tuple[str, ...] = SOURCE_UIDS) -> str:
return json.dumps([mapping_record(row["source_model"], source_uids) for row in profiles(SOURCE_UIDS[0])])
@@ -0,0 +1,304 @@
"""Synthetic V8 shapes only; never a reviewed SDK/profile or release packet."""
import hashlib
import json
from copy import deepcopy
from dataclasses import FrozenInstanceError
from typing import cast
import pytest
from pydantic import ValidationError
from typing_extensions import TypedDict
from services.entities.model_billing_gemini_mapping import (
GEMINI_SOURCE_EMBEDDING_MODELS,
GEMINI_SOURCE_LLM_MODELS,
GEMINI_SOURCE_UID,
SourceGeminiVariantMapping,
gemini_source_model_type,
gemini_source_operations,
)
from services.entities.model_billing_gemini_v8_mapping import (
GEMINI_0913_SOURCE_UID,
SelectedGeminiV8SourceVariant,
SourceGeminiV8VariantMapping,
SourceGeminiV8VariantSelection,
)
from tests.helpers.unit.model_billing_gemini_profiles import profiles, variant_record
class SyntheticAdapter(TypedDict):
id: str
revision: str
rules_digest: str
class SyntheticTarget(TypedDict):
plugin_id: str
provider: str
model_type: str
model: str
catalog_revision: str
minimum_plugin_version: str
class SyntheticVariant(TypedDict):
variant_id: str
source_plugin_uid: str
source_settings: dict[str, str]
source_schema_digest: str
source_runtime_schema_digest: str
source_profile_id: str
parameter_adapter: SyntheticAdapter
target: SyntheticTarget
operations: list[str]
conformance_fixture_ids: list[str]
class SyntheticRecord(TypedDict):
schema_version: int
mapping_revision: str
source: dict[str, str]
settlement_owner: str
pool_types: list[str]
variants: list[SyntheticVariant]
def synthetic_record(model: str = "gemini-2.5-flash") -> SyntheticRecord:
kind = gemini_source_model_type(model)
llm = model in GEMINI_SOURCE_LLM_MODELS
settings = (
{
"source_base_policy": "unset_or_exact_google_root",
"request_metadata_policy": "system_false_only",
"file_url_policy": "actual_system_absent_or_empty_only",
}
if llm
else {"source_base_policy": "not_used", "request_metadata_policy": "not_used", "file_url_policy": "not_used"}
)
return {
"schema_version": 8,
"mapping_revision": "synthetic-v8-shape-not-published",
"source": {
"provider_id": "langgenius/gemini/google",
"model_type": kind.value,
"model": model,
"mode": "chat" if llm else "text-embedding",
},
"settlement_owner": "shared_credit_pool",
"pool_types": ["paid", "trial"],
"variants": [
{
"variant_id": f"synthetic-{version}-{model}",
"source_plugin_uid": uid,
"source_settings": deepcopy(settings),
# Syntax examples, not real source or target digest evidence.
"source_schema_digest": "sha256:" + "a" * 64,
"source_runtime_schema_digest": "sha256:" + "b" * 64,
"source_profile_id": f"gemini{version}-native-v1:{model}",
"parameter_adapter": {"id": adapter, "revision": "1", "rules_digest": "sha256:" + "c" * 64},
"target": {
"plugin_id": "langgenius/tokener",
"provider": "tokener",
"model_type": kind.value,
"model": model,
"catalog_revision": "synthetic-not-a-live-catalog",
"minimum_plugin_version": "0.0.0.dev0",
},
"operations": sorted(gemini_source_operations(model)),
"conformance_fixture_ids": ["synthetic-shape-only"],
}
for version, uid, adapter in (
("0912", GEMINI_SOURCE_UID, "gemini_credit_source_v1"),
("0913", GEMINI_0913_SOURCE_UID, "gemini_credit_source_v2"),
)
],
}
def selection(record: SyntheticRecord) -> dict[str, object]:
row = record["variants"][0]
return {
"schema_version": 8,
**{
key: row[key]
for key in (
"variant_id",
"source_plugin_uid",
"source_settings",
"source_schema_digest",
"source_runtime_schema_digest",
)
},
"registry_digest": "sha256:" + "d" * 64,
}
@pytest.mark.parametrize("model", sorted(GEMINI_SOURCE_LLM_MODELS | GEMINI_SOURCE_EMBEDDING_MODELS))
def test_exact_two_uid_shapes_and_each_single_variant_round_trip(model: str) -> None:
raw = synthetic_record(model)
parsed = SourceGeminiV8VariantMapping.model_validate(raw)
assert parsed.model_dump(mode="json") == raw
assert SourceGeminiV8VariantMapping.model_validate_json(parsed.model_dump_json()) == parsed
for row in raw["variants"]:
one: SyntheticRecord = {**raw, "variants": [row]}
assert (
SourceGeminiV8VariantMapping.model_validate(one).variants[0].source_plugin_uid == row["source_plugin_uid"]
)
frozen = SourceGeminiV8VariantSelection.model_validate(selection(one))
assert SourceGeminiV8VariantSelection.model_validate_json(frozen.model_dump_json()) == frozen
@pytest.mark.parametrize("value", [True, False, 8.0, "8", 6, None])
def test_mapping_and_selection_require_integer_eight_without_coercion(value: object) -> None:
raw = synthetic_record()
with pytest.raises(ValidationError, match="integer 8"):
SourceGeminiV8VariantMapping.model_validate({**raw, "schema_version": value})
with pytest.raises(ValidationError, match="integer 8"):
SourceGeminiV8VariantSelection.model_validate({**selection(raw), "schema_version": value})
@pytest.mark.parametrize("mutation", ["none", "three", "variant_id", "selector", "pools"])
def test_finite_variant_and_selector_uniqueness(mutation: str) -> None:
raw = synthetic_record()
if mutation == "none":
raw["variants"] = []
elif mutation == "three":
raw["variants"].append(deepcopy(raw["variants"][0]))
elif mutation == "variant_id":
raw["variants"][1]["variant_id"] = raw["variants"][0]["variant_id"]
elif mutation == "selector":
duplicate = deepcopy(raw["variants"][0])
duplicate["variant_id"] = "different-id-same-selector"
raw["variants"][1] = duplicate
else:
raw["pool_types"] = ["trial", "trial"]
with pytest.raises(ValidationError):
SourceGeminiV8VariantMapping.model_validate(raw)
@pytest.mark.parametrize("index", [0, 1])
@pytest.mark.parametrize("field", ["uid", "profile", "adapter", "revision"])
def test_uid_profile_and_adapter_identity_cannot_be_crossed(index: int, field: str) -> None:
raw = synthetic_record()
item, other = raw["variants"][index], raw["variants"][1 - index]
if field == "uid":
item["source_plugin_uid"] = other["source_plugin_uid"]
elif field == "profile":
item["source_profile_id"] = other["source_profile_id"]
elif field == "adapter":
item["parameter_adapter"]["id"] = other["parameter_adapter"]["id"]
else:
item["parameter_adapter"]["revision"] = "2"
with pytest.raises(ValidationError):
SourceGeminiV8VariantMapping.model_validate(raw)
@pytest.mark.parametrize("where", ["root", "source", "variant", "settings", "adapter", "target"])
def test_extra_fields_cannot_add_origin_credentials_or_byok_authority(where: str) -> None:
raw = synthetic_record()
row = raw["variants"][0]
target = cast(
dict[str, object],
{
"root": raw,
"source": raw["source"],
"variant": row,
"settings": row["source_settings"],
"adapter": row["parameter_adapter"],
"target": row["target"],
}[where],
)
target["byok_or_origin_override"] = "not-a-routing-authority"
with pytest.raises(ValidationError, match="Extra inputs"):
SourceGeminiV8VariantMapping.model_validate(raw)
@pytest.mark.parametrize(
"mutation",
[
"provider",
"unknown_uid",
"source_type",
"source_mode",
"target_type",
"target_model",
"settings",
"missing_op",
"extra_op",
"duplicate_op",
"duplicate_fixture",
"bool_digest",
],
)
@pytest.mark.parametrize("model", ["gemini-2.5-flash", "gemini-embedding-001", "gemini-embedding-2-preview"])
def test_model_type_mode_operations_and_settings_remain_closed(mutation: str, model: str) -> None:
raw = synthetic_record(model)
row = raw["variants"][0]
if mutation == "provider":
raw["source"]["provider_id"] = "langgenius/openai/openai"
elif mutation == "unknown_uid":
row["source_plugin_uid"] = GEMINI_SOURCE_UID.replace("0.9.12", "0.9.13")
elif mutation == "source_type":
raw["source"]["model_type"] = "text-embedding" if model in GEMINI_SOURCE_LLM_MODELS else "llm"
elif mutation == "source_mode":
raw["source"]["mode"] = "text-embedding" if model in GEMINI_SOURCE_LLM_MODELS else "chat"
elif mutation == "target_type":
row["target"]["model_type"] = "text-embedding" if model in GEMINI_SOURCE_LLM_MODELS else "llm"
elif mutation == "target_model":
row["target"]["model"] = "gemini-3.1-flash-lite" if model != "gemini-3.1-flash-lite" else "gemini-2.5-flash"
elif mutation == "settings":
row["source_settings"]["source_base_policy"] = (
"not_used" if model in GEMINI_SOURCE_LLM_MODELS else "unset_or_exact_google_root"
)
elif mutation == "missing_op":
row["operations"].pop()
elif mutation == "extra_op":
row["operations"].append("tts/invoke")
elif mutation == "duplicate_op":
row["operations"].append(row["operations"][0])
elif mutation == "duplicate_fixture":
row["conformance_fixture_ids"] *= 2
else:
cast(dict[str, object], row)["source_schema_digest"] = True
with pytest.raises(ValidationError):
SourceGeminiV8VariantMapping.model_validate(raw)
def test_selected_wrapper_is_frozen_and_only_projects_its_declaration() -> None:
parsed = SourceGeminiV8VariantMapping.model_validate(synthetic_record())
row = parsed.variants[1]
selected = SelectedGeminiV8SourceVariant(parsed, row, "sha256:" + "d" * 64)
assert (selected.mapping_revision, selected.source, selected.settlement_owner, selected.pool_types) == (
parsed.mapping_revision,
parsed.source,
parsed.settlement_owner,
parsed.pool_types,
)
assert (
selected.source_schema_digest,
selected.parameter_adapter,
selected.target,
selected.operations,
selected.conformance_fixture_ids,
) == (row.source_schema_digest, row.parameter_adapter, row.target, row.operations, row.conformance_fixture_ids)
with pytest.raises(FrozenInstanceError):
selected.registry_digest = "sha256:" + "e" * 64 # type: ignore[read-only]
def test_existing_v6_real_fixtures_keep_c9_parse_dump_bytes_and_digest() -> None:
# Captured from unchanged C9 before authoring this DTO, not generated from
# the new family or made-up 0913 source profiles.
old = [SourceGeminiVariantMapping.model_validate(variant_record(row)) for row in profiles()]
canonical = json.dumps(
[row.model_dump(mode="json") for row in old], sort_keys=True, separators=(",", ":"), ensure_ascii=False
).encode()
assert hashlib.sha256(canonical).hexdigest() == "553c65d987506bad246c040a54b74827ec23f56396daa7694f4ecdd14bc8ccd7"
assert hashlib.sha256("\n".join(row.model_dump_json() for row in old).encode()).hexdigest() == (
"97acbdb6bfc3fe0914bad33de975ee2959480fdc4ee136119c91b5ea80d78d8b"
)
for item in old:
raw = item.model_dump(mode="json")
raw["variants"][0]["source_plugin_uid"] = GEMINI_0913_SOURCE_UID
with pytest.raises(ValidationError):
SourceGeminiVariantMapping.model_validate(raw)
@@ -0,0 +1 @@
{"encoding":"gzip+base64","raw_sha256":"8c32f42e9a623fae60f0da32633425938fb6557c4c93ea6975b7f9714dfb3dd7","payload_base64":"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 truncated
@@ -0,0 +1,179 @@
"""The nine real Source0913 schemas/pins; no target installation or model call."""
from dataclasses import replace
from operator import itemgetter
from typing import cast
import pytest
from typing_extensions import TypedDict
from graphon.model_runtime.entities.model_entities import AIModelEntity, ModelType
from services import model_billing_gemini_credit_source_v2_adapter as adapter
from services.entities.model_billing_gemini_mapping import GEMINI_SOURCE_UID, GeminiSourceSettings
from services.entities.model_billing_gemini_v8_mapping import GEMINI_0913_SOURCE_UID
from services.entities.model_billing_mapping import SourceParameterContract, model_schema_digest
from tests.helpers.unit.model_billing_gemini_profiles import GeminiProfile
from tests.helpers.unit.model_billing_gemini_v8_profiles import SOURCE_PROVIDER, profile_digest, profiles, schema
class BuildArguments(TypedDict, closed=True):
adapter_id: str
adapter_revision: str
expected_rules_digest: str
source_provider: str
source_model: str
source_plugin_unique_identifier: str
source_schema: AIModelEntity
expected_source_schema_digest: str
expected_source_runtime_schema_digest: str
target_model: str
source_settings: GeminiSourceSettings
source_runtime_schema: AIModelEntity | None
class MarkerArguments(TypedDict, closed=True):
source_provider: str
source_model: str
model_type: ModelType
target_model: str
def arguments(row: GeminiProfile) -> BuildArguments:
return {
"adapter_id": row["adapter_id"],
"adapter_revision": row["adapter_revision"],
"expected_rules_digest": profile_digest(row),
"source_provider": SOURCE_PROVIDER,
"source_model": row["source_model"],
"source_plugin_unique_identifier": GEMINI_0913_SOURCE_UID,
"source_schema": schema(row),
"expected_source_schema_digest": row["source_schema_digest"],
"expected_source_runtime_schema_digest": row["source_runtime_schema_digest"],
"target_model": row["target_model"],
"source_settings": GeminiSourceSettings(**row["source_settings"]),
"source_runtime_schema": schema(row, runtime=True),
}
@pytest.mark.parametrize("row", profiles(GEMINI_0913_SOURCE_UID), ids=itemgetter("source_model"))
def test_real_catalog_runtime_rules_marker_and_prospective_restore(row: GeminiProfile) -> None:
args = arguments(row)
contract = adapter.build_gemini_credit_source_contract(**args)
assert type(contract) is adapter.GeminiCreditSourceV2Contract
assert contract.profile_id == row["profile_id"]
assert contract.adapter_id == "gemini_credit_source_v2"
assert contract.rules_digest == profile_digest(row)
assert model_schema_digest(args["source_schema"]) == contract.source_schema_digest
runtime = args["source_runtime_schema"]
assert runtime is not None
assert model_schema_digest(runtime) == contract.source_runtime_schema_digest
marker = adapter.gemini_credit_source_marker(
contract,
source_provider=SOURCE_PROVIDER,
source_model=row["source_model"],
model_type=ModelType(row["model_type"]),
target_model=row["target_model"],
)
assert set(marker) == {
"schema_version",
"profile_id",
"source_plugin_uid",
"source_model",
"source_schema_digest",
"rules_digest",
}
assert marker["source_plugin_uid"] == GEMINI_0913_SOURCE_UID
assert (
adapter.restore_gemini_credit_source_contract(
marker,
source_provider=SOURCE_PROVIDER,
source_model=row["source_model"],
model_type=ModelType(row["model_type"]),
target_model=row["target_model"],
source_settings=args["source_settings"],
expected_source_runtime_schema_digest=row["source_runtime_schema_digest"],
source_runtime_schema=runtime,
)
== contract
)
# None means frozen/prospective, never a live observed source RPC.
prospective = args.copy()
prospective["source_runtime_schema"] = None
assert adapter.build_gemini_credit_source_contract(**prospective) == contract
@pytest.mark.parametrize("row", profiles(GEMINI_0913_SOURCE_UID), ids=itemgetter("source_model"))
@pytest.mark.parametrize(
("field", "value"),
[
("adapter_id", "gemini_credit_source_v1"),
("adapter_revision", "2"),
("source_provider", "langgenius/openai/openai"),
("source_plugin_unique_identifier", GEMINI_SOURCE_UID),
("source_plugin_unique_identifier", GEMINI_0913_SOURCE_UID.replace("0.9.13", "0.9.14")),
("source_model", "unreviewed-model"),
("target_model", "unreviewed-target"),
("expected_rules_digest", "sha256:" + "a" * 64),
("expected_source_schema_digest", "sha256:" + "b" * 64),
("expected_source_runtime_schema_digest", "sha256:" + "c" * 64),
],
)
def test_each_independent_pin_and_identity_is_fail_closed(row: GeminiProfile, field: str, value: str) -> None:
args = arguments(row)
cast(dict[str, object], args)[field] = value
with pytest.raises(adapter.GeminiCreditSourceV2AdapterError):
adapter.build_gemini_credit_source_contract(**args)
@pytest.mark.parametrize("row", profiles(GEMINI_0913_SOURCE_UID), ids=itemgetter("source_model"))
@pytest.mark.parametrize("runtime", [False, True])
def test_real_entity_full_metadata_drift_is_not_erased(row: GeminiProfile, runtime: bool) -> None:
args = arguments(row)
key = "source_runtime_schema" if runtime else "source_schema"
observed = args[key]
assert isinstance(observed, AIModelEntity)
changed = observed.model_dump(mode="json")
changed["label"] = {"en_US": "changed actual Source metadata"}
cast(dict[str, object], args)[key] = AIModelEntity.model_validate(changed)
with pytest.raises(adapter.GeminiCreditSourceV2AdapterError):
adapter.build_gemini_credit_source_contract(**args)
@pytest.mark.parametrize("row", profiles(GEMINI_0913_SOURCE_UID), ids=itemgetter("source_model"))
def test_marker_requires_exact_concrete_factory_and_never_adopts_other_family(row: GeminiProfile) -> None:
args = arguments(row)
contract = adapter.build_gemini_credit_source_contract(**args)
kwargs: MarkerArguments = {
"source_provider": SOURCE_PROVIDER,
"source_model": row["source_model"],
"model_type": ModelType(row["model_type"]),
"target_model": row["target_model"],
}
generic = SourceParameterContract(
profile_id=contract.profile_id,
source_plugin_unique_identifier=contract.source_plugin_unique_identifier,
source_model=contract.source_model,
source_schema_digest=contract.source_schema_digest,
target_model=contract.target_model,
rules_digest=contract.rules_digest,
adapter_id=contract.adapter_id,
algorithm_revision=contract.algorithm_revision,
source_runtime_schema_digest=contract.source_runtime_schema_digest,
)
for forged in (replace(contract, rules_digest="sha256:" + "0" * 64), generic):
with pytest.raises(adapter.GeminiCreditSourceV2AdapterError):
adapter.gemini_credit_source_marker(cast(adapter.GeminiCreditSourceV2Contract, forged), **kwargs)
marker = adapter.gemini_credit_source_marker(contract, **kwargs)
for changed in (
{**marker, "schema_version": True},
{**marker, "profile_id": str(marker["profile_id"]).replace("0913", "0912")},
{**marker, "source_plugin_uid": GEMINI_SOURCE_UID},
{**marker, "extra": "not-authority"},
):
with pytest.raises(adapter.GeminiCreditSourceV2AdapterError):
adapter.restore_gemini_credit_source_contract(
changed,
**kwargs,
source_settings=args["source_settings"],
expected_source_runtime_schema_digest=row["source_runtime_schema_digest"],
)
@@ -1736,3 +1736,86 @@ def test_credit_llm_family_checks_selected_source_and_every_prospective_target(
gateway.validate_target("tenant", _CREDIT_LLM_REVISION, inventory)
with pytest.raises(ModelRouteUnmapped):
gateway.validate_target("tenant", _CREDIT_LLM_REVISION, {**inventory, "prospective_variants": []})
@pytest.mark.parametrize(
"source_uid",
[
"langgenius/gemini:0.9.12@9bb9eff3f9c99a8f1f87bdd5e0f178d5493918939dd0e02825ae8383bd0fd7ed",
"langgenius/gemini:0.9.13@4378187cfc50d4253573f4d96baa13228d8ed2eb746ac3bae492a8eaee2da458",
],
)
@pytest.mark.parametrize("model", ["gemini-2.5-flash", "gemini-embedding-001", "gemini-embedding-2-preview"])
def test_v8_real_target_identity_guard_never_normalizes_wrong_models(source_uid: str, model: str) -> None:
from services.entities.model_billing_gemini_mapping import GeminiSourceSettings
from services.model_billing_source_variants import GeminiV8SourceVariantContext, source_mapping_revision
from tests.helpers.unit import model_billing_gemini_v8_profiles as gemini
row = next(item for item in gemini.profiles(source_uid) if item["source_model"] == model)
observed = gemini.schema(row)
registry = source_mapping_revision(gemini.registry(), gemini.REVISION, normalize_provider=str)
selected = registry.resolve(
(gemini.SOURCE_PROVIDER, observed.model_type, model),
context=GeminiV8SourceVariantContext(source_uid, GeminiSourceSettings(**row["source_settings"])),
)
target = gemini.schema(row, runtime=True)
module._assert_target_source_identity(selected, target)
changed = target.model_dump(mode="json")
changed["model"] = "unreviewed-target-identity"
with pytest.raises(ModelRouteUnmapped):
module._assert_target_source_identity(selected, AIModelEntity.model_validate(changed))
@pytest.mark.parametrize("version", [6, 8])
@pytest.mark.parametrize("model", ["gemini-embedding-001", "gemini-embedding-2-preview"])
def test_real_v6_v8_dimension_guards_keep_selected_and_prospective_distinct(version: int, model: str) -> None:
from services.entities.model_billing_gemini_mapping import GeminiSourceSettings
from services.model_billing_source_variants import (
GeminiSourceVariantContext,
GeminiV8SourceVariantContext,
source_mapping_revision,
)
from tests.helpers.unit import model_billing_gemini_profiles as legacy
from tests.helpers.unit import model_billing_gemini_v8_profiles as current
if version == 6:
row = next(item for item in legacy.profiles() if item["source_model"] == model)
registry = source_mapping_revision(legacy.registry(), legacy.REVISION, normalize_provider=str)
context = GeminiSourceVariantContext(legacy.SOURCE_UID, GeminiSourceSettings(**row["source_settings"]))
else:
uid = current.SOURCE_UIDS[1]
row = next(item for item in current.profiles(uid) if item["source_model"] == model)
registry = source_mapping_revision(current.registry(), current.REVISION, normalize_provider=str)
context = GeminiV8SourceVariantContext(uid, GeminiSourceSettings(**row["source_settings"]))
target = current.schema(row, runtime=True)
selected = registry.resolve((current.SOURCE_PROVIDER, target.model_type, model), context=context)
module._assert_target_source_identity(selected, target)
wrong_target = target.model_dump(mode="json")
wrong_target["model"] = "unreviewed-target-identity"
with pytest.raises(ModelRouteUnmapped):
module._assert_target_source_identity(selected, AIModelEntity.model_validate(wrong_target))
actual = module.embedding_dimensions_contract(target)
module._assert_target_embedding_dimensions(
mapping=selected,
kind=target.model_type,
prospective_only=False,
source={"embedding_dimensions": actual},
schema=target,
)
with pytest.raises(ModelRouteUnmapped):
module._assert_target_embedding_dimensions(
mapping=selected,
kind=target.model_type,
prospective_only=False,
source={"embedding_dimensions": "unreviewed-vector-space"},
schema=target,
)
# There is no installed-source dimension fact for a prospective row. The
# production path independently verifies its exact runtime schema first.
module._assert_target_embedding_dimensions(
mapping=selected,
kind=target.model_type,
prospective_only=True,
source={},
schema=target,
)
@@ -16,6 +16,7 @@ from core.entities.provider_entities import ProviderQuotaType, QuotaConfiguratio
from core.hosting_configuration import HostingProvider, PaidHostingQuota
from graphon.model_runtime.entities.model_entities import AIModelEntity, ModelType
from services.entities.model_billing_embedding_mapping import SelectedEmbeddingSourceVariant
from services.entities.model_billing_gemini_v8_mapping import SelectedGeminiV8SourceVariant
from services.entities.model_billing_mapping import (
ModelMapping,
SelectedSourceVariant,
@@ -44,6 +45,7 @@ from services.model_billing_openai_provider110_adapter import (
from services.model_billing_openai_provider110_adapter import _REVIEWED_CONTRACTS
from services.model_billing_openai_provider110_adapter import _REVIEWED_CONTRACTS as CURRENT_SOURCE_CONTRACTS
from services.model_billing_source_variants import SourceVariantContext, selection_payload, source_endpoint_class
from tests.helpers.unit import model_billing_gemini_v8_profiles as gemini_v8
from tests.helpers.unit.model_billing_source_profiles import (
DAEMON_REVISION,
EMBEDDING_MODELS,
@@ -2133,3 +2135,179 @@ def test_credit_llm_family_append_preserves_all_prior_registry_shapes_and_digest
drifted.restore_selection(
(SOURCE_PROVIDER, ModelType.LLM, frozen.source.model), selection_payload(frozen).model_dump(mode="json")
)
@pytest.mark.parametrize("source_uid", gemini_v8.SOURCE_UIDS)
@pytest.mark.parametrize("model", [row["source_model"] for row in gemini_v8.profiles(gemini_v8.SOURCE_UIDS[0])])
def test_v8_real_two_uid_resolution_factory_restore_and_prospective(source_uid: str, model: str) -> None:
from services import model_billing_gemini_credit_source_adapter as legacy
from services import model_billing_gemini_credit_source_v2_adapter as current
from services.entities.model_billing_gemini_v8_mapping import SourceGeminiV8VariantSelection
from services.model_billing_mapping_service import hosted_gemini_source_fact, mapping_has_required_operations
rows = gemini_v8.profiles(source_uid)
row = next(item for item in rows if item["source_model"] == model)
schemas = [gemini_v8.schema(item) for item in rows]
observed = gemini_v8.schema(row)
registry = source_mapping_revision(gemini_v8.registry(), gemini_v8.REVISION)
fact = hosted_gemini_source_fact(
provider=gemini_v8.SOURCE_PROVIDER,
source_uid=source_uid,
models=schemas,
credentials={"google_api_key": "unit-source-key-never-forwarded"},
)
selected = resolve_source_mapping(
registry,
(gemini_v8.SOURCE_PROVIDER, observed.model_type, model),
source_uid=source_uid,
fact=None,
gemini_fact=fact,
schema=observed,
)
assert type(selected) is SelectedGeminiV8SourceVariant
assert selected.variant.source_plugin_uid == source_uid
assert mapping_has_required_operations(selected)
contract = build_source_adapter_contract(
selected,
source_provider=gemini_v8.SOURCE_PROVIDER,
source_plugin_unique_identifier=source_uid,
source_schema=observed,
source_credentials=None,
)
expected_type = (
legacy.GeminiCreditSourceContract
if source_uid == gemini_v8.SOURCE_UIDS[0]
else current.GeminiCreditSourceV2Contract
)
assert type(contract) is expected_type
assert contract == restore_variant_source_contract(selected)
marker = source_parameter_marker(
contract,
source_provider=gemini_v8.SOURCE_PROVIDER,
source_model=model,
model_type=observed.model_type,
target_model=model,
)
assert marker["source_plugin_uid"] == source_uid
assert "unit-source-key" not in json.dumps(marker)
frozen = selection_payload(selected)
assert type(frozen) is SourceGeminiV8VariantSelection
assert frozen.schema_version == 8
assert (
registry.restore_selection(
(gemini_v8.SOURCE_PROVIDER, observed.model_type, model), frozen.model_dump(mode="json")
)
== selected
)
assert len(registry.selected_prospective()) == 18
validate_frozen_mapping_evidence(
selected,
provider=gemini_v8.SOURCE_PROVIDER,
model=model,
model_type=observed.model_type,
target_model=model,
operations=tuple(selected.operations),
source_contract=contract,
tts_contract=None,
)
@pytest.mark.parametrize("source_uid", gemini_v8.SOURCE_UIDS)
def test_v8_fresh_facts_unknown_uid_drift_and_wrong_context_cannot_authorize(source_uid: str) -> None:
from core.entities.provider_entities import HostedGeminiSourceFact
from services.entities.model_billing_gemini_mapping import GeminiSourceSettings
from services.model_billing_mapping_service import (
gemini_source_variant_context,
gemini_v8_source_variant_context,
hosted_gemini_source_fact,
)
from services.model_billing_source_variants import GeminiSourceVariantContext, GeminiV8SourceVariantContext
row = gemini_v8.profiles(source_uid)[0]
observed = gemini_v8.schema(row)
identity = (gemini_v8.SOURCE_PROVIDER, observed.model_type, row["source_model"])
registry = source_mapping_revision(gemini_v8.registry(), gemini_v8.REVISION)
fact = hosted_gemini_source_fact(
provider=gemini_v8.SOURCE_PROVIDER,
source_uid=source_uid,
models=[observed],
credentials={},
)
assert fact is not None
def context(value: HostedGeminiSourceFact | None) -> GeminiV8SourceVariantContext | None:
return gemini_v8_source_variant_context(
value,
provider=gemini_v8.SOURCE_PROVIDER,
source_uid=source_uid,
model_type=observed.model_type,
schema=observed,
)
assert context(fact) is not None
assert context(None) is None
assert context(replace(fact, plugin_unique_identifier="unknown")) is None
assert context(replace(fact, catalog_schema_digests=())) is None
assert context(replace(fact, llm_file_url_policy="unreviewed")) is None
assert (
hosted_gemini_source_fact(
provider=gemini_v8.SOURCE_PROVIDER,
source_uid=source_uid + "x",
models=[observed],
credentials={},
)
is None
)
assert (
hosted_gemini_source_fact(
provider=gemini_v8.SOURCE_PROVIDER,
source_uid=source_uid,
models=[observed],
credentials=None,
)
is None
)
with pytest.raises(ValueError, match="V8 Gemini fact family"):
registry.resolve(
identity, context=GeminiSourceVariantContext(source_uid, GeminiSourceSettings(**row["source_settings"]))
)
if source_uid == gemini_v8.SOURCE_UIDS[1]:
assert (
gemini_source_variant_context(
fact,
provider=gemini_v8.SOURCE_PROVIDER,
source_uid=source_uid,
model_type=observed.model_type,
schema=observed,
)
is None
)
@pytest.mark.parametrize(
("field", "error"),
[
("schema_version", "integer 8"),
("variant_id", "Frozen source variant changed"),
("source_plugin_uid", "literal_error"),
("registry_digest", "string_pattern_mismatch"),
("source_runtime_schema_digest", "string_pattern_mismatch"),
],
)
def test_v8_saved_selection_tampering_is_not_a_revision_rebase(field: str, error: str) -> None:
from services.entities.model_billing_gemini_mapping import GeminiSourceSettings
from services.model_billing_source_variants import GeminiV8SourceVariantContext
source_uid = gemini_v8.SOURCE_UIDS[1]
row = gemini_v8.profiles(source_uid)[0]
observed = gemini_v8.schema(row)
identity = (gemini_v8.SOURCE_PROVIDER, observed.model_type, row["source_model"])
registry = source_mapping_revision(gemini_v8.registry(), gemini_v8.REVISION)
selected = registry.resolve(
identity, context=GeminiV8SourceVariantContext(source_uid, GeminiSourceSettings(**row["source_settings"]))
)
assert isinstance(selected, SelectedGeminiV8SourceVariant)
payload = selection_payload(selected).model_dump(mode="json")
payload[field] = True if field == "schema_version" else "changed"
with pytest.raises(ValueError, match=error):
registry.restore_selection(identity, payload)