@shop-os/modelkit 0.2.2 → 0.2.4

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.
@@ -219,8 +219,9 @@ interface CatalogDisplay {
219
219
  /** Chat picker highlight flag. */
220
220
  recommended?: boolean;
221
221
  /**
222
- * Picker position: lower comes first; rows without one keep catalog order
223
- * after the ordered ones. Set it to surface a new model at the top.
222
+ * Picker position: higher comes first; rows without one keep catalog order
223
+ * after the ordered ones. Give a new model the next number up to surface
224
+ * it at the top.
224
225
  */
225
226
  sortOrder?: number;
226
227
  /**
@@ -430,10 +431,18 @@ declare const CatalogModelSchema: z.ZodType<CatalogModel>;
430
431
  declare const CatalogSchema: z.ZodType<CatalogModel[]>;
431
432
 
432
433
  type CatalogOrigin = "remote" | "last-good" | "snapshot";
434
+ interface PrimeCatalogResult {
435
+ origin: CatalogOrigin;
436
+ rowCount: number;
437
+ revision?: string;
438
+ error?: string;
439
+ }
433
440
  interface LiveCatalogState {
434
441
  catalog: Catalog;
435
- memo: Promise<unknown> | undefined;
436
- timer: ReturnType<typeof setInterval> | undefined;
442
+ memo: Promise<PrimeCatalogResult> | undefined;
443
+ timer: (ReturnType<typeof setInterval> & {
444
+ unref?: () => void;
445
+ }) | undefined;
437
446
  revision: string | undefined;
438
447
  origin: CatalogOrigin;
439
448
  }
@@ -460,11 +469,9 @@ interface CatalogSource {
460
469
  logger?: Pick<Console, "debug" | "info" | "warn" | "error">;
461
470
  }
462
471
 
463
- interface PrimeCatalogResult {
464
- origin: CatalogOrigin;
465
- rowCount: number;
472
+ interface CatalogEnvelope {
473
+ rows: CatalogModel[];
466
474
  revision?: string;
467
- error?: string;
468
475
  }
469
476
  /** Fetch, validate, swap into liveCatalog. Never throws. Second call returns the same promise. */
470
477
  declare function primeCatalog(source: CatalogSource): Promise<PrimeCatalogResult>;
@@ -525,4 +532,4 @@ declare function isModelKitError(err: unknown): err is ModelKitError;
525
532
  /** Resolve caller options against a catalog row, dispatching on `model.type`. */
526
533
  declare function resolveOptions(model: CatalogModel, request: ImageRequest | VideoRequest | AudioRequest, onUnsupported?: OnUnsupported): ResolveResult<ImageRequest | VideoRequest | AudioRequest>;
527
534
 
528
- export { ADAPTER_IDS, type AdapterEndpoints, type AdapterId, type AspectRatio, type AudioRequest, type AudioResult, type CallContext, Catalog, type CatalogAuth, type CatalogCache, type CatalogCapabilities, type CatalogDisplay, type CatalogModel, CatalogModelSchema, type CatalogOrigin, CatalogSchema, type CatalogSource, type GeneratedImage, IMAGE_MODELS, type ImageBytes, type ImageCallOptions, type ImageCallResult, type ImageQuality, type ImageRequest, type ImageResult, type ImageSafetySetting, type ImageSize, type JsonObject, type JsonPrimitive, type JsonValue, type Lifecycle, type LiveCatalogState, MODELS, type MediaPart, type MediaRef, type ModelConstraints, type ModelKitConfig, ModelKitError, type ModelKitErrorCode, type ModelKitErrorInit, type ModelType, OTHER_MODELS, type OnUnsupported, type OutputFormat, type PricingKind, type PrimeCatalogResult, type ProviderErrorBody, type ProviderKeyName, type ProviderKeys, type ProviderOptionValue, type ProviderOptions, type ReferenceLimits, type RequiredInput, type ResolveResult, type Routing, type SupportedOption, TEXT_MODELS, type UpscaleOptions, type UsageEvent, type UsageModality, type UsageUnit, VIDEO_MODELS, type VideoCallJob, type VideoCallOptions, type VideoJob, type VideoModel, type VideoRequest, type VideoResolution, type VideoResult, type Warning, isModelKitError, liveCatalog, liveState, nearestAspectRatio, primeCatalog, resetLiveCatalog, resolveAudioOptions, resolveImageOptions, resolveOptions, resolveVideoOptions };
535
+ export { ADAPTER_IDS, type AdapterEndpoints, type AdapterId, type AspectRatio, type AudioRequest, type AudioResult, type CallContext, Catalog, type CatalogAuth, type CatalogCache, type CatalogCapabilities, type CatalogDisplay, type CatalogEnvelope, type CatalogModel, CatalogModelSchema, type CatalogOrigin, CatalogSchema, type CatalogSource, type GeneratedImage, IMAGE_MODELS, type ImageBytes, type ImageCallOptions, type ImageCallResult, type ImageQuality, type ImageRequest, type ImageResult, type ImageSafetySetting, type ImageSize, type JsonObject, type JsonPrimitive, type JsonValue, type Lifecycle, type LiveCatalogState, MODELS, type MediaPart, type MediaRef, type ModelConstraints, type ModelKitConfig, ModelKitError, type ModelKitErrorCode, type ModelKitErrorInit, type ModelType, OTHER_MODELS, type OnUnsupported, type OutputFormat, type PricingKind, type PrimeCatalogResult, type ProviderErrorBody, type ProviderKeyName, type ProviderKeys, type ProviderOptionValue, type ProviderOptions, type ReferenceLimits, type RequiredInput, type ResolveResult, type Routing, type SupportedOption, TEXT_MODELS, type UpscaleOptions, type UsageEvent, type UsageModality, type UsageUnit, VIDEO_MODELS, type VideoCallJob, type VideoCallOptions, type VideoJob, type VideoModel, type VideoRequest, type VideoResolution, type VideoResult, type Warning, isModelKitError, liveCatalog, liveState, nearestAspectRatio, primeCatalog, resetLiveCatalog, resolveAudioOptions, resolveImageOptions, resolveOptions, resolveVideoOptions };
package/dist/catalog.d.ts CHANGED
@@ -219,8 +219,9 @@ interface CatalogDisplay {
219
219
  /** Chat picker highlight flag. */
220
220
  recommended?: boolean;
221
221
  /**
222
- * Picker position: lower comes first; rows without one keep catalog order
223
- * after the ordered ones. Set it to surface a new model at the top.
222
+ * Picker position: higher comes first; rows without one keep catalog order
223
+ * after the ordered ones. Give a new model the next number up to surface
224
+ * it at the top.
224
225
  */
225
226
  sortOrder?: number;
226
227
  /**
@@ -430,10 +431,18 @@ declare const CatalogModelSchema: z.ZodType<CatalogModel>;
430
431
  declare const CatalogSchema: z.ZodType<CatalogModel[]>;
431
432
 
432
433
  type CatalogOrigin = "remote" | "last-good" | "snapshot";
434
+ interface PrimeCatalogResult {
435
+ origin: CatalogOrigin;
436
+ rowCount: number;
437
+ revision?: string;
438
+ error?: string;
439
+ }
433
440
  interface LiveCatalogState {
434
441
  catalog: Catalog;
435
- memo: Promise<unknown> | undefined;
436
- timer: ReturnType<typeof setInterval> | undefined;
442
+ memo: Promise<PrimeCatalogResult> | undefined;
443
+ timer: (ReturnType<typeof setInterval> & {
444
+ unref?: () => void;
445
+ }) | undefined;
437
446
  revision: string | undefined;
438
447
  origin: CatalogOrigin;
439
448
  }
@@ -460,11 +469,9 @@ interface CatalogSource {
460
469
  logger?: Pick<Console, "debug" | "info" | "warn" | "error">;
461
470
  }
462
471
 
463
- interface PrimeCatalogResult {
464
- origin: CatalogOrigin;
465
- rowCount: number;
472
+ interface CatalogEnvelope {
473
+ rows: CatalogModel[];
466
474
  revision?: string;
467
- error?: string;
468
475
  }
469
476
  /** Fetch, validate, swap into liveCatalog. Never throws. Second call returns the same promise. */
470
477
  declare function primeCatalog(source: CatalogSource): Promise<PrimeCatalogResult>;
@@ -525,4 +532,4 @@ declare function isModelKitError(err: unknown): err is ModelKitError;
525
532
  /** Resolve caller options against a catalog row, dispatching on `model.type`. */
526
533
  declare function resolveOptions(model: CatalogModel, request: ImageRequest | VideoRequest | AudioRequest, onUnsupported?: OnUnsupported): ResolveResult<ImageRequest | VideoRequest | AudioRequest>;
527
534
 
528
- export { ADAPTER_IDS, type AdapterEndpoints, type AdapterId, type AspectRatio, type AudioRequest, type AudioResult, type CallContext, Catalog, type CatalogAuth, type CatalogCache, type CatalogCapabilities, type CatalogDisplay, type CatalogModel, CatalogModelSchema, type CatalogOrigin, CatalogSchema, type CatalogSource, type GeneratedImage, IMAGE_MODELS, type ImageBytes, type ImageCallOptions, type ImageCallResult, type ImageQuality, type ImageRequest, type ImageResult, type ImageSafetySetting, type ImageSize, type JsonObject, type JsonPrimitive, type JsonValue, type Lifecycle, type LiveCatalogState, MODELS, type MediaPart, type MediaRef, type ModelConstraints, type ModelKitConfig, ModelKitError, type ModelKitErrorCode, type ModelKitErrorInit, type ModelType, OTHER_MODELS, type OnUnsupported, type OutputFormat, type PricingKind, type PrimeCatalogResult, type ProviderErrorBody, type ProviderKeyName, type ProviderKeys, type ProviderOptionValue, type ProviderOptions, type ReferenceLimits, type RequiredInput, type ResolveResult, type Routing, type SupportedOption, TEXT_MODELS, type UpscaleOptions, type UsageEvent, type UsageModality, type UsageUnit, VIDEO_MODELS, type VideoCallJob, type VideoCallOptions, type VideoJob, type VideoModel, type VideoRequest, type VideoResolution, type VideoResult, type Warning, isModelKitError, liveCatalog, liveState, nearestAspectRatio, primeCatalog, resetLiveCatalog, resolveAudioOptions, resolveImageOptions, resolveOptions, resolveVideoOptions };
535
+ export { ADAPTER_IDS, type AdapterEndpoints, type AdapterId, type AspectRatio, type AudioRequest, type AudioResult, type CallContext, Catalog, type CatalogAuth, type CatalogCache, type CatalogCapabilities, type CatalogDisplay, type CatalogEnvelope, type CatalogModel, CatalogModelSchema, type CatalogOrigin, CatalogSchema, type CatalogSource, type GeneratedImage, IMAGE_MODELS, type ImageBytes, type ImageCallOptions, type ImageCallResult, type ImageQuality, type ImageRequest, type ImageResult, type ImageSafetySetting, type ImageSize, type JsonObject, type JsonPrimitive, type JsonValue, type Lifecycle, type LiveCatalogState, MODELS, type MediaPart, type MediaRef, type ModelConstraints, type ModelKitConfig, ModelKitError, type ModelKitErrorCode, type ModelKitErrorInit, type ModelType, OTHER_MODELS, type OnUnsupported, type OutputFormat, type PricingKind, type PrimeCatalogResult, type ProviderErrorBody, type ProviderKeyName, type ProviderKeys, type ProviderOptionValue, type ProviderOptions, type ReferenceLimits, type RequiredInput, type ResolveResult, type Routing, type SupportedOption, TEXT_MODELS, type UpscaleOptions, type UsageEvent, type UsageModality, type UsageUnit, VIDEO_MODELS, type VideoCallJob, type VideoCallOptions, type VideoJob, type VideoModel, type VideoRequest, type VideoResolution, type VideoResult, type Warning, isModelKitError, liveCatalog, liveState, nearestAspectRatio, primeCatalog, resetLiveCatalog, resolveAudioOptions, resolveImageOptions, resolveOptions, resolveVideoOptions };
package/dist/catalog.js CHANGED
@@ -119,6 +119,12 @@ var GEMINI_RATIOS = [
119
119
  "adaptive"
120
120
  ];
121
121
  function geminiImage(id, label, aliases, sizes, display, exposure, references) {
122
+ const constraints = {
123
+ aspectRatios: [...GEMINI_RATIOS],
124
+ sizes,
125
+ supports: ["safetySettings", "temperature"]
126
+ };
127
+ if (references !== void 0) constraints.references = references;
122
128
  const model = {
123
129
  id,
124
130
  aliases,
@@ -128,12 +134,7 @@ function geminiImage(id, label, aliases, sizes, display, exposure, references) {
128
134
  providerModelId: id,
129
135
  lifecycle: "active",
130
136
  exposure,
131
- constraints: {
132
- aspectRatios: [...GEMINI_RATIOS],
133
- sizes,
134
- supports: ["safetySettings", "temperature"],
135
- ...references ? { references } : {}
136
- },
137
+ constraints,
137
138
  defaults: { size: "1K", aspectRatio: "1:1" },
138
139
  usage: { ...IMAGE_USAGE, slug: "gemini" },
139
140
  pricingKind: "image_size",
@@ -2034,31 +2035,31 @@ var liveState = store[KEY] ??= {
2034
2035
  var liveCatalog = liveState.catalog;
2035
2036
 
2036
2037
  // src/catalog/load.ts
2038
+ import { z as z2 } from "zod";
2037
2039
  function rowCount() {
2038
2040
  return liveCatalog.list({ lifecycle: ["active", "deprecated", "retired"] }).length;
2039
2041
  }
2040
2042
  function authHeaders(auth) {
2041
2043
  return "bearer" in auth ? { Authorization: `Bearer ${auth.bearer}` } : { "x-api-key": auth.apiKey };
2042
2044
  }
2045
+ var EnvelopeSchema = z2.object({
2046
+ rows: CatalogSchema,
2047
+ revision: z2.string().optional()
2048
+ });
2049
+ function toEnvelope(data) {
2050
+ if (data.rows.length === 0) throw new Error("invalid catalog response: no rows");
2051
+ const envelope = { rows: data.rows };
2052
+ if (data.revision !== void 0) envelope.revision = data.revision;
2053
+ return envelope;
2054
+ }
2043
2055
  function describeError(err) {
2044
2056
  return err instanceof Error ? err.message : String(err);
2045
2057
  }
2046
- function parseEnvelope(json) {
2047
- if (typeof json !== "object" || json === null || !("rows" in json)) {
2048
- throw new Error("invalid catalog response: missing rows");
2049
- }
2050
- const rows = CatalogSchema.parse(json.rows);
2051
- const rev = json.revision;
2052
- if (typeof rev === "string") return { rows, revision: rev };
2053
- return { rows };
2054
- }
2055
2058
  function logPrimed(logger, result) {
2056
- const { origin: loggedOrigin, rowCount: loggedCount, revision: loggedRevision } = result;
2057
- logger.info("[modelkit] catalog primed", {
2058
- origin: loggedOrigin,
2059
- rowCount: loggedCount,
2060
- revision: loggedRevision
2061
- });
2059
+ const revision = result.revision === void 0 ? "" : ` revision=${result.revision}`;
2060
+ logger.info(
2061
+ `[modelkit] catalog primed origin=${result.origin} rowCount=${result.rowCount}${revision}`
2062
+ );
2062
2063
  }
2063
2064
  async function fetchRemote(source, logger) {
2064
2065
  const fetchImpl = source.fetch ?? globalThis.fetch;
@@ -2071,7 +2072,9 @@ async function fetchRemote(source, logger) {
2071
2072
  if (res.status === 304) return { kept: true };
2072
2073
  if (!res.ok) throw new Error(`catalog fetch failed with status ${res.status}`);
2073
2074
  const json = await res.json();
2074
- const { rows, revision: rev } = parseEnvelope(json);
2075
+ const parsed = EnvelopeSchema.safeParse(json);
2076
+ if (!parsed.success) throw new Error("invalid catalog response: missing rows");
2077
+ const { rows, revision: rev } = toEnvelope(parsed.data);
2075
2078
  if (rev === void 0) return { rows, fromCache: false };
2076
2079
  return { rows, revision: rev, fromCache: false };
2077
2080
  }
@@ -2080,7 +2083,7 @@ async function writeCache(source, logger, rows, rev) {
2080
2083
  try {
2081
2084
  await source.cache.set(JSON.stringify({ rows, revision: rev }));
2082
2085
  } catch (err) {
2083
- logger.warn("[modelkit] catalog cache write failed", err);
2086
+ logger.warn(`[modelkit] catalog cache write failed: ${describeError(err)}`);
2084
2087
  }
2085
2088
  }
2086
2089
  async function prime(source, logger) {
@@ -2101,12 +2104,14 @@ async function prime(source, logger) {
2101
2104
  logPrimed(logger, result);
2102
2105
  return result;
2103
2106
  } catch (err) {
2104
- logger.warn("[modelkit] catalog remote failed, trying cache", err);
2107
+ logger.warn(`[modelkit] catalog remote failed, trying cache: ${describeError(err)}`);
2105
2108
  const error = describeError(err);
2106
2109
  try {
2107
2110
  const cached = await source.cache?.get();
2108
2111
  if (!cached) throw new Error("no cached catalog");
2109
- const { rows, revision: rev } = parseEnvelope(JSON.parse(cached));
2112
+ const cachedParsed = EnvelopeSchema.safeParse(JSON.parse(cached));
2113
+ if (!cachedParsed.success) throw new Error("invalid catalog response: missing rows");
2114
+ const { rows, revision: rev } = toEnvelope(cachedParsed.data);
2110
2115
  liveCatalog.replace(rows);
2111
2116
  liveState.origin = "last-good";
2112
2117
  liveState.revision = rev;
@@ -2119,7 +2124,9 @@ async function prime(source, logger) {
2119
2124
  logPrimed(logger, result);
2120
2125
  return result;
2121
2126
  } catch (cacheErr) {
2122
- logger.warn("[modelkit] catalog cache failed, using snapshot", cacheErr);
2127
+ logger.warn(
2128
+ `[modelkit] catalog cache failed, using snapshot: ${describeError(cacheErr)}`
2129
+ );
2123
2130
  liveCatalog.replace([...MODELS]);
2124
2131
  liveState.origin = "snapshot";
2125
2132
  liveState.revision = void 0;
@@ -2142,23 +2149,24 @@ async function refresh(source, logger) {
2142
2149
  liveState.revision = fetched.revision;
2143
2150
  await writeCache(source, logger, fetched.rows, fetched.revision);
2144
2151
  } catch (err) {
2145
- logger.warn("[modelkit] catalog refresh failed, keeping current rows", err);
2152
+ logger.warn(
2153
+ `[modelkit] catalog refresh failed, keeping current rows: ${describeError(err)}`
2154
+ );
2146
2155
  }
2147
2156
  }
2148
2157
  function primeCatalog(source) {
2149
- const memo = liveState.memo;
2150
- if (memo) return memo;
2158
+ if (liveState.memo) return liveState.memo;
2151
2159
  const logger = source.logger ?? console;
2152
- liveState.memo = prime(source, logger).then((result) => {
2160
+ const pending = prime(source, logger).then((result) => {
2153
2161
  const ttlMs = source.ttlMs ?? 3e5;
2154
2162
  if (ttlMs > 0 && liveState.timer === void 0) {
2155
2163
  liveState.timer = setInterval(() => void refresh(source, logger), ttlMs);
2156
- const maybeUnref = liveState.timer;
2157
- maybeUnref.unref?.();
2164
+ liveState.timer.unref?.();
2158
2165
  }
2159
2166
  return result;
2160
2167
  });
2161
- return liveState.memo;
2168
+ liveState.memo = pending;
2169
+ return pending;
2162
2170
  }
2163
2171
  function resetLiveCatalog() {
2164
2172
  if (liveState.timer !== void 0) {