Skip to content

feat(sync): add ai& sync module with auto-merge allowlist and motif family - #7040

Merged
rekram1-node merged 10 commits into
anomalyco:devfrom
islomjon-aiand:aia-683-aiand-sync-adapter
Sep 17, 2026
Merged

rekram1-node merged 10 commits into
anomalyco:devfrom
islomjon-aiand:aia-683-aiand-sync-adapter

Conversation

@islomjon-aiand

@islomjon-aiand islomjon-aiand commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Adds a sync module for ai& (providers/aiand), whose GET /v1/api.json publishes this repo's shape directly — the aiand provider entry is read and translation is near-identity. Registered in the sync registry and the direct group, with an aiand:sync script and an "ai& Notes" section in sync.md.

What this change set contains

The catalog side of this PR is smaller than it was: dev's #6839 (2026-09-11) already brought the ai& TOMLs to the live feed — cache_read pricing, the gateway-enforced reasoning levels, refreshed headers, and the [interleaved] side-channel blocks — so after rebasing onto it, bun models:sync aiand against the live feed is a no-op for 8 of 11 files, which is the parity proof the adapter needs. What the diff does change:

  • New lab file models/motif-technologies/motif-3.toml and the provider file factored onto it. Motif 3 is open-weights (155 safetensors shards, ungated, MIT — https://huggingface.co/Motif-Technologies/Motif-3), correcting the previous inline open_weights = false; tool calling and temperature are cited from the model card and a 2026-09-14 live probe (real tool_calls response; temperature reaches the sampler). Release date 2026-08-07 is the HF repo creation date.
  • kimi-k2.7-code / kimi-k3: temperature = true — a host-specific delta from the feed (ai& forwards temperature and the engines honor it; lab files say false for Moonshot's own API).
  • Header refreshes: kimi-k3 and gpt-oss-120b re-probed 2026-09-14 (effort sets unchanged); qwen3.8-27b documents that high now returns 200 via ai&'s announced substitution to xhigh (X-Reasoning-Effort), so it stays unlisted.

Every published reasoning level on all 11 models was verified by live probe on 2026-09-14 (each returns 200; each unpublished value returns 400 or the announced substitution above).

Evidence

Claim Source
Pricing incl. cache_read, limits, capability flags, modalities GET https://api.aiand.com/v1/api.json (aiand entry), accessed 2026-09-14 — the adapter's own input; bun models:sync aiand --dry-run is a no-op against it
Reasoning levels per model (every published value → 200, every unpublished → 400) Live probe against api.aiand.com on 2026-09-14, 11 models × 7 values; each TOML's leading comment records its row
qwen3.8 high → 200 via substitution to xhigh Same probe; X-Reasoning-Effort: xhigh on the response; documented in qwen3.8-27b.toml
Motif 3 open weights, MIT, release 2026-08-07 https://huggingface.co/Motif-Technologies/Motif-3 — repo created 2026-08-07, 155 safetensors shards, ungated, license:mit
Motif 3 tool calling / temperature Model card (agentic tool use, vLLM --tool-call-parser motif, evals at temperature 1.0) + live probe 2026-09-14 (real tool_calls response; temperature 0.2 vs 1.7 changes output)
Motif 3 structured_output = false Live probe 2026-09-14: response_format: json_schema ignored, prose reply
Kimi temperature = true on this host Feed capability flag; host forwards temperature and the engines honor it (lab files record Moonshot's own API as false)

Adapter authority policy

Host facts come from the feed: prices (including cache_read), limits, capability flags, modalities, gateway-enforced reasoning_options, deprecated status, and the reasoning side channel (interleaved, with a gateway default of message.reasoning_content for reasoners until the feed publishes it). Lab-owned fields — name, description, family, release_date, last_updated, knowledge, open_weights — are never asserted from the gateway on a factored file: they appear only as deltas the authored TOML already carried on top of its base_model (read from context.authored(), never the base-resolved merge), so a full-inline file being factored for the first time, or a new file, inherits the lab entry outright. On a standalone file curated values win for those fields.

New feed ids resolve their base_model by normalized match against models/ (full id, then unique filename — ai&'s lab prefixes differ from the directory names, e.g. deepseek-ai/ vs models/deepseek/); an unresolvable new id is returned from missingModelID, so the runner preserves any existing local entry and opens a deduped missing-model issue. An empty feed fails the run instead of authorizing deletion of the local catalog. family passes through ModelFamily.safeParse and is omitted when unknown.

reasoning_options follow the feed's assertion exactly: an omitted list asserts nothing (authored options stay), an explicit [] asserts "no caller controls", a non-empty list whose effort values the schema doesn't know yet keeps the authored options; when a reasoner ends up with no schema-valid set and nothing authored, the model fails with MissingReasoningOptionsError (local file preserved, missing-model issue opened) rather than ever writing an invented []. toggle/budget_tokens are parsed (so a feed publishing one never aborts the run) but never written, from feed or authored file — ai& has a single reasoning wire path (reasoning_effort, "none" = off) and no separate toggle or token-budget field; created files get a leading header stating exactly that; omitted entirely on non-reasoners. preserveDescriptions is off so the runner never re-injects a pre-factor description. A curated alpha/beta survives an omitted feed status; a curated deprecated does not (the feed owns deprecation).

Asks

  • Add aiand to REVIEWED_REASONING_PROVIDERS — all 11 ai& models are reasoning models, so without it every hourly sync PR waits on a maintainer. The adapter's empty-options guard above is the safety argument: a feed vocabulary change can't strip caller controls and auto-merge that way.
  • Add motif to ModelFamilyValues — needed by the new lab file; the adapter degrades gracefully (omits family) if you'd rather trim this.

Validation

bun models:sync aiand --dry-run → write → second dry run is a no-op (11 unchanged) → bun validate passes → bun test (27 tests in packages/core/test/aiand.test.ts plus the allowlist assertion in auto-merge.test.ts; the pre-existing failures on dev are untouched).

@islomjon-aiand
islomjon-aiand marked this pull request as ready for review September 14, 2026 04:56
@github-actions

Copy link
Copy Markdown
Contributor

Action items

  • [high] [violation] packages/core/src/sync/providers/aiand.ts:276 - Check: reasoning_options must be omitted when reasoning is false (schema refine + peers like wandb/tinfoil). Why: buildAiandModel always assigns reasoning_options (including []). For reasoning: false, SyncedAuthoredModel fails with “Cannot set reasoning_options when reasoning is false”, so any non-reasoner on the feed stalls the hourly sync. Action: Set reasoning_options only when model.reasoning === true (else undefined); add a unit test for a non-reasoning feed model.
  • [high] [violation] packages/core/src/sync/providers/aiand.ts:310 - Check: Non-lab hosts must use base_model when a lab model is nameable (AGENTS.md blocker; peers resolve via existing?.base_model ?? resolve…). Why: Factoring runs only if a local file already has base_model. A new feed ID with no local TOML is written as a full inline definition (no base_model), which breaks override-only policy and can auto-merge incomplete third-party rows. Action: Resolve base_model for new IDs (map feed id → models/…, or skipCreates + missing-model issues when unresolved); never create unfactored third-party full definitions when a lab entry exists or can be added.
  • [medium] [possible mistake] models/motif-technologies/motif-3.toml:48 - Check: Lab capability flags need evidence; provider previously had tool_call = false / temperature = false. Why: The new lab file sets tool_call = true and temperature = true (and the provider now inherits them). The PR body only evidences open weights / MIT / HF date, not tools or temperature, so catalog capabilities may be wrong. Action: Cite first-party/HF evidence for tool calling and temperature, or keep conservative false until verified; if only the gateway differs, put overrides on the provider file instead of the lab entry.
  • [low] [violation] packages/core/test/auto-merge.test.ts:97 - Check: Allowlist changes should be covered by the reviewed-providers test. Why: aiand was added to REVIEWED_REASONING_PROVIDERS but the test still lists only the prior providers, so a regression dropping aiand would not fail CI. Action: Include "aiand" in that allowlist assertion.

@islomjon-aiand
islomjon-aiand force-pushed the aia-683-aiand-sync-adapter branch from 5ceebc2 to ec88eae Compare September 14, 2026 05:20
@github-actions

Copy link
Copy Markdown
Contributor

Action items

  • [high] [violation] packages/core/src/sync/providers/aiand.ts:241 - Check: Authoritative deletion must not wipe the catalog on an empty or partial feed. Why: parseModels returns Object.values(...) with no empty-catalog guard, and deleteMissing is left at the runner default (true). An empty aiand.models object (or a transient feed that omits the entry) produces zero desired models and deletes every local TOML under providers/aiand/models. Peers such as LLM Gateway and Cloudflare AI Gateway fail loudly instead. Action: Reject an empty model list in parseModels/fetchModels (or set deleteMissing: false if the feed is not lifecycle-authoritative), and add a test for that failure path.
  • [medium] [violation] packages/core/src/sync/providers/aiand.ts:277 - Check: Feed-authoritative reasoning_options must not invent “no caller control” when the feed omits controls. Why: Omitted reasoning_options on a reasoning: true model becomes [] (feedReasoningOptions starts empty, and the authored fallback only runs when the feed list was non-empty then filtered away). The runner then keeps that explicit [] via preserveReasoningOptions, so hourly sync can permanently replace probed effort sets with empty controls and auto-merge them under REVIEWED_REASONING_PROVIDERS. Action: When the feed omits reasoning_options on a reasoner, preserve authored options or fail the model for manual review; only write [] when the feed explicitly publishes an empty control set. Cover omit-vs-empty in tests.

@github-actions github-actions Bot added the reviewer: ready Automated review found no actionable items label Sep 14, 2026
@islomjon-aiand
islomjon-aiand force-pushed the aia-683-aiand-sync-adapter branch from ec88eae to fc9e830 Compare September 14, 2026 05:41
@github-actions github-actions Bot removed the reviewer: ready Automated review found no actionable items label Sep 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Action items

  • [high] [violation] packages/core/src/sync/providers/aiand.ts:292 - Check: Lab/base_model files stay override-only; lab-owned fields are not restated from the gateway. Why: description is taken as model.description ?? existing?.description, so any feed description wins over both the lab entry and a hand-authored provider override. On the next hourly sync, factorBaseModel will write a provider-level description whenever the feed text differs from models/…, and it can erase a curated override. Action: Prefer curated/lab description (existing?.description first, or omit description entirely when base_model is set so the lab value inherits), matching how name / release_date are handled.
  • [high] [violation] packages/core/src/sync/providers/aiand.ts:173 - Check: Sync modules that claim near-identity with this repo’s api.json shape must accept the full catalog reasoning_options schema. Why: Local ReasoningOption only allows type = "effort". A feed entry with toggle or budget_tokens (valid catalog shapes) fails Zod parse for that model and aborts the whole AiandResponse parse, so the hourly job cannot sync. Action: Parse with the shared ReasoningOption from schema.ts (or an equivalent discriminated union), and map/preserve non-effort controls instead of requiring effort only.
  • [medium] [violation] packages/core/src/sync/providers/aiand.ts:306 - Check: Release dates are lab metadata; provider files must not invent overrides from the gateway. Why: For new feed IDs (existing === undefined) the adapter still sets release_date: model.release_date before factorBaseModel. If that date differs from models/<lab>/…, the first create writes a provider release_date override even though the PR/sync.md policy says the gateway is not authoritative for release dates. Action: When factoring with base_model, omit feed release_date (and other lab-owned fields) so new files inherit from the lab entry unless there is a real host-specific delta.

@islomjon-aiand
islomjon-aiand force-pushed the aia-683-aiand-sync-adapter branch from fc9e830 to d9e921d Compare September 14, 2026 06:04
@islomjon-aiand

Copy link
Copy Markdown
Contributor Author

All three addressed with one rule: on base-factored files, lab-owned fields (name, description, family, release_date, last_updated, knowledge, open_weights) are never asserted from the feed — they come from the curated file, so authored overrides survive and new files inherit the lab entry (a test covers a new create whose feed disagrees with the lab). Feed reasoning_options now accept the full catalog shape: toggle/budget_tokens parse via the shared schema and pass through, while effort values stay leniently parsed so unknown vocabulary filters per value instead of aborting the run.

@github-actions

Copy link
Copy Markdown
Contributor

No actionable findings.

@github-actions github-actions Bot added the reviewer: ready Automated review found no actionable items label Sep 14, 2026
fenilmodi00

This comment was marked as outdated.

fenilmodi00

This comment was marked as outdated.

@fenilmodi00 fenilmodi00 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebased this onto current dev for you: fenilmodi00/models.dev@dev...fenilmodi00:models.dev:pr-7040-rebased

Cherry-pick those commits onto your branch and the merge conflicts are gone. The rebase keeps all 11 [interleaved] blocks from #6839 (your adapter preserves them via existing?.interleaved), reruns the sync against the live feed, and refreshes the kimi-k3 and gpt-oss-120b headers with a 2026-09-14 live probe. bun validate and the aiand test suite pass on it.

@islomjon-aiand

Copy link
Copy Markdown
Contributor Author

Thanks for the rebase, Fenil — adopted your branch and rebased once more onto current dev (one trivial conflict: friendli in the direct group, kept both). Verified all 11 [interleaved] blocks survive. One correction on top: the regen against dev's motif-3 file preserved its stale inline lab fields (open_weights = false, release 08-12) as overrides against the new lab entry, so that file is now override-only and inherits from models/motif-technologies/motif-3.toml. Sync is a no-op against the live feed, validate green.

@islomjon-aiand
islomjon-aiand force-pushed the aia-683-aiand-sync-adapter branch from d9e921d to ee5249e Compare September 15, 2026 00:32
@github-actions github-actions Bot removed the reviewer: ready Automated review found no actionable items label Sep 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Action items

  • [medium] [violation] packages/core/src/sync/providers/aiand.ts:179 - Check: Feed-authoritative lifecycle status (absence = active; only curated alpha/beta survives omission). Why: status: model.status ?? existing?.status keeps a curated deprecated forever when the feed omits status, contradicting the adapter comment and sync.md (“Absence means active”; feed owns deprecated). Active routes can stay marked deprecated after the gateway clears them. Action: Preserve only non-deprecated curated statuses on omission (e.g. keep alpha/beta, clear deprecated when the feed has no status), matching the documented policy.
  • [low] [violation] packages/core/src/sync/providers/aiand.ts:116 - Check: skippedNotice must no-op on an empty skip list (peer adapters). Why: skippedNotice always returns a string, so every clean sync emits Skipped 0 feed model(s)… into the sync report/PR body. Action: Return [] when ids.length === 0, then format the notice only for real skips.

@islomjon-aiand

Copy link
Copy Markdown
Contributor Author

Both addressed: a curated deprecated is now cleared when the feed omits status (alpha/beta still survive — the feed owns deprecation, absence means active), and skippedNotice returns [] on a clean sync. Tests cover both.

@github-actions

Copy link
Copy Markdown
Contributor

Action items

  • [high] [violation] providers/aiand/models/ - Check: First-sync catalog corrections claimed in the PR must land in this change set. Why: The body says all 11 models get live-feed updates (including 2026-09-14 reasoning probes and rewritten stale headers; e.g. qwen3.8-27b high→xhigh substitution note). The diff only updates motif-3, kimi-k2.7-code, kimi-k3, and a probe comment on gpt-oss-120b. The other eight TOMLs stay on older headers/values (e.g. qwen3.8-27b.toml still cites the 2026-08-29 probe and does not document the substitution quirk). Action: Re-run bun aiand:sync (or hand-apply the feed) so every providers/aiand/models/**/*.toml matches the claimed feed/probe state, including headers.
  • [high] [violation] packages/core/src/sync/providers/aiand.ts:322 - Check: Near-identity api.json adapters must publish provider-only interleaved from the feed (see wandb.ts). Why: AiandModel never parses interleaved, and buildAiandModel only keeps existing?.interleaved. Every current aiand reasoner uses reasoning_content; a new feed reasoner with no local file will omit the side channel even when the feed publishes it, so automation creates incomplete reasoners. Action: Parse feed interleaved (same catalog shapes as the schema) and set interleaved from the feed with a safe existing fallback; cover create + update in aiand.test.ts.
  • [medium] [violation] packages/core/src/sync/providers/aiand.ts:255 - Check: Skips that need lab metadata should use missingModelID so the runner preserves locals and opens missing-model issues (sync.md). Why: Unresolvable new IDs only hit sourceID + skippedNotice. They are treated as absent (delete risk for any future path mismatch) and never enter the missing-model issue flow that Friendli-style multi-lab factoring uses. Action: Return the skipped ID from missingModelID when the skip is “no lab base yet,” keep intentional skips at undefined, and document the issue behavior in the ai& sync.md notes.

@islomjon-aiand

Copy link
Copy Markdown
Contributor Author

All three addressed. The PR body now describes the rebased change set honestly — dev's #6839 already landed cache_read, the enforced levels, and the interleaved blocks, so the sync is a no-op on 8 of 11 files (that's the parity proof); the diff's real content is the motif lab file + factoring, the two Kimi temperature = true deltas, and header refreshes, with qwen3.8 now recording the announced high → xhigh substitution from today's probe. The adapter parses interleaved from the feed with an authored fallback and a gateway default of message.reasoning_content for reasoners, so a new reasoner is never created without its side channel. Skipped new ids go through missingModelID so the runner preserves local entries and opens deduped missing-model issues.

@github-actions

Copy link
Copy Markdown
Contributor

Action items

  • [high] [violation] packages/core/src/sync/providers/aiand.ts:243 - Check: Override-only base_model files must keep only provider-specific fields and real deltas (AGENTS.md → Override-only provider files). Why: translateModel / buildAiandModel use context.existing() (base-resolved merge) for “curated” name, description, release_date, last_updated, knowledge, and open_weights. On a first factor of a full-inline local file, those lab values look authored, so factorBaseModel can re-emit identical lab fields as provider overrides (or pin wrong host values). Patch 2 already did this for Motif 3 (open_weights = false, stale dates); Patch 4 only cleaned that one file. Action: Resolve base_model / omit / lab-owned curated fields from context.authored(), and only treat values present on the authored TOML as overrides; add a regression test that factors a full-inline existing Motif-like file onto a lab entry with no redundant lab fields.
  • [medium] [violation] providers/aiand/models/motif-technologies/motif-3.toml:1 - Check: Non-lab hosts must use complete lab metadata + override-only provider entries; first sync corrections claimed in the PR must land in the branch. Why: Final Motif provider state still omits required host fields that only exist on the new lab file in this PR (base_model, corrected open_weights, tool/temperature inheritance), while the PR body says the first sync includes Motif factoring and open-weights correction. Base checkout still has the full-inline Motif entry; the Motif lab file exists only in the diff. Action: Ship the final Motif provider TOML as override-only (base_model = "motif-technologies/motif-3" plus cost / reasoning_options / interleaved only) and ensure the lab entry is present so validation resolves the merge.
  • [medium] [possible mistake] packages/core/src/sync/providers/aiand.ts:242 - Check: Sync modules must preserve hand-authored provider overrides and not expand factored files (sync.md → Provider Modules / Runner Responsibilities). Why: Passing the resolved model into factoring also treats inherited lab limit.input, modalities, and capability flags as if they were local overrides when deciding omit/keep behavior, so later feed churn can rewrite files differently than peers that separate authored vs existing (e.g. Friendli, Baseten, Cortecs). Action: Mirror the authored/existing split used by those adapters for omit lists and non-feed fields; cover with a test that an existing factored file keeps only feed deltas after sync.
  • [low] [possible mistake] .pr-review/pull-request.json:4 - Check: Data-changing PRs should cite first-party pricing/docs/API evidence mapped to claims. Why: The body asserts catalog-wide cache_read fills, gateway-enforced reasoning sets, and Motif open-weights/date facts from live probes and HF, but the truncated body and most provider TOMLs still point at older /v1/models headers; only some files get 2026-09-14 probe notes. Action: Map each material claim to a concrete source (api.json path, probe date, HF) in the PR body and align leading TOML headers after the authoritative sync write.

@github-actions github-actions Bot added the reviewer: ready Automated review found no actionable items label Sep 15, 2026
@islomjon-aiand

Copy link
Copy Markdown
Contributor Author

Clean pass this time. Overrides now come from the authored TOML, not the base-resolved merge — that was the root cause behind the last few rounds. Lab fields on factored files only appear as deltas the file already had on its base_model, so a full-inline file factored for the first time inherits the lab entry (regression test added). All 11 headers cite the 2026-09-14 probe matrix, and the PR body has an evidence table mapping each claim to its source.

@github-actions github-actions Bot removed the reviewer: ready Automated review found no actionable items label Sep 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

No actionable findings.

@github-actions github-actions Bot added the reviewer: ready Automated review found no actionable items label Sep 15, 2026
@islomjon-aiand

Copy link
Copy Markdown
Contributor Author

@fenilmodi00 branch is final — rebased on current dev, review bot clean, validate green, merge state clean. Ready when you are.

@fenilmodi00

fenilmodi00 commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Looks good to me. @rekram1-node — this is ready for a final review when you get a chance; you merged my earlier ai& PRs (#6839, #5806).

islomjon-aiand and others added 7 commits September 15, 2026 13:36
…amily

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Rerun of the ai& sync after cherry-picking onto current dev.
Interleaved reasoning_content blocks from anomalyco#6839 are preserved by the
adapter (existing?.interleaved); motif-3 factors onto the new lab entry.
Live reasoning_effort probes on 2026-09-14 (negative controls included)
confirm the authored effort sets are unchanged on the gateway.
The rebased regen kept dev's stale inline lab fields (open_weights = false,
release_date 2026-08-12) as overrides against the new lab file. Lab facts now
inherit from models/motif-technologies/motif-3.toml; the [interleaved] block
from anomalyco#6839 is preserved.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…notice

The feed owns deprecation and absence means active, so a curated deprecated
no longer survives a feed that omits status (alpha/beta still do). A clean
sync no longer emits a zero-count skip notice into the report.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… skips to missing-model issues

Parse the feed's interleaved (authored fallback, gateway default of
message.reasoning_content for reasoners) so a new reasoner is never created
without its side channel; return skipped ids from missingModelID so the runner
preserves local entries and opens deduped issues. qwen3.8 header records the
2026-09-14 probe including the announced high→xhigh substitution.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…s to the 2026-09-14 probes

Lab-owned fields on factored files come only from deltas the authored file
already carried on its base_model (context.authored, never the base-resolved
merge), so a full-inline file factored for the first time inherits the lab
entry instead of re-emitting stale values as overrides — the Motif regression
in general form. Host fields stay feed-authoritative. All 11 headers now cite
the 2026-09-14 probe matrix (11 models x 7 effort values).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@islomjon-aiand
islomjon-aiand force-pushed the aia-683-aiand-sync-adapter branch from e92feb1 to f454a50 Compare September 15, 2026 04:36
@github-actions github-actions Bot removed the reviewer: ready Automated review found no actionable items label Sep 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Action items

  • [high] [violation] packages/core/src/sync/providers/aiand.ts:218 - Check: Override-only base_model files must not restate lab fields identical to the base (AGENTS.md → Override-only provider files); peers that factor and omit matching descriptions set preserveDescriptions: false (e.g. Friendli). Why: buildAiandModel correctly omits lab-owned description on first factor / inherit, but the runner still runs default preserveDescription, which re-injects the pre-factor authored description whenever the translator leaves it unset. That recreates a redundant description override (the Motif-style regression patch 7 tried to fix) on the next bun models:sync aiand for any full-inline → factored transition. Action: Set preserveDescriptions: false on the aiand provider (and cover first-factor with a runner-level or integration expectation that the written TOML stays free of a lab-identical description).
  • [medium] [violation] packages/core/src/sync/providers/aiand.ts:242 - Check: Every toggle reasoning control needs a leading top-of-file wire-path comment (AGENTS.md → Reasoning options / Toggle); sync creates must supply header when no on-disk header exists. Why: The feed can publish { type = "toggle" } and the adapter passes it through, but translateModel never returns header. New auto-created reasoners with toggle (provider is on the auto-merge allowlist) would be written without the required Toggle wire comment. Peers (OpenRouter, Friendli, LLM Gateway, Merge Gateway) emit toggle headers from translateModel. Action: When built reasoning_options include toggle, return a leading header documenting the exact ai& wire path (and add a unit test for that create path).

…d created files with a reasoning-wire header

preserveDescriptions is off so a full-inline → factored transition cannot
recreate a lab-identical description override (runner-level test covers the
Motif shape end to end). translateModel now returns a leading header for
creates naming the reasoning wire path, so a toggle control is never written
without it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Action items

  • [high] [violation] packages/core/src/sync/providers/aiand.ts - Check: Relay adapters must not invent reasoning_options = [] (no caller control) from uncertainty, and auto-merge allowlisting must not land incomplete reasoner controls without review (AGENTS.md Reasoning options; preserveReasoningOptions + REVIEWED_REASONING_PROVIDERS). Why: For reasoning = true, omitted feed reasoning_options (or a non-empty effort list that filters to nothing) makes resolveReasoningOptions return undefined. Lab metadata never carries reasoning_options, so the runner’s preserveReasoningOptions stamps [] on creates/updates with no authored options. With aiand on the auto-merge allowlist, that “no control” shape can merge hourly without review even though the module treats the feed as authoritative for gateway effort sets. Action: When the feed marks a model as reasoning but does not yield a schema-valid non-empty control set (and there is no authored set to keep), fail that model with MissingReasoningOptionsError (or equivalent skip that preserves locals and does not write []). Do not allowlist auto-merge until incomplete feed rows cannot become [].

…g [] be written

A reasoner whose feed yields no schema-valid reasoning_options and has no
authored set to keep now throws MissingReasoningOptionsError: the runner
preserves the local file, reports the reason, and routes the id to the
missing-model issue flow. An explicit [] from the feed remains the feed's own
assertion. Runner-level test covers the untouched-file path.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Action items

  • [high] [violation] packages/core/src/sync/providers/aiand.ts:420 - Check: AGENTS.md Reasoning options — never invent budget_tokens unless this host has a real reasoning-budget wire field. Why: resolveReasoningOptions passes budget_tokens through unchanged after Zod accepts the catalog shape. The create header even states ai& has no token-budget control, yet a feed that publishes budget_tokens (or stale authored budget on update) would still write it into provider TOMLs and, once allowlisted, auto-merge as a false control surface. Action: Drop feed/authored budget_tokens (or fail with MissingReasoningOptionsError when that would empty the control set), and stop emitting a budget wire comment that contradicts host capability.
  • [high] [violation] packages/core/src/sync/providers/aiand.ts:427 - Check: AGENTS.md / audit-reasoning-options — do not pair toggle with effort that already includes none; off is effort=none only. Why: Non-effort options are returned as-is. A feed row of toggle + effort values containing none (or toggle alone when off is the same reasoning_effort field) would be written and auto-merged. The seeded header text (Toggle: reasoning_effort = "none" (off) vs the graded levels) encodes that invalid shape instead of collapsing to effort-with-none. Action: Normalize like Eden AI / LLM Gateway peers: if effort includes none, strip toggle; if the only off control is reasoning_effort=none, author effort values (including none) and never a separate toggle; keep toggle only for a true separate on/off wire path.

…reasoning wire path

reasoning_effort ("none" = off) is the only control this host exposes, so
toggle and budget_tokens are parsed for tolerance but dropped from feed and
authored options alike; an emptied set falls through to the existing
fail-for-review path. The create header states the single wire path instead
of describing controls the host does not have.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

No actionable findings.

@github-actions github-actions Bot added the reviewer: ready Automated review found no actionable items label Sep 15, 2026
@rekram1-node
rekram1-node merged commit 71c3858 into anomalyco:dev Sep 17, 2026
2 checks passed
0genlab pushed a commit to 0genlab/models.dev that referenced this pull request Sep 18, 2026
Resolves the only conflict, in packages/core/src/sync/index.ts: dev added
the `aiand` provider (anomalyco#7040) at the head of the alphabetical registry while
this branch added `aihubmix` in the same position. Both are kept, ordered
`aiand` then `aihubmix`, across all three sites (import, the providers type,
the providers object). No logic is involved — it is an insertion-order
conflict.

Checked the parts that merged cleanly but could still drift: `groups` is new
on dev, and `aihubmix` is in `aggregators` where a gateway belongs, not in
`direct`. sync.test.ts and sync.md merged without conflict.

Tests on the merge result: 232 pass / 3 fail. The same 3 fail on a clean
origin/dev checkout (Hyper reasoning inheritance, DeepInfra live modalities,
LLM Gateway case variant), as do the tsc errors in sync.test.ts, so both are
pre-existing on dev and not introduced here. Base has 194 pass / 3 fail, so
this branch adds 38 passing tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

reviewer: ready Automated review found no actionable items

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants