Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sdk/nexent/core/model_service/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Model service contracts and provider adapters."""
21 changes: 21 additions & 0 deletions sdk/nexent/core/model_service/profiles/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2025 models.dev

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
39 changes: 39 additions & 0 deletions sdk/nexent/core/model_service/profiles/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Nexent model profile source catalog

## Source and scope

Selected authored TOML files are copied byte-for-byte from
[models.dev](https://github.com/anomalyco/models.dev), commit
`e69e1844210e5cfe7c7e7f68d57328bc7451a51c`.
The original MIT copyright and permission notice is retained in [LICENSE](LICENSE).

The initial inventory contains 21 model files, 21 provider-model files and three
provider files for Alibaba China, Volcengine and Volcengine Coding Plan. It covers
selected recent Qwen, GLM, DeepSeek and MiniMax models. This is source material,
not a verified support list. Pricing remains reference data; this change does
not implement cost estimation.

## File ownership

- `models/` and `providers/` retain upstream paths, spelling, comments and bytes.
- `manifest.toml` pins source kinds, paths, hashes and the upstream revision.
- Nexent normalization and API binding rules belong under `rules/` separately;
do not silently rewrite upstream files.
- Source references are provenance. Saved outlets retain their resolved
configuration and do not recompose it when the catalog changes.

## Updating the selection

1. Select one upstream commit and inspect its authored schema and generator.
2. Copy reviewed files and their complete `base_model` dependencies.
3. Preserve original bytes and paths; update manifest hashes and revision.
4. Review every field against the versioned Nexent mapping rules, including
fields retained as references or explicitly ignored.
5. Run integrity, parser, normalization, composition and installed-package
checks. Run the reusable real-model matrix before declaring support.
6. Keep deleted upstream entries locally unless deliberately removed in a Nexent
release; do not modify saved outlets automatically.

No upstream TypeScript project, online synchronization or npm dependency is
required at runtime. Model weight licenses and service terms remain separate
from the license of these descriptive files.
1 change: 1 addition & 0 deletions sdk/nexent/core/model_service/profiles/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Local model profile definitions, loading and resolution."""
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Private parsing of the pinned models.dev authored source format."""
134 changes: 134 additions & 0 deletions sdk/nexent/core/model_service/profiles/_models_dev/reader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
"""Read the complete declared source inventory before semantic normalization."""

import hashlib
import tomllib
from dataclasses import dataclass
from pathlib import Path
from types import MappingProxyType
from typing import Literal, Mapping

from pydantic import Field, ValidationError

from nexent.core.model_service.profiles.contracts import AtomicProfileReference, NonBlankString, ProfileContract


SourceKind = Literal["model", "provider", "provider_model"]


class SourceEntry(ProfileContract):
"""One source file whose bytes are pinned by the catalog manifest."""

kind: SourceKind
path: NonBlankString
content_sha256: NonBlankString


class SourceManifest(ProfileContract):
"""Versioned source inventory; mapping and runtime API bindings are separate."""

schema_version: int = Field(ge=1, le=1)
source_schema_ref: Literal["models_dev_authored_v1"]
upstream_url: Literal["https://github.com/anomalyco/models.dev"]
upstream_revision: NonBlankString
sources: list[SourceEntry] = Field(min_length=1)


class SourceReadError(ValueError):
"""Sanitized source diagnostic without embedding file contents or OS errors."""

def __init__(self, category: str, file_path: str, source_kind: str = "manifest"):
self.category = category
self.file_path = file_path
self.source_kind = source_kind
self.source_path = ""
self.rule_id = "source_inventory_v1"
super().__init__(f"{category}: {source_kind}: {file_path}")


@dataclass(frozen=True)
class SourceDocument:
"""Deeply read-only authored document, not a resolved runtime profile."""

kind: SourceKind
key: str
file_path: str
content_sha256: str
data: Mapping[str, object]


def _freeze(value: object) -> object:
if isinstance(value, dict):
return MappingProxyType({key: _freeze(item) for key, item in value.items()})
if isinstance(value, list):
return tuple(_freeze(item) for item in value)
return value


def _read(root: Path, path: str, kind: str) -> bytes:
try:
candidate = (root / path).resolve()
if not candidate.is_relative_to(root):
raise SourceReadError("SOURCE_PATH_OUTSIDE_ROOT", path, kind)
return candidate.read_bytes()
except (OSError, RuntimeError):
raise SourceReadError("SOURCE_FILE_UNAVAILABLE", path, kind) from None


def _parse(data: bytes, path: str, kind: str) -> dict:
try:
return tomllib.loads(data.decode("utf-8"))
except (UnicodeDecodeError, tomllib.TOMLDecodeError):
raise SourceReadError("SOURCE_TOML_INVALID", path, kind) from None


def _key(entry: SourceEntry) -> str:
parts = entry.path.split("/")
if entry.kind == "model" and len(parts) >= 3 and parts[0] == "models":
return entry.path[len("models/") : -len(".toml")]
if entry.kind == "provider" and len(parts) == 3 and parts[0] == "providers" and parts[2] == "provider.toml":
return parts[1]
if entry.kind == "provider_model" and len(parts) >= 4 and parts[0] == "providers" and parts[2] == "models":
return parts[1] + "/" + "/".join(parts[3:])[: -len(".toml")]
raise SourceReadError("SOURCE_KIND_PATH_MISMATCH", entry.path, entry.kind)


def read_sources(root: Path) -> tuple[SourceDocument, ...]:
"""Fail the whole inventory on errors; do not expose a partial catalog."""
root = root.resolve()
raw_manifest = _parse(_read(root, "manifest.toml", "manifest"), "manifest.toml", "manifest")
try:
manifest = SourceManifest.model_validate(raw_manifest)
if len(manifest.upstream_revision) != 40 or any(
char not in "0123456789abcdef" for char in manifest.upstream_revision
):
raise ValueError("Invalid upstream commit")
except (ValidationError, ValueError):
raise SourceReadError("SOURCE_MANIFEST_INVALID", "manifest.toml") from None

documents = []
identities = set()
paths = set()
for entry in manifest.sources:
try:
AtomicProfileReference(
key=entry.path,
catalog_revision=manifest.upstream_revision,
file_path=entry.path,
content_sha256=entry.content_sha256,
)
except ValidationError:
raise SourceReadError("SOURCE_REFERENCE_INVALID", entry.path, entry.kind) from None
if not entry.path.endswith(".toml") or entry.path.split("/")[-1] == ".toml":
raise SourceReadError("SOURCE_KIND_PATH_MISMATCH", entry.path, entry.kind)
key = _key(entry)
identity = (entry.kind, key)
if entry.path in paths or identity in identities:
raise SourceReadError("SOURCE_DUPLICATE", entry.path, entry.kind)
paths.add(entry.path)
identities.add(identity)
data = _read(root, entry.path, entry.kind)
if hashlib.sha256(data).hexdigest() != entry.content_sha256:
raise SourceReadError("SOURCE_DIGEST_MISMATCH", entry.path, entry.kind)
parsed = _parse(data, entry.path, entry.kind)
documents.append(SourceDocument(entry.kind, key, entry.path, entry.content_sha256, _freeze(parsed)))
return tuple(documents)
131 changes: 131 additions & 0 deletions sdk/nexent/core/model_service/profiles/contracts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
"""Strict profile primitives, independent of provider clients and persistence."""

import json
from typing import Annotated, Literal, Self

from pydantic import BaseModel, ConfigDict, Field, StringConstraints, model_validator


SupportStatus = Literal["supported", "unsupported", "unknown"]
NonBlankString = Annotated[str, StringConstraints(pattern=r"\S")]
PositiveTokens = Annotated[int, Field(gt=0)]


class ProfileContract(BaseModel):
"""Reject undeclared fields and coercion at the profile boundary."""

model_config = ConfigDict(strict=True, extra="forbid", frozen=True)


class ContextCapabilities(ProfileContract):
"""Effective service limits; missing limits remain unknown."""

combined_window: PositiveTokens | None = None
input_limit: PositiveTokens | None = None
output_limit: PositiveTokens | None = None

@model_validator(mode="after")
def validate_limits(self) -> Self:
if self.combined_window is not None:
for limit in (self.input_limit, self.output_limit):
if limit is not None and limit > self.combined_window:
raise ValueError("Service limits cannot exceed the combined context window")
return self


class ToggleControl(ProfileContract):
"""Explicitly supported thinking switch values, not the current setting."""

mode: Literal["toggle"] = "toggle"
parameter_key: Literal["enable_thinking"] = "enable_thinking"
values: list[bool] = Field(min_length=1)

@model_validator(mode="after")
def validate_values(self) -> Self:
if len(set(self.values)) != len(self.values):
raise ValueError("Toggle values must be unique")
return self


class EffortControl(ProfileContract):
"""Provider-declared effort values; no universal effort enum is inferred."""

mode: Literal["effort"] = "effort"
parameter_key: Literal["reasoning_effort"] = "reasoning_effort"
values: list[NonBlankString] = Field(min_length=1)

@model_validator(mode="after")
def validate_values(self) -> Self:
if len(set(self.values)) != len(self.values):
raise ValueError("Effort values must be unique")
return self


class BudgetTokensControl(ProfileContract):
"""Token bounds and explicitly declared sentinel values."""

mode: Literal["budget_tokens"] = "budget_tokens"
parameter_key: Literal["reasoning_budget_tokens"] = "reasoning_budget_tokens"
min: Annotated[int, Field(ge=0)]
max: Annotated[int, Field(ge=0)]
special_values: list[int] = Field(default_factory=list)

@model_validator(mode="after")
def validate_range(self) -> Self:
if self.min > self.max:
raise ValueError("Budget minimum cannot exceed maximum")
if len(set(self.special_values)) != len(self.special_values):
raise ValueError("Special budget values must be unique")
return self


ReasoningControl = Annotated[ToggleControl | EffortControl | BudgetTokensControl, Field(discriminator="mode")]


class ReasoningCapabilities(ProfileContract):
"""Capability declarations with unknown distinct from unsupported."""

status: SupportStatus = "unknown"
controls: list[ReasoningControl] | None = None
response_paths: list[NonBlankString] = Field(default_factory=list)

@model_validator(mode="after")
def validate_controls(self) -> Self:
if self.status == "unsupported" and (self.controls or self.response_paths):
raise ValueError("Unsupported reasoning cannot declare controls or response paths")
if len(set(self.response_paths)) != len(self.response_paths):
raise ValueError("Reasoning response paths must be unique")
if self.controls is not None:
modes = [control.mode for control in self.controls]
keys = [control.parameter_key for control in self.controls]
if len(set(modes)) != len(modes) or len(set(keys)) != len(keys):
raise ValueError("Reasoning control modes and parameter keys must be unique")
encoded = json.dumps(
[control.model_dump(mode="json") for control in self.controls],
ensure_ascii=False,
separators=(",", ":"),
).encode("utf-8")
if len(encoded) > 64 * 1024:
raise ValueError("Reasoning controls exceed the 64 KiB UTF-8 limit")
return self


class AtomicProfileReference(ProfileContract):
"""Provenance only; runtime loading never recomposes from this reference."""

key: NonBlankString
catalog_revision: NonBlankString
file_path: NonBlankString
content_sha256: Annotated[str, StringConstraints(pattern=r"^[a-f0-9]{64}$")]

@model_validator(mode="after")
def validate_source_path(self) -> Self:
parts = self.file_path.split("/")
if (
"\\" in self.file_path
or ":" in self.file_path
or any(ord(character) < 32 for character in self.file_path)
or any(part in ("", ".", "..") for part in parts)
):
raise ValueError("Source paths must be canonical relative POSIX paths")
return self
Loading
Loading