Commit Graph
351 Commits
Author SHA1 Message Date
can1357 ffab5689a0 Merge PR #5497: fix(catalog): prune unsupported Codex account models (@roboomp)
# Conflicts:
#	packages/catalog/src/discovery/codex.ts
#	packages/catalog/src/models.json
#	packages/catalog/test/codex-discovery.test.ts
2026-07-18 21:02:46 +02:00
can1357 401fca701b Merge PR #5448: fix(coding-agent): rescue snapcompact dead-end when nothing is summarizable (@roboomp) 2026-07-18 21:01:41 +02:00
can1357 157e940d5e Merge PR #5786: fix(auth): scoped post-login model refresh and stripped cache credentials (@roboomp)
# Conflicts:
#	packages/catalog/src/model-cache.ts
2026-07-18 20:14:11 +02:00
can1357 1acda6c1e6 style: formatted merge resolutions with biome 2026-07-18 19:58:59 +02:00
can1357 c2b241401b Merge PR #5919: fix(providers): sanitize boolean subschemas for grammar backends (@roboomp)
# Conflicts:
#	packages/catalog/src/compat/openai.ts
#	packages/catalog/src/types.ts
2026-07-18 19:58:22 +02:00
can1357 5c9b5f7b64 Merge PR #5890: fix(ai): allow custom OAuth fingerprint header overrides (@roboomp) 2026-07-18 19:57:45 +02:00
roboomp cc9fba7513 fix(catalog): normalized kimi k3 reasoning efforts
- Derived the mandatory low, high, and max ladder for Kimi K3 across OpenAI-compatible routes.
- Mapped generic requested tiers onto K3 wire values and defaulted the model to max.
- Added request-level regression coverage for LiteLLM-compatible models.

Fixes #5983
2026-07-18 11:36:38 +00:00
can1357 f60c7791c1 fix(catalog): used Moonshot MFJS schema for Kimi models on all hosts
- Enable `moonshot-mfjs` tool schema flavor for Kimi-family ids on any host, not just native endpoints, since proxies forward schemas verbatim to Moonshot's validator.
2026-07-18 06:27:36 +02:00
roboomp b468f3a7af docs(catalog): correct grammar flavor additionalProperties contract
The grammar tool-schema flavor preserves boolean additionalProperties/unevaluatedProperties rather than stripping them; the doc comment wrongly promised the Ollama-style strip.
2026-07-17 22:39:45 +00:00
roboomp 2eb35e300f fix(providers): sanitize boolean subschemas for grammar backends
Local grammar-constrained OpenAI-compatible servers (llama.cpp, LM Studio,
vLLM) build a GBNF grammar from tool JSON Schemas and 400 with
"Unrecognized schema: true" on a bare boolean subschema. The task tool's
open outputSchema field normalizes to boolean `true` (issue #1179), which
the converter cannot compile, breaking every tool request.

Add a "grammar" tool-schema flavor, auto-detected for local backends, that
widens bare boolean/empty subschemas into a value-accepting primitive union
while preserving closed-object `additionalProperties: false`.

Fixes #5914
2026-07-17 22:35:44 +00:00
can1357 3848a37f9a Merge PR #5820: fix(catalog): read litellm per-model cost from rich metadata (@roboomp) 2026-07-17 21:22:31 +02:00
can1357 8577371187 Merge PR #5896: fix(kimi-code): preserve K3 native effort contract (@roboomp) 2026-07-17 21:22:08 +02:00
roboomp 913ec0baae fix(kimi-code): preserved k3 native effort contract
- Parsed live named efforts, mandatory-thinking state, and model protocol metadata.

- Sent native Kimi named efforts and adaptive Anthropic override efforts without generic token budgets.

Fixes #5893
2026-07-17 18:19:00 +00:00
roboomp 67ca037b17 fix(ai): allowed custom oauth fingerprint headers
Added an opt-in compatibility flag for non-official Anthropic OAuth endpoints while preserving authoritative OAuth and Cloudflare credentials.

Fixes #5888
2026-07-17 17:44:47 +00:00
roboomp 40ea23181a fix(catalog): bumped litellm rich cache version
Invalidated rich-v4 rows so upgraded clients immediately refresh models with corrected per-model pricing instead of serving stale zero-cost entries until TTL expiry.
2026-07-17 09:01:13 +00:00
roboomp 29fc224509 fix(catalog): read litellm per-model cost from rich metadata
mapLiteLLMRichEntry read token limits and capabilities from LiteLLM's
rich model_info but hardcoded cost to the bundled reference or a zero
sentinel, so any model absent from the bundled catalog / models.dev
displayed as free even when LiteLLM reported real pricing.

Read input_cost_per_token / output_cost_per_token (and cache costs) via
getLiteLLMCost, converting per-token to per-million, and carry cost
through the cross-endpoint merge in fetchLiteLLMRichModels. Fall back to
the bundled reference only when LiteLLM omits cost.

Fixes #5818
2026-07-17 08:55:41 +00:00
roboomp bab156183e fix(catalog): suppressed LiteLLM fallback warning on retryable 401
Skipped recording 401 rich-endpoint failures as fallback diagnostics so the caller's auth-retry path (withAuth refresh/sibling rotation) is not pre-empted by a warning from a stale first credential.

Kept 403 and other non-retryable failures warn-worthy.

Fixes #5801
2026-07-17 07:46:40 +00:00
roboomp 63cac8dfd5 fix(catalog): warned on LiteLLM metadata fallback
Logged one actionable warning per LiteLLM management base when rich metadata discovery fails, while keeping missing 404 routes silent.

Documented metadata-route permissions and covered forbidden versus absent endpoints.

Fixes #5801
2026-07-17 07:38:06 +00:00
can1357 c71aa775e0 fix(catalog): restored regenerated models.json with behavior-level tests
Reinstates the catalog regeneration (glm-4.5 reasoning/effort metadata,
refreshed pricing and limits) that the previous commit wrongly rolled
back. The three failing tests were pinned to stale upstream metadata;
they now assert the durable contracts instead: K2.7-Code stays above
the 32,768 K2-family cap and tracks the bundled reference, and K3
asserts effort-mode metadata while the wire-body test remains the
binding reasoning_effort=max contract.
2026-07-17 06:22:44 +02:00
can1357 5394081390 fix(catalog): restored bundled models.json to the tested snapshot
A stale regenerated models.json rode the previous commit from the
shared index; it contradicted the Fireworks K2.7-Code output-ceiling
and Moonshot K3 reasoning contracts (#1849, #5756). Restored the
snapshot those tests verify; a deliberate catalog refresh should
reconcile the K3/K2.7 policies first.
2026-07-17 06:13:22 +02:00
can1357 731a2cb5b2 test(natives): gave timeout drain repro a spawn-proof deadline
The 50ms budget raced external-process spawn on cold CI runners: cancel
could fire before yes produced output, so the builtin tail flushed an
empty ring buffer (0 lines instead of 5, Linux x64 modern). 750ms keeps
the post-cancel drain scenario while outlasting spawn latency.
2026-07-17 06:09:51 +02:00
roboomp cc688c6b5c fix(catalog): restored headers omitted from model cache
Recorded which cached model ids had headers omitted and which header sets cannot be reconstructed from current static inputs.

Fresh/offline cache reads now restore exact static headers before returning models. Dynamic-only or dynamically-augmented header models bypass fresh-cache reuse and refetch online; offline and failure fallbacks omit them instead of returning unusable models without required transport headers.

Bumped the cache schema to v10 and added static, dynamic, offline, and raw-persistence regressions.

Fixes #5780
2026-07-17 03:27:12 +00:00
roboomp 3ab9ef29c1 fix(catalog): omitted all headers from model cache
Replaced the incomplete credential-header denylist with a default-deny cache boundary: no model header values are persisted because custom providers may use arbitrary authentication header names.

Bumped the cache schema to v9 and enabled SQLite secure_delete so older header-bearing rows are invalidated without leaving credential bytes in free pages. Added coverage for X-Goog-Api-Key, X-Access-Token, arbitrary headers, and physical scrubbing of pre-v9 cache rows.

Fixes #5780
2026-07-17 03:12:28 +00:00
roboomp c654abc980 fix(auth): scoped post-login model refresh and stripped cache credentials
Native /login and /logout (plus setup-wizard sign-in and RPC login)
refreshed model discovery with the default all-provider
online-if-uncached strategy, which reused a fresh authoritative cache row
and never re-ran fetchDynamicModels with the just-persisted credential,
so newly authenticated models stayed unavailable in-session and stale
endpoint data survived a relogin. Each auth-completion path now awaits a
provider-scoped refreshProvider(providerId, "online").

Also fixed writeModelCache serializing credential-bearing request headers
(Authorization, X-Api-Key, api-key, cookie, proxy-authorization) into the
plaintext models.db; they are now stripped before persistence and
re-derived on load from AuthStorage / provider config.

Fixes #5780
2026-07-17 03:03:25 +00:00
can1357 34cd2df096 merge PR #5758 via eval/pr-5758: fix(ai): honored kimi-k3 131k output limit 2026-07-17 04:40:05 +02:00
can1357 f2959f255e merge PR #5735 via eval/pr-5735: fix(catalog): sourced Umans PAYG model pricing 2026-07-17 04:40:04 +02:00
can1357 dace1ca535 merge PR #5707 via eval/pr-5707: fix(catalog): pinned gpt-5.6 codex discovery fallback to 372k 2026-07-17 04:39:15 +02:00
can1357 6e0b9d34f2 feat(catalog): increased maxTokens to 65,536 for Kimi K2.7-Code models on Fireworks
- Updated models.json to set maxTokens to 65536 for Kimi K2.7-Code entries.
- Adjusted openai-compat logic to use a new 65,536 ceiling for K2.7-Code while preserving the 32,768 cap for older K2 models.
- Modified tests to verify the new token limit and ensure K2.7-Code models are excluded from the older cap.
2026-07-17 03:49:38 +02:00
roboomp fdb5d8bd0e fix(catalog): kept kimi-k3 reasoning on forced tool choices
Native Kimi K3 always reasons via reasoning_effort: "max" and is newly marked
requiresEffort. The Kimi-family disableReasoningOnForcedToolChoice rule (added
for the K2.x Moonshot 400 "tool_choice 'specified' is incompatible with
thinking enabled", #827) applies only to the binary thinking block K3 never
sends, so it wrongly stripped K3's effort on forced-tool turns — e.g. plan-mode
toolChoice: "required" — leaving mandatory reasoning off on the wire.

- Exempted native K3 from disableReasoningOnForcedToolChoice.
- Added a regression test asserting reasoning_effort=max survives a forced
  tool_choice turn while no thinking block is emitted.

Fixes #5756
2026-07-16 21:44:03 +00:00
roboomp c98b1b83d3 fix(catalog): corrected moonshot kimi-k3 pricing and reasoning transport
Native moonshot/kimi-k3 is dynamically discovered but has no bundled or
models.dev reference, so mapWithBundledReference fell through to the generic
dynamic defaults: zero token cost, null limits, text-only input, and no
reasoning. /models then labeled the paid model "Free".

- Added isKimiK3ModelId identity helper for any-namespace K3 ids.
- Stamped Moonshot's official K3 pricing ($3 input / $0.30 cache-hit / $15
  output), 1,048,576-token context, 131,072 default max output, image input,
  and always-on reasoning in the moonshot discovery mapper.
- Routed native K3 reasoning through OpenAI-style reasoning_effort: "max"
  instead of the K2.x binary thinking: { type } block, which K3 does not use.
- Widened the 300s reasoning stream-idle floor to cover native K3.

Fixes #5756
2026-07-16 21:35:50 +00:00
roboomp 0becfbe197 fix(catalog): sourced Umans PAYG model pricing
- Repointed the Umans models.dev descriptor to published PAYG rates.
- Backfilled authoritative discovery rows and the Flash technical alias.
- Added runtime, descriptor, and bundled catalog regression coverage.

Fixes #5733
2026-07-16 17:39:22 +00:00
roboomp 1945734b42 fix(catalog): pinned gpt-5.6 codex discovery fallback to 372k
The generation-time policy pin only corrected the bundled JSON. Logged-in
Codex users hit fetchCodexModels() at runtime, and mergeDynamicModel prefers
any positive dynamic contextWindow over the bundled one, so the 272000
discovery fallback re-overwrote the 372000 bundle on every live refresh.

Made the Codex discovery context_window fallback SKU-aware: GPT-5.6
luna/sol/terra now fall back to 372000 (their upstream hard capacity) when
upstream omits the field, matching the generation-time policy.

Fixes #5705
2026-07-16 13:46:45 +00:00
roboomp 62c164d256 fix(catalog): pinned gpt-5.6 codex context window to 372k
Codex discovery falls back to DEFAULT_CONTEXT_WINDOW (272000) when upstream
omits context_window, which overwrote the previously-bundled 372000 hard
capacity for openai-codex gpt-5.6 luna/sol/terra on regen. OpenAI's Codex
model registry declares context_window = max_context_window = 372000, and a
direct Responses request with 350,317 input tokens completes, proving 272K is
not the route's hard cap.

Pinned these SKUs to 372000 in applyOpenAICatalogPolicy and refreshed the
bundled entries.

Fixes #5705
2026-07-16 13:39:04 +00:00
can1357 b68c7245f7 merged PR #5408: fix(catalog): widen GLM coding-plan idle timeout to OpenCode gateways 2026-07-16 03:32:04 +02:00
can1357 b865e6a4d7 fix(catalog): scope Kimi K2.7 timeout to Moonshot 2026-07-16 03:32:02 +02:00
can1357 9c78b7e7b0 merged PR #5428: fix(catalog): extend streamIdleTimeoutMs floor to Kimi K2.7 Code 2026-07-16 03:32:02 +02:00
can1357 d7241e572f fix(catalog): invalidate stale MAI Code routes 2026-07-16 03:31:58 +02:00
can1357 51b7601fc5 merged PR #5613: fix(catalog): route Copilot mai-code models to the /responses endpoint 2026-07-16 03:31:58 +02:00
can1357 ee7a6eb01b merged PR #5608: fix(ai): omit sampling params for OpenAI reasoning models 2026-07-16 03:31:57 +02:00
can1357 6783c3a473 merged PR #5573: fix: disable eager tool streaming for custom Anthropic endpoints 2026-07-16 03:31:57 +02:00
can1357 8ab29822b2 merged PR #5603: fix(catalog): sourced zai GLM pricing from PAYG models.dev key 2026-07-16 03:31:55 +02:00
can1357 03c48d073b fix: fixed OpenRouter usage reconciliation and updated model catalog entries
- Applied `applyOpenRouterReportedCost` in completion parsing and shared usage population so reported OpenRouter charges are now reconciled before tier adjustment.
- Scaled usage component costs by the reported-to-estimated ratio and retained an input-only fallback when estimated totals were missing.
- Added OpenRouter-specific usage tests for SSE responses and chunk parsing to assert done-message totals and component sums match reported cost.
- Updated the model catalog with new provider/model records and revised costs, limits, and metadata.
2026-07-16 02:58:30 +02:00
roboomp 4d89b29028 fix(catalog): routed copilot mai-code models to responses api
GitHub Copilot's mai-code-1-flash-picker (and other mai-* models) are
served only through the /responses endpoint; the classifier routed them
to /chat/completions, which returned 400 unsupported_api_for_model.

Added the mai- prefix to isCopilotResponsesModelId so both dynamic
discovery (inferCopilotApi) and bundled resolution
(COPILOT_API_RESOLUTION_RULES) select openai-responses, and updated the
bundled models.json entry to match.

Fixes #5612
2026-07-15 20:13:11 +00:00
roboomp f6de373506 fix(ai): omitted unsupported reasoning sampling params
- Added resolved sampling-parameter compatibility for OpenAI o-series and GPT-5+ models.
- Stopped Responses and Chat Completions payloads from forwarding temperature and related controls to restricted models.
- Added catalog and wire-payload regressions for GitHub Copilot GPT-5.6 Luna.

Fixes #5606
2026-07-15 19:30:53 +00:00
roboomp fdf79caf20 fix(catalog): sourced zai GLM pricing from PAYG models.dev key
The `zai` provider descriptor mapped the models.dev `zai-coding-plan`
key, which reports all-$0 subscription rates, so 13 of 14 GLM SKUs
showed token cost as "Free" in /models. The models.dev `zai`
pay-as-you-go key carries the real per-token rates for the identical
model ids, matching how other subscription providers surface comparison
pricing.

- Point the `zai` descriptor at the `zai` models.dev key.
- Regenerate the bundled zai cost blocks from the PAYG rates.
- Add issue-5598 regression test against the descriptor + mapper.

Fixes #5598
2026-07-15 17:47:03 +00:00
roboomp 0069a84c9f fix(catalog): apply local stream-timeout floor to loopback proxies
A litellm proxy on a loopback baseUrl fronting a local llama.cpp/vLLM server
was excluded from isLocalOpenAICompatBackend (PROXY_OPENAI_COMPAT_PROVIDERS)
so replayReasoningContent stays off proxies that may forward to an unrelated
cloud upstream. That exclusion also stripped the 300s LOCAL_OPENAI_COMPAT
stream-timeout floor, so the first-event budget fell back to the 100s default.
A slow prefill on a large prompt (llama.cpp "non-consecutive token position"
KV thrash + reprocess) then exceeded 100s, aborting with "OpenAI completions
stream timed out while waiting for the first event" and retry-looping.

Decouple the stream-timeout floor from the replay gate: the floor now applies
to any loopback/RFC1918 backend (including proxies) because widening the abort
ceiling only helps a slow local upstream and never forwards an extra wire
field. Reasoning replay stays gated to first-party local providers. Applied to
both the completions and responses compat builders.

Fixes #4786
2026-07-15 14:32:39 +00:00
roboomp 4b3ec660f3 fix(catalog): disabled eager streaming for custom anthropic
Defaulted eager tool input streaming to the canonical Anthropic API while allowing explicit models.yml opt-in for compatible proxies.

Fixes #5572
2026-07-15 11:20:12 +00:00
can1357 7dded47aa1 Merge PR #5409: fix(catalog): sync OpenCode models from live catalogs (@roboomp) 2026-07-14 23:11:09 +02:00
roboomp 5ec402fc10 fix(catalog): force codex refresh for authoritative pruning
Built-in discovery skipped the OAuth refresh whenever a fresh authoritative cache existed, so an openai-codex user with an expired access token never got the model manager constructed and stale bundled models (e.g. gpt-5.4-nano) stayed selectable for the full cache TTL. Force the refresh for authoritative providers and forward the registry fetch through the Codex manager so discovery honors the configured transport.

Fixes #5364
2026-07-14 20:47:46 +00:00
roboomp b61dddc783 fix(catalog): partitioned opencode model caches
Authoritative OpenCode model catalogs now use credential-and-endpoint-specific cache namespaces so one account cannot reuse another account's entitlements.

Fixes #4769
2026-07-14 20:08:32 +00:00