@oh-my-pi/pi-catalog 18.2.11 → 18.3.1

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.
Files changed (41) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +1 -1
  3. package/THIRD-PARTY-NOTICES.txt +3 -3
  4. package/dist/types/compat/auth-ids.d.ts +1 -1
  5. package/dist/types/compat/fallback-credit.d.ts +7 -0
  6. package/dist/types/compat/output-limits.d.ts +5 -0
  7. package/dist/types/compat/provider-ids.d.ts +1 -1
  8. package/dist/types/compat/server-side-fallback.d.ts +7 -0
  9. package/dist/types/compat/types.d.ts +4 -0
  10. package/dist/types/discovery/cursor-proto.d.ts +1 -1
  11. package/dist/types/discovery/devin-proto.d.ts +1 -1
  12. package/dist/types/types.d.ts +37 -7
  13. package/package.json +8 -5
  14. package/src/compat/auth-ids.ts +1 -0
  15. package/src/compat/axes.ts +25 -0
  16. package/src/compat/fallback-credit.ts +13 -0
  17. package/src/compat/output-limits.ts +8 -0
  18. package/src/compat/provider-ids.ts +1 -0
  19. package/src/compat/resolve.ts +2 -0
  20. package/src/compat/rules/README.md +4 -0
  21. package/src/compat/rules/auth/anthropic.kdl +1 -0
  22. package/src/compat/rules/auth/apple.kdl +4 -0
  23. package/src/compat/rules/auth/openai-codex.kdl +1 -0
  24. package/src/compat/rules/auth/xai-oauth.kdl +1 -0
  25. package/src/compat/rules/classes/anthropic.kdl +46 -16
  26. package/src/compat/rules/classes/openai.kdl +3 -0
  27. package/src/compat/rules/providers/anthropic.kdl +15 -0
  28. package/src/compat/rules/providers/apple.kdl +8 -0
  29. package/src/compat/rules/providers/yolo-auto.kdl +8 -2
  30. package/src/compat/rules.json +1 -1
  31. package/src/compat/server-side-fallback.ts +13 -0
  32. package/src/compat/types.ts +4 -0
  33. package/src/discovery/codex.ts +29 -4
  34. package/src/discovery/cursor-proto.ts +1 -1
  35. package/src/discovery/devin-proto.ts +1 -1
  36. package/src/discovery/devin.ts +60 -1
  37. package/src/models.json +1 -1
  38. package/src/provider-models/cache-provider-id.ts +5 -0
  39. package/src/provider-models/openai-compat.ts +30 -7
  40. package/src/provider-models/special.ts +12 -2
  41. package/src/types.ts +39 -6
@@ -175,6 +175,11 @@ export function resolveModelCacheProviderId(providerId: string, options: ModelCa
175
175
  const baseUrl = options.baseUrl ?? getDefaultModelDiscoveryBaseUrl(providerId)!;
176
176
  return `vllm:models-v2:${Bun.hash(baseUrl).toString(36)}`;
177
177
  }
178
+ case "devin":
179
+ // v2: rows cached before Fusion pairings carried their lead uid as
180
+ // `requestModelId` send the composite uid and fail with
181
+ // `permission_denied: no API providers are available`.
182
+ return "devin:models-v2";
178
183
  default:
179
184
  return providerId;
180
185
  }
@@ -4710,8 +4710,8 @@ export function sakanaModelManagerOptions(config?: SakanaModelManagerConfig): Mo
4710
4710
 
4711
4711
  const AIAND_DEFAULT_BASE_URL = "https://api.aiand.com/v1";
4712
4712
 
4713
- /** `reasoning_efforts` wire values ai& reports, mapped onto pi effort levels. */
4714
- const AIAND_EFFORT_BY_WIRE_VALUE: Record<string, Effort> = {
4713
+ /** Effort wire values discovery endpoints report (`reasoning_efforts`, `thinking`), mapped onto pi effort levels. */
4714
+ const EFFORT_BY_WIRE_VALUE: Record<string, Effort> = {
4715
4715
  minimal: Effort.Minimal,
4716
4716
  low: Effort.Low,
4717
4717
  medium: Effort.Medium,
@@ -4728,18 +4728,23 @@ function normalizeAiandBaseUrl(baseUrl: string | undefined): string {
4728
4728
 
4729
4729
  const AIAND_STATIC_MODEL_IDS = seedModels("aiand").map(model => model.id);
4730
4730
 
4731
- function mapAiandThinking(entry: OpenAICompatibleModelRecord): ThinkingConfig | undefined {
4732
- const efforts = Array.isArray(entry.reasoning_efforts)
4733
- ? entry.reasoning_efforts.flatMap(value =>
4734
- typeof value === "string" && AIAND_EFFORT_BY_WIRE_VALUE[value] ? [AIAND_EFFORT_BY_WIRE_VALUE[value]] : [],
4731
+ /** Parse a discovered effort list, dropping unknown wire values; empty when absent or unrecognized. */
4732
+ function parseWireEfforts(value: unknown): Effort[] {
4733
+ return Array.isArray(value)
4734
+ ? value.flatMap(item =>
4735
+ typeof item === "string" && EFFORT_BY_WIRE_VALUE[item] ? [EFFORT_BY_WIRE_VALUE[item]] : [],
4735
4736
  )
4736
4737
  : [];
4738
+ }
4739
+
4740
+ function mapAiandThinking(entry: OpenAICompatibleModelRecord): ThinkingConfig | undefined {
4741
+ const efforts = parseWireEfforts(entry.reasoning_efforts);
4737
4742
  if (efforts.length === 0) {
4738
4743
  return undefined;
4739
4744
  }
4740
4745
  const defaultLevel =
4741
4746
  typeof entry.reasoning_effort_default === "string"
4742
- ? AIAND_EFFORT_BY_WIRE_VALUE[entry.reasoning_effort_default]
4747
+ ? EFFORT_BY_WIRE_VALUE[entry.reasoning_effort_default]
4743
4748
  : undefined;
4744
4749
  return {
4745
4750
  mode: "effort",
@@ -4896,8 +4901,26 @@ function mapYoloAutoModel(
4896
4901
  reference: ModelSpec<"openai-completions"> | undefined,
4897
4902
  ): ModelSpec<"openai-completions"> {
4898
4903
  const model = mapWithBundledReference(entry, defaults, reference);
4904
+ // `/v1/models` advertises each reasoning model's accepted effort ladder in
4905
+ // `thinking`; it is authoritative over the seed/reference ladder. Rows
4906
+ // without the field (e.g. `yolo-small`) keep the reference surface.
4907
+ const efforts = parseWireEfforts(entry.thinking);
4908
+ const thinking: ThinkingConfig | undefined =
4909
+ efforts.length > 0
4910
+ ? {
4911
+ ...model.thinking,
4912
+ mode: model.thinking?.mode ?? "effort",
4913
+ efforts,
4914
+ defaultLevel:
4915
+ model.thinking?.defaultLevel && efforts.includes(model.thinking.defaultLevel)
4916
+ ? model.thinking.defaultLevel
4917
+ : undefined,
4918
+ }
4919
+ : model.thinking;
4899
4920
  return {
4900
4921
  ...model,
4922
+ ...(efforts.length > 0 && { reasoning: true }),
4923
+ thinking,
4901
4924
  // Flat-rate and no-store are provider-wide: they must win whether the
4902
4925
  // reference came from the yolo bundle, the global index, or nowhere.
4903
4926
  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
@@ -77,7 +77,8 @@ export function openaiCodexModelManagerOptions(
77
77
 
78
78
  /**
79
79
  * Merge complete per-account Codex catalogs into one authoritative list,
80
- * deduped by model id (first account to expose an id wins).
80
+ * deduped by model id. The first account to expose an id supplies its spec;
81
+ * account access is merged from every account whose catalog lists that id.
81
82
  *
82
83
  * Returns `null` when any account's fetch failed transiently, so a partial list
83
84
  * cannot replace the previous or bundled authoritative catalog. An account
@@ -102,7 +103,15 @@ function unionCodexModels(
102
103
  }
103
104
  catalogs++;
104
105
  for (const model of result.models) {
105
- if (!byId.has(model.id)) byId.set(model.id, model);
106
+ const existing = byId.get(model.id);
107
+ if (!existing) {
108
+ byId.set(model.id, model);
109
+ } else if (model.accountAccess) {
110
+ byId.set(model.id, {
111
+ ...existing,
112
+ accountAccess: { ...existing.accountAccess, ...model.accountAccess },
113
+ });
114
+ }
106
115
  }
107
116
  }
108
117
  return catalogs > 0 ? [...byId.values()] : null;
@@ -336,6 +345,7 @@ export function devinModelManagerOptions(config: DevinModelManagerConfig = {}):
336
345
  const staticModels = seedModels<"devin-agent">("devin");
337
346
  return {
338
347
  providerId: "devin",
348
+ cacheProviderId: resolveModelCacheProviderId("devin"),
339
349
  // A configured host serves its own Cascade deployment; keep the seed on it.
340
350
  staticModels:
341
351
  baseUrl === undefined || baseUrl === DEVIN_DEFAULT_BASE_URL
package/src/types.ts CHANGED
@@ -20,7 +20,8 @@ export type KnownApi =
20
20
  | "ollama-chat"
21
21
  | "cursor-agent"
22
22
  | "gitlab-duo-agent"
23
- | "devin-agent";
23
+ | "devin-agent"
24
+ | "apple-foundation-models";
24
25
  export type Api = KnownApi | (string & {});
25
26
 
26
27
  /** Catalog kinds used to isolate role-specific runners from session chat models. */
@@ -478,6 +479,13 @@ export interface OpenAICompat {
478
479
  * sent as the top-level `reasoning.effort`.
479
480
  */
480
481
  supportsConfigurationUpdate?: boolean;
482
+ /**
483
+ * Whether the Responses WebSocket accepts `response.steer`, which queues user
484
+ * input into the in-flight response (GPT-6 family). Default: rule-detected.
485
+ * Set `false` for proxies that reject the event; steering then waits for the
486
+ * next request boundary.
487
+ */
488
+ supportsSteering?: boolean;
481
489
  /** Whether streamed reasoning deltas for the same field may repeat the full cumulative text snapshot. Default: false. */
482
490
  reasoningDeltasMayBeCumulative?: boolean;
483
491
  /** Strip leaked DeepSeek chat-template special tokens from visible content deltas. Default: auto-detected. */
@@ -519,17 +527,17 @@ export interface AnthropicCompat {
519
527
  /** Whether thinking requests may include `context_management` and its beta header. Default: true. */
520
528
  supportsContextManagement?: boolean;
521
529
  /**
522
- * Whether the model lineage supports Anthropic server-side compaction
523
- * (`compact-2026-01-12`: the `compact_20260112` edit and replayed
524
- * `compaction` blocks). Rule-owned per model line; the beta covers the
525
- * adaptive-thinking generation onward and rejects older lines. Default: false.
530
+ * Whether the model and host support Anthropic on-demand compaction
531
+ * (`compact-2026-09-04` requests and signed replay). Enabled on Opus 4.6+,
532
+ * Sonnet 4.6+, Fable/Mythos 5+ on supported hosts. Default: false.
526
533
  */
527
534
  supportsServerCompaction?: boolean;
528
535
  /**
529
536
  * Whether the model is served by the first-party Anthropic provider (its
530
537
  * default route is the official API). Rule-owned on the provider; the
531
538
  * compaction transport pairs it with a per-request effective-URL check
532
- * because reroutes leave it stale-true. Default: false.
539
+ * because reroutes leave it stale-true. Vertex is selected by its provider
540
+ * contract instead. Default: false.
533
541
  */
534
542
  firstPartyProvider?: boolean;
535
543
  /**
@@ -874,6 +882,7 @@ export type ResolvedOpenAICompat = ResolvedOpenAISharedCompat &
874
882
  | "strictResponsesPairing"
875
883
  | "supportsImageDetailOriginal"
876
884
  | "supportsConfigurationUpdate"
885
+ | "supportsSteering"
877
886
  | "stripImageInput"
878
887
  | "thinkingLoopGuard"
879
888
  | "whenThinking"
@@ -913,6 +922,11 @@ export interface ResolvedOpenAIResponsesCompat extends ResolvedOpenAISharedCompa
913
922
  * the item type with 400.
914
923
  */
915
924
  supportsConfigurationUpdate: boolean;
925
+ /**
926
+ * Whether the WebSocket transport may send `response.steer` to deliver user
927
+ * input into the in-flight response. Rule-owned: GPT-6 family.
928
+ */
929
+ supportsSteering: boolean;
916
930
  /** Inject the `# Juice: 0 !important` developer item when reasoning is forced off (gpt-5.6+). */
917
931
  requiresReasoningOffJuiceInstruction: boolean;
918
932
  /**
@@ -1163,6 +1177,16 @@ export type ModelTokenizer =
1163
1177
  | "kimi-k2"
1164
1178
  | "glm5";
1165
1179
 
1180
+ /** One account's discovered entitlements on a model; see {@link Model.accountAccess}. */
1181
+ export interface ModelAccountAccess {
1182
+ /**
1183
+ * Codex `available_access_programs.cyber`: cyber access programs this account
1184
+ * may request on the model (`standard`, `daybreak_blue`, `daybreak_red`).
1185
+ * Absent when the backend reported no program metadata.
1186
+ */
1187
+ cyberPrograms?: readonly string[];
1188
+ }
1189
+
1166
1190
  // Model interface for the unified model system
1167
1191
  export interface Model<TApi extends Api = Api> {
1168
1192
  id: string;
@@ -1257,6 +1281,15 @@ export interface Model<TApi extends Api = Api> {
1257
1281
  * their single wire id) and on bundled snapshots that predate discovery.
1258
1282
  */
1259
1283
  cursorMaxModeRoutes?: Readonly<Record<string, boolean>>;
1284
+ /**
1285
+ * Per-account availability recorded by multi-account discovery: provider
1286
+ * account id (Codex: ChatGPT `chatgpt_account_id`) → that account's
1287
+ * entitlements on this model. An account appears only when its own catalog
1288
+ * lists the model, so credential selection can route account-gated models
1289
+ * (e.g. `gpt-daybreak-blue-latest`) straight to eligible accounts. Absent on
1290
+ * bundled/config rows and on single-account discovery.
1291
+ */
1292
+ accountAccess?: Readonly<Record<string, ModelAccountAccess>>;
1260
1293
  cost: ModelCost;
1261
1294
  /** Premium Copilot requests charged per user-initiated request (defaults to 1). */
1262
1295
  premiumMultiplier?: number;