diff --git a/sdk/nexent/core/model_service/__init__.py b/sdk/nexent/core/model_service/__init__.py new file mode 100644 index 0000000000..8bbf7e4f38 --- /dev/null +++ b/sdk/nexent/core/model_service/__init__.py @@ -0,0 +1 @@ +"""Model service contracts and provider adapters.""" diff --git a/sdk/nexent/core/model_service/profiles/LICENSE b/sdk/nexent/core/model_service/profiles/LICENSE new file mode 100644 index 0000000000..9ef000844a --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/LICENSE @@ -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. diff --git a/sdk/nexent/core/model_service/profiles/README.md b/sdk/nexent/core/model_service/profiles/README.md new file mode 100644 index 0000000000..4797c583c6 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/README.md @@ -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. diff --git a/sdk/nexent/core/model_service/profiles/__init__.py b/sdk/nexent/core/model_service/profiles/__init__.py new file mode 100644 index 0000000000..b32bda4f07 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/__init__.py @@ -0,0 +1 @@ +"""Local model profile definitions, loading and resolution.""" diff --git a/sdk/nexent/core/model_service/profiles/_models_dev/__init__.py b/sdk/nexent/core/model_service/profiles/_models_dev/__init__.py new file mode 100644 index 0000000000..363963c931 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/_models_dev/__init__.py @@ -0,0 +1 @@ +"""Private parsing of the pinned models.dev authored source format.""" diff --git a/sdk/nexent/core/model_service/profiles/_models_dev/reader.py b/sdk/nexent/core/model_service/profiles/_models_dev/reader.py new file mode 100644 index 0000000000..0ab4bfb84e --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/_models_dev/reader.py @@ -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) diff --git a/sdk/nexent/core/model_service/profiles/contracts.py b/sdk/nexent/core/model_service/profiles/contracts.py new file mode 100644 index 0000000000..1e80413cca --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/contracts.py @@ -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 diff --git a/sdk/nexent/core/model_service/profiles/manifest.toml b/sdk/nexent/core/model_service/profiles/manifest.toml new file mode 100644 index 0000000000..5ef8ac216d --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/manifest.toml @@ -0,0 +1,229 @@ +schema_version = 1 +source_schema_ref = "models_dev_authored_v1" +upstream_url = "https://github.com/anomalyco/models.dev" +upstream_revision = "e69e1844210e5cfe7c7e7f68d57328bc7451a51c" + +[[sources]] +kind = "model" +path = "models/alibaba/qwen3.5-27b.toml" +content_sha256 = "15e1c86123b937d3152f69e87650f3b3bbfd9600f8bbfbc5361a6f5e9f69fc16" + +[[sources]] +kind = "model" +path = "models/alibaba/qwen3.5-35b-a3b.toml" +content_sha256 = "50a139d95791c9c5e145f4a0f115f18c3d38840202c7683e8861f05fe4ffc6be" + +[[sources]] +kind = "model" +path = "models/alibaba/qwen3.5-397b-a17b.toml" +content_sha256 = "d064d5959f3dca64beb7108a38280877719e89709db7775f932a5ee791e3924e" + +[[sources]] +kind = "model" +path = "models/alibaba/qwen3.5-flash.toml" +content_sha256 = "39a4329d9772432e58cf92044f143bd7e1445b434ee65830acad958b72322d5c" + +[[sources]] +kind = "model" +path = "models/alibaba/qwen3.5-plus.toml" +content_sha256 = "15c6b3b7f334219ee6d43c76d1a004e57469e4a4e780e4b254c91474d5cb1bd4" + +[[sources]] +kind = "model" +path = "models/alibaba/qwen3.8-27b.toml" +content_sha256 = "5a7c7ec1b513c3268756c02fa240f09ba438bce594cbb7d34ebb4f71c4a448e0" + +[[sources]] +kind = "model" +path = "models/alibaba/qwen3.8-2.4t-a95b.toml" +content_sha256 = "067a17c3a34382a3e286414e8f6ef4ad31844716ed85af41fdab7061ba44add4" + +[[sources]] +kind = "model" +path = "models/alibaba/qwen3.8-flash.toml" +content_sha256 = "7fc097dbfdcbcf827fc28c17e23bafda6d695ce5d16d96fb65612e4cae581dcc" + +[[sources]] +kind = "model" +path = "models/alibaba/qwen3.8-max.toml" +content_sha256 = "ee87c9af3b4188b86dc8ee3d045e9a18a0b611b5db1e47cfc3f88b1672164634" + +[[sources]] +kind = "model" +path = "models/alibaba/qwen3-coder-next.toml" +content_sha256 = "1f4175a40524b382f1e9efac28e4454b477a2f4ccf5a460134b9ed12cb829229" + +[[sources]] +kind = "model" +path = "models/zhipuai/glm-5.1.toml" +content_sha256 = "8c7069a86e0ef764d2a1d0ebb30156abed0cf7b27e5b972c224a5cd9aee27b40" + +[[sources]] +kind = "model" +path = "models/zhipuai/glm-5.2.toml" +content_sha256 = "6ed303f1feeaed5496e919b6c7ae999e2743505a22ed97062b5c833adf37ce13" + +[[sources]] +kind = "model" +path = "models/zhipuai/glm-5.3.toml" +content_sha256 = "8022f2c087c0ad8bdf9f8ed4fe950fda5f7f37ef2a121c577e87fbe28d159c29" + +[[sources]] +kind = "model" +path = "models/zhipuai/glm-5.3-flash.toml" +content_sha256 = "7cdb7a1cfea9ab7e7c3e3392f0fdad0ac9c3f9c92e2f71a2d109788c5d02f843" + +[[sources]] +kind = "model" +path = "models/deepseek/deepseek-v4-flash.toml" +content_sha256 = "02ae90fe9be99047c373f3862afe72367c7a96a7aef7f43864c0bcd9e22da194" + +[[sources]] +kind = "model" +path = "models/deepseek/deepseek-v4-pro.toml" +content_sha256 = "bd08e3df5404ff5f795ac91b44ef34ac7c29a6911de0bd9fded3739501e47996" + +[[sources]] +kind = "model" +path = "models/deepseek/deepseek-v4-flash-0731.toml" +content_sha256 = "cb0133fb9f376da44fc6ee512c8a3ba0399626bb026805f608f265e504511c4e" + +[[sources]] +kind = "model" +path = "models/deepseek/deepseek-v4-pro-0813.toml" +content_sha256 = "e005b286813f8bcf39ecc4397b36a99895532c97bbc2c83f21a94dbaa85455ea" + +[[sources]] +kind = "model" +path = "models/deepseek/deepseek-v4.1-flash.toml" +content_sha256 = "ef594fbed1c96863ff728e31530dbc1987d8862e36c5f1b5f08e5376d631aee0" + +[[sources]] +kind = "model" +path = "models/minimax/MiniMax-M2.7.toml" +content_sha256 = "c63b15b0f281e217f466b973439cfd1876b23d636288cd4f7102ef28a57df761" + +[[sources]] +kind = "model" +path = "models/minimax/MiniMax-M3.toml" +content_sha256 = "a1d815dc34328bd0719fc557794d696205a7506a06515f8e2d84c24f3bce1b1e" + +[[sources]] +kind = "provider" +path = "providers/alibaba-cn/provider.toml" +content_sha256 = "0060172cf93a8db8b8427021030a3ad5c388c919f7fc47df9723ba8b08d5f54b" + +[[sources]] +kind = "provider" +path = "providers/volcengine/provider.toml" +content_sha256 = "b504a2ab81fccb036105dde4a626f486d82e37ceaf348249baaf0b5c8e234377" + +[[sources]] +kind = "provider" +path = "providers/volcengine-coding-plan/provider.toml" +content_sha256 = "15439498a42304ac424f73810fdf8593ee87d19c05bff271c64383afe6b06ee8" + +[[sources]] +kind = "provider_model" +path = "providers/alibaba-cn/models/qwen3.5-397b-a17b.toml" +content_sha256 = "59342059889eac4ab4829384b954db58c72104f9ffc682441d7b39b319b80fb9" + +[[sources]] +kind = "provider_model" +path = "providers/alibaba-cn/models/qwen3.5-flash.toml" +content_sha256 = "48d81041f3babeb002b73184e151df0bb4304b1679137c12e396951bbe9c16fe" + +[[sources]] +kind = "provider_model" +path = "providers/alibaba-cn/models/qwen3.5-plus.toml" +content_sha256 = "5bd06ed609ab5ceeeecf8012a4ea587d5365fcd49c17f10bfb729f1a436fee0e" + +[[sources]] +kind = "provider_model" +path = "providers/alibaba-cn/models/qwen3.8-flash.toml" +content_sha256 = "f496c5f293e2196f69bcd2f705cbb12548f14a1923d6b35d10400cbc7a1c817b" + +[[sources]] +kind = "provider_model" +path = "providers/alibaba-cn/models/qwen3.8-max.toml" +content_sha256 = "1b1b47992952fb615bdce07fdeea93bdf445b36375acae6e5e812e6aecb9bd08" + +[[sources]] +kind = "provider_model" +path = "providers/alibaba-cn/models/glm-5.1.toml" +content_sha256 = "f49b1f19c24db0d339b7bafb8c909c15bdaf5dc3765f9befef66b1166e10c520" + +[[sources]] +kind = "provider_model" +path = "providers/alibaba-cn/models/glm-5.2.toml" +content_sha256 = "dbfbc406418c60aa33f33eed147f8d47a98f544b6f5cb50bf96e20fb5c38a2c2" + +[[sources]] +kind = "provider_model" +path = "providers/alibaba-cn/models/glm-5.3.toml" +content_sha256 = "6ce1f84a6cd1af13f823e846b750e4f39d90aa4f008178091a118f88765dfe2f" + +[[sources]] +kind = "provider_model" +path = "providers/alibaba-cn/models/deepseek-v4-flash.toml" +content_sha256 = "b7f6b5d17332d596883c8d5ac7de1c9e885dc4df8e9fc2ea996420e202a7febb" + +[[sources]] +kind = "provider_model" +path = "providers/alibaba-cn/models/deepseek-v4-pro.toml" +content_sha256 = "db39defdd8ed98cf27ccb03f9884431c1e52f1b5d6a88591888d5801bb1e0ac3" + +[[sources]] +kind = "provider_model" +path = "providers/alibaba-cn/models/deepseek-v4.1-flash.toml" +content_sha256 = "fe4c026f77d2a2b837d390dcef3da521b5dc3298eafb1e06199360cc0c6cd5d0" + +[[sources]] +kind = "provider_model" +path = "providers/alibaba-cn/models/MiniMax/MiniMax-M2.7.toml" +content_sha256 = "d14f335b07a27d36e697d350d2aac28d6f9215e6ad4c2912ff9fe8bd5ac7c2f4" + +[[sources]] +kind = "provider_model" +path = "providers/volcengine/models/deepseek-v4-flash-ga-260731.toml" +content_sha256 = "8012bc8a96ff1a96a56b64721e5e144d4ff997b70985c34483b95c7469de13c1" + +[[sources]] +kind = "provider_model" +path = "providers/volcengine/models/deepseek-v4-pro-ga-260813.toml" +content_sha256 = "444e6d130d11e3132d34e3afe4d878f96120beef51db5946f206d96bc8dfdec8" + +[[sources]] +kind = "provider_model" +path = "providers/volcengine/models/glm-5-2-260617.toml" +content_sha256 = "092fcf694c283b90a71cde982d4231d63e4a53544665d4a481e306b4cb1bed1a" + +[[sources]] +kind = "provider_model" +path = "providers/volcengine/models/glm-5-3-flash-260828.toml" +content_sha256 = "34b35e1742e663e54d1231baa5282fc1497b255d60764df21e018c8a78da04a2" + +[[sources]] +kind = "provider_model" +path = "providers/volcengine-coding-plan/models/deepseek-v4-flash.toml" +content_sha256 = "be24a803ea861218c4ad9fc60025a424cb275b95e7c02507699776ce37869a99" + +[[sources]] +kind = "provider_model" +path = "providers/volcengine-coding-plan/models/deepseek-v4-pro.toml" +content_sha256 = "b359870df413e10509083d9b56a62453c530e0f600ca5628ae3279043df2ee57" + +[[sources]] +kind = "provider_model" +path = "providers/volcengine-coding-plan/models/glm-5.3.toml" +content_sha256 = "6fb6ebfb16a106cfb22e5f887326d661b96c1b67df4f826fdf6d02cceded4782" + +[[sources]] +kind = "provider_model" +path = "providers/volcengine-coding-plan/models/glm-5.3-flash.toml" +content_sha256 = "8ca9644166cb0cdc479049a0f7467a6cebded93cd0d3bef00a66e462b77111f3" + +[[sources]] +kind = "provider_model" +path = "providers/volcengine-coding-plan/models/minimax-m3.toml" +content_sha256 = "c2998f64873231e71f62be2da7983afd4c1af76e7a129f232007e65a58c24e24" diff --git a/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3-coder-next.toml b/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3-coder-next.toml new file mode 100644 index 0000000000..cce2c7bb62 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3-coder-next.toml @@ -0,0 +1,27 @@ +# https://qwen.ai/blog?id=qwen3-coder-next +# https://huggingface.co/Qwen/Qwen3-Coder-Next +# https://www.qwencloud.com/models/qwen3-coder-next +name = "Qwen3 Coder Next" +description = "Open-weight Qwen coding model for agents, repository edits, and multi-turn tool use" +family = "qwen" +release_date = "2026-02-03" +last_updated = "2026-02-03" +attachment = false +reasoning = false +temperature = true +tool_call = true +structured_output = true +knowledge = "2025-09" +open_weights = true + +[limit] +context = 262_144 +output = 65_536 + +[modalities] +input = ["text"] +output = ["text"] + +[[weights]] +label = "Hugging Face" +url = "https://huggingface.co/Qwen/Qwen3-Coder-Next" diff --git a/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.5-27b.toml b/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.5-27b.toml new file mode 100644 index 0000000000..93ad247dd8 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.5-27b.toml @@ -0,0 +1,29 @@ +name = "Qwen3.5 27B" +description = "Qwen vision-language model for visual reasoning, documents, and agent tasks" +family = "qwen" +release_date = "2026-02-23" +last_updated = "2026-02-23" +attachment = true +reasoning = true +temperature = true +tool_call = true +structured_output = true +open_weights = true + +[limit] +context = 262_144 +output = 65_536 + +[modalities] +input = ["text", "image", "video", "audio"] +output = ["text"] + +[[weights]] +label = "Hugging Face" +url = "https://huggingface.co/Qwen/Qwen3.5-27B" + +[[benchmarks]] +name = "SWE-Bench Verified" +score = 72.4 +metric = "resolved" +source = "https://huggingface.co/Qwen/Qwen3.5-27B" diff --git a/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.5-35b-a3b.toml b/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.5-35b-a3b.toml new file mode 100644 index 0000000000..36700f959e --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.5-35b-a3b.toml @@ -0,0 +1,23 @@ +name = "Qwen3.5 35B-A3B" +description = "Qwen vision-language model for visual reasoning, documents, and agent tasks" +family = "qwen" +release_date = "2026-02-23" +last_updated = "2026-02-23" +attachment = true +reasoning = true +temperature = true +tool_call = true +structured_output = true +open_weights = true + +[limit] +context = 262_144 +output = 65_536 + +[modalities] +input = ["text", "image", "video", "audio"] +output = ["text"] + +[[weights]] +label = "Hugging Face" +url = "https://huggingface.co/Qwen/Qwen3.5-35B-A3B" diff --git a/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.5-397b-a17b.toml b/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.5-397b-a17b.toml new file mode 100644 index 0000000000..103227c16b --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.5-397b-a17b.toml @@ -0,0 +1,29 @@ +name = "Qwen3.5 397B-A17B" +description = "Large open Qwen multimodal MoE for visual agents and long technical tasks" +family = "qwen" +release_date = "2026-02-15" +last_updated = "2026-02-15" +attachment = true +reasoning = true +temperature = true +tool_call = true +structured_output = true +open_weights = true + +[limit] +context = 262_144 +output = 65_536 + +[modalities] +input = ["text", "image", "video", "audio"] +output = ["text"] + +[[weights]] +label = "Hugging Face" +url = "https://huggingface.co/Qwen/Qwen3.5-397B-A17B" + +[[benchmarks]] +name = "SWE-Bench Verified" +score = 76.4 +metric = "resolved" +source = "https://huggingface.co/Qwen/Qwen3.5-397B-A17B" diff --git a/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.5-flash.toml b/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.5-flash.toml new file mode 100644 index 0000000000..800ff85f43 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.5-flash.toml @@ -0,0 +1,22 @@ +# https://help.aliyun.com/en/model-studio/qwen3-5-flash +# https://www.alibabacloud.com/help/en/model-studio/deep-thinking +name = "Qwen3.5 Flash" +description = "Qwen vision-language model for visual reasoning, documents, and agent tasks" +family = "qwen" +release_date = "2026-02-23" +last_updated = "2026-02-23" +attachment = true +reasoning = true +temperature = true +tool_call = true +structured_output = true +open_weights = false + + +[limit] +context = 1_000_000 +output = 65_536 + +[modalities] +input = ["text", "image", "video"] +output = ["text"] diff --git a/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.5-plus.toml b/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.5-plus.toml new file mode 100644 index 0000000000..7f04f4c2fe --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.5-plus.toml @@ -0,0 +1,19 @@ +name = "Qwen3.5 Plus" +description = "Qwen vision-language model for visual reasoning, documents, and agent tasks" +family = "qwen" +release_date = "2026-02-16" +last_updated = "2026-02-16" +attachment = false +reasoning = true +temperature = true +tool_call = true +knowledge = "2025-04" +open_weights = false + +[limit] +context = 1_000_000 +output = 65_536 + +[modalities] +input = ["text", "image", "video"] +output = ["text"] diff --git a/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.8-2.4t-a95b.toml b/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.8-2.4t-a95b.toml new file mode 100644 index 0000000000..b30a03ea6b --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.8-2.4t-a95b.toml @@ -0,0 +1,33 @@ +# Sources (accessed 2026-08-16): +# https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B +# https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B/raw/main/README.md +# https://qwen.ai/blog?id=qwen3.8 +# https://openrouter.ai/qwen/qwen3.8-2.4t-a95b +# Open-weight twin of Qwen3.8 Max: text-only, thinking always on, +# reasoning_effort low|medium|xhigh (default xhigh). Native context 262K, +# extensible to ~1.01M. Distinct from closed multimodal qwen3.8-max. + +name = "Qwen3.8 2.4T A95B" +description = "Open-weight sparse MoE (2.4T total, 95B active), the open-weight twin of Qwen3.8 Max for coding, research, complex reasoning, and agentic workflows" +family = "qwen" +release_date = "2026-08-12" +last_updated = "2026-08-12" +attachment = false +reasoning = true +temperature = true +tool_call = true +structured_output = true +open_weights = true +license = "qwen3.8-max" + +[limit] +context = 262_144 +output = 131_072 + +[modalities] +input = ["text"] +output = ["text"] + +[[weights]] +label = "Hugging Face" +url = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" diff --git a/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.8-27b.toml b/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.8-27b.toml new file mode 100644 index 0000000000..4517f55223 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.8-27b.toml @@ -0,0 +1,236 @@ +# Benchmark caveats and evaluation harnesses: https://huggingface.co/Qwen/Qwen3.8-27B#evaluation +# Sources (accessed 2026-08-15): +# https://huggingface.co/Qwen/Qwen3.8-27B +# https://huggingface.co/api/models/Qwen/Qwen3.8-27B +# https://qwen.ai/blog?id=qwen3.8 +# Hub lastModified 2026-08-14T15:00:01Z is the open-weight drop. +# Do not use Hub createdAt 2026-08-05 (staged countdown page). + +name = "Qwen3.8 27B" +description = "Dense 27B vision-language model for coding, agent tasks, and image and video understanding" +family = "qwen" +release_date = "2026-08-14" +last_updated = "2026-08-14" +attachment = true +reasoning = true +temperature = true +tool_call = true +structured_output = true +open_weights = true + +[limit] +context = 262_144 +output = 32_768 + +[modalities] +input = ["text", "image", "video"] +output = ["text"] + +[[weights]] +label = "Hugging Face" +url = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "SWE-bench Pro" +score = 61.7 +metric = "resolved" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "Terminal-Bench" +score = 73 +metric = "score" +version = "2.1" +harness = "Terminus" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "NL2Repo" +score = 42.3 +metric = "score" +harness = "Claude Code" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "DeepSWE" +score = 42.2 +metric = "score" +version = "1.1" +harness = "Claude Code" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "QwenSWEBench" +score = 79 +metric = "avg@3" +harness = "Claude Code" +dataset = "internal" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "CoWorkBench" +score = 70.7 +metric = "score" +dataset = "internal" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "JobBench" +score = 33.4 +metric = "score" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "Agents' Last Exam" +score = 20.4 +metric = "pass@1" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "Agents' Last Exam" +score = 42.9 +metric = "score" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "IFBench" +score = 79.5 +metric = "score" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "GPQA Diamond" +score = 89.2 +metric = "score" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "Humanity's Last Exam" +score = 30.8 +metric = "score" +variant = "without tools; GPT-4o judge" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "LiveCodeBench" +score = 90.3 +metric = "score" +version = "6" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "OSWorld-Verified" +score = 84.3 +metric = "score" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "WebArena-Verified" +score = 64.8 +metric = "score" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" +harness = "OSWorld scaffold; official WebArena-Verified grader" + +[[benchmarks]] +name = "AndroidWorld" +score = 81.9 +metric = "score" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "SWE-MM" +score = 38.6 +metric = "score" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "RealWorldQA" +score = 85.9 +metric = "score" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "ERQA" +score = 65.5 +metric = "score" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "RecreationBench" +score = 47.1 +metric = "score" +dataset = "internal" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "ClawEval-MM" +score = 57.4 +metric = "pass@3" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "ClawEval-MM" +score = 56.9 +metric = "average score" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "Vision2Web" +score = 62.9 +metric = "score" +harness = "Claude Code" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" +variant = "gpt-5.4-2026-03-05 judge" + +[[benchmarks]] +name = "MathVision" +score = 90 +metric = "score" +variant = "without code interpreter" +dataset = "corrected annotations" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "MathVision" +score = 94.6 +metric = "score" +variant = "with code interpreter" +dataset = "corrected annotations" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "BabyVision" +score = 65.7 +metric = "score" +variant = "without code interpreter" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "BabyVision" +score = 85.6 +metric = "score" +variant = "with code interpreter" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" + +[[benchmarks]] +name = "CharXiv Reasoning" +score = 83.7 +metric = "score" +variant = "without code interpreter" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" +dataset = "corrected annotations" + +[[benchmarks]] +name = "CharXiv Reasoning" +score = 90.2 +metric = "score" +variant = "with code interpreter" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" +dataset = "corrected annotations" + +[[benchmarks]] +name = "OmniDocBench" +score = 91.1 +metric = "score" +version = "1.5" +source = "https://huggingface.co/Qwen/Qwen3.8-27B" diff --git a/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.8-flash.toml b/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.8-flash.toml new file mode 100644 index 0000000000..2ee8a5ff53 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.8-flash.toml @@ -0,0 +1,19 @@ +# Source: https://www.qwencloud.com/models/qwen3.8-flash +name = "Qwen3.8 Flash" +description = "Qwen vision-language model for visual reasoning, documents, and agent tasks" +family = "qwen" +release_date = "2026-08-26" +last_updated = "2026-08-26" +attachment = true +reasoning = true +tool_call = true +structured_output = true +open_weights = false + +[limit] +context = 1_000_000 +output = 131_072 + +[modalities] +input = ["text", "image", "video"] +output = ["text"] diff --git a/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.8-max.toml b/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.8-max.toml new file mode 100644 index 0000000000..76a956fd3f --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/alibaba/qwen3.8-max.toml @@ -0,0 +1,266 @@ +# These are the Qwen3.8-Max column of the official model card, not a claim about a separately evaluated local checkpoint. +# Sources (accessed 2026-08-06): +# https://www.qwencloud.com/models/qwen3.8-max +# https://www.qianwenai.com/models/qwen3.8-max +# https://help.aliyun.com/zh/model-studio/qwen3-8-max +# https://www.alibabacloud.com/help/en/model-studio/qwen3-8-max +# https://help.aliyun.com/zh/model-studio/pdf-understanding +# https://platform.qianwenai.com/docs/developer-guides/tool-calling/pdf-understanding +# https://docs.qwencloud.com/token-plan/personal/token-plan-personal-overview +# https://help.aliyun.com/zh/model-studio/token-plan-personal-overview +# https://help.aliyun.com/en/model-studio/token-plan-personal-overview +# https://docs.qwencloud.com/developer-guides/getting-started/text-generation-models +# https://docs.qwencloud.com/developer-guides/text-generation/thinking +# https://docs.qwencloud.com/developer-guides/clients-and-developer-tools/opencode +# https://platform.qianwenai.com/docs/developer-guides/clients-and-developer-tools/opencode +# https://qwen.ai/blog?id=qwen3.8 +# PDF input: Model Studio / 千问AI docs list only qwen3.8-max under PDF理解 +# (type:file / file_url|file_data). Model pages list Image/Text/Video badges +# and separately list PDF理解 as a Completions built-in tool. Beijing-region +# availability note on help.aliyun.com; lab capability still includes pdf. + +name = "Qwen3.8 Max" +description = "2.4-trillion-parameter MoE flagship for coding, professional work, multimodal understanding, and long-horizon agentic workflows" +family = "qwen" +release_date = "2026-08-03" +last_updated = "2026-08-03" +attachment = true +reasoning = true +temperature = true +tool_call = true +open_weights = false + +[limit] +context = 1_000_000 +output = 131_072 + +[modalities] +input = ["text", "image", "video", "pdf"] +output = ["text"] + +[[benchmarks]] +name = "Terminal-Bench" +score = 86.6 +metric = "avg@10" +version = "2.1" +harness = "Claude Code" +variant = "5h timeout" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "SWE-Bench Pro" +score = 67.7 +metric = "resolved" +harness = "Claude Code" +dataset = "Qwen refined and corrected task set" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "DeepSWE" +score = 56.6 +metric = "score" +version = "1.1" +harness = "Claude Code" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "NL2Repo" +score = 55.9 +metric = "score" +harness = "Claude Code" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "FrontierSWE" +score = 73.5 +metric = "dominance score" +date = "2026-08-03" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "MLS-Bench-Lite" +score = 41 +metric = "score" +harness = "Claude Code" +variant = "5h timeout" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "PaperBench" +score = 93 +metric = "score" +harness = "BasicAgent" +variant = "Code-Dev; 3 runs; 12h timeout; Opus 4.6 judge" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "AndroidBench" +score = 75.1 +metric = "avg@3" +dataset = "95 public tasks" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "QwenSWEBench" +score = 80.7 +metric = "avg@3" +harness = "Claude Code" +dataset = "internal" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "QwenQoderBench" +score = 58.4 +metric = "avg@5" +harness = "Claude Code" +dataset = "internal" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "QwenReactBench" +score = 1724 +metric = "Elo" +dataset = "internal" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "QwenSVGBench" +score = 1713 +metric = "Elo" +dataset = "internal" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "CoWorkBench" +score = 74.8 +metric = "score" +dataset = "internal" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "WorkSpaceBench" +score = 67.7 +metric = "score" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "JobBench" +score = 53.4 +metric = "score" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "SkillsBench" +score = 70.2 +metric = "avg@3" +version = "1.1" +dataset = "87 tasks" +harness = "OpenCode" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "Agents' Last Exam" +score = 27 +metric = "pass@1" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "Agents' Last Exam" +score = 52.4 +metric = "score" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "AutomationBench" +score = 27.3 +metric = "pass@1" +dataset = "600 public tasks" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "Toolathlon-Verified" +score = 72.5 +metric = "pass@1" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "WideSearch" +score = 81.9 +metric = "average item F1" +harness = "Qwen-Agent" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "Humanity's Last Exam" +score = 56.2 +metric = "score" +variant = "with tools" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "Humanity's Last Exam" +score = 43.6 +metric = "score" +variant = "without tools" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "GPQA Diamond" +score = 92.6 +metric = "score" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "IFBench" +score = 82.8 +metric = "score" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "$OneMillion-Bench" +score = 52.5 +metric = "expert score" +variant = "gemini-3.1-pro-preview judge" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "HealthBench" +score = 60.2 +metric = "score" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "PLawBench" +score = 73.2 +metric = "score" +variant = "gemini-3.1-pro-preview judge" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "PRBench" +score = 57.6 +metric = "score" +variant = "legal" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "PRBench" +score = 58.3 +metric = "score" +variant = "finance" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "MRCR" +score = 92.9 +metric = "score" +version = "2" +dataset = "256K; 8-needle" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" + +[[benchmarks]] +name = "LongBench" +score = 66.3 +metric = "score" +version = "2" +source = "https://huggingface.co/Qwen/Qwen3.8-2.4T-A95B" diff --git a/sdk/nexent/core/model_service/profiles/models/deepseek/deepseek-v4-flash-0731.toml b/sdk/nexent/core/model_service/profiles/models/deepseek/deepseek-v4-flash-0731.toml new file mode 100644 index 0000000000..61479ce86a --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/deepseek/deepseek-v4-flash-0731.toml @@ -0,0 +1,105 @@ +name = "DeepSeek V4 Flash 0731" +description = "Official DeepSeek V4 Flash release with enhanced agentic capabilities and integrated DSpark speculative decoding" +family = "deepseek-flash" +release_date = "2026-07-31" +last_updated = "2026-07-31" +attachment = false +reasoning = true +temperature = true +tool_call = true +structured_output = true +knowledge = "2025-05" +open_weights = true +license = "MIT" + +[limit] +context = 1_000_000 +output = 384_000 + +[modalities] +input = ["text"] +output = ["text"] + +[[weights]] +label = "Hugging Face" +url = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash-0731" + +[[benchmarks]] +name = "Terminal-Bench" +score = 82.7 +metric = "pass@1" +variant = "max" +version = "2.1" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash-0731" + +[[benchmarks]] +name = "NL2Repo" +score = 54.2 +metric = "resolve rate" +variant = "max effort" +harness = "DeepSeek Harness minimal mode" +source = "https://api-docs.deepseek.com/updates/" +date = "2026-07-31" + +[[benchmarks]] +name = "CyberGym" +score = 76.7 +metric = "score" +variant = "max effort" +harness = "DeepSeek Harness minimal mode" +source = "https://api-docs.deepseek.com/updates/" +date = "2026-07-31" + +[[benchmarks]] +name = "DeepSWE" +score = 54.4 +metric = "resolve rate" +variant = "max effort" +harness = "DeepSeek Harness minimal mode" +source = "https://api-docs.deepseek.com/updates/" +date = "2026-07-31" + +[[benchmarks]] +name = "Toolathlon-Verified" +score = 70.3 +metric = "score" +variant = "max effort" +harness = "DeepSeek Harness minimal mode" +source = "https://api-docs.deepseek.com/updates/" +date = "2026-07-31" + +[[benchmarks]] +name = "Agents' Last Exam" +score = 25.2 +metric = "score" +variant = "max effort" +harness = "DeepSeek Harness minimal mode" +source = "https://api-docs.deepseek.com/updates/" +date = "2026-07-31" + +[[benchmarks]] +name = "AutomationBench" +score = 25.1 +metric = "success rate" +variant = "max effort" +dataset = "public" +source = "https://api-docs.deepseek.com/updates/" +date = "2026-07-31" + +[[benchmarks]] +name = "DSBench-FullStack" +score = 68.7 +metric = "score" +variant = "max effort" +dataset = "internal" +source = "https://api-docs.deepseek.com/updates/" +date = "2026-07-31" + +[[benchmarks]] +name = "DSBench-Hard" +score = 59.6 +metric = "score" +variant = "max effort" +dataset = "internal" +source = "https://api-docs.deepseek.com/updates/" +date = "2026-07-31" diff --git a/sdk/nexent/core/model_service/profiles/models/deepseek/deepseek-v4-flash.toml b/sdk/nexent/core/model_service/profiles/models/deepseek/deepseek-v4-flash.toml new file mode 100644 index 0000000000..5f521d77d2 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/deepseek/deepseek-v4-flash.toml @@ -0,0 +1,183 @@ +# Added benchmarks are from the original V4 preview instruct-model comparison, not the later 0731/0813 releases. +name = "DeepSeek V4 Flash" +description = "Fast DeepSeek V4 lane for economical reasoning, coding, and long-context work" +family = "deepseek-flash" +release_date = "2026-04-24" +last_updated = "2026-04-24" +attachment = false +reasoning = true +temperature = true +tool_call = true +structured_output = true +knowledge = "2025-05" +open_weights = true + +[limit] +context = 1_000_000 +output = 384_000 + +[modalities] +input = ["text"] +output = ["text"] + +[[weights]] +label = "Hugging Face" +url = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "SWE-Bench Verified" +score = 79 +metric = "resolved" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "MMLU-Pro" +score = 86.2 +metric = "EM" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "SimpleQA-Verified" +score = 34.1 +metric = "pass@1" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "Chinese SimpleQA" +score = 78.9 +metric = "pass@1" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "GPQA Diamond" +score = 88.1 +metric = "pass@1" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "Humanity's Last Exam" +score = 34.8 +metric = "pass@1" +variant = "preview checkpoint; max effort; without tools" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "LiveCodeBench" +score = 91.6 +metric = "pass@1" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "Codeforces" +score = 3052 +metric = "rating" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "HMMT" +score = 94.8 +metric = "pass@1" +variant = "preview checkpoint; max effort" +dataset = "February 2026" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "IMOAnswerBench" +score = 88.4 +metric = "pass@1" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "MathArena Apex" +score = 33 +metric = "pass@1" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "MathArena Apex Shortlist" +score = 85.7 +metric = "pass@1" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "MRCR" +score = 78.7 +metric = "MMR" +variant = "preview checkpoint; max effort" +dataset = "1M context" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "CorpusQA" +score = 60.5 +metric = "accuracy" +variant = "preview checkpoint; max effort" +dataset = "1M context" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "Terminal-Bench" +score = 56.9 +metric = "accuracy" +variant = "preview checkpoint; max effort" +version = "2.0" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "SWE-Bench Pro" +score = 52.6 +metric = "resolved" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "SWE-Bench Multilingual" +score = 73.3 +metric = "resolved" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "BrowseComp" +score = 73.2 +metric = "pass@1" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "Humanity's Last Exam" +score = 45.1 +metric = "pass@1" +variant = "preview checkpoint; max effort; with tools" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "MCP Atlas" +score = 69 +metric = "pass@1" +variant = "preview checkpoint; max effort" +dataset = "public" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "GDPval-AA" +score = 1395 +metric = "Elo" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" + +[[benchmarks]] +name = "Toolathlon" +score = 47.8 +metric = "pass@1" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash" diff --git a/sdk/nexent/core/model_service/profiles/models/deepseek/deepseek-v4-pro-0813.toml b/sdk/nexent/core/model_service/profiles/models/deepseek/deepseek-v4-pro-0813.toml new file mode 100644 index 0000000000..dade234dbb --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/deepseek/deepseek-v4-pro-0813.toml @@ -0,0 +1,106 @@ +# Public code-agent benchmarks use DeepSeek Harness minimal mode, max effort, temperature=1.0, top_p=0.95. +# https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro-0813 +name = "DeepSeek V4 Pro 0813" +description = "DeepSeek V4 Pro snapshot with million-token context and support for thinking and non-thinking modes" +family = "deepseek-thinking" +release_date = "2026-08-12" +last_updated = "2026-08-22" +attachment = false +reasoning = true +temperature = true +tool_call = true +structured_output = true +open_weights = true +license = "MIT" + +[limit] +context = 1_000_000 +output = 384_000 + +[modalities] +input = ["text"] +output = ["text"] + +[[weights]] +label = "Hugging Face" +url = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro-0813" + +[[benchmarks]] +name = "Humanity's Last Exam" +score = 42.7 +metric = "score" +variant = "without tools" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro-0813" + +[[benchmarks]] +name = "Humanity's Last Exam" +score = 60 +metric = "score" +variant = "with tools" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro-0813" + +[[benchmarks]] +name = "Terminal-Bench" +score = 87.9 +metric = "score" +harness = "DeepSeek Harness minimal mode" +variant = "max effort" +version = "2.1" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro-0813" + +[[benchmarks]] +name = "NL2Repo" +score = 61.5 +metric = "score" +harness = "DeepSeek Harness minimal mode" +variant = "max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro-0813" + +[[benchmarks]] +name = "CyberGym" +score = 83.3 +metric = "score" +harness = "DeepSeek Harness minimal mode" +variant = "max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro-0813" + +[[benchmarks]] +name = "DeepSWE" +score = 62.7 +metric = "score" +harness = "DeepSeek Harness minimal mode" +variant = "max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro-0813" + +[[benchmarks]] +name = "Toolathlon-Verified" +score = 74.1 +metric = "score" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro-0813" + +[[benchmarks]] +name = "Agents' Last Exam" +score = 25.7 +metric = "score" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro-0813" + +[[benchmarks]] +name = "AutomationBench" +score = 31.8 +metric = "score" +dataset = "public" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro-0813" + +[[benchmarks]] +name = "DSBench-FullStack" +score = 71.1 +metric = "score" +dataset = "internal" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro-0813" + +[[benchmarks]] +name = "DSBench-Hard" +score = 67.2 +metric = "score" +dataset = "internal" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro-0813" diff --git a/sdk/nexent/core/model_service/profiles/models/deepseek/deepseek-v4-pro.toml b/sdk/nexent/core/model_service/profiles/models/deepseek/deepseek-v4-pro.toml new file mode 100644 index 0000000000..c0bb4099ca --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/deepseek/deepseek-v4-pro.toml @@ -0,0 +1,217 @@ +# Added benchmarks are from the original V4 preview instruct-model comparison, not the later 0731/0813 releases. +name = "DeepSeek V4 Pro" +description = "Open MoE flagship with million-token context for coding and long agent runs" +family = "deepseek-thinking" +release_date = "2026-04-24" +last_updated = "2026-04-24" +attachment = false +reasoning = true +temperature = true +tool_call = true +structured_output = true +knowledge = "2025-05" +open_weights = true + +[limit] +context = 1_000_000 +output = 384_000 + +[modalities] +input = ["text"] +output = ["text"] + +[[weights]] +label = "Hugging Face" +url = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "SWE-Bench Verified" +score = 80.6 +metric = "resolved" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "Artificial Analysis Coding Agent Index" +score = 50.1 +metric = "average pass@1" +harness = "Claude Code" +variant = "high" +source = "https://artificialanalysis.ai/agents/coding-agents" + +[[benchmarks]] +name = "SWE-Atlas Codebase QnA" +score = 67.8 +metric = "pass@1" +harness = "Claude Code" +variant = "high" +source = "https://artificialanalysis.ai/agents/coding-agents" + +[[benchmarks]] +name = "SWE-Bench Pro" +score = 18 +metric = "pass@1" +harness = "Claude Code" +variant = "high" +dataset = "hard-aa" +source = "https://artificialanalysis.ai/agents/coding-agents" + +[[benchmarks]] +name = "Terminal-Bench" +score = 64.7 +metric = "pass@1" +harness = "Claude Code" +variant = "high" +version = "2.1" +source = "https://artificialanalysis.ai/agents/coding-agents" + +[[benchmarks]] +name = "MMLU-Pro" +score = 87.5 +metric = "EM" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "SimpleQA-Verified" +score = 57.9 +metric = "pass@1" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "Chinese SimpleQA" +score = 84.4 +metric = "pass@1" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "GPQA Diamond" +score = 90.1 +metric = "pass@1" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "Humanity's Last Exam" +score = 37.7 +metric = "pass@1" +variant = "preview checkpoint; max effort; without tools" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "LiveCodeBench" +score = 93.5 +metric = "pass@1" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "Codeforces" +score = 3206 +metric = "rating" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "HMMT" +score = 95.2 +metric = "pass@1" +variant = "preview checkpoint; max effort" +dataset = "February 2026" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "IMOAnswerBench" +score = 89.8 +metric = "pass@1" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "MathArena Apex" +score = 38.3 +metric = "pass@1" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "MathArena Apex Shortlist" +score = 90.2 +metric = "pass@1" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "MRCR" +score = 83.5 +metric = "MMR" +variant = "preview checkpoint; max effort" +dataset = "1M context" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "CorpusQA" +score = 62 +metric = "accuracy" +variant = "preview checkpoint; max effort" +dataset = "1M context" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "Terminal-Bench" +score = 67.9 +metric = "accuracy" +variant = "preview checkpoint; max effort" +version = "2.0" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "SWE-Bench Pro" +score = 55.4 +metric = "resolved" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "SWE-Bench Multilingual" +score = 76.2 +metric = "resolved" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "BrowseComp" +score = 83.4 +metric = "pass@1" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "Humanity's Last Exam" +score = 48.2 +metric = "pass@1" +variant = "preview checkpoint; max effort; with tools" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "MCP Atlas" +score = 73.6 +metric = "pass@1" +variant = "preview checkpoint; max effort" +dataset = "public" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "GDPval-AA" +score = 1554 +metric = "Elo" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" + +[[benchmarks]] +name = "Toolathlon" +score = 51.8 +metric = "pass@1" +variant = "preview checkpoint; max effort" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro" diff --git a/sdk/nexent/core/model_service/profiles/models/deepseek/deepseek-v4.1-flash.toml b/sdk/nexent/core/model_service/profiles/models/deepseek/deepseek-v4.1-flash.toml new file mode 100644 index 0000000000..16a1174cf7 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/deepseek/deepseek-v4.1-flash.toml @@ -0,0 +1,311 @@ +# Benchmarks use instruct weights, temperature=1.0, top_p=0.95; not the base-model table. +# Source: https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash#instruct-model +# Open weights (MIT): https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash +name = "DeepSeek V4.1 Flash" +description = "DeepSeek V4.1 Flash model for reasoning and agentic coding" +family = "deepseek-flash" +release_date = "2026-09-10" +last_updated = "2026-09-10" +attachment = true +reasoning = true +temperature = true +tool_call = true +structured_output = true +knowledge = "2025-05" +open_weights = true +license = "MIT" + +[limit] +context = 1_000_000 +output = 384_000 + +[modalities] +input = ["text", "image"] +output = ["text"] + +[[weights]] +label = "Hugging Face" +url = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "GPQA Diamond" +score = 90.9 +metric = "pass@1" +variant = "reasoning_effort=100" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "MathArena Apex" +score = 65.6 +metric = "pass@1" +variant = "reasoning_effort=100" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "Humanity's Last Exam" +score = 36.8 +metric = "pass@1" +variant = "reasoning_effort=100" +dataset = "full set" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "Humanity's Last Exam" +score = 39.1 +metric = "pass@1" +variant = "reasoning_effort=100" +dataset = "text-only subset" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "Codeforces" +score = 3471 +metric = "rating" +variant = "reasoning_effort=100" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "Terminal-Bench" +score = 90.6 +metric = "pass@1" +variant = "reasoning_effort=100" +version = "2.1" +harness = "DeepSeek Harness minimal mode" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "Terminal-Bench" +score = 30.0 +metric = "pass@1" +variant = "reasoning_effort=100" +version = "3.0" +harness = "DeepSeek Harness minimal mode" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "Terminal-Bench" +score = 31.2 +metric = "pass@1" +variant = "reasoning_effort=100" +version = "4.0" +harness = "DeepSeek Harness minimal mode" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "DeepSWE" +score = 74.2 +metric = "resolved" +variant = "reasoning_effort=100" +version = "1.1" +harness = "mini-swe-agent" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "ProgramBench" +score = 20.3 +metric = "almost@1" +variant = "reasoning_effort=100" +harness = "DeepSeek Harness minimal mode" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "NL2Repo" +score = 64.0 +metric = "score" +variant = "reasoning_effort=100" +harness = "DeepSeek Harness minimal mode" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "CyberGym" +score = 88.1 +metric = "pass@1" +variant = "reasoning_effort=100" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "ExploitGym" +score = 15.3 +metric = "pass@1" +variant = "reasoning_effort=100" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "AutomationBench" +score = 54.8 +metric = "pass@1" +variant = "reasoning_effort=100" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "Agents' Last Exam" +score = 31.8 +metric = "pass@1" +variant = "reasoning_effort=100" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "SEC-Bench Pro" +score = 62.8 +metric = "pass@1" +variant = "reasoning_effort=100" +harness = "Claude Code" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "Humanity's Last Exam" +score = 63.9 +metric = "pass@1" +variant = "reasoning_effort=100; with tools" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "Chartography" +score = 78.9 +metric = "pass@1" +variant = "reasoning_effort=100; with tools" +harness = "Claude Code" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "BabyVision" +score = 89.6 +metric = "pass@1" +variant = "reasoning_effort=100; with tools" +harness = "Claude Code" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "ZeroBench" +score = 49.0 +metric = "pass@5" +variant = "reasoning_effort=100; with tools" +harness = "Claude Code" +dataset = "main" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "DeepSWE" +score = 69.8 +metric = "resolved" +variant = "reasoning_effort=100" +version = "1.1" +harness = "Claude Code" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "Terminal-Bench" +score = 88.0 +metric = "pass@1" +variant = "reasoning_effort=100" +version = "2.1" +harness = "Claude Code" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "DeepSWE" +score = 65.6 +metric = "resolved" +variant = "reasoning_effort=100" +version = "1.1" +harness = "Codex" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "Terminal-Bench" +score = 84.1 +metric = "pass@1" +variant = "reasoning_effort=100" +version = "2.1" +harness = "Codex" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "DeepSWE" +score = 65.5 +metric = "resolved" +variant = "reasoning_effort=100" +version = "1.1" +harness = "OpenCode" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "Terminal-Bench" +score = 85.0 +metric = "pass@1" +variant = "reasoning_effort=100" +version = "2.1" +harness = "OpenCode" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "DeepSWE" +score = 66.2 +metric = "resolved" +variant = "reasoning_effort=100" +version = "1.1" +harness = "Pi" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "Terminal-Bench" +score = 86.1 +metric = "pass@1" +variant = "reasoning_effort=100" +version = "2.1" +harness = "Pi" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "Terminal-Bench" +score = 90.3 +metric = "pass@1" +variant = "reasoning_effort=100" +version = "2.1" +harness = "mini-swe-agent" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "DeepSWE" +score = 72.6 +metric = "resolved" +variant = "reasoning_effort=100" +version = "1.1" +harness = "DeepSeek Harness minimal mode" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "DeepSWE" +score = 70.5 +metric = "resolved" +variant = "reasoning_effort=100" +version = "1.1" +harness = "DeepSeek Harness standard mode" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "Terminal-Bench" +score = 85.8 +metric = "pass@1" +variant = "reasoning_effort=100" +version = "2.1" +harness = "DeepSeek Harness standard mode" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "DeepSWE" +score = 67.6 +metric = "resolved" +variant = "reasoning_effort=100" +version = "1.1" +harness = "DeepSeek Harness PTC mode" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" + +[[benchmarks]] +name = "Terminal-Bench" +score = 85.8 +metric = "pass@1" +variant = "reasoning_effort=100" +version = "2.1" +harness = "DeepSeek Harness PTC mode" +source = "https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash" diff --git a/sdk/nexent/core/model_service/profiles/models/minimax/MiniMax-M2.7.toml b/sdk/nexent/core/model_service/profiles/models/minimax/MiniMax-M2.7.toml new file mode 100644 index 0000000000..e72eaabdce --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/minimax/MiniMax-M2.7.toml @@ -0,0 +1,46 @@ +name = "MiniMax-M2.7" +description = "Open MiniMax flagship for coding agents, office automation, and complex environments" +family = "minimax" +release_date = "2026-03-18" +last_updated = "2026-03-18" +attachment = false +reasoning = true +temperature = true +tool_call = true +open_weights = true + +[limit] +context = 204_800 +output = 131_072 + +[modalities] +input = ["text"] +output = ["text"] + +[[weights]] +label = "Hugging Face" +url = "https://huggingface.co/MiniMaxAI/MiniMax-M2.7" + +[[benchmarks]] +name = "SWE-Bench Verified" +score = 79.9 +metric = "resolved" +harness = "Claude Code" +source = "https://www.minimax.io/blog/minimax-m3" +date = "2026-06-01" + +[[benchmarks]] +name = "SWE-Bench Pro" +score = 56.2 +metric = "resolve rate" +harness = "Claude Code" +source = "https://www.minimax.io/blog/minimax-m3" +date = "2026-06-01" + +[[benchmarks]] +name = "Terminal-Bench" +score = 51.1 +metric = "success rate" +version = "2.1" +source = "https://www.minimax.io/blog/minimax-m3" +date = "2026-06-01" diff --git a/sdk/nexent/core/model_service/profiles/models/minimax/MiniMax-M3.toml b/sdk/nexent/core/model_service/profiles/models/minimax/MiniMax-M3.toml new file mode 100644 index 0000000000..31ad8eeb00 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/minimax/MiniMax-M3.toml @@ -0,0 +1,67 @@ +name = "MiniMax-M3" +description = "MiniMax multimodal model for long-context coding, perception, and agent planning" +family = "minimax" +release_date = "2026-06-01" +last_updated = "2026-06-01" +attachment = true +reasoning = true +temperature = true +tool_call = true +open_weights = true + +[limit] +context = 1_048_576 +output = 512_000 + +[modalities] +input = ["text", "image", "video"] +output = ["text"] + +[[weights]] +label = "Hugging Face" +url = "https://huggingface.co/MiniMaxAI/MiniMax-M3" + +[[benchmarks]] +name = "SWE-Bench Verified" +score = 80.5 +metric = "resolved" +harness = "Claude Code" +source = "https://www.minimax.io/blog/minimax-m3" +date = "2026-06-01" + +[[benchmarks]] +name = "SWE-Bench Pro" +score = 59.0 +metric = "resolve rate" +harness = "Claude Code" +source = "https://www.minimax.io/blog/minimax-m3" +date = "2026-06-01" + +[[benchmarks]] +name = "Terminal-Bench" +score = 66.0 +metric = "success rate" +version = "2.1" +source = "https://www.minimax.io/blog/minimax-m3" +date = "2026-06-01" + +[[benchmarks]] +name = "BrowseComp" +score = 83.52 +metric = "accuracy" +source = "https://www.minimax.io/blog/minimax-m3" +date = "2026-06-01" + +[[benchmarks]] +name = "MCP Atlas" +score = 74.2 +metric = "success rate" +source = "https://www.minimax.io/blog/minimax-m3" +date = "2026-06-01" + +[[benchmarks]] +name = "OSWorld-Verified" +score = 70.06 +metric = "success rate" +source = "https://www.minimax.io/blog/minimax-m3" +date = "2026-06-01" diff --git a/sdk/nexent/core/model_service/profiles/models/zhipuai/glm-5.1.toml b/sdk/nexent/core/model_service/profiles/models/zhipuai/glm-5.1.toml new file mode 100644 index 0000000000..61860d5017 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/zhipuai/glm-5.1.toml @@ -0,0 +1,53 @@ +name = "GLM-5.1" +description = "Strong GLM coding model for agentic engineering, terminals, and repository generation" +family = "glm" +release_date = "2026-04-07" +last_updated = "2026-04-07" +attachment = false +reasoning = true +temperature = true +tool_call = true +structured_output = true +open_weights = true + +[limit] +context = 200_000 +output = 131_072 + +[modalities] +input = ["text"] +output = ["text"] + +[[weights]] +label = "Hugging Face" +url = "https://huggingface.co/zai-org/GLM-5.1" + +[[benchmarks]] +name = "Artificial Analysis Coding Agent Index" +score = 52.7 +metric = "average pass@1" +harness = "Claude Code" +source = "https://artificialanalysis.ai/agents/coding-agents" + +[[benchmarks]] +name = "SWE-Atlas Codebase QnA" +score = 73.2 +metric = "pass@1" +harness = "Claude Code" +source = "https://artificialanalysis.ai/agents/coding-agents" + +[[benchmarks]] +name = "SWE-Bench Pro" +score = 19.8 +metric = "pass@1" +harness = "Claude Code" +dataset = "hard-aa" +source = "https://artificialanalysis.ai/agents/coding-agents" + +[[benchmarks]] +name = "Terminal-Bench" +score = 65.1 +metric = "pass@1" +harness = "Claude Code" +version = "2.1" +source = "https://artificialanalysis.ai/agents/coding-agents" diff --git a/sdk/nexent/core/model_service/profiles/models/zhipuai/glm-5.2.toml b/sdk/nexent/core/model_service/profiles/models/zhipuai/glm-5.2.toml new file mode 100644 index 0000000000..292a8dff6d --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/zhipuai/glm-5.2.toml @@ -0,0 +1,167 @@ +name = "GLM-5.2" +description = "Open flagship GLM for long-horizon coding agents and million-token context work" +family = "glm" +release_date = "2026-06-13" +last_updated = "2026-06-13" +attachment = false +reasoning = true +temperature = true +tool_call = true +structured_output = true +open_weights = true + +[limit] +context = 1_000_000 +output = 131_072 + +[modalities] +input = ["text"] +output = ["text"] + +[[weights]] +label = "Hugging Face" +url = "https://huggingface.co/zai-org/GLM-5.2" + +[[benchmarks]] +name = "SWE-Bench Pro" +score = 62.1 +metric = "resolve rate" +source = "https://z.ai/blog/glm-5.2" +date = "2026-06-16" + +[[benchmarks]] +name = "Terminal-Bench" +score = 82.7 +metric = "success rate" +harness = "Claude Code" +version = "2.1" +source = "https://z.ai/blog/glm-5.2" +date = "2026-06-16" + +[[benchmarks]] +name = "FrontierSWE" +score = 74.4 +metric = "dominance" +source = "https://z.ai/blog/glm-5.2" +date = "2026-06-16" + +[[benchmarks]] +name = "Humanity's Last Exam" +score = 40.5 +metric = "accuracy" +dataset = "text-only subset" +source = "https://z.ai/blog/glm-5.2" +date = "2026-06-16" + +[[benchmarks]] +name = "Humanity's Last Exam" +score = 54.7 +metric = "accuracy" +variant = "with tools" +dataset = "text-only subset" +source = "https://z.ai/blog/glm-5.2" +date = "2026-06-16" + +[[benchmarks]] +name = "CritPt" +score = 20.9 +metric = "accuracy" +source = "https://z.ai/blog/glm-5.2" +date = "2026-06-16" + +[[benchmarks]] +name = "AIME" +score = 99.2 +metric = "accuracy" +version = "2026" +source = "https://z.ai/blog/glm-5.2" +date = "2026-06-16" + +[[benchmarks]] +name = "HMMT" +score = 94.4 +metric = "accuracy" +version = "November 2025" +source = "https://z.ai/blog/glm-5.2" +date = "2026-06-16" + +[[benchmarks]] +name = "HMMT" +score = 92.5 +metric = "accuracy" +version = "February 2026" +source = "https://z.ai/blog/glm-5.2" +date = "2026-06-16" + +[[benchmarks]] +name = "IMOAnswerBench" +score = 91.0 +metric = "accuracy" +source = "https://z.ai/blog/glm-5.2" +date = "2026-06-16" + +[[benchmarks]] +name = "GPQA Diamond" +score = 91.2 +metric = "accuracy" +source = "https://z.ai/blog/glm-5.2" +date = "2026-06-16" + +[[benchmarks]] +name = "NL2Repo" +score = 48.9 +metric = "resolve rate" +source = "https://z.ai/blog/glm-5.2" +date = "2026-06-16" + +[[benchmarks]] +name = "DeepSWE" +score = 46.2 +metric = "resolve rate" +source = "https://z.ai/blog/glm-5.2" +date = "2026-06-16" + +[[benchmarks]] +name = "Program Bench" +score = 63.7 +metric = "score" +source = "https://z.ai/blog/glm-5.2" +date = "2026-06-16" + +[[benchmarks]] +name = "Terminal-Bench" +score = 81.0 +metric = "success rate" +harness = "Terminus 2" +version = "2.1" +source = "https://z.ai/blog/glm-5.2" +date = "2026-06-16" + +[[benchmarks]] +name = "PostTrainBench" +score = 34.3 +metric = "score" +source = "https://z.ai/blog/glm-5.2" +date = "2026-06-16" + +[[benchmarks]] +name = "SWE Marathon" +score = 13.0 +metric = "resolve rate" +source = "https://z.ai/blog/glm-5.2" +date = "2026-06-16" + +[[benchmarks]] +name = "MCP Atlas" +score = 76.8 +metric = "score" +dataset = "public subset" +source = "https://z.ai/blog/glm-5.2" +date = "2026-06-16" + +[[benchmarks]] +name = "Tool-Decathlon" +score = 48.2 +metric = "score" +source = "https://z.ai/blog/glm-5.2" +date = "2026-06-16" diff --git a/sdk/nexent/core/model_service/profiles/models/zhipuai/glm-5.3-flash.toml b/sdk/nexent/core/model_service/profiles/models/zhipuai/glm-5.3-flash.toml new file mode 100644 index 0000000000..6f713eea56 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/zhipuai/glm-5.3-flash.toml @@ -0,0 +1,70 @@ +# Scores: https://raw.githubusercontent.com/zai-org/GLM-5/refs/heads/main/resources/bench_53.png +# Open weights: https://huggingface.co/zai-org/GLM-5.3-Flash (MIT, safetensors) +name = "GLM-5.3-Flash" +description = "Native multimodal GLM model for efficient coding and long-horizon agent tasks" +family = "glm-flash" +release_date = "2026-08-26" +last_updated = "2026-08-26" +attachment = true +reasoning = true +temperature = true +tool_call = true +structured_output = true +open_weights = true + +[limit] +context = 1_000_000 +output = 131_072 + +[modalities] +input = ["text", "image", "video", "pdf"] +output = ["text"] + +[[benchmarks]] +name = "Terminal-Bench" +score = 84.3 +metric = "pass@1" +variant = "max effort" +version = "2.1" +harness = "Claude Code 2.1.207" +source = "https://huggingface.co/zai-org/GLM-5.3-Flash" + +[[benchmarks]] +name = "DeepSWE" +score = 63.4 +metric = "resolved" +variant = "max effort" +version = "1.1" +harness = "mini-swe-agent" +source = "https://huggingface.co/zai-org/GLM-5.3-Flash" + +[[benchmarks]] +name = "Agents' Last Exam" +score = 26.3 +metric = "score" +variant = "max effort" +source = "https://huggingface.co/zai-org/GLM-5.3-Flash" + +[[benchmarks]] +name = "AutomationBench" +score = 48.8 +metric = "pass@1" +variant = "max effort" +version = "1.0.6" +source = "https://huggingface.co/zai-org/GLM-5.3-Flash" + +[[benchmarks]] +name = "Humanity's Last Exam" +score = 55.3 +metric = "accuracy" +variant = "max effort; with tools" +dataset = "full set" +source = "https://huggingface.co/zai-org/GLM-5.3-Flash" + +[[benchmarks]] +name = "GDPval-AA" +score = 1773 +metric = "Elo" +variant = "max effort" +version = "2" +source = "https://huggingface.co/zai-org/GLM-5.3-Flash" diff --git a/sdk/nexent/core/model_service/profiles/models/zhipuai/glm-5.3.toml b/sdk/nexent/core/model_service/profiles/models/zhipuai/glm-5.3.toml new file mode 100644 index 0000000000..e8c11c17ae --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/models/zhipuai/glm-5.3.toml @@ -0,0 +1,158 @@ +# Benchmark settings and caveats: https://huggingface.co/zai-org/GLM-5.3#footnotes +name = "GLM-5.3" +description = "Flagship GLM model for long-horizon coding, agents, and complex project delivery" +family = "glm" +release_date = "2026-08-14" +last_updated = "2026-08-14" +attachment = false +reasoning = true +temperature = true +tool_call = true +structured_output = true +open_weights = true + +[limit] +context = 1_000_000 +output = 131_072 + +[modalities] +input = ["text"] +output = ["text"] + +[[benchmarks]] +name = "Terminal-Bench" +score = 88.2 +metric = "pass@1" +variant = "max effort" +version = "2.1" +harness = "Claude Code 2.1.207" +source = "https://huggingface.co/zai-org/GLM-5.3" + +[[benchmarks]] +name = "Terminal-Bench" +score = 28.3 +metric = "avg@3" +variant = "max effort" +version = "3.0" +harness = "Claude Code 2.1.207" +source = "https://huggingface.co/zai-org/GLM-5.3" + +[[benchmarks]] +name = "DeepSWE" +score = 66.9 +metric = "resolved" +variant = "max effort; 6h timeout; 400K context" +version = "1.1" +source = "https://huggingface.co/zai-org/GLM-5.3" +harness = "mini-swe-agent" + +[[benchmarks]] +name = "NL2Repo" +score = 58.0 +metric = "score" +variant = "max effort" +source = "https://huggingface.co/zai-org/GLM-5.3" + +[[benchmarks]] +name = "ProgramBench" +score = 19.0 +metric = "almost solved" +variant = "max effort" +source = "https://huggingface.co/zai-org/GLM-5.3" + +[[benchmarks]] +name = "FrontierSWE" +score = 78.1 +metric = "dominance score" +variant = "max effort" +date = "2026-08-14" +source = "https://huggingface.co/zai-org/GLM-5.3" + +[[benchmarks]] +name = "SWE-Marathon" +score = 42.5 +metric = "score" +variant = "max effort; modified anti-cheat checks" +version = "1.1" +harness = "Claude Code 2.1.207" +source = "https://huggingface.co/zai-org/GLM-5.3" + +[[benchmarks]] +name = "PostTrainBench" +score = 39.8 +metric = "weighted average" +variant = "max effort; 3 runs; modified external-API checks" +harness = "Claude Code 2.1.207" +source = "https://huggingface.co/zai-org/GLM-5.3" + +[[benchmarks]] +name = "CyberGym" +score = 84.5 +metric = "pass@1" +variant = "max effort" +harness = "Claude Code 2.1.207" +source = "https://huggingface.co/zai-org/GLM-5.3" + +[[benchmarks]] +name = "ExploitGym" +score = 105 +metric = "tasks solved" +variant = "max effort; 2h rescaled timeout" +dataset = "869 tasks" +harness = "Claude Code 2.1.207" +source = "https://huggingface.co/zai-org/GLM-5.3" + +[[benchmarks]] +name = "ExploitGym" +score = 130 +metric = "tasks solved" +variant = "max effort; 6h rescaled timeout" +dataset = "869 tasks" +harness = "Claude Code 2.1.207" +source = "https://huggingface.co/zai-org/GLM-5.3" + +[[benchmarks]] +name = "ExploitBench" +score = 54.4 +metric = "average coverage" +variant = "max effort; union over 3 revisions" +harness = "Claude Code 2.1.207" +source = "https://huggingface.co/zai-org/GLM-5.3" + +[[benchmarks]] +name = "Toolathlon-Verified" +score = 73 +metric = "pass@1" +variant = "max effort" +source = "https://huggingface.co/zai-org/GLM-5.3" + +[[benchmarks]] +name = "AutomationBench" +score = 48.2 +metric = "pass@1" +variant = "max effort" +version = "1.0.6" +source = "https://huggingface.co/zai-org/GLM-5.3" + +[[benchmarks]] +name = "Agents' Last Exam" +score = 28.5 +metric = "score" +variant = "max effort; CLI" +harness = "Claude Code 2.1.207" +source = "https://huggingface.co/zai-org/GLM-5.3" + +[[benchmarks]] +name = "Humanity's Last Exam" +score = 62.5 +metric = "accuracy" +variant = "max effort; with tools" +source = "https://huggingface.co/zai-org/GLM-5.3" + +[[benchmarks]] +name = "GDPval-AA" +score = 1769 +metric = "Elo" +variant = "max effort" +version = "2" +source = "https://huggingface.co/zai-org/GLM-5.3" diff --git a/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/MiniMax/MiniMax-M2.7.toml b/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/MiniMax/MiniMax-M2.7.toml new file mode 100644 index 0000000000..80d471831f --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/MiniMax/MiniMax-M2.7.toml @@ -0,0 +1,25 @@ +name = "MiniMax-M2.7" +description = "MiniMax model for chat, coding, office work, and agentic tasks" +family = "minimax" +release_date = "2026-03-18" +last_updated = "2026-03-18" +attachment = false +reasoning = true +temperature = true +tool_call = true +open_weights = true +reasoning_options = [] + +[cost] +input = 0.30 +output = 1.20 +cache_read = 0.06 +cache_write = 0.375 + +[limit] +context = 204_800 +output = 131_072 + +[modalities] +input = ["text"] +output = ["text"] diff --git a/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/deepseek-v4-flash.toml b/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/deepseek-v4-flash.toml new file mode 100644 index 0000000000..f37c5ab26f --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/deepseek-v4-flash.toml @@ -0,0 +1,16 @@ +base_model = "deepseek/deepseek-v4-flash" + +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "effort" +values = ["high", "max"] + +[interleaved] +field = "reasoning_content" + +[cost] +input = 0.14 +output = 0.28 +cache_read = 0.0028 diff --git a/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/deepseek-v4-pro.toml b/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/deepseek-v4-pro.toml new file mode 100644 index 0000000000..722857a529 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/deepseek-v4-pro.toml @@ -0,0 +1,16 @@ +base_model = "deepseek/deepseek-v4-pro" + +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "effort" +values = ["high", "max"] + +[interleaved] +field = "reasoning_content" + +[cost] +input = 0.435 +output = 0.87 +cache_read = 0.003625 diff --git a/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/deepseek-v4.1-flash.toml b/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/deepseek-v4.1-flash.toml new file mode 100644 index 0000000000..6fe0ab8159 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/deepseek-v4.1-flash.toml @@ -0,0 +1,27 @@ +# CNY→USD rate: 6.721845, 2026-09-18, source: https://open.er-api.com/v6/latest/USD +# Sources (accessed 2026-09-18): +# https://bailian.console.aliyun.com/cn-beijing?tab=model#/model-market/detail/deepseek-v4.1-flash?serviceSite=asia-pacific-china +# https://help.aliyun.com/zh/model-studio/deepseek-api — capability table, +# reasoning_effort ladder, max_tokens default (393_216, shared with thinking) +# https://help.aliyun.com/zh/model-studio/billing-for-model-studio — Beijing +# peak/off-peak pricing: CNY 2/1 input, 8/4 output per 1M tokens with context +# cache discount; peak price converted to USD using the rate above (off-peak +# is half). +# Hybrid reasoning: enable_thinking = true|false toggles thinking; +# reasoning_effort = low|high|max (default high) — low is only supported on +# v4.1-flash / v4-flash-0731 / v4-pro-0813, and v4.1-flash is the current +# low-tier bearer. reasoning_content streams in deltas. Responses API +# supported (Beijing and Singapore only). Limits and modalities are identical +# to the deepseek lab entry (1M context, 384_000 output, text+image input), +# so they are inherited and not restated. +base_model = "deepseek/deepseek-v4.1-flash" + +reasoning_options = [{ type = "toggle" }, { type = "effort", values = ["low", "high", "max"] }] + +[interleaved] +field = "reasoning_content" + +[cost] +input = 0.29754 +output = 1.19015 +cache_read = 0.01488 diff --git a/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/glm-5.1.toml b/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/glm-5.1.toml new file mode 100644 index 0000000000..e19b35f1e8 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/glm-5.1.toml @@ -0,0 +1,45 @@ +# Chinese mainland deployment is tiered on input tokens per request; every +# token in a request bills at its tier's unit price. The 0.87/3.48 previously +# published here matches neither band; both bands below are taken from the +# vendor page. No cache-read price is published for either band, so the +# existing curated cache_read is retained on the base and not restated. +# https://www.alibabacloud.com/help/en/model-studio/model-pricing (accessed 2026-08-26) +name = "GLM-5.1" +description = "Flagship GLM model for hybrid reasoning, coding, and agentic engineering" +family = "glm" +release_date = "2026-04-14" +last_updated = "2026-04-14" +attachment = false +reasoning = true +structured_output = true +temperature = true +tool_call = true +open_weights = true + +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "budget_tokens" +max = 131_072 + +[interleaved] +field = "reasoning_content" + +[cost] +input = 0.825 +output = 3.301 +cache_read = 0.17 + +[[cost.tiers]] +tier = { type = "context", size = 32_000 } +input = 1.1 +output = 3.851 + +[limit] +context = 202_752 +output = 128_000 + +[modalities] +input = ["text"] +output = ["text"] diff --git a/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/glm-5.2.toml b/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/glm-5.2.toml new file mode 100644 index 0000000000..b847c801b2 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/glm-5.2.toml @@ -0,0 +1,22 @@ +base_model = "zhipuai/glm-5.2" + +reasoning_options = [] + +[interleaved] +field = "reasoning_content" + +# First party price citation here +# https://bailian.console.alibabacloud.com/cn-beijing?tab=model#/model-market/detail/glm-5.2?serviceSite=asia-pacific-china +[cost] +input = 1.1 +output = 3.851 +cache_read = 0.275 +cache_write = 0 + +[limit] +context = 1000000 +output = 128_000 + +[modalities] +input = ["text"] +output = ["text"] diff --git a/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/glm-5.3.toml b/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/glm-5.3.toml new file mode 100644 index 0000000000..f6d0f6e67e --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/glm-5.3.toml @@ -0,0 +1,25 @@ +# GLM-5.3 on Alibaba Bailian (Model Studio, Beijing): always-on thinking with +# reasoning_effort low|high|max (default max). Thinking cannot be turned off +# (enable_thinking only accepts true; passing false errors) and there is no +# thinking_budget — so a single effort option, no toggle, no budget. +# reasoning_content is streamed in deltas. +# Pricing: Beijing CNY 8 / 28 / 2 (cache hit) per 1M tokens, same list price +# as glm-5.2 on the same host (see providers/alibaba-cn/models/glm-5.2.toml). +# Limits and modalities are identical to the zhipuai lab entry +# (1M context, 131_072 output, text-only), so they are inherited and not restated. +# https://bailian.console.aliyun.com/cn-beijing?tab=model#/model-market/detail/glm-5.3?serviceSite=asia-pacific-china +# https://docs.bigmodel.cn/cn/guide/models/text/glm-5.3 +base_model = "zhipuai/glm-5.3" + +[[reasoning_options]] +type = "effort" +values = ["low", "high", "max"] + +[interleaved] +field = "reasoning_content" + +[cost] +input = 1.1 +output = 3.851 +cache_read = 0.275 +cache_write = 0 diff --git a/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/qwen3.5-397b-a17b.toml b/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/qwen3.5-397b-a17b.toml new file mode 100644 index 0000000000..8bafd8221f --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/providers/alibaba-cn/models/qwen3.5-397b-a17b.toml @@ -0,0 +1,42 @@ +# Chinese mainland deployment is tiered on input tokens per request: +# 0 reasoning_tokens 57, disabled -> 0). +# No graded effort: the same body accepts reasoning_effort, but acceptance is not +# effect. Over n=5 runs per level on a prompt hard enough to consume the budget, +# none and minimal were hard zeros (the off switch) while the graded values fully +# overlapped -- low 659/873/216/487/845, medium 271/1548/556/296/1245, +# high 121/123/132/349/262, xhigh 928/753/268/480/110, max 811/435/570/910/623. +# 'high' sits below 'low', so the levels are not separable and only the toggle is +# declared, matching the toggle the lab (providers/deepseek) exposes. +base_model = "deepseek/deepseek-v4-flash" + +[[reasoning_options]] +type = "toggle" + +[interleaved] +field = "reasoning_content" + +[cost] +input = 0 +output = 0 +cache_read = 0 diff --git a/sdk/nexent/core/model_service/profiles/providers/volcengine-coding-plan/models/deepseek-v4-pro.toml b/sdk/nexent/core/model_service/profiles/providers/volcengine-coding-plan/models/deepseek-v4-pro.toml new file mode 100644 index 0000000000..68e7561f92 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/providers/volcengine-coding-plan/models/deepseek-v4-pro.toml @@ -0,0 +1,22 @@ +# Coding Plan model name from https://www.volcengine.com/docs/82379/1928261 +# (accessed 2026-08-26). Subscription tier: no per-token price. +# Toggle: thinking.type = enabled|disabled, POST /api/coding/v3/chat/completions +# (verified: enabled -> reasoning_tokens 79, disabled -> 0). +# No graded effort: the same body accepts reasoning_effort, but acceptance is not +# effect. Over n=5 runs per level on a prompt hard enough to consume the budget, +# none and minimal were hard zeros (the off switch) while the graded values fully +# overlapped -- low 200/517/616/638/313, high 466/673/604/1075/415, +# max 389/204/240/1535/688. The levels are not separable, so only the toggle is +# declared, matching the toggle the lab (providers/deepseek) exposes. +base_model = "deepseek/deepseek-v4-pro" + +[[reasoning_options]] +type = "toggle" + +[interleaved] +field = "reasoning_content" + +[cost] +input = 0 +output = 0 +cache_read = 0 diff --git a/sdk/nexent/core/model_service/profiles/providers/volcengine-coding-plan/models/glm-5.3-flash.toml b/sdk/nexent/core/model_service/profiles/providers/volcengine-coding-plan/models/glm-5.3-flash.toml new file mode 100644 index 0000000000..45dd0b497e --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/providers/volcengine-coding-plan/models/glm-5.3-flash.toml @@ -0,0 +1,17 @@ +# Coding Plan model name from https://www.volcengine.com/docs/82379/1928261 +# (accessed 2026-09-11): the model list includes both glm-5.3 (glm-latest) +# and glm-5.3-flash. Subscription tier: no per-token price. +# Effort levels mirror providers/zai-coding-plan/glm-5.3-flash.toml. +base_model = "zhipuai/glm-5.3-flash" + +[[reasoning_options]] +type = "effort" +values = ["low", "high", "max"] + +[interleaved] +field = "reasoning_content" + +[cost] +input = 0 +output = 0 +cache_read = 0 diff --git a/sdk/nexent/core/model_service/profiles/providers/volcengine-coding-plan/models/glm-5.3.toml b/sdk/nexent/core/model_service/profiles/providers/volcengine-coding-plan/models/glm-5.3.toml new file mode 100644 index 0000000000..8d75263dbe --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/providers/volcengine-coding-plan/models/glm-5.3.toml @@ -0,0 +1,30 @@ +# Coding Plan model name from https://www.volcengine.com/docs/82379/1928261 +# (accessed 2026-08-26). Subscription tier: no per-token price. +# Effort: POST /api/coding/v3/chat/completions accepts low|medium|high|xhigh|max, +# but only the three effective levels are declared. This model reports +# reasoning_tokens = 0 on every level, so the measure is reasoning_content length; +# over n=5 runs per level on a prompt hard enough to consume the thinking budget: +# low 0 0 0 0 0 medium 0 0 0 0 0 -> medium aliases low +# high 169 149 0 188 0 +# xhigh 2840 1943 3338 4655 6279 max 2363 4567 2962 4606 2327 +# -> xhigh aliases max +# Three distinct tiers, matching the lab (providers/zai) and the coding-plan peers. +# Volcengine's mapping table (82379/1449737) covers glm-5-2-260617 but not 5.3, and +# that row disagrees with what 5.3 does here (it maps low/medium to high, whereas +# 5.3 returns no reasoning at all on both), so these levels are set from the +# measurements above rather than from that table. +# No toggle: both reasoning_effort=none|minimal and thinking.type=disabled are +# rejected with 'not supported by this model'. +base_model = "zhipuai/glm-5.3" + +[[reasoning_options]] +type = "effort" +values = ["low", "high", "max"] + +[interleaved] +field = "reasoning_content" + +[cost] +input = 0 +output = 0 +cache_read = 0 diff --git a/sdk/nexent/core/model_service/profiles/providers/volcengine-coding-plan/models/minimax-m3.toml b/sdk/nexent/core/model_service/profiles/providers/volcengine-coding-plan/models/minimax-m3.toml new file mode 100644 index 0000000000..60ca6e93c0 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/providers/volcengine-coding-plan/models/minimax-m3.toml @@ -0,0 +1,21 @@ +# Coding Plan model name from https://www.volcengine.com/docs/82379/1928261 +# (accessed 2026-08-26). Subscription tier: no per-token price. +# Toggle: thinking.type = enabled|disabled, POST /api/coding/v3/chat/completions +# Toggle only, matching first-party MiniMax and minimax-coding-plan. +# The same body also accepts reasoning_effort, but acceptance is not effect: +# over n=3 runs per level on a hard arithmetic prompt, reasoning_content length was +# minimal 1161/1033/805, high 1195/741/840, max 957/709/1088 -- fully overlapping, +# so no graded control is declared. 'none' is likewise accepted without disabling +# thinking (reasoning_tokens stays non-zero), so thinking.type is the real switch. +base_model = "minimax/MiniMax-M3" + +[[reasoning_options]] +type = "toggle" + +[interleaved] +field = "reasoning_content" + +[cost] +input = 0 +output = 0 +cache_read = 0 diff --git a/sdk/nexent/core/model_service/profiles/providers/volcengine-coding-plan/provider.toml b/sdk/nexent/core/model_service/profiles/providers/volcengine-coding-plan/provider.toml new file mode 100644 index 0000000000..7420f6ed56 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/providers/volcengine-coding-plan/provider.toml @@ -0,0 +1,42 @@ +name = "Volcengine Ark Coding Plan" +env = ["ARK_CODING_PLAN_API_KEY"] +npm = "@ai-sdk/openai-compatible" +# Coding Plan is a subscription tier with its own base URL. Volcengine warns that +# calling the pay-as-you-go https://ark.cn-beijing.volces.com/api/v3 with a Coding +# Plan key does NOT draw down the subscription and bills separately, so the two +# providers must stay distinct. +# The env var is deliberately not ARK_API_KEY: /api/coding/v3 does not check which +# plan a key belongs to, so a pay-as-you-go key reaches it and bills per token. +# Sharing ARK_API_KEY would light up both providers at once and let a user pick a +# Coding Plan entry while silently paying pay-as-you-go rates. +# Reasoning HTTP format (accessed 2026-08-26): +# OpenAI Chat: POST /api/coding/v3/chat/completions; `thinking.type` = enabled or +# disabled (`auto` is rejected on most models); `reasoning_effort` is accepted on +# every model but only some values have effect, so each file declares just the +# levels it honours, measured on this endpoint (n=4-6 per level, 2026-08-27): +# doubao-seed-2.1-turbo / 2.0-lite / evolving -> none|low|high +# (medium overlaps low, xhigh and max overlap high rather than exceeding it) +# glm-5.3 -> low|high|max +# (rejects none and minimal outright; medium aliases low, xhigh aliases max) +# deepseek-v4-flash / -pro -> toggle only +# (graded values fully overlap; on Flash 'high' lands below 'low') +# kimi-k2.7-code -> no controls +# minimax-m3 -> toggle only +# (tolerates none but still spends reasoning tokens on it, so it is not an +# off switch there; thinking.type is) +# Plaintext reasoning is in `choices[].message.reasoning_content` +# and the encrypted block in `choices[].message.encrypted_content`. +# Anthropic: base https://ark.cn-beijing.volces.com/api/coding, POST /v1/messages +# with `thinking.type` and `output_config.effort`. +# Model names here are the short console labels (doubao-seed-2.1-turbo). This +# endpoint is the more permissive of the two: it accepts the dated IDs as well +# (verified 2026-08-27 - doubao-seed-2-1-turbo-260628, doubao-seed-2-0-lite-260428 +# and glm-5-3-260930 all resolve here), whereas the pay-as-you-go /api/v3 accepts +# only the dated form and 404s on a short label. The short labels are used because +# they are what the Coding Plan console shows. `ark-code-latest` follows whichever +# model is selected in the console. +# Sources: +# https://www.volcengine.com/docs/82379/1928261 +# https://www.volcengine.com/docs/82379/2546386 +doc = "https://www.volcengine.com/docs/82379/1928261" +api = "https://ark.cn-beijing.volces.com/api/coding/v3" diff --git a/sdk/nexent/core/model_service/profiles/providers/volcengine/models/deepseek-v4-flash-ga-260731.toml b/sdk/nexent/core/model_service/profiles/providers/volcengine/models/deepseek-v4-flash-ga-260731.toml new file mode 100644 index 0000000000..85e6279908 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/providers/volcengine/models/deepseek-v4-flash-ga-260731.toml @@ -0,0 +1,21 @@ +# Model ID verified against POST /api/v3/chat/completions (2026-08-27): `deepseek-v4-flash-ga-260731` +# CNY→USD rate: 6.737012, 2026-08-26, source: https://open.er-api.com/v6/latest/USD +# CNY list price source: https://www.volcengine.com/docs/82379/1544106 +# Toggle: thinking.type = enabled|disabled +# Effort: reasoning_effort = minimal|low|medium|high +base_model = "deepseek/deepseek-v4-flash-0731" + +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "effort" +values = ["minimal", "low", "medium", "high"] + +[interleaved] +field = "reasoning_content" + +[cost] +input = 0.4453 +output = 1.3359 +cache_read = 0.01484 diff --git a/sdk/nexent/core/model_service/profiles/providers/volcengine/models/deepseek-v4-pro-ga-260813.toml b/sdk/nexent/core/model_service/profiles/providers/volcengine/models/deepseek-v4-pro-ga-260813.toml new file mode 100644 index 0000000000..369ff4ef40 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/providers/volcengine/models/deepseek-v4-pro-ga-260813.toml @@ -0,0 +1,21 @@ +# Model ID verified against POST /api/v3/chat/completions (2026-08-27): `deepseek-v4-pro-ga-260813` +# CNY→USD rate: 6.737012, 2026-08-26, source: https://open.er-api.com/v6/latest/USD +# CNY list price source: https://www.volcengine.com/docs/82379/1544106 +# Toggle: thinking.type = enabled|disabled +# Effort: reasoning_effort = minimal|low|medium|high +base_model = "deepseek/deepseek-v4-pro-0813" + +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "effort" +values = ["minimal", "low", "medium", "high"] + +[interleaved] +field = "reasoning_content" + +[cost] +input = 1.3359 +output = 4.00771 +cache_read = 0.04453 diff --git a/sdk/nexent/core/model_service/profiles/providers/volcengine/models/glm-5-2-260617.toml b/sdk/nexent/core/model_service/profiles/providers/volcengine/models/glm-5-2-260617.toml new file mode 100644 index 0000000000..64005aefe7 --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/providers/volcengine/models/glm-5-2-260617.toml @@ -0,0 +1,21 @@ +# Model ID verified against POST /api/v3/chat/completions (2026-08-27): `glm-5-2-260617` +# CNY→USD rate: 6.737012, 2026-08-26, source: https://open.er-api.com/v6/latest/USD +# CNY list price source: https://www.volcengine.com/docs/82379/1544106 +# Toggle: thinking.type = enabled|disabled +# Effort: reasoning_effort = minimal|low|medium|high +base_model = "zhipuai/glm-5.2" + +[[reasoning_options]] +type = "toggle" + +[[reasoning_options]] +type = "effort" +values = ["minimal", "low", "medium", "high"] + +[interleaved] +field = "reasoning_content" + +[cost] +input = 1.18747 +output = 4.15615 +cache_read = 0.29687 diff --git a/sdk/nexent/core/model_service/profiles/providers/volcengine/models/glm-5-3-flash-260828.toml b/sdk/nexent/core/model_service/profiles/providers/volcengine/models/glm-5-3-flash-260828.toml new file mode 100644 index 0000000000..98cb87ee9b --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/providers/volcengine/models/glm-5-3-flash-260828.toml @@ -0,0 +1,18 @@ +# Model ID verified against POST /api/v3/chat/completions (2026-09-16): `glm-5-3-flash-260828` +# CNY→USD rate: 6.737012, 2026-08-26, source: https://open.er-api.com/v6/latest/USD +# CNY list price source: https://docs.volcengine.com/docs/82379/1449737 (深度思考) + 智谱官方价目表 +# GLM-5.3-Flash always reasons (thinking cannot be disabled on this model ID) +# Effort: reasoning_effort = low|high|max +base_model = "zhipuai/glm-5.3-flash" + +[[reasoning_options]] +type = "effort" +values = ["low", "high", "max"] + +[interleaved] +field = "reasoning_content" + +[cost] +input = 0.11875 +output = 0.41563 +cache_read = 0.03414 diff --git a/sdk/nexent/core/model_service/profiles/providers/volcengine/provider.toml b/sdk/nexent/core/model_service/profiles/providers/volcengine/provider.toml new file mode 100644 index 0000000000..6ca805b6ab --- /dev/null +++ b/sdk/nexent/core/model_service/profiles/providers/volcengine/provider.toml @@ -0,0 +1,23 @@ +name = "Volcengine Ark" +env = ["ARK_API_KEY"] +npm = "@ai-sdk/openai-compatible" +# Reasoning HTTP format (accessed 2026-08-26): +# OpenAI Chat: POST /api/v3/chat/completions; `thinking.type` = enabled|disabled +# (`auto` is documented but rejected with "Unsupported thinking type for the +# current model" on every model here except doubao-seed-1-6-flash), +# `reasoning_effort` = none|minimal|low|medium|high|xhigh|max (none and minimal +# disable thinking; doubao-seed-1-6-251015 accepts only the middle four). +# Plaintext reasoning is in +# `choices[].message.reasoning_content`, encrypted block is in +# `choices[].message.encrypted_content` (returned by default). +# Responses: POST /api/v3/responses; `reasoning.effort`; encrypted block requires +# explicit `include = ["reasoning.encrypted_content"]`. +# Anthropic: POST /api/v3/compatible/v1/messages; `thinking.type`, +# `output_config.effort` = low|high|max; plaintext thinking is in +# `content[thinking].thinking`, signature in `content[thinking].signature` (returned by default). +# Sources: +# https://www.volcengine.com/docs/82379/1298459 +# https://www.volcengine.com/docs/82379/1330310 +# https://www.volcengine.com/docs/82379/2636748 +doc = "https://www.volcengine.com/docs/82379/1330310" +api = "https://ark.cn-beijing.volces.com/api/v3" diff --git a/sdk/pyproject.toml b/sdk/pyproject.toml index 4f95a9ac31..b1f928ca20 100644 --- a/sdk/pyproject.toml +++ b/sdk/pyproject.toml @@ -103,6 +103,7 @@ exclude = ["tests*", "examples*"] namespaces = true [tool.setuptools.package-data] +"nexent.core.model_service.profiles" = ["**/*.toml", "README.md", "LICENSE"] "nexent.core.prompts" = ["zh/*/*.yaml", "en/*/*.yaml"] "nexent.assets" = ["*.png", "*.jpg", "*.gif", "*.webp"] diff --git a/test-e2e/changes/requirements/MODEL-PROFILE-CATALOG-20261013.yaml b/test-e2e/changes/requirements/MODEL-PROFILE-CATALOG-20261013.yaml new file mode 100644 index 0000000000..26c17cd90e --- /dev/null +++ b/test-e2e/changes/requirements/MODEL-PROFILE-CATALOG-20261013.yaml @@ -0,0 +1,43 @@ +schema_version: '1.0' +change: + change_id: MODEL-PROFILE-CATALOG-20261013 + change_type: requirement + requirement_id: MODEL-PROFILE-CATALOG-20261013 + title: Package the pinned China-region model profile source inventory + description: Catalog source slice; no runtime consumer or support certification + is introduced. + affected_features: + existing: [] + added: + - SDK-MODEL-PROFILE-CATALOG + modified: [] + retired: [] + affected_cases: + existing: [] + added: [] + modified: [] + retired: [] + traditional_ut: + decision: add + behaviors: + - The reviewed inventory has 21 model, 21 provider-model and 3 provider files, + all with verified manifest hashes. + - Every declared base_model dependency is in the selection; TOML parses without + requiring upstream TypeScript. + - SDK wheels retain the manifest, source files, README and complete upstream MIT + license. + - Controlled TOML reader rejects path escapes, invalid manifest versions, duplicates, + missing sources, digest mismatch and malformed TOML without returning a partial + inventory. + - Read source documents preserve exact source identity and deeply immutable nested + data; loading is not semantic normalization. + reason: Isolated source/package integrity checks; later reader, normalization + and composition steps need their own component verification. + test_selectors: + - test/sdk/core/model_service/test_catalog_inventory.py + - test/sdk/core/model_service/test_source_reader.py + no_case_change_reason: No API or runtime behavior is connected. Existing Cases remain + unchanged; installed-package inspection supplies artifact evidence, not Agent + acceptance. + notes: SPEC AC-01/16 subset. Source inventory is distinct from verified support; + live-model acceptance remains pending. diff --git a/test-e2e/changes/requirements/MODEL-PROFILE-CONTRACTS-20261013.yaml b/test-e2e/changes/requirements/MODEL-PROFILE-CONTRACTS-20261013.yaml new file mode 100644 index 0000000000..e260eb7bf3 --- /dev/null +++ b/test-e2e/changes/requirements/MODEL-PROFILE-CONTRACTS-20261013.yaml @@ -0,0 +1,28 @@ +schema_version: '1.0' +change: + change_id: MODEL-PROFILE-CONTRACTS-20261013 + change_type: requirement + requirement_id: MODEL-PROFILE-CONTRACTS-20261013 + title: Add strict model profile contract primitives + description: First local implementation slice of the approved model-access / NativeAgent SPEC; no existing runtime is connected or modified. + affected_features: + existing: [] + added: [SDK-MODEL-PROFILE-CONTRACTS] + modified: [] + retired: [] + affected_cases: + existing: [] + added: [] + modified: [] + retired: [] + traditional_ut: + decision: add + behaviors: + - Unknown capacity remains null and known limits reject booleans, numeric strings, zero, negatives and service limits above the combined window. + - Toggle, effort and budget controls preserve explicitly declared values and reject duplicate modes/keys, invalid types, ranges, unknown fields and unsupported-with-controls. + - Source references retain exact identity/digests, reject unsafe paths and round-trip through strict JSON validation without loading external sources. + reason: These are isolated domain validation contracts; existing model UI/runtime Cases do not exercise them, and a duplicate formal D1 would add no component evidence. Catalog parsing/composition and live runtime verification belong to subsequent slices. + test_selectors: + - test/sdk/core/model_service/test_profile_contracts.py + no_case_change_reason: No API, provider, database, tool execution or user journey is connected in this slice. Preserve all historical Cases; formal integration coverage will be added with the owning implementation. + notes: Implements only profile primitives under SPEC AC-01/02. Overall feature acceptance remains pending; neither formal runtime acceptance nor model compatibility is claimed. diff --git a/test-e2e/features/SDK-MODEL-PROFILE-CATALOG/cases.md b/test-e2e/features/SDK-MODEL-PROFILE-CATALOG/cases.md new file mode 100644 index 0000000000..a1a090f4ea --- /dev/null +++ b/test-e2e/features/SDK-MODEL-PROFILE-CATALOG/cases.md @@ -0,0 +1,5 @@ +# SDK-MODEL-PROFILE-CATALOG 关联用例 + +此页由结构化用例生成,不手工编辑。 + +当前测试基线未保留关联用例。 diff --git a/test-e2e/features/SDK-MODEL-PROFILE-CATALOG/feature.yaml b/test-e2e/features/SDK-MODEL-PROFILE-CATALOG/feature.yaml new file mode 100644 index 0000000000..899f55e1fe --- /dev/null +++ b/test-e2e/features/SDK-MODEL-PROFILE-CATALOG/feature.yaml @@ -0,0 +1,22 @@ +schema_version: '1.0' +module: + id: SDK-MODEL-SERVICE + name: SDK model service +feature: + feature_id: SDK-MODEL-PROFILE-CATALOG + name: Local model profile source catalog + status: planned + description: Pinned source inventory and package resources for the upcoming local + resolver. + business_rules: + - rule_id: SDK-MODEL-PROFILE-CATALOG-RULE-01 + description: Selected authored TOML retains exact upstream bytes and complete + base_model dependencies. + - rule_id: SDK-MODEL-PROFILE-CATALOG-RULE-02 + description: Inventory inclusion is not verified model support; runtime uses saved + resolved outlets. + required_test_stages: [] + source: + requirement_ids: + - MODEL-PROFILE-CATALOG-20261013 + notes: Source and package integrity only; no runtime integration. diff --git a/test-e2e/features/SDK-MODEL-PROFILE-CONTRACTS/cases.md b/test-e2e/features/SDK-MODEL-PROFILE-CONTRACTS/cases.md new file mode 100644 index 0000000000..903c7086ec --- /dev/null +++ b/test-e2e/features/SDK-MODEL-PROFILE-CONTRACTS/cases.md @@ -0,0 +1,5 @@ +# SDK-MODEL-PROFILE-CONTRACTS 关联用例 + +此页由结构化用例生成,不手工编辑。 + +当前测试基线未保留关联用例。 diff --git a/test-e2e/features/SDK-MODEL-PROFILE-CONTRACTS/feature.yaml b/test-e2e/features/SDK-MODEL-PROFILE-CONTRACTS/feature.yaml new file mode 100644 index 0000000000..5b6a238185 --- /dev/null +++ b/test-e2e/features/SDK-MODEL-PROFILE-CONTRACTS/feature.yaml @@ -0,0 +1,20 @@ +schema_version: '1.0' +module: + id: SDK-MODEL-SERVICE + name: SDK model service +feature: + feature_id: SDK-MODEL-PROFILE-CONTRACTS + name: Model profile contract primitives + status: planned + description: Strict provider-neutral capacity, reasoning and source-reference contracts used by the upcoming catalog and outlet layers. + business_rules: + - rule_id: SDK-MODEL-PROFILE-CONTRACTS-RULE-01 + description: Unknown capacity and capability stay distinct from explicit unsupported; known token limits are positive strict integers. + - rule_id: SDK-MODEL-PROFILE-CONTRACTS-RULE-02 + description: Reasoning controls use declared toggle, effort or token-budget domains; duplicates, invalid types, inconsistent support and unknown fields fail validation. + - rule_id: SDK-MODEL-PROFILE-CONTRACTS-RULE-03 + description: Atomic references carry exact source identity and digests with relative source paths; they are traceability, not runtime recomposition instructions. + required_test_stages: [] + source: + requirement_ids: [MODEL-PROFILE-CONTRACTS-20261013] + notes: SPEC AC-01 and AC-02 subset only; the current slice has no catalog, persistence, provider or Agent runtime integration. Traditional UT proves these domain contracts. Later slices supply independent component/API/runtime evidence. diff --git a/test/sdk/core/model_service/test_catalog_inventory.py b/test/sdk/core/model_service/test_catalog_inventory.py new file mode 100644 index 0000000000..b9b23103d8 --- /dev/null +++ b/test/sdk/core/model_service/test_catalog_inventory.py @@ -0,0 +1,60 @@ +"""AC-01/16: integrity of the reviewed source inventory, not model support.""" + +import hashlib +import tomllib +from collections import Counter +from pathlib import Path + +import pytest + +CATALOG_ROOT = ( + Path(__file__).resolve().parents[4] / "sdk/nexent/core/model_service/profiles" +) +MANIFEST = tomllib.loads((CATALOG_ROOT / "manifest.toml").read_text()) + + +def test_reviewed_inventory_is_pinned_and_complete(): + assert MANIFEST["schema_version"] == 1 + assert MANIFEST["source_schema_ref"] == "models_dev_authored_v1" + assert MANIFEST["upstream_revision"] == "e69e1844210e5cfe7c7e7f68d57328bc7451a51c" + sources = MANIFEST["sources"] + assert Counter(source["kind"] for source in sources) == { + "model": 21, + "provider_model": 21, + "provider": 3, + } + paths = [source["path"] for source in sources] + assert len(paths) == len(set(paths)) + actual = { + str(path.relative_to(CATALOG_ROOT)) + for folder in ("models", "providers") + for path in (CATALOG_ROOT / folder).rglob("*.toml") + } + assert actual == set(paths) + + +@pytest.mark.parametrize( + "source", MANIFEST["sources"], ids=lambda source: source["path"] +) +def test_source_bytes_match_manifest_and_dependencies_are_present(source): + path = CATALOG_ROOT / source["path"] + data = path.read_bytes() + assert hashlib.sha256(data).hexdigest() == source["content_sha256"] + parsed = tomllib.loads(data.decode("utf-8")) + if "base_model" in parsed: + assert f"models/{parsed['base_model']}.toml" in { + item["path"] for item in MANIFEST["sources"] if item["kind"] == "model" + } + if source["kind"] == "provider": + assert parsed["api"].startswith("https://") + assert isinstance(parsed["env"], list) + + +def test_license_and_scope_notice_ship_with_inventory(): + license_text = (CATALOG_ROOT / "LICENSE").read_text() + assert "Copyright (c) 2025 models.dev" in license_text + assert "Permission is hereby granted, free of charge" in license_text + assert "THE SOFTWARE IS PROVIDED" in license_text + readme = (CATALOG_ROOT / "README.md").read_text() + assert MANIFEST["upstream_revision"] in readme + assert "not a verified support list" in readme diff --git a/test/sdk/core/model_service/test_profile_contracts.py b/test/sdk/core/model_service/test_profile_contracts.py new file mode 100644 index 0000000000..0bd9ee1c7b --- /dev/null +++ b/test/sdk/core/model_service/test_profile_contracts.py @@ -0,0 +1,184 @@ +"""AC-01/02: strict profile primitives, without provider or database I/O.""" + +import pytest +from nexent.core.model_service.profiles.contracts import ( + AtomicProfileReference, + BudgetTokensControl, + ContextCapabilities, + EffortControl, + ReasoningCapabilities, + ToggleControl, +) +from pydantic import ValidationError + + +def test_context_unknown_and_independent_limits(): + assert ContextCapabilities().model_dump() == { + "combined_window": None, + "input_limit": None, + "output_limit": None, + } + profile = ContextCapabilities( + combined_window=100, input_limit=100, output_limit=100 + ) + assert ContextCapabilities.model_validate_json(profile.model_dump_json()) == profile + assert ContextCapabilities(output_limit=1).combined_window is None + + +@pytest.mark.parametrize("value", [True, False, "200000", 1.0, 0, -1]) +@pytest.mark.parametrize("field", ["combined_window", "input_limit", "output_limit"]) +def test_context_rejects_invalid_token_limits(field, value): + with pytest.raises(ValidationError): + ContextCapabilities(**{field: value}) + + +@pytest.mark.parametrize("field", ["input_limit", "output_limit"]) +def test_context_rejects_service_limit_above_window(field): + with pytest.raises(ValidationError): + ContextCapabilities(combined_window=100, **{field: 101}) + + +def test_reasoning_controls_preserve_declared_values_and_round_trip(): + profile = ReasoningCapabilities( + status="supported", + controls=[ + ToggleControl(values=[False, True]), + EffortControl(values=["low", "xhigh", "provider-specific"]), + BudgetTokensControl(min=0, max=100, special_values=[-1]), + ], + response_paths=["choices[].delta.reasoning_content"], + ) + assert ( + ReasoningCapabilities.model_validate_json(profile.model_dump_json()) == profile + ) + assert profile.controls[0].values[0] is False + assert profile.controls[2].special_values == [-1] + assert "current_value" not in profile.model_dump_json() + + +def test_reasoning_unknown_and_explicit_no_controls_remain_distinct(): + assert ReasoningCapabilities().controls is None + assert ReasoningCapabilities(status="unsupported", controls=[]).controls == [] + assert ( + ReasoningCapabilities(controls=[ToggleControl(values=[True])]).status + == "unknown" + ) + + +@pytest.mark.parametrize( + "control", + [ + {"mode": "toggle", "values": [1]}, + {"mode": "toggle", "values": [False, False]}, + {"mode": "toggle", "values": []}, + {"mode": "toggle", "values": [True], "parameter_key": "reasoning"}, + {"mode": "effort", "values": ["high", "high"]}, + {"mode": "effort", "values": [" "]}, + {"mode": "effort", "values": [1]}, + {"mode": "effort", "values": []}, + {"mode": "budget_tokens", "min": 10, "max": 9}, + {"mode": "budget_tokens", "min": -1, "max": 9}, + {"mode": "budget_tokens", "min": 0, "max": True}, + {"mode": "budget_tokens", "min": 0, "max": 9, "special_values": [False]}, + {"mode": "budget_tokens", "min": 0, "max": 9, "special_values": [-1, -1]}, + {"mode": "unknown"}, + {"mode": "toggle", "values": [True], "unexpected": 1}, + ], +) +def test_reasoning_rejects_invalid_controls(control): + with pytest.raises(ValidationError): + ReasoningCapabilities(controls=[control]) + + +@pytest.mark.parametrize( + "payload", + [ + {"status": "unsupported", "controls": [{"mode": "toggle", "values": [True]}]}, + {"status": "unsupported", "response_paths": ["reasoning_content"]}, + { + "status": "supported", + "controls": [ + {"mode": "effort", "values": ["low"]}, + {"mode": "effort", "values": ["high"]}, + ], + }, + {"response_paths": ["reasoning_content", "reasoning_content"]}, + {"response_paths": [""]}, + {"status": True}, + {"status": "unknown", "extra": 1}, + ], +) +def test_reasoning_rejects_conflicting_or_unknown_fields(payload): + with pytest.raises(ValidationError): + ReasoningCapabilities(**payload) + + +def test_reasoning_size_limit_counts_utf8_bytes(): + ReasoningCapabilities(controls=[EffortControl(values=["a" * 65000])]) + with pytest.raises(ValidationError, match="64 KiB"): + ReasoningCapabilities(controls=[EffortControl(values=["思" * 22000])]) + + +def reference_payload(): + return { + "key": "qwen/Qwen3.8", + "catalog_revision": "catalog-v1", + "file_path": "models/qwen/model.toml", + "content_sha256": "a" * 64, + } + + +def test_atomic_reference_round_trip_preserves_exact_identity(): + profile = AtomicProfileReference(**reference_payload()) + assert ( + AtomicProfileReference.model_validate_json(profile.model_dump_json()) == profile + ) + assert profile.key == "qwen/Qwen3.8" + + +@pytest.mark.parametrize( + "path", + [ + "/tmp/model.toml", + "../x.toml", + "models/../x.toml", + "models/./x.toml", + "models//x.toml", + "C:/x.toml", + "models\\x.toml", + "", + "models/", + "models/\x00file.toml", + ], +) +def test_atomic_reference_rejects_unsafe_paths(path): + with pytest.raises(ValidationError): + AtomicProfileReference(**{**reference_payload(), "file_path": path}) + + +@pytest.mark.parametrize( + "updates", + [ + {"content_sha256": "a" * 63}, + {"content_sha256": "A" * 64}, + {"content_sha256": "g" * 64}, + {"key": " "}, + {"catalog_revision": ""}, + {"unknown": "field"}, + ], +) +def test_atomic_reference_rejects_invalid_provenance(updates): + with pytest.raises(ValidationError): + AtomicProfileReference(**{**reference_payload(), **updates}) + + +def test_context_rejects_unknown_fields(): + with pytest.raises(ValidationError): + ContextCapabilities(max_tokens=100) + + +def test_contract_fields_cannot_be_reassigned_without_validation(): + profile = ContextCapabilities(combined_window=100) + with pytest.raises(ValidationError): + profile.combined_window = 0 + assert profile.combined_window == 100 diff --git a/test/sdk/core/model_service/test_source_reader.py b/test/sdk/core/model_service/test_source_reader.py new file mode 100644 index 0000000000..064d849e1f --- /dev/null +++ b/test/sdk/core/model_service/test_source_reader.py @@ -0,0 +1,134 @@ +"""Unit proof for controlled local sources; normalization is a separate contract.""" + +import hashlib +from pathlib import Path + +import pytest +from nexent.core.model_service.profiles._models_dev.reader import ( + SourceReadError, + read_sources, +) + +CATALOG_ROOT = ( + Path(__file__).resolve().parents[4] / "sdk/nexent/core/model_service/profiles" +) + + +def write_inventory( + root, + *, + data=b'name = "Test"\n[limit]\ncontext = 100\n', + path="models/test/model.toml", + kind="model", + digest=None, + version="1", + extra="", + copies=1, +): + digest = digest or hashlib.sha256(data).hexdigest() + (root / "manifest.toml").write_text( + f'schema_version = {version}\nsource_schema_ref = "models_dev_authored_v1"\n' + 'upstream_url = "https://github.com/anomalyco/models.dev"\n' + f'upstream_revision = "{"a" * 40}"\n{extra}\n' + + ( + f'[[sources]]\nkind = "{kind}"\npath = "{path}"\ncontent_sha256 = "{digest}"\n' + * copies + ) + ) + if not path.startswith("/") and ".." not in path.split("/"): + target = root / path + target.parent.mkdir(parents=True, exist_ok=True) + target.write_bytes(data) + + +def test_loads_pinned_inventory_with_exact_nested_model_identity(): + documents = read_sources(CATALOG_ROOT) + assert len(documents) == 45 + assert any( + document.key == "alibaba-cn/MiniMax/MiniMax-M2.7" for document in documents + ) + assert {document.key for document in documents if document.kind == "provider"} == { + "alibaba-cn", + "volcengine", + "volcengine-coding-plan", + } + + +def test_authored_documents_are_deeply_immutable(tmp_path): + write_inventory( + tmp_path, + data=b'name = "Test"\nvalues = ["low", "high"]\n[limit]\ncontext = 100\n', + ) + documents = read_sources(tmp_path) + assert isinstance(documents, tuple) + doc = documents[0] + assert doc.data["values"] == ("low", "high") + with pytest.raises(TypeError): + doc.data["limit"]["context"] = 0 + with pytest.raises(TypeError): + doc.data["name"] = "Changed" + + +@pytest.mark.parametrize( + "changes,category", + [ + ({"path": "../outside.toml"}, "SOURCE_REFERENCE_INVALID"), + ({"path": "/tmp/outside.toml"}, "SOURCE_REFERENCE_INVALID"), + ({"path": "models/./test.toml"}, "SOURCE_REFERENCE_INVALID"), + ( + {"path": "providers/test/provider.toml", "kind": "model"}, + "SOURCE_KIND_PATH_MISMATCH", + ), + ({"digest": "a" * 64}, "SOURCE_DIGEST_MISMATCH"), + ({"digest": "wrong"}, "SOURCE_REFERENCE_INVALID"), + ({"data": b"name = ["}, "SOURCE_TOML_INVALID"), + ({"data": b"\xff"}, "SOURCE_TOML_INVALID"), + ({"copies": 2}, "SOURCE_DUPLICATE"), + ({"copies": 0}, "SOURCE_MANIFEST_INVALID"), + ({"version": "2"}, "SOURCE_MANIFEST_INVALID"), + ({"version": "1.0"}, "SOURCE_MANIFEST_INVALID"), + ({"path": "models/test/model.json"}, "SOURCE_KIND_PATH_MISMATCH"), + ({"path": "models/test/.toml"}, "SOURCE_KIND_PATH_MISMATCH"), + ({"version": "true"}, "SOURCE_MANIFEST_INVALID"), + ({"extra": "unexpected = 1"}, "SOURCE_MANIFEST_INVALID"), + ], +) +def test_rejects_invalid_inventory_before_returning_partial_data( + tmp_path, changes, category +): + write_inventory(tmp_path, **changes) + with pytest.raises(SourceReadError) as caught: + read_sources(tmp_path) + assert caught.value.category == category + assert "name =" not in str(caught.value) + assert caught.value.rule_id == "source_inventory_v1" + + +def test_missing_manifest_and_source_are_explicit_errors(tmp_path): + with pytest.raises(SourceReadError, match="SOURCE_FILE_UNAVAILABLE"): + read_sources(tmp_path) + write_inventory(tmp_path) + (tmp_path / "models/test/model.toml").unlink() + with pytest.raises(SourceReadError, match="SOURCE_FILE_UNAVAILABLE"): + read_sources(tmp_path) + + +def test_symlink_to_outside_root_is_rejected(tmp_path): + root = tmp_path / "catalog" + root.mkdir() + write_inventory(root) + target = root / "models/test/model.toml" + target.unlink() + outside = tmp_path / "outside.toml" + outside.write_text('name = "Outside"') + target.symlink_to(outside) + with pytest.raises(SourceReadError, match="SOURCE_PATH_OUTSIDE_ROOT"): + read_sources(root) + + +def test_invalid_upstream_commit_is_rejected(tmp_path): + write_inventory(tmp_path) + manifest = tmp_path / "manifest.toml" + manifest.write_text(manifest.read_text().replace("a" * 40, "not-a-commit")) + with pytest.raises(SourceReadError, match="SOURCE_MANIFEST_INVALID"): + read_sources(tmp_path)