@oh-my-pi/pi-catalog 18.1.11 → 18.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [18.1.12] - 2026-09-06
6
+
7
+ ### Added
8
+
9
+ - Added Muse Code as a provider with Muse Spark models and live account-scoped discovery.
10
+ - Muse Code subscriptions now resolve a compact edit-prompt variant, cutting recurring per-request tool bytes without touching other providers.
11
+ - Added Meta's new `max` reasoning effort tier to Muse Spark 1.3 (standard) on the Meta Model API and Muse Code.
12
+
13
+ ### Fixed
14
+
15
+ - Fixed OpenCode Go/Zen live model discovery (`GET /v1/models`) missing `x-opencode-session` and omp's `User-Agent`: discovery requests now attribute with the stable install id so the requests OpenCode flags as `Bun fetch` carry the required session header.
16
+ - Fixed GPT-6 Astra requests through GitHub Copilot failing with an unsupported endpoint error ([#10874](https://github.com/can1357/oh-my-pi/pull/10874) by [@xpcmdshell](https://github.com/xpcmdshell)).
17
+ - Fixed GPT-6 Astra showing as free with a 272K-token window in the OpenAI Codex catalog by applying its documented pricing; `/extended-context` enables the wire-advertised 872K-token maximum ([#10980](https://github.com/can1357/oh-my-pi/pull/10980) by [@H4vC](https://github.com/H4vC)).
18
+ - Fixed GPT-6 Astra compacting early at a 272K-token window with its full window gated behind `/extended-context`: it now defaults to the documented 1.05M-token window.
19
+ - Made extended-context catalog rebuilds faster by resolving each model's maximum window once per process ([#11039](https://github.com/can1357/oh-my-pi/pull/11039) by [@H4vC](https://github.com/H4vC)).
20
+
5
21
  ## [18.1.9] - 2026-09-04
6
22
 
7
23
  ### Added
@@ -1,4 +1,4 @@
1
1
  /** Every provider with an `auth/<id>.kdl` policy. */
2
- export type AuthProviderId = "abliteration" | "aiand" | "aimlapi" | "alibaba-coding-plan" | "alibaba-token-plan" | "amazon-bedrock" | "anthropic" | "azure" | "baseten" | "bedrock-mantle" | "cerebras" | "cline-pass" | "cloudflare-ai-gateway" | "coreweave" | "cursor" | "deepinfra" | "deepseek" | "devin" | "exa" | "firepass" | "fireworks" | "github-copilot" | "gitlab-duo" | "gitlab-duo-agent" | "gmi-cloud" | "google" | "google-antigravity" | "google-gemini-cli" | "google-vertex" | "groq" | "huggingface" | "kagi" | "kilo" | "kimi-code" | "litellm" | "llama.cpp" | "lm-studio" | "meta" | "minimax" | "minimax-code" | "minimax-code-cn" | "mistral" | "moonshot" | "nanogpt" | "novita" | "nvidia" | "ollama" | "ollama-cloud" | "openai" | "openai-codex" | "openai-codex-device" | "opencode-go" | "opencode-zen" | "openrouter" | "parallel" | "perplexity" | "qianfan" | "qwen-portal" | "sakana" | "siliconflow" | "siliconflow-cn" | "synthetic" | "tavily" | "together" | "umans" | "venice" | "vercel-ai-gateway" | "vllm" | "wafer-serverless" | "xai" | "xai-oauth" | "xiaomi" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-sgp" | "yolo-auto" | "zai" | "zai-coding-plan" | "zenmux" | "zhipu-coding-plan";
2
+ export type AuthProviderId = "abliteration" | "aiand" | "aimlapi" | "alibaba-coding-plan" | "alibaba-token-plan" | "amazon-bedrock" | "anthropic" | "azure" | "baseten" | "bedrock-mantle" | "cerebras" | "cline-pass" | "cloudflare-ai-gateway" | "coreweave" | "cursor" | "deepinfra" | "deepseek" | "devin" | "exa" | "firepass" | "fireworks" | "github-copilot" | "gitlab-duo" | "gitlab-duo-agent" | "gmi-cloud" | "google" | "google-antigravity" | "google-gemini-cli" | "google-vertex" | "groq" | "huggingface" | "kagi" | "kilo" | "kimi-code" | "litellm" | "llama.cpp" | "lm-studio" | "meta" | "minimax" | "minimax-code" | "minimax-code-cn" | "mistral" | "moonshot" | "muse-code" | "nanogpt" | "novita" | "nvidia" | "ollama" | "ollama-cloud" | "openai" | "openai-codex" | "openai-codex-device" | "opencode-go" | "opencode-zen" | "openrouter" | "parallel" | "perplexity" | "qianfan" | "qwen-portal" | "sakana" | "siliconflow" | "siliconflow-cn" | "synthetic" | "tavily" | "together" | "umans" | "venice" | "vercel-ai-gateway" | "vllm" | "wafer-serverless" | "xai" | "xai-oauth" | "xiaomi" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-sgp" | "yolo-auto" | "zai" | "zai-coding-plan" | "zenmux" | "zhipu-coding-plan";
3
3
  /** Providers whose policy declares a `login` flow (the `/login` roster). */
4
- export type LoginProviderId = "abliteration" | "aiand" | "alibaba-coding-plan" | "alibaba-token-plan" | "anthropic" | "baseten" | "cerebras" | "cline-pass" | "cloudflare-ai-gateway" | "coreweave" | "cursor" | "deepinfra" | "deepseek" | "devin" | "exa" | "firepass" | "fireworks" | "github-copilot" | "gitlab-duo" | "gitlab-duo-agent" | "gmi-cloud" | "google-antigravity" | "google-gemini-cli" | "huggingface" | "kagi" | "kilo" | "kimi-code" | "litellm" | "llama.cpp" | "lm-studio" | "meta" | "minimax-code" | "minimax-code-cn" | "moonshot" | "nanogpt" | "novita" | "nvidia" | "ollama" | "ollama-cloud" | "openai-codex" | "openai-codex-device" | "opencode-go" | "opencode-zen" | "openrouter" | "parallel" | "perplexity" | "qianfan" | "qwen-portal" | "sakana" | "siliconflow" | "siliconflow-cn" | "synthetic" | "tavily" | "together" | "umans" | "venice" | "vercel-ai-gateway" | "vllm" | "wafer-serverless" | "xai" | "xai-oauth" | "xiaomi" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-sgp" | "yolo-auto" | "zai" | "zai-coding-plan" | "zenmux" | "zhipu-coding-plan";
4
+ export type LoginProviderId = "abliteration" | "aiand" | "alibaba-coding-plan" | "alibaba-token-plan" | "anthropic" | "baseten" | "cerebras" | "cline-pass" | "cloudflare-ai-gateway" | "coreweave" | "cursor" | "deepinfra" | "deepseek" | "devin" | "exa" | "firepass" | "fireworks" | "github-copilot" | "gitlab-duo" | "gitlab-duo-agent" | "gmi-cloud" | "google-antigravity" | "google-gemini-cli" | "huggingface" | "kagi" | "kilo" | "kimi-code" | "litellm" | "llama.cpp" | "lm-studio" | "meta" | "minimax-code" | "minimax-code-cn" | "moonshot" | "muse-code" | "nanogpt" | "novita" | "nvidia" | "ollama" | "ollama-cloud" | "openai-codex" | "openai-codex-device" | "opencode-go" | "opencode-zen" | "openrouter" | "parallel" | "perplexity" | "qianfan" | "qwen-portal" | "sakana" | "siliconflow" | "siliconflow-cn" | "synthetic" | "tavily" | "together" | "umans" | "venice" | "vercel-ai-gateway" | "vllm" | "wafer-serverless" | "xai" | "xai-oauth" | "xiaomi" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-sgp" | "yolo-auto" | "zai" | "zai-coding-plan" | "zenmux" | "zhipu-coding-plan";
@@ -0,0 +1,7 @@
1
+ import type { Model } from "../types.js";
2
+ /**
3
+ * Maximum prompt window for extended context. Live discovery takes precedence
4
+ * over rule-owned fallbacks for older bundled or cached model metadata. Resolve
5
+ * at catalog composition time so frozen bundled rows need no runtime mutation.
6
+ */
7
+ export declare function resolveMaxContextWindow(model: Model): number | undefined;
@@ -367,6 +367,7 @@ export type CompiledCredentialExpiry = {
367
367
  path: string;
368
368
  fromPath?: string;
369
369
  skewMs: number;
370
+ fallbackMs?: number;
370
371
  } | {
371
372
  mode: "jwt";
372
373
  skewMs: number;
@@ -262,6 +262,11 @@ export declare const CATALOG_PROVIDERS: readonly [{
262
262
  readonly defaultModel: "devstral-medium-latest";
263
263
  readonly envVars: readonly ["MISTRAL_API_KEY"];
264
264
  readonly createModelManagerOptions: (config: ModelManagerConfig) => import("../index.js").ModelManagerOptions<"openai-completions", unknown>;
265
+ }, {
266
+ readonly id: "muse-code";
267
+ readonly defaultModel: "muse-spark-1.3";
268
+ readonly createModelManagerOptions: (config: ModelManagerConfig) => import("../index.js").ModelManagerOptions<"openai-responses", unknown>;
269
+ readonly dynamicModelsAuthoritative: true;
265
270
  }, {
266
271
  readonly id: "meta";
267
272
  readonly defaultModel: "muse-spark-1.1";
@@ -509,6 +509,9 @@ export interface MetaModelManagerConfig {
509
509
  fetch?: FetchImpl;
510
510
  }
511
511
  export declare function metaModelManagerOptions(config?: MetaModelManagerConfig): ModelManagerOptions<"openai-responses">;
512
+ /** Muse Code shares Meta Model API's model capabilities and equivalent token pricing. */
513
+ export declare const MUSE_CODE_STATIC_MODELS: readonly ModelSpec<"openai-responses">[];
514
+ export declare function museCodeModelManagerOptions(config?: MetaModelManagerConfig): ModelManagerOptions<"openai-responses">;
512
515
  export interface MoonshotModelManagerConfig {
513
516
  apiKey?: string;
514
517
  baseUrl?: string;
@@ -653,6 +653,8 @@ export interface ResolvedOpenAISharedCompat {
653
653
  isOpenRouterHost: boolean;
654
654
  /** Whether this endpoint needs a max-token field even when caller did not set one. */
655
655
  alwaysSendMaxTokens: boolean;
656
+ /** Clamp a requested output-token count to the model's advertised ceiling. */
657
+ clampOutputToModelMax: boolean;
656
658
  openRouterRouting?: OpenAICompat["openRouterRouting"];
657
659
  /** Provider-specific wire model-id transform applied to the base id. */
658
660
  wireModelIdMode: "raw" | "cline-pass" | "firepass" | "fireworks" | "openrouter";
@@ -673,7 +675,7 @@ export interface ResolvedOpenAISharedCompat {
673
675
  * `buildModel`; request handlers read fields and never detect, resolve, or
674
676
  * allocate.
675
677
  */
676
- export type ResolvedOpenAICompat = ResolvedOpenAISharedCompat & Required<Omit<OpenAICompat, "supportsDeveloperRole" | "supportsReasoningEffort" | "reasoningEffortMap" | "supportsReasoningParams" | "supportsReasoningSummary" | "supportsSamplingParams" | "supportsPenaltyAndStopParams" | "thinkingFormat" | "kimiApiFormat" | "reasoningDisableMode" | "omitReasoningEffort" | "includeEncryptedReasoning" | "filterReasoningHistory" | "disableReasoningOnForcedToolChoice" | "disableReasoningOnToolChoice" | "supportsToolChoice" | "supportsForcedToolChoice" | "supportsNamedToolChoice" | "reasoningContentField" | "requiresReasoningContentForToolCalls" | "requiresReasoningContentForAllAssistantTurns" | "allowsSyntheticReasoningContentForToolCalls" | "replayReasoningContent" | "qwenPreserveThinking" | "qwenTemplateReasoningEffort" | "requiresThinkingAsText" | "requiresMistralToolIds" | "requiresToolResultName" | "requiresAssistantAfterToolResult" | "requiresAssistantContentForToolCalls" | "stripDeepseekSpecialTokens" | "streamMarkupHealingPattern" | "reasoningDeltasMayBeCumulative" | "emptyLengthFinishIsContextError" | "usesOpenAIToolCallIdLimit" | "promptCacheSessionHeader" | "supportsPromptCacheBreakpoints" | "promptCacheBreakpointTtl" | "openRouterRouting" | "isOpenRouterHost" | "supportsStrictMode" | "supportsLongPromptCacheRetention" | "alwaysSendMaxTokens" | "wireModelIdMode" | "vercelGatewayRouting" | "extraBody" | "toolStrictMode" | "toolSchemaFlavor" | "streamFirstEventTimeoutMs" | "streamIdleTimeoutMs" | "cacheControlFormat" | "thinkingKeep" | "strictResponsesPairing" | "supportsImageDetailOriginal" | "stripImageInput" | "thinkingLoopGuard" | "whenThinking">> & {
678
+ export type ResolvedOpenAICompat = ResolvedOpenAISharedCompat & Required<Omit<OpenAICompat, "supportsDeveloperRole" | "supportsReasoningEffort" | "reasoningEffortMap" | "supportsReasoningParams" | "supportsReasoningSummary" | "supportsSamplingParams" | "supportsPenaltyAndStopParams" | "thinkingFormat" | "kimiApiFormat" | "reasoningDisableMode" | "omitReasoningEffort" | "includeEncryptedReasoning" | "filterReasoningHistory" | "disableReasoningOnForcedToolChoice" | "disableReasoningOnToolChoice" | "supportsToolChoice" | "supportsForcedToolChoice" | "supportsNamedToolChoice" | "reasoningContentField" | "requiresReasoningContentForToolCalls" | "requiresReasoningContentForAllAssistantTurns" | "allowsSyntheticReasoningContentForToolCalls" | "replayReasoningContent" | "qwenPreserveThinking" | "qwenTemplateReasoningEffort" | "requiresThinkingAsText" | "requiresMistralToolIds" | "requiresToolResultName" | "requiresAssistantAfterToolResult" | "requiresAssistantContentForToolCalls" | "stripDeepseekSpecialTokens" | "streamMarkupHealingPattern" | "reasoningDeltasMayBeCumulative" | "emptyLengthFinishIsContextError" | "usesOpenAIToolCallIdLimit" | "promptCacheSessionHeader" | "supportsPromptCacheBreakpoints" | "promptCacheBreakpointTtl" | "openRouterRouting" | "isOpenRouterHost" | "supportsStrictMode" | "supportsLongPromptCacheRetention" | "alwaysSendMaxTokens" | "clampOutputToModelMax" | "wireModelIdMode" | "vercelGatewayRouting" | "extraBody" | "toolStrictMode" | "toolSchemaFlavor" | "streamFirstEventTimeoutMs" | "streamIdleTimeoutMs" | "cacheControlFormat" | "thinkingKeep" | "strictResponsesPairing" | "supportsImageDetailOriginal" | "stripImageInput" | "thinkingLoopGuard" | "whenThinking">> & {
677
679
  vercelGatewayRouting?: OpenAICompat["vercelGatewayRouting"];
678
680
  extraBody?: OpenAICompat["extraBody"];
679
681
  cacheControlFormat?: OpenAICompat["cacheControlFormat"];
@@ -942,6 +944,8 @@ export interface Model<TApi extends Api = Api> {
942
944
  /** Premium Copilot requests charged per user-initiated request (defaults to 1). */
943
945
  premiumMultiplier?: number;
944
946
  contextWindow: number | null;
947
+ /** Optional larger prompt window available when extended context is enabled. */
948
+ maxContextWindow?: number;
945
949
  maxTokens: number | null;
946
950
  /**
947
951
  * When `true`, providers MUST omit `max_output_tokens` (Responses) /
@@ -1023,6 +1027,13 @@ export interface Model<TApi extends Api = Api> {
1023
1027
  * - `"function"` or undefined: JSON function-tool with `{input: string}` (spec §1.2).
1024
1028
  */
1025
1029
  applyPatchToolType?: "freeform" | "function";
1030
+ /**
1031
+ * Edit-tool description density for this model. `"compact"` selects the
1032
+ * terse mode prompt (all operations and invariants preserved) for hosts
1033
+ * where per-request prompt bytes are the dominant cost. Generated catalog
1034
+ * policy sets it; the edit tool falls back to the full prompt when unset.
1035
+ */
1036
+ editPromptVariant?: "full" | "compact";
1026
1037
  /**
1027
1038
  * Force OAuth-style request shaping for providers whose API key prefix doesn't
1028
1039
  * match an OAuth token (e.g. routing Anthropic traffic through a proxy that
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-catalog",
4
- "version": "18.1.11",
4
+ "version": "18.1.13",
5
5
  "description": "Model catalog for omp: bundled model database, provider discovery descriptors, model identity, classification, and equivalence",
6
6
  "homepage": "https://omp.sh",
7
7
  "author": "Stencil Labs, Inc.",
@@ -35,12 +35,12 @@
35
35
  "gen:proto": "bun scripts/generate-protocols.ts"
36
36
  },
37
37
  "dependencies": {
38
- "@oh-my-pi/omptype": "18.1.11",
39
- "@oh-my-pi/pi-utils": "18.1.11"
38
+ "@oh-my-pi/omptype": "18.1.13",
39
+ "@oh-my-pi/pi-utils": "18.1.13"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@bgotink/kdl": "0.4.0",
43
- "@oh-my-pi/pi-ai": "18.1.11",
43
+ "@oh-my-pi/pi-ai": "18.1.13",
44
44
  "@types/bun": "^1.3.14"
45
45
  },
46
46
  "engines": {
package/src/build.ts CHANGED
@@ -52,6 +52,10 @@ function applyCatalogAssignments<TApi extends Api>(model: Model<TApi>, catalog:
52
52
  if (applyPatchToolType === "freeform" || applyPatchToolType === "function") {
53
53
  model.applyPatchToolType = applyPatchToolType;
54
54
  }
55
+ const editPromptVariant = catalog.editPromptVariant;
56
+ if (editPromptVariant === "full" || editPromptVariant === "compact") {
57
+ model.editPromptVariant = editPromptVariant;
58
+ }
55
59
  const requiresCursorToolSchemaProjection = catalog.requiresCursorToolSchemaProjection;
56
60
  if (requiresCursorToolSchemaProjection === true) {
57
61
  model.requiresCursorToolSchemaProjection = true;
@@ -45,6 +45,7 @@ export type AuthProviderId =
45
45
  | "minimax-code-cn"
46
46
  | "mistral"
47
47
  | "moonshot"
48
+ | "muse-code"
48
49
  | "nanogpt"
49
50
  | "novita"
50
51
  | "nvidia"
@@ -119,6 +120,7 @@ export type LoginProviderId =
119
120
  | "minimax-code"
120
121
  | "minimax-code-cn"
121
122
  | "moonshot"
123
+ | "muse-code"
122
124
  | "nanogpt"
123
125
  | "novita"
124
126
  | "nvidia"
@@ -90,7 +90,7 @@ export const AXES: Readonly<Record<string, AxisDef>> = {
90
90
  "allows-synthetic-reasoning-content-for-tool-calls": wire("allowsSyntheticReasoningContentForToolCalls", OAI),
91
91
  "always-send-max-tokens": wire("alwaysSendMaxTokens", OAI),
92
92
  "cache-control-format": wire("cacheControlFormat", OAI, "scalar", ["anthropic"]),
93
- "clamp-output-to-model-max": wire("clampOutputToModelMax", ["openai"]),
93
+ "clamp-output-to-model-max": wire("clampOutputToModelMax", OAI),
94
94
  "disable-reasoning-on-forced-tool-choice": wire("disableReasoningOnForcedToolChoice", OAI),
95
95
  "disable-reasoning-on-tool-choice": wire("disableReasoningOnToolChoice", OAI),
96
96
  "drop-thinking-when-reasoning-effort": wire("dropThinkingWhenReasoningEffort", ["openai"]),
@@ -271,11 +271,13 @@ export const AXES: Readonly<Record<string, AxisDef>> = {
271
271
  "context-window-floor": { key: "contextWindowFloor", set: "catalog", shape: "scalar" },
272
272
  "cost-patch": { key: "costPatch", set: "catalog", shape: "object" },
273
273
  "delegation-bias": { key: "delegationBias", set: "catalog", shape: "scalar", values: DELEGATION_BIASES },
274
+ "edit-prompt-variant": { key: "editPromptVariant", set: "catalog", shape: "scalar", values: ["full", "compact"] },
274
275
  "edit-revision": { key: "editRevision", set: "catalog", shape: "scalar" },
275
276
  "input-modalities": { key: "inputModalities", set: "catalog", shape: "array", values: ["text", "image"] },
276
277
  "limits-patch": { key: "limitsPatch", set: "catalog", shape: "object" },
277
278
  "long-context-cost": { key: "longContext", set: "catalog", shape: "object" },
278
279
  "long-usage-limit-fallback": { key: "longUsageLimitFallback", set: "catalog", shape: "scalar" },
280
+ "max-context-window": { key: "maxContextWindow", set: "catalog", shape: "scalar" },
279
281
  "requires-cursor-tool-schema-projection": {
280
282
  key: "requiresCursorToolSchemaProjection",
281
283
  set: "catalog",
@@ -0,0 +1,31 @@
1
+ import { toModelSpec } from "../provider-models/bundled-references";
2
+ import type { Model } from "../types";
3
+ import { resolveModelPolicy } from "./resolve";
4
+
5
+ /**
6
+ * Rule-owned fallback maxima by `provider/id/api`. The rule table is static
7
+ * per process (compiled into rules.json), so one resolution per model key is
8
+ * enough — composition calls this per model on every rebuild while extended
9
+ * context is enabled, and the full policy resolve (identity classification
10
+ * plus cascade walk) is wasted work per call.
11
+ */
12
+ const ruleFallbackCache = new Map<string, number | undefined>();
13
+
14
+ /**
15
+ * Maximum prompt window for extended context. Live discovery takes precedence
16
+ * over rule-owned fallbacks for older bundled or cached model metadata. Resolve
17
+ * at catalog composition time so frozen bundled rows need no runtime mutation.
18
+ */
19
+ export function resolveMaxContextWindow(model: Model): number | undefined {
20
+ const maximum = model.maxContextWindow;
21
+ if (typeof maximum === "number" && Number.isFinite(maximum) && maximum > 0) {
22
+ return maximum;
23
+ }
24
+
25
+ const key = `${model.provider} ${model.id} ${model.api}`;
26
+ if (ruleFallbackCache.has(key)) return ruleFallbackCache.get(key);
27
+ const fallback = resolveModelPolicy(toModelSpec(model)).catalog.maxContextWindow;
28
+ const resolved = typeof fallback === "number" && Number.isFinite(fallback) && fallback > 0 ? fallback : undefined;
29
+ ruleFallbackCache.set(key, resolved);
30
+ return resolved;
31
+ }
@@ -753,6 +753,7 @@ function resolveOpenAIResponsesPolicy(
753
753
  wireModelIdMode: isOpenRouter ? "openrouter" : "raw",
754
754
  toolSchemaFlavor: facts.is("kimi") ? "moonshot-mfjs" : undefined,
755
755
  alwaysSendMaxTokens: facts.is("kimi"),
756
+ clampOutputToModelMax: false,
756
757
  supportsObfuscationOptOut: isOpenAIUrl || provider === "openai",
757
758
  officialEndpoint: isOfficialOpenAIEndpoint(provider, baseUrl),
758
759
  harmonyLeakMitigation: false,
@@ -276,7 +276,7 @@ auth "anthropic" {
276
276
  credential {
277
277
  access "access_token" // dot path; `claim="a|b"` reads JWT claims; `literal="…"` pins a value
278
278
  refresh "refresh_token"
279
- expires "seconds" path="expires_in" from="created_at" skew-ms=300000 // or `expires "jwt" fallback-ms=N` / `expires "never"`
279
+ expires "seconds" path="expires_in" from="created_at" skew-ms=300000 fallback-ms=3600000 // or `expires "jwt" fallback-ms=N` / `expires "never"`
280
280
  email "account.email_address" // also account-id, org-id, org-name, project-id, api-endpoint, enterprise-url
281
281
  }
282
282
  userinfo url="https://…/userinfo" email="email" account-id="sub"
@@ -5,7 +5,7 @@ login-order "openai-codex" "anthropic" "zai" "zai-coding-plan" "kimi-code" "open
5
5
  "cursor" "devin" "google-antigravity" "google-gemini-cli" "openai-codex-device" "xai" "xai-oauth" \
6
6
  "gitlab-duo" "gitlab-duo-agent" "alibaba-coding-plan" "alibaba-token-plan" "aiand" "abliteration" "zhipu-coding-plan" \
7
7
  "umans" "qwen-portal" "sakana" "minimax-code" "minimax-code-cn" "xiaomi" "xiaomi-token-plan-sgp" \
8
- "xiaomi-token-plan-ams" "xiaomi-token-plan-cn" "firepass" "cline-pass" "deepseek" "meta" "moonshot" \
8
+ "xiaomi-token-plan-ams" "xiaomi-token-plan-cn" "firepass" "cline-pass" "deepseek" "muse-code" "meta" "moonshot" \
9
9
  "cerebras" "baseten" "fireworks" "together" "nvidia" "novita" "deepinfra" "huggingface" "perplexity" \
10
10
  "qianfan" "venice" "siliconflow" "siliconflow-cn" "synthetic" "nanogpt" "wafer-serverless" "coreweave" \
11
11
  "vercel-ai-gateway" "cloudflare-ai-gateway" "litellm" "kilo" "zenmux" "opencode-zen" "opencode-go" \
@@ -0,0 +1,28 @@
1
+ auth "muse-code" {
2
+ name "Muse Code (Subscription)"
3
+ expiry "jwt-or-never"
4
+ login "device-code" {
5
+ client-id "1031625952748946"
6
+ device url="https://auth.meta.com/oidc/device/authorization/" {
7
+ headers {
8
+ Accept "application/json"
9
+ "x-api-version" "1.0.0"
10
+ }
11
+ }
12
+ token url="https://auth.meta.com/oidc/device/token/" {
13
+ headers {
14
+ Accept "application/json"
15
+ "x-api-version" "1.0.0"
16
+ }
17
+ }
18
+ response user-code="user_code" device-code="device_code" verification-uri="verification_uri" verification-uri-complete="verification_uri_complete" interval="interval" expires-in="expires_in"
19
+ instructions "Enter code: {user_code}"
20
+ credential {
21
+ // Model requests use the minted API key, not the account token. Meta's
22
+ // device response omits expiry and rejects refresh_token grants.
23
+ expires "never"
24
+ }
25
+ after-exchange hook="muse-code-key"
26
+ }
27
+ refresh "none"
28
+ }
@@ -3,7 +3,13 @@
3
3
  class "meta" {
4
4
  // Exact ids on purpose: only an exact selector upgrades hosts whose
5
5
  // discovery misreports a Muse Spark revision as non-reasoning.
6
- models "muse-spark-1.2" "muse-spark-1.2-contributor" "muse-spark-1.3" "muse-spark-1.3-contributor" {
6
+ // muse-spark-1.3 exposes the max effort tier; older/contributor revisions
7
+ // keep the 5-tier ladder.
8
+ models "muse-spark-1.3" {
9
+ thinking-efforts "minimal" "low" "medium" "high" "xhigh" "max"
10
+ thinking-mode "effort"
11
+ }
12
+ models "muse-spark-1.1" "muse-spark-1.2" "muse-spark-1.2-contributor" "muse-spark-1.3-contributor" {
7
13
  thinking-efforts "minimal" "low" "medium" "high" "xhigh"
8
14
  thinking-mode "effort"
9
15
  }
@@ -3,6 +3,7 @@
3
3
  provider "meta" {
4
4
  include-encrypted-reasoning #true
5
5
  supports-reasoning-effort #true
6
+ clamp-output-to-model-max #true
6
7
  class "unknown" {
7
8
  thinking-efforts "minimal" "low" "medium" "high" "xhigh"
8
9
  thinking-mode "effort"
@@ -0,0 +1,16 @@
1
+ // Muse Code subscriptions use the same Model API wire contract as direct Meta API keys.
2
+
3
+ provider "muse-code" {
4
+ include-encrypted-reasoning #true
5
+ supports-reasoning-effort #true
6
+ clamp-output-to-model-max #true
7
+ // Subscription tier bills per request; the compact edit prompt cuts the
8
+ // recurring tool-schema bytes. Verified 2026-09-05 against api.meta.ai/v1:
9
+ // `custom` tools are rejected with 400 "`custom` tools are not supported
10
+ // on this endpoint", so apply-patch must stay a function tool here.
11
+ edit-prompt-variant "compact"
12
+ class "unknown" {
13
+ thinking-efforts "minimal" "low" "medium" "high" "xhigh"
14
+ thinking-mode "effort"
15
+ }
16
+ }
@@ -29,6 +29,29 @@ provider "openai-codex" {
29
29
  cache-write 15.625
30
30
  }
31
31
  }
32
+ // Codex discovery still reports Astra's stale 272K window with
33
+ // max_context_window=872000 (client 0.153.1, 2026-09-04) — the same stale
34
+ // pair it reports for Luna/Sol/Terra. Public docs list a 1.05M window and
35
+ // live Codex traffic succeeds past the wire maximum (895,302 input tokens
36
+ // observed, including cached input), so floor to the documented window like
37
+ // the GPT-5.6 1M floor below. Astra carries no long-context surcharge, so
38
+ // the window must not be gated behind `/extended-context`; the
39
+ // `maximum > contextWindow` guard then ignores the stale 872K live maximum.
40
+ // Pricing stays at the documented credit-equivalent rates, with free cache
41
+ // writes and no >272K multiplier.
42
+ models "gpt-6-astra" "gpt-6-astra-wm" {
43
+ cost-patch {
44
+ input 10.0
45
+ output 50.0
46
+ cache-read 1.0
47
+ cache-write 0
48
+ }
49
+ service-tier-cost {
50
+ flex 0.5
51
+ priority 2.5
52
+ }
53
+ context-window-floor 1050000
54
+ }
32
55
  class "openai" {
33
56
  revision ">=5.3 <5.7" {
34
57
  thinking-mode "effort"
@@ -118,4 +141,8 @@ provider "openai-codex" {
118
141
  models "gpt-5.6-luna" "gpt-5.6-sol" "gpt-5.6-terra" {
119
142
  context-window-floor 1000000
120
143
  }
144
+ // (No `max-context-window` fallback: the 1.05M floor already exceeds the
145
+ // stale 872K wire maximum, so offline and cached rows compose to the
146
+ // documented window and the live maximum is ignored by the
147
+ // `maximum > contextWindow` guard — same as Luna/Sol/Terra above.)
121
148
  }
@@ -127,6 +127,7 @@ behavior {
127
127
  // Meta's /v1/models lists image generation and transcription SKUs beside
128
128
  // the Muse Spark chat models.
129
129
  exclude-models provider="meta" prefix="muse-image-" prefix="muse-voice-"
130
+ exclude-models provider="muse-code" prefix="muse-image-" prefix="muse-voice-"
130
131
  // NanoGPT's roster interleaves non-text SKUs by name token.
131
132
  exclude-models provider="nanogpt" substring="embedding" substring="image" substring="vision" \
132
133
  substring="audio" substring="speech" substring="transcribe" substring="moderation" \
@@ -154,7 +155,7 @@ behavior {
154
155
  api-routes provider="github-copilot" default="openai-completions" {
155
156
  route "anthropic-messages" glob="claude-haiku-*" glob="claude-sonnet-*" glob="claude-opus-*" \
156
157
  glob="claude-fable-*" glob="claude-mythos-*"
157
- route "openai-responses" exact="grok-4.5" exact="grok-4.6" prefix="gpt-5" prefix="oswe" prefix="mai-"
158
+ route "openai-responses" exact="grok-4.5" exact="grok-4.6" prefix="gpt-5" prefix="gpt-6" prefix="oswe" prefix="mai-"
158
159
  }
159
160
  // ZenMux fronts Anthropic ids on a dedicated Messages endpoint; every
160
161
  // other namespace stays on chat completions.