@oh-my-pi/pi-catalog 17.4.2 → 18.0.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.
@@ -63,13 +63,13 @@ export function resolveModelCacheProviderId(providerId: string, options: ModelCa
63
63
  }
64
64
  case "opencode-go":
65
65
  case "opencode-zen": {
66
- // v2: muse-spark-1.2 rows cached before the reasoning/thinking
67
- // recovery carry `reasoning: false` and must be refetched.
66
+ // v3: gateway-first rows cached before stencil enrichment carry null
67
+ // limits and `reasoning: false`; use a fresh namespace so they refetch.
68
68
  const configuredBaseUrl = options.baseUrl ?? getDefaultModelDiscoveryBaseUrl(providerId)!;
69
69
  const trimmedBaseUrl = configuredBaseUrl.endsWith("/") ? configuredBaseUrl.slice(0, -1) : configuredBaseUrl;
70
70
  const discoveryBaseUrl = trimmedBaseUrl.endsWith("/v1") ? trimmedBaseUrl : `${trimmedBaseUrl}/v1`;
71
71
  const scope = `${options.apiKey ?? ""}\u0000${discoveryBaseUrl}`;
72
- return `${providerId}:models-v2:${Bun.hash(scope).toString(36)}`;
72
+ return `${providerId}:models-v3:${Bun.hash(scope).toString(36)}`;
73
73
  }
74
74
  case "github-copilot": {
75
75
  // Copilot model specs bake in the plan-specific endpoint (personal vs
@@ -1,5 +1,6 @@
1
1
  import { fetchAntigravityDiscoveryModels } from "../discovery/antigravity";
2
2
  import { fetchGeminiModels } from "../discovery/gemini";
3
+ import { fetchGeminiCliQuotaModels } from "../discovery/gemini-cli";
3
4
  import { isGeminiModelId } from "../identity/family";
4
5
  import type { ModelManagerOptions } from "../model-manager";
5
6
  import type { FetchImpl } from "../types";
@@ -26,6 +27,8 @@ export interface GoogleAntigravityModelManagerConfig {
26
27
 
27
28
  export interface GoogleGeminiCliModelManagerConfig {
28
29
  oauthToken?: string;
30
+ /** GCP project id required by Workspace/Standard credentials for quota discovery. */
31
+ projectId?: string;
29
32
  endpoint?: string;
30
33
  fetch?: FetchImpl;
31
34
  }
@@ -87,13 +90,18 @@ export function googleGeminiCliModelManagerOptions(
87
90
  ...(token
88
91
  ? {
89
92
  fetchDynamicModels: async () => {
93
+ const fetcher = toDiscoveryFetch(config?.fetch);
90
94
  const models = await fetchAntigravityDiscoveryModels({
91
95
  token,
92
- fetcher: toDiscoveryFetch(config?.fetch),
96
+ fetcher,
93
97
  collapseTable: GEMINI_CLI_VARIANT_COLLAPSE_TABLE,
94
98
  });
99
+ // Antigravity's fetchAvailableModels is unreachable for
100
+ // credentials without Antigravity entitlement (Code Assist
101
+ // Standard returns HTTP 403). Fall back to the account's own
102
+ // retrieveUserQuota list on Cloud Code Assist.
95
103
  if (models === null) {
96
- return null;
104
+ return fetchGeminiCliQuotaModels({ token, projectId: config?.projectId, endpoint, fetcher });
97
105
  }
98
106
  return models
99
107
  .filter(m => isGeminiModelId(m.id))
@@ -2594,6 +2594,16 @@ function openCodeModelManagerOptions(
2594
2594
  ];
2595
2595
  return hints.includes("openai-responses") ? "openai-responses" : undefined;
2596
2596
  };
2597
+ const resolveApi = (id: string, defaultApi: Api): Api => {
2598
+ const base = openCodeBaseModelId(id);
2599
+ return (
2600
+ apiOverrides[id] ??
2601
+ (base ? apiOverrides[base] : undefined) ??
2602
+ references.get(id)?.api ??
2603
+ fallbackApi(id, base) ??
2604
+ defaultApi
2605
+ );
2606
+ };
2597
2607
  return {
2598
2608
  providerId,
2599
2609
  cacheProviderId: resolveModelCacheProviderId(providerId, { apiKey, baseUrl: discoveryBaseUrl }),
@@ -2604,6 +2614,18 @@ function openCodeModelManagerOptions(
2604
2614
  // completions after the pin shipped). Sibling-catalog drift is bounded
2605
2615
  // by the 2h cache TTL instead.
2606
2616
  dropCachedModelIdsOnStaticMismatch: Object.keys(apiOverrides),
2617
+ modelsDev: {
2618
+ fetch: () => fetchWellKnownModels(config?.fetch),
2619
+ map: payload => {
2620
+ if (!isRecord(payload)) return [];
2621
+ return mapModelsDevToModels(payload, OPENCODE_MODELS_DEV_DESCRIPTORS)
2622
+ .filter(model => model.provider === providerId)
2623
+ .map(model => {
2624
+ const api = resolveApi(model.id, "openai-completions");
2625
+ return { ...model, api, baseUrl: openCodeBaseUrlForApi(api, basePath) };
2626
+ });
2627
+ },
2628
+ },
2607
2629
  ...(apiKey && {
2608
2630
  fetchDynamicModels: () =>
2609
2631
  fetchOpenAICompatibleModels<Api>({
@@ -2614,16 +2636,9 @@ function openCodeModelManagerOptions(
2614
2636
  mapModel: (entry, defaults) => {
2615
2637
  const reference = references.get(defaults.id);
2616
2638
  const name = toModelName(entry.name, reference?.name ?? defaults.name);
2617
- const base = openCodeBaseModelId(defaults.id);
2618
- // Pins win over bundled references (stale bundled routes
2619
- // must not stick), and a base-id pin covers its billing
2620
- // variants; the responses fallback covers gateway-first ids.
2621
- const api =
2622
- apiOverrides[defaults.id] ??
2623
- (base ? apiOverrides[base] : undefined) ??
2624
- reference?.api ??
2625
- fallbackApi(defaults.id, base) ??
2626
- defaults.api;
2639
+ // Pins and bundled routing hints win over the metadata-only
2640
+ // stencil fallback; the fallback never selects a transport.
2641
+ const api = resolveApi(defaults.id, defaults.api);
2627
2642
  const baseUrl = openCodeBaseUrlForApi(api, basePath);
2628
2643
  if (isMuseSparkModelId(defaults.id)) {
2629
2644
  // Gateway lists these as bare ids with no capability
@@ -6255,6 +6270,29 @@ const MODELS_DEV_PROVIDER_DESCRIPTORS_GOOGLE_VERTEX: readonly ModelsDevProviderD
6255
6270
  }),
6256
6271
  ];
6257
6272
 
6273
+ const OPENCODE_MODELS_DEV_DESCRIPTORS: readonly ModelsDevProviderDescriptor[] = [
6274
+ openAiCompletionsDescriptor("opencode", "opencode-zen", "https://opencode.ai/zen/v1", {
6275
+ filterModel: filterActiveToolCallModels,
6276
+ resolveApi: (modelId, raw) =>
6277
+ resolveApiByRules(
6278
+ modelId,
6279
+ raw,
6280
+ OPENCODE_ZEN_API_RESOLUTION.rules,
6281
+ OPENCODE_ZEN_API_RESOLUTION.defaultResolution,
6282
+ ),
6283
+ }),
6284
+ openAiCompletionsDescriptor("opencode-go", "opencode-go", "https://opencode.ai/zen/go/v1", {
6285
+ filterModel: filterActiveToolCallModels,
6286
+ resolveApi: (modelId, raw) =>
6287
+ resolveApiByRules(
6288
+ modelId,
6289
+ raw,
6290
+ OPENCODE_GO_API_RESOLUTION.rules,
6291
+ OPENCODE_GO_API_RESOLUTION.defaultResolution,
6292
+ ),
6293
+ }),
6294
+ ];
6295
+
6258
6296
  const MODELS_DEV_PROVIDER_DESCRIPTORS_SPECIALIZED: readonly ModelsDevProviderDescriptor[] = [
6259
6297
  // --- Azure OpenAI ---
6260
6298
  // OpenAI-family models hosted on Azure, served via the Responses API. baseUrl
@@ -6276,28 +6314,8 @@ const MODELS_DEV_PROVIDER_DESCRIPTORS_SPECIALIZED: readonly ModelsDevProviderDes
6276
6314
  ),
6277
6315
  // --- Mistral ---
6278
6316
  openAiCompletionsDescriptor("mistral", "mistral", "https://api.mistral.ai/v1"),
6279
- // --- OpenCode Zen ---
6280
- openAiCompletionsDescriptor("opencode", "opencode-zen", "https://opencode.ai/zen/v1", {
6281
- filterModel: filterActiveToolCallModels,
6282
- resolveApi: (modelId, raw) =>
6283
- resolveApiByRules(
6284
- modelId,
6285
- raw,
6286
- OPENCODE_ZEN_API_RESOLUTION.rules,
6287
- OPENCODE_ZEN_API_RESOLUTION.defaultResolution,
6288
- ),
6289
- }),
6290
- // --- OpenCode Go ---
6291
- openAiCompletionsDescriptor("opencode-go", "opencode-go", "https://opencode.ai/zen/go/v1", {
6292
- filterModel: filterActiveToolCallModels,
6293
- resolveApi: (modelId, raw) =>
6294
- resolveApiByRules(
6295
- modelId,
6296
- raw,
6297
- OPENCODE_GO_API_RESOLUTION.rules,
6298
- OPENCODE_GO_API_RESOLUTION.defaultResolution,
6299
- ),
6300
- }),
6317
+ // --- OpenCode Zen / Go ---
6318
+ ...OPENCODE_MODELS_DEV_DESCRIPTORS,
6301
6319
  // --- GitHub Copilot ---
6302
6320
  openAiCompletionsDescriptor("github-copilot", "github-copilot", COPILOT_BASE_URL, {
6303
6321
  defaultContextWindow: 128000,
package/src/types.ts CHANGED
@@ -157,6 +157,7 @@ export type OpenAIReasoningDisableMode =
157
157
  | "lowest-effort"
158
158
  | "none-effort"
159
159
  | "openrouter-enabled-false"
160
+ | "venice-disable-thinking"
160
161
  | "zai-thinking-disabled"
161
162
  | "qwen-enable-thinking-false"
162
163
  | "qwen-template-false";
@@ -880,6 +881,12 @@ export type ModelTokenizer =
880
881
  // Model interface for the unified model system
881
882
  export interface Model<TApi extends Api = Api> {
882
883
  id: string;
884
+ /**
885
+ * Whether provider-bound private-use glyphs require reversible ASCII tokenization.
886
+ * Materialized by `buildModel`; request handlers read this capability instead of
887
+ * inferring it from the transport API.
888
+ */
889
+ requiresGlyphTokenization?: boolean;
883
890
  /**
884
891
  * Model id to send on the wire when it differs from `id`. Used by catalog
885
892
  * variants that present one upstream model under several local entries —
@@ -999,6 +1006,18 @@ export interface Model<TApi extends Api = Api> {
999
1006
  * `options.isOAuth = true` for the underlying provider call.
1000
1007
  */
1001
1008
  isOAuth?: boolean;
1009
+ /**
1010
+ * Amazon Bedrock Guardrail id or ARN attached to every Converse request for
1011
+ * this model. Set from `providers.amazon-bedrock.guardrailIdentifier`; the
1012
+ * streaming layer forwards it as `options.guardrailIdentifier` so accounts
1013
+ * that gate `bedrock:InvokeModel*` on the `bedrock:GuardrailIdentifier`
1014
+ * condition key stop returning an explicit deny.
1015
+ */
1016
+ guardrailIdentifier?: string;
1017
+ /** Bedrock guardrail version. Defaults to `"DRAFT"` at request time when unset. */
1018
+ guardrailVersion?: string;
1019
+ /** Bedrock guardrail trace verbosity. */
1020
+ guardrailTrace?: "enabled" | "disabled" | "enabled_full";
1002
1021
  }
1003
1022
 
1004
1023
  /**
@@ -1007,7 +1026,7 @@ export interface Model<TApi extends Api = Api> {
1007
1026
  * sparse override shape and nothing is resolved yet.
1008
1027
  */
1009
1028
  export interface ModelSpec<TApi extends Api = Api>
1010
- extends Omit<Model<TApi>, "compat" | "compatConfig" | "supportsComputerUseConfig"> {
1029
+ extends Omit<Model<TApi>, "compat" | "compatConfig" | "requiresGlyphTokenization" | "supportsComputerUseConfig"> {
1011
1030
  /** Sparse compatibility overrides; resolved into `Model.compat` by `buildModel`. */
1012
1031
  compat?: CompatConfigOf<TApi>;
1013
1032
  }