@oh-my-pi/pi-catalog 18.2.10 → 18.3.0

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 (36) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +1 -1
  3. package/THIRD-PARTY-NOTICES.txt +1 -1
  4. package/dist/types/compat/auth-ids.d.ts +2 -2
  5. package/dist/types/compat/provider-ids.d.ts +1 -1
  6. package/dist/types/compat/types.d.ts +4 -0
  7. package/dist/types/discovery/cursor-proto.d.ts +1 -1
  8. package/dist/types/discovery/devin-proto.d.ts +1 -1
  9. package/dist/types/provider-models/openai-compat.d.ts +25 -0
  10. package/dist/types/types.d.ts +24 -6
  11. package/package.json +8 -5
  12. package/src/compat/auth-ids.ts +3 -0
  13. package/src/compat/provider-ids.ts +2 -0
  14. package/src/compat/rules/README.md +4 -0
  15. package/src/compat/rules/auth/_order.kdl +1 -1
  16. package/src/compat/rules/auth/anthropic.kdl +1 -0
  17. package/src/compat/rules/auth/apple.kdl +4 -0
  18. package/src/compat/rules/auth/openai-codex.kdl +1 -0
  19. package/src/compat/rules/auth/stepfun.kdl +13 -0
  20. package/src/compat/rules/auth/xai-oauth.kdl +1 -0
  21. package/src/compat/rules/classes/anthropic.kdl +23 -18
  22. package/src/compat/rules/providers/apple.kdl +8 -0
  23. package/src/compat/rules/providers/openai-codex.kdl +16 -0
  24. package/src/compat/rules/providers/stepfun.kdl +95 -0
  25. package/src/compat/rules/runtime/behavior.kdl +10 -2
  26. package/src/compat/rules.json +1 -1
  27. package/src/compat/types.ts +4 -0
  28. package/src/discovery/codex.ts +29 -4
  29. package/src/discovery/cursor-proto.ts +1 -1
  30. package/src/discovery/devin-proto.ts +1 -1
  31. package/src/model-manager.ts +8 -2
  32. package/src/models.json +1 -1
  33. package/src/provider-models/descriptors.ts +2 -0
  34. package/src/provider-models/openai-compat.ts +92 -1
  35. package/src/provider-models/special.ts +11 -2
  36. package/src/types.ts +26 -6
@@ -552,6 +552,10 @@ export interface CompiledAuthProvider {
552
552
  name: string;
553
553
  env?: { vars: string[] } | { hook: string };
554
554
  allowsMissingApiKey?: boolean;
555
+ /** Qualify credential and usage-report identity by org when an email may have multiple subscriptions. */
556
+ orgScopedIdentity?: boolean;
557
+ /** Environment variables carrying this provider's own OAuth bearer, excluding borrowed API-key aliases. */
558
+ oauthTokenEnv?: string[];
555
559
  /** APIs whose provider transport resolves credentials without a stored account. */
556
560
  nativeAuthApis?: string[];
557
561
  available?: boolean;
@@ -70,6 +70,7 @@ const codexModelEntrySchema = type({
70
70
  "prefer_websockets?": "unknown",
71
71
  "use_responses_lite?": "unknown",
72
72
  "tool_mode?": "unknown",
73
+ "available_access_programs?": "unknown",
73
74
  });
74
75
 
75
76
  const codexModelsResponseSchema = type({
@@ -161,7 +162,7 @@ export async function fetchCodexModels(options: CodexModelDiscoveryOptions): Pro
161
162
  continue;
162
163
  }
163
164
 
164
- const models = normalizeCodexModels(payload, baseUrl);
165
+ const models = normalizeCodexModels(payload, baseUrl, options.accountId);
165
166
  if (models === null) {
166
167
  continue;
167
168
  }
@@ -223,7 +224,11 @@ function normalizeClientVersion(value: unknown): string | undefined {
223
224
  return trimmed;
224
225
  }
225
226
 
226
- function normalizeCodexModels(payload: unknown, baseUrl: string): ModelSpec<"openai-codex-responses">[] | null {
227
+ function normalizeCodexModels(
228
+ payload: unknown,
229
+ baseUrl: string,
230
+ accountId: string | undefined,
231
+ ): ModelSpec<"openai-codex-responses">[] | null {
227
232
  const parsedResponse = codexModelsResponseSchema(payload);
228
233
  if (parsedResponse instanceof type.errors) {
229
234
  return null;
@@ -250,10 +255,10 @@ function normalizeCodexModels(payload: unknown, baseUrl: string): ModelSpec<"ope
250
255
  const normalized: NormalizedCodexModel[] = [];
251
256
  for (const parsed of parsedEntries) {
252
257
  const canonicalSlug = plainCounterpartForWorkerSlug(parsed.slug, bundledCodexModelIds) ?? parsed.slug;
253
- normalized.push(buildNormalizedCodexModel(parsed, parsed.slug, canonicalSlug, baseUrl));
258
+ normalized.push(buildNormalizedCodexModel(parsed, parsed.slug, canonicalSlug, baseUrl, accountId));
254
259
  const plainSlug = canonicalSlug !== parsed.slug ? canonicalSlug : null;
255
260
  if (plainSlug && !advertisedSlugs.has(plainSlug)) {
256
- normalized.push(buildNormalizedCodexModel(parsed, plainSlug, canonicalSlug, baseUrl));
261
+ normalized.push(buildNormalizedCodexModel(parsed, plainSlug, canonicalSlug, baseUrl, accountId));
257
262
  }
258
263
  }
259
264
 
@@ -288,6 +293,7 @@ function plainCounterpartForWorkerSlug(slug: string, bundledCodexModelIds: Reado
288
293
 
289
294
  interface ParsedCodexModelEntry {
290
295
  slug: string;
296
+ cyberPrograms: string[] | undefined;
291
297
  name: string;
292
298
  contextWindow: number | null;
293
299
  maxContextWindow: number | null;
@@ -316,8 +322,19 @@ function parseCodexModelEntry(entry: unknown): ParsedCodexModelEntry | null {
316
322
  return null;
317
323
  }
318
324
 
325
+ const programs = payload.available_access_programs;
326
+ let cyberPrograms: string[] | undefined;
327
+ if (programs !== null && typeof programs === "object" && "cyber" in programs && Array.isArray(programs.cyber)) {
328
+ cyberPrograms = [];
329
+ for (const program of programs.cyber) {
330
+ const name = toNonEmptyString(program);
331
+ if (name) cyberPrograms.push(name);
332
+ }
333
+ }
334
+
319
335
  return {
320
336
  slug,
337
+ cyberPrograms,
321
338
  name: toNonEmptyString(payload.display_name) ?? slug,
322
339
  contextWindow: toPositiveInt(payload.context_window),
323
340
  maxContextWindow: toPositiveInt(payload.max_context_window),
@@ -342,6 +359,7 @@ function buildNormalizedCodexModel(
342
359
  slug: string,
343
360
  canonicalSlug: string,
344
361
  baseUrl: string,
362
+ accountId: string | undefined,
345
363
  ): NormalizedCodexModel {
346
364
  // Codex discovery historically omitted `context_window` for GPT-5.6-family
347
365
  // SKUs (#5705); luna/sol/terra additionally floor the reported value because
@@ -371,6 +389,13 @@ function buildNormalizedCodexModel(
371
389
  api: "openai-codex-responses",
372
390
  provider: "openai-codex",
373
391
  baseUrl,
392
+ ...(accountId && accountId.trim().length > 0
393
+ ? {
394
+ accountAccess: {
395
+ [accountId]: parsed.cyberPrograms === undefined ? {} : { cyberPrograms: parsed.cyberPrograms },
396
+ },
397
+ }
398
+ : {}),
374
399
  reasoning: parsed.reasoning,
375
400
  input: parsed.input,
376
401
  // Codex discovery omits pricing; documented subscription credit-equivalent
@@ -1,7 +1,7 @@
1
1
  // @generated by packages/catalog/scripts/proto-parser.ts - DO NOT EDIT
2
2
 
3
3
  /**
4
- * Cursor agent protocol declarations used by Oh My Pi.
4
+ * Cursor agent protocol declarations used by omp.
5
5
  *
6
6
  * Each declaration retains only fields consumed by the client or its protocol tests.
7
7
  */
@@ -1,7 +1,7 @@
1
1
  // @generated by packages/catalog/scripts/proto-parser.ts - DO NOT EDIT
2
2
 
3
3
  /**
4
- * Devin protocol declarations used by Oh My Pi.
4
+ * Devin protocol declarations used by omp.
5
5
  *
6
6
  * Each declaration retains only fields consumed by the client or its protocol tests.
7
7
  */
@@ -631,7 +631,13 @@ function mergeDynamicModel<TApi extends Api>(existingModel: Model<TApi>, dynamic
631
631
  };
632
632
  }
633
633
  // Re-build from spec stage: sparse compat comes from `compatConfig` (the
634
- // verbatim override vocabulary), never the resolved `compat` record.
634
+ // verbatim override vocabulary), never the resolved `compat` record. The
635
+ // override is transport-scoped, so a bundled row authored for one API must
636
+ // not follow an id whose discovered route moved: Copilot's chat-completions
637
+ // rows carry `supportsReasoningEffort: false`, which would silently strip
638
+ // the effort dial once the id is pinned to Responses (#12901).
639
+ const compat =
640
+ dynamicModel.compatConfig ?? (dynamicModel.api === existingModel.api ? existingModel.compatConfig : undefined);
635
641
  return buildModel({
636
642
  ...existingModel,
637
643
  ...dynamicModel,
@@ -654,7 +660,7 @@ function mergeDynamicModel<TApi extends Api>(existingModel: Model<TApi>, dynamic
654
660
  ? { ...existingModel.headers, ...dynamicModel.headers }
655
661
  : existingModel.headers,
656
662
  resolveHeaders,
657
- compat: dynamicModel.compatConfig ?? existingModel.compatConfig,
663
+ compat,
658
664
  contextPromotionTarget: dynamicModel.contextPromotionTarget ?? existingModel.contextPromotionTarget,
659
665
  } as ModelSpec<TApi>);
660
666
  }