You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Replaces the standalone packages/core/script/generate-friendli.ts generator with a SyncProvider at packages/core/src/sync/providers/friendli.ts, wired into bun models:sync friendli (registered in providers and groups.direct in packages/core/src/sync/index.ts).
Source: https://api.friendli.ai/serverless/v1/models (no auth required).
[high] [violation]packages/core/src/sync/providers/friendli.ts:471 - Check: Provider sync must not invent false non-reasoning overrides for lab reasoners. Why:const reasoning = model.reasoning === true treats a missing API reasoning field as false. That value is passed into factorBaseModel, so an omitted flag becomes an explicit reasoning = false override, and preserveReasoningOptions then strips reasoning_options. Hourly sync can mark real reasoners as non-reasoning whenever Friendli omits the field. Action: Treat API reasoning as tri-state: true/false only when present; when absent, leave reasoning unset on factored entries so lab metadata wins (and keep existing authored reasoning for full-inline updates).
[medium] [violation]packages/core/src/sync/providers/friendli.ts:480 - Check: Factored Friendli models must surface host-authoritative capability deltas, including tool_call. Why: The full-inline path sets tool_call from model.functionality.tool_call, but the factorBaseModel override object omits it entirely. If Friendli disables tools for a lab model that has tool_call = true (or the reverse), the catalog keeps the lab value and misreports the Friendli surface. Action: Pass tool_call: model.functionality.tool_call into the factored overrides (same as structured_output), so only real deltas are written.
[medium] [possible mistake]providers/friendli/models/MiniMaxAI/MiniMax-M2.5.toml:9 - Check:budget_tokens only when this host exposes a real reasoning-budget control for that model. Why: This PR replaces lab/peer reasoning_options = [] (MiniMax first-party and other hosts) with unbounded budget_tokens. The PR body live-verifies reasoning_budget on GLM-5.3, gemma-4-31B-it, and DeepSeek-V3.2, not MiniMax-M2.5. If the catalog advertises budget incorrectly for MiniMax, clients get a fake control. Action: Confirm with a Friendli request on MiniMaxAI/MiniMax-M2.5 that reasoning_budget actually caps reasoning_content; if not, keep [] (or the real control set) instead of authoring budget_tokens.
Follow-up in 1fca2b7, rebalancing toward the repo's conventions per maintainer direction:
budget_tokens dropped everywhere.translateReasoningOptions now filters budget_tokens out (the zod schema still validates the raw shape). MiniMax-M2.5, whose only catalog control was budget, publishes reasoning_options = [] per the established always-on convention (Venice precedent). All 7 TOMLs hand-adjusted to match; bun models:sync friendli --dry-run now reports 0 created / 0 updated / 0 removed / 7 unchanged against the committed files, so the module and the authored files agree byte-for-byte.
Catalog removals are now authoritative.deleteMissing: true: a model absent from GET /serverless/v1/models — or past its deprecation_date — is deleted from this catalog on the next sync (translateModel skips it, the runner removes the file). A deprecation_date in the API is treated as equivalent to the model disappearing from the catalog. skippedNotice/missingNotice updated accordingly.
[high] [violation]packages/core/src/sync/providers/friendli.ts (translateReasoningOptions) - Check:reasoning_options must reflect this host’s real caller controls; [] means no control, and budget_tokens is allowed when the host exposes a real reasoning-token budget (AGENTS.md → Reasoning options; audit skill budget rules). Why: Patch 3 drops every budget_tokens entry even though the same PR documents a live-verified Friendli reasoning_budget field (GLM-5.3, gemma-4-31B-it, DeepSeek-V3.2, MiniMax-M2.5) and providers/friendli/provider.toml still lists it. That is not “always-on / no control.” For MiniMax-M2.5 the only remaining control becomes reasoning_options = [], which falsely claims no caller control. Other peers (OpenRouter, Requesty, Merge Gateway, etc.) do publish budget_tokens when the host supports it; there is no repo rule that openai-compatible relays may only emit toggle/effort. Action: Keep budget_tokens whenever the Friendli catalog reports it (bounds optional/omitted is fine if min/max are unsafe). Restore budget_tokens on models that expose it, restore the Budget wire-path header for those files, and do not author [] for MiniMax while reasoning_budget is a real control.
[low] [possible mistake]providers/friendli/models/zai-org/GLM-5.3.toml - Check: Material pricing changes should be backed by a mapped first-party citation in the PR body. Why: Input/output/cache_read move from 1.4 / 4.4 / 0.26 to 1.26 / 3.96 / 0.234 with no PR-body note of what source supports the new rates. Action: Cite the Friendli pricing/docs/API field that yields these USD/MTok values (and the per-token→per-million conversion if that is how they are derived).
[high] budget_tokens restored, unbounded. You are right — dropping a live-verified control while provider.toml documents it was a false narrowing, and MiniMax-M2.5's [] would claim no caller control on a host that does expose reasoning_budget. translateReasoningOptions again emits { type = budget_tokens } (never min/max — GLM-5.3 accepted reasoning_budget=1_048_577 above its reported max), the Budget wire-path header is restored, and the module comment records the live verification (budget=10 truncated MiniMax reasoning at ~46 chars mid-sentence while completion_tokens continued to a full 2051-token answer; budget=2000 produced 1011 chars of reasoning under the identical prompt). bun models:sync friendli regenerated all 7 files; second dry-run is clean (0/0/0, 7 unchanged).
[low] GLM-5.3 pricing citation. The 1.26/3.96/0.234 USD/MTok rates are Friendli's live catalog: GET /serverless/v1/models → pricing per-token USD strings 0.00000126/0.00000396/0.000000234 × 1e6 (accessed 2026-09-13). The old 1.4/4.4/0.26 were stale hand-authored values from feat(friendli): add GLM-5.3 provider model #5776; the sync now prices every model from the live catalog. Added a 'Pricing source' section to the PR body.
[high] [violation]packages/core/src/sync/providers/friendli.ts:796 - Check: Authoritative deleteMissing syncs must not wipe the catalog on an empty/faulty upstream response. Why: Final deleteMissing: true (default-on) plus parseModels returning FriendliResponse.parse(raw).data with no non-empty guard means a transient empty/partial GET /serverless/v1/models body produces zero desired models and deletes every local Friendli TOML. Peers that delete (e.g. LLM Gateway, Cloudflare AI Gateway) fail closed on empty catalogs for this reason. Action: Reject empty (and, if appropriate, suspiciously shrunken) parsed catalogs before translate/delete, or keep deleteMissing: false until that guard exists.
[medium] [violation]packages/core/src/sync/providers/friendli.ts:1055 - Check: Sync must preserve base_model on updates when the lab target is temporarily unresolvable (sync.md / deepinfra-style factoring). Why: Creates skip only when existing === undefined && factorBase === undefined. For an already-tracked factored file, if resolveLabModelSync returns undefined (lab file missing, case/map miss, models/ read failure), buildFriendliModel takes the full-inline path and preserveBaseModels: false does not restore the on-disk base_model, so the next sync can expand override-only files into full copies and drop inheritance. Action: On updates, prefer existing.base_model when lab resolution fails (deepinfra pattern), or only full-inline when there was never a base; do not unfactor stable base_model entries.
[medium] [violation]packages/core/src/sync/providers/friendli.ts:962 - Check: Authored reasoning_options effort values must be schema-valid (none|minimal|low|medium|high|xhigh|max|default). Why:translateReasoningOptions pushes API effort objects via as with values: z.array(z.string()). Friendli’s own docs list values outside the catalog enum (e.g. ultracode). One invalid value fails SyncedAuthoredModel parse and aborts the whole Friendli sync job. Action: Filter effort values to the schema set (drop/skip unknown); if nothing remains after filter, handle explicitly rather than casting through.
[low] [possible mistake]providers/friendli/models/zai-org/GLM-5.3.toml:1367 - Check: Material cost changes should be supported by a direct, claim-mapped source in the PR body. Why: Input/output/cache_read move from 1.4 / 4.4 / 0.26 to 1.26 / 3.96 / 0.234 while the PR body only names the models endpoint generally, so the delta cannot be reviewed against a stated price field or doc section. Action: In the PR body, cite the exact pricing source (API field or docs) and map it to these USD/MTok figures (including the ×1e6 conversion if prices are per-token).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces the standalone
packages/core/script/generate-friendli.tsgenerator with aSyncProvideratpackages/core/src/sync/providers/friendli.ts, wired intobun models:sync friendli(registered inprovidersandgroups.directinpackages/core/src/sync/index.ts).Source:
https://api.friendli.ai/serverless/v1/models(no auth required).