@shop-os/modelkit 0.1.8 → 0.1.9

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/dist/index.d.cts CHANGED
@@ -175,6 +175,11 @@ interface ModelConstraints {
175
175
  durationPresets?: number[];
176
176
  /** Curated quality choices for rows whose `supports` includes "quality". */
177
177
  qualityOptions?: string[];
178
+ /**
179
+ * Exact pixel size per aspect ratio for rows an app must size verbatim
180
+ * (gpt-image-2 keeps its historic WxH contract); callers pass it as `exactSize`.
181
+ */
182
+ exactSizes?: Record<string, string>;
178
183
  references?: ReferenceLimits;
179
184
  requires?: RequiredInput[];
180
185
  supports?: SupportedOption[];
@@ -216,6 +221,11 @@ interface CatalogDisplay {
216
221
  costTier?: 1 | 2 | 3;
217
222
  /** Chat picker highlight flag. */
218
223
  recommended?: boolean;
224
+ /**
225
+ * Picker position: lower comes first; rows without one keep catalog order
226
+ * after the ordered ones. Set it to surface a new model at the top.
227
+ */
228
+ sortOrder?: number;
219
229
  }
220
230
  /** Capability flags a UI keys off. Absent means false / unknown. */
221
231
  interface CatalogCapabilities {
@@ -227,7 +237,8 @@ interface CatalogCapabilities {
227
237
  acceptsSourceVideo?: boolean;
228
238
  /** Video rows: first/last frames and reference images are mutually exclusive inputs. */
229
239
  framesExcludeReferences?: boolean;
230
- /** Text rows. */
240
+ /** Text rows. `reasoning`: the model streams reasoning the UI should surface. */
241
+ reasoning?: boolean;
231
242
  vision?: boolean;
232
243
  tools?: boolean;
233
244
  structuredOutput?: boolean;
@@ -250,11 +261,21 @@ interface CatalogModel {
250
261
  */
251
262
  exposure: "catalog" | "internal";
252
263
  constraints: ModelConstraints;
253
- defaults: Partial<Omit<ImageRequest, "model" | "prompt"> & Omit<VideoRequest, "model" | "prompt"> & Omit<AudioRequest, "model" | "prompt">>;
264
+ defaults: Partial<Omit<ImageRequest, "model" | "prompt"> & Omit<VideoRequest, "model" | "prompt"> & Omit<AudioRequest, "model" | "prompt"> & {
265
+ temperature?: number;
266
+ }>;
267
+ /** Provider options merged under the caller's; text rows carry their reasoning / thinking tuning here. */
254
268
  providerOptions?: ProviderOptions;
269
+ /**
270
+ * `slug` and `providerLabel` keep an app's historic usage-event names for a
271
+ * row (e.g. cowork emits `image_gen_<slug>` from provider `<providerLabel>`);
272
+ * absent means the app derives them from the id and display.provider.
273
+ */
255
274
  usage: {
256
275
  unit: UsageUnit;
257
276
  modality: UsageModality;
277
+ slug?: string;
278
+ providerLabel?: string;
258
279
  };
259
280
  pricingKind: PricingKind;
260
281
  /** Required on every `active` row so a picker can render it without a hand-written catalog. */
package/dist/index.d.ts CHANGED
@@ -175,6 +175,11 @@ interface ModelConstraints {
175
175
  durationPresets?: number[];
176
176
  /** Curated quality choices for rows whose `supports` includes "quality". */
177
177
  qualityOptions?: string[];
178
+ /**
179
+ * Exact pixel size per aspect ratio for rows an app must size verbatim
180
+ * (gpt-image-2 keeps its historic WxH contract); callers pass it as `exactSize`.
181
+ */
182
+ exactSizes?: Record<string, string>;
178
183
  references?: ReferenceLimits;
179
184
  requires?: RequiredInput[];
180
185
  supports?: SupportedOption[];
@@ -216,6 +221,11 @@ interface CatalogDisplay {
216
221
  costTier?: 1 | 2 | 3;
217
222
  /** Chat picker highlight flag. */
218
223
  recommended?: boolean;
224
+ /**
225
+ * Picker position: lower comes first; rows without one keep catalog order
226
+ * after the ordered ones. Set it to surface a new model at the top.
227
+ */
228
+ sortOrder?: number;
219
229
  }
220
230
  /** Capability flags a UI keys off. Absent means false / unknown. */
221
231
  interface CatalogCapabilities {
@@ -227,7 +237,8 @@ interface CatalogCapabilities {
227
237
  acceptsSourceVideo?: boolean;
228
238
  /** Video rows: first/last frames and reference images are mutually exclusive inputs. */
229
239
  framesExcludeReferences?: boolean;
230
- /** Text rows. */
240
+ /** Text rows. `reasoning`: the model streams reasoning the UI should surface. */
241
+ reasoning?: boolean;
231
242
  vision?: boolean;
232
243
  tools?: boolean;
233
244
  structuredOutput?: boolean;
@@ -250,11 +261,21 @@ interface CatalogModel {
250
261
  */
251
262
  exposure: "catalog" | "internal";
252
263
  constraints: ModelConstraints;
253
- defaults: Partial<Omit<ImageRequest, "model" | "prompt"> & Omit<VideoRequest, "model" | "prompt"> & Omit<AudioRequest, "model" | "prompt">>;
264
+ defaults: Partial<Omit<ImageRequest, "model" | "prompt"> & Omit<VideoRequest, "model" | "prompt"> & Omit<AudioRequest, "model" | "prompt"> & {
265
+ temperature?: number;
266
+ }>;
267
+ /** Provider options merged under the caller's; text rows carry their reasoning / thinking tuning here. */
254
268
  providerOptions?: ProviderOptions;
269
+ /**
270
+ * `slug` and `providerLabel` keep an app's historic usage-event names for a
271
+ * row (e.g. cowork emits `image_gen_<slug>` from provider `<providerLabel>`);
272
+ * absent means the app derives them from the id and display.provider.
273
+ */
255
274
  usage: {
256
275
  unit: UsageUnit;
257
276
  modality: UsageModality;
277
+ slug?: string;
278
+ providerLabel?: string;
258
279
  };
259
280
  pricingKind: PricingKind;
260
281
  /** Required on every `active` row so a picker can render it without a hand-written catalog. */
package/dist/index.js CHANGED
@@ -130,7 +130,7 @@ function geminiImage(id, label, aliases, sizes, display, exposure) {
130
130
  supports: ["safetySettings", "temperature"]
131
131
  },
132
132
  defaults: { size: "1K", aspectRatio: "1:1" },
133
- usage: { ...IMAGE_USAGE },
133
+ usage: { ...IMAGE_USAGE, slug: "gemini" },
134
134
  pricingKind: "image_size",
135
135
  display,
136
136
  capabilities: { ...IMAGE_GENERATE_EDIT }
@@ -198,6 +198,15 @@ var IMAGE_MODELS = [
198
198
  lifecycle: "active",
199
199
  exposure: "catalog",
200
200
  constraints: {
201
+ exactSizes: {
202
+ "1:1": "1024x1024",
203
+ "3:2": "1536x1024",
204
+ "2:3": "1024x1536",
205
+ "16:9": "2048x1152",
206
+ "9:16": "1152x2048",
207
+ "4:5": "1024x1280",
208
+ "5:4": "1280x1024"
209
+ },
201
210
  aspectRatios: ["1:1", "3:2", "2:3", "16:9", "9:16", "4:5", "5:4", "adaptive"],
202
211
  sizes: ["1K", "2K", "4K"],
203
212
  qualityOptions: ["auto", "low", "medium", "high"],
@@ -205,7 +214,7 @@ var IMAGE_MODELS = [
205
214
  supports: ["quality", "count"]
206
215
  },
207
216
  defaults: { size: "1K", aspectRatio: "adaptive", quality: "auto" },
208
- usage: { ...IMAGE_USAGE },
217
+ usage: { ...IMAGE_USAGE, slug: "gpt" },
209
218
  pricingKind: "image_size",
210
219
  display: {
211
220
  provider: "openai",
@@ -225,6 +234,15 @@ var IMAGE_MODELS = [
225
234
  lifecycle: "active",
226
235
  exposure: "internal",
227
236
  constraints: {
237
+ exactSizes: {
238
+ "1:1": "1024x1024",
239
+ "3:2": "1536x1024",
240
+ "2:3": "1024x1536",
241
+ "16:9": "2048x1152",
242
+ "9:16": "1152x2048",
243
+ "4:5": "1024x1280",
244
+ "5:4": "1280x1024"
245
+ },
228
246
  aspectRatios: ["1:1", "3:2", "2:3", "16:9", "9:16", "4:5", "5:4", "adaptive"],
229
247
  sizes: ["1K", "2K", "4K"],
230
248
  qualityOptions: ["auto", "low", "medium", "high"],
@@ -251,6 +269,15 @@ var IMAGE_MODELS = [
251
269
  lifecycle: "active",
252
270
  exposure: "internal",
253
271
  constraints: {
272
+ exactSizes: {
273
+ "1:1": "1024x1024",
274
+ "3:2": "1536x1024",
275
+ "2:3": "1024x1536",
276
+ "16:9": "2048x1152",
277
+ "9:16": "1152x2048",
278
+ "4:5": "1024x1280",
279
+ "5:4": "1280x1024"
280
+ },
254
281
  aspectRatios: ["1:1", "3:2", "2:3", "16:9", "9:16", "4:5", "5:4", "adaptive"],
255
282
  sizes: ["1K", "2K", "4K"],
256
283
  qualityOptions: ["auto", "low", "medium", "high"],
@@ -296,7 +323,7 @@ var IMAGE_MODELS = [
296
323
  supports: ["count", "outputFormat"]
297
324
  },
298
325
  defaults: { size: "1K", aspectRatio: "1:1", outputFormat: "png", count: 1 },
299
- usage: { ...IMAGE_USAGE },
326
+ usage: { ...IMAGE_USAGE, slug: "muse" },
300
327
  pricingKind: "image_size",
301
328
  display: {
302
329
  provider: "meta",
@@ -713,6 +740,14 @@ function text(id, label, providerModelId, extra) {
713
740
  ...extra
714
741
  };
715
742
  }
743
+ var ANTHROPIC_THINKING = {
744
+ anthropic: { thinking: { type: "enabled", budgetTokens: 4e3 }, sendReasoning: true }
745
+ };
746
+ var ANTHROPIC_ADAPTIVE = {
747
+ anthropic: { thinking: { type: "adaptive", display: "summarized" }, sendReasoning: true }
748
+ };
749
+ var OPENAI_REASONING = { openai: { reasoningEffort: "medium", reasoningSummary: "auto" } };
750
+ var DEEPSEEK_THINKING = { deepseek: { thinking: { type: "enabled" } } };
716
751
  var TEXT_MODELS = [
717
752
  text("gpt-4o", "GPT-4o", "gpt-4o", {
718
753
  exposure: "internal",
@@ -791,6 +826,7 @@ var TEXT_MODELS = [
791
826
  }
792
827
  }),
793
828
  text("gpt-5.6-luna", "GPT-5.6 Luna", "gpt-5.6-luna", {
829
+ providerOptions: OPENAI_REASONING,
794
830
  exposure: "catalog",
795
831
  display: {
796
832
  provider: "openai",
@@ -798,6 +834,7 @@ var TEXT_MODELS = [
798
834
  description: "OpenAI GPT-5.6 Luna cost-optimized tier of the GPT-5.6 reasoning family; text and image input, 1.05M-token context."
799
835
  },
800
836
  capabilities: {
837
+ reasoning: true,
801
838
  vision: true,
802
839
  tools: true,
803
840
  structuredOutput: true,
@@ -805,6 +842,7 @@ var TEXT_MODELS = [
805
842
  }
806
843
  }),
807
844
  text("gpt-5.6-terra", "GPT-5.6 Terra", "gpt-5.6-terra", {
845
+ providerOptions: OPENAI_REASONING,
808
846
  exposure: "catalog",
809
847
  display: {
810
848
  provider: "openai",
@@ -812,6 +850,7 @@ var TEXT_MODELS = [
812
850
  description: "OpenAI GPT-5.6 Terra balanced tier of the GPT-5.6 reasoning family; text and image input, 1.05M-token context."
813
851
  },
814
852
  capabilities: {
853
+ reasoning: true,
815
854
  vision: true,
816
855
  tools: true,
817
856
  structuredOutput: true,
@@ -819,6 +858,7 @@ var TEXT_MODELS = [
819
858
  }
820
859
  }),
821
860
  text("gpt-5.6-sol", "GPT-5.6 Sol", "gpt-5.6-sol", {
861
+ providerOptions: OPENAI_REASONING,
822
862
  exposure: "catalog",
823
863
  display: {
824
864
  provider: "openai",
@@ -826,6 +866,7 @@ var TEXT_MODELS = [
826
866
  description: "OpenAI GPT-5.6 Sol flagship tier of the GPT-5.6 reasoning family; text and image input, 1.05M-token context."
827
867
  },
828
868
  capabilities: {
869
+ reasoning: true,
829
870
  vision: true,
830
871
  tools: true,
831
872
  structuredOutput: true,
@@ -845,6 +886,7 @@ var TEXT_MODELS = [
845
886
  }),
846
887
  // Anthropic retired the dated 4.0 ids; callers that still send them get 4.6.
847
888
  text("claude-sonnet-4-6", "Claude Sonnet 4.6", "claude-sonnet-4-6", {
889
+ providerOptions: ANTHROPIC_THINKING,
848
890
  exposure: "catalog",
849
891
  aliases: [
850
892
  "claude-sonnet-4.6",
@@ -858,6 +900,7 @@ var TEXT_MODELS = [
858
900
  description: "Anthropic Claude Sonnet 4.6 (legacy) balanced model; text and image input, 1M-token context."
859
901
  },
860
902
  capabilities: {
903
+ reasoning: true,
861
904
  vision: true,
862
905
  tools: true,
863
906
  structuredOutput: true,
@@ -865,6 +908,7 @@ var TEXT_MODELS = [
865
908
  }
866
909
  }),
867
910
  text("claude-sonnet-5", "Claude Sonnet 5", "claude-sonnet-5", {
911
+ providerOptions: ANTHROPIC_ADAPTIVE,
868
912
  exposure: "catalog",
869
913
  display: {
870
914
  provider: "anthropic",
@@ -872,6 +916,7 @@ var TEXT_MODELS = [
872
916
  description: "Anthropic Claude Sonnet 5 current balanced model; text and image input, 1M-token context."
873
917
  },
874
918
  capabilities: {
919
+ reasoning: true,
875
920
  vision: true,
876
921
  tools: true,
877
922
  structuredOutput: true,
@@ -879,6 +924,7 @@ var TEXT_MODELS = [
879
924
  }
880
925
  }),
881
926
  text("claude-opus-4-8", "Claude Opus 4.8", "claude-opus-4-8", {
927
+ providerOptions: ANTHROPIC_ADAPTIVE,
882
928
  exposure: "catalog",
883
929
  aliases: ["claude-opus-4.8", "claude-opus-4", "claude-opus-4.0", "claude-opus-4-20250514"],
884
930
  display: {
@@ -887,6 +933,7 @@ var TEXT_MODELS = [
887
933
  description: "Anthropic Claude Opus 4.8 (legacy) frontier model; text and image input, 1M-token context."
888
934
  },
889
935
  capabilities: {
936
+ reasoning: true,
890
937
  vision: true,
891
938
  tools: true,
892
939
  structuredOutput: true,
@@ -894,6 +941,7 @@ var TEXT_MODELS = [
894
941
  }
895
942
  }),
896
943
  text("claude-haiku-4-5", "Claude Haiku 4.5", "claude-haiku-4-5", {
944
+ providerOptions: ANTHROPIC_THINKING,
897
945
  exposure: "catalog",
898
946
  aliases: ["claude-haiku-4.5", "claude-haiku-4-5-20251001", "claude-haiku-4"],
899
947
  display: {
@@ -901,7 +949,13 @@ var TEXT_MODELS = [
901
949
  costTier: 1,
902
950
  description: "Anthropic Claude Haiku 4.5 fast model with near-frontier intelligence; text and image input, 200K-token context."
903
951
  },
904
- capabilities: { vision: true, tools: true, structuredOutput: true, contextWindow: 2e5 }
952
+ capabilities: {
953
+ reasoning: true,
954
+ vision: true,
955
+ tools: true,
956
+ structuredOutput: true,
957
+ contextWindow: 2e5
958
+ }
905
959
  }),
906
960
  text("claude-opus-5", "Claude Opus 5", "claude-opus-5", {
907
961
  exposure: "internal",
@@ -1093,15 +1147,21 @@ var TEXT_MODELS = [
1093
1147
  contextWindow: 128e3
1094
1148
  }
1095
1149
  }),
1096
- text("deepseek-v4-flash", "DeepSeek V4 Flash", "deepseek-v4-flash", {
1150
+ // DeepSeek retired V4 Flash upstream and routes the old id to V4.1 Flash at
1151
+ // Flash rates (https://api-docs.deepseek.com/news/news260910/); the old id
1152
+ // stays an alias so stored selections keep resolving.
1153
+ text("deepseek-flash", "DeepSeek V4.1 Flash", "deepseek-flash", {
1154
+ providerOptions: DEEPSEEK_THINKING,
1155
+ aliases: ["deepseek-v4-flash"],
1097
1156
  exposure: "catalog",
1098
1157
  display: {
1099
1158
  provider: "deepseek",
1100
1159
  costTier: 1,
1101
1160
  recommended: true,
1102
- description: "DeepSeek V4 Flash thinking/non-thinking model with vision, tool calls, and JSON output; 1M-token context and up to 384K output tokens."
1161
+ description: "DeepSeek V4.1 Flash thinking/non-thinking model with vision, tool calls, and JSON output; 1M-token context and up to 384K output tokens."
1103
1162
  },
1104
1163
  capabilities: {
1164
+ reasoning: true,
1105
1165
  vision: true,
1106
1166
  tools: true,
1107
1167
  structuredOutput: true,
@@ -1109,6 +1169,7 @@ var TEXT_MODELS = [
1109
1169
  }
1110
1170
  }),
1111
1171
  text("deepseek-v4-pro", "DeepSeek V4 Pro", "deepseek-v4-pro", {
1172
+ providerOptions: DEEPSEEK_THINKING,
1112
1173
  exposure: "catalog",
1113
1174
  display: {
1114
1175
  provider: "deepseek",
@@ -1116,6 +1177,7 @@ var TEXT_MODELS = [
1116
1177
  description: "DeepSeek V4 Pro thinking/non-thinking text model with tool calls and JSON output (no vision); 1M-token context and up to 384K output tokens."
1117
1178
  },
1118
1179
  capabilities: {
1180
+ reasoning: true,
1119
1181
  vision: false,
1120
1182
  tools: true,
1121
1183
  structuredOutput: true,
@@ -1139,6 +1201,7 @@ var TEXT_MODELS = [
1139
1201
  }),
1140
1202
  // Moonshot retired kimi-k2.5 on 2026-08-31 and no longer publishes its specs.
1141
1203
  text("kimi-k2.5", "Kimi K2.5", "kimi-k2.5", {
1204
+ defaults: { temperature: 1 },
1142
1205
  exposure: "catalog",
1143
1206
  display: {
1144
1207
  provider: "moonshot",
@@ -1148,6 +1211,7 @@ var TEXT_MODELS = [
1148
1211
  capabilities: {}
1149
1212
  }),
1150
1213
  text("kimi-k3", "Kimi K3", "kimi-k3", {
1214
+ defaults: { temperature: 1 },
1151
1215
  exposure: "catalog",
1152
1216
  display: {
1153
1217
  provider: "moonshot",
@@ -1155,6 +1219,7 @@ var TEXT_MODELS = [
1155
1219
  description: "Moonshot Kimi K3 flagship model with native visual understanding and always-on thinking; text, image, and video input, 1M-token context."
1156
1220
  },
1157
1221
  capabilities: {
1222
+ reasoning: true,
1158
1223
  vision: true,
1159
1224
  tools: true,
1160
1225
  structuredOutput: true,
@@ -1209,7 +1274,7 @@ var VIDEO_MODELS = [
1209
1274
  supports: ["lastFrame"]
1210
1275
  },
1211
1276
  defaults: { durationSeconds: 8, resolution: "720p", aspectRatio: "16:9" },
1212
- usage: { ...VIDEO_USAGE },
1277
+ usage: { ...VIDEO_USAGE, slug: "veo" },
1213
1278
  pricingKind: "video_per_second",
1214
1279
  display: {
1215
1280
  provider: "google",
@@ -1301,7 +1366,7 @@ var VIDEO_MODELS = [
1301
1366
  supports: []
1302
1367
  },
1303
1368
  defaults: {},
1304
- usage: { ...VIDEO_USAGE },
1369
+ usage: { ...VIDEO_USAGE, slug: "gemini_omni" },
1305
1370
  pricingKind: "video_per_second",
1306
1371
  display: {
1307
1372
  provider: "google",
@@ -1360,7 +1425,7 @@ var VIDEO_MODELS = [
1360
1425
  aspectRatio: "16:9",
1361
1426
  generateAudio: true
1362
1427
  },
1363
- usage: { ...VIDEO_USAGE },
1428
+ usage: { ...VIDEO_USAGE, slug: "seedance2", providerLabel: "byteplus" },
1364
1429
  pricingKind: "video_per_second",
1365
1430
  display: {
1366
1431
  provider: "bytedance",
@@ -1482,7 +1547,7 @@ var VIDEO_MODELS = [
1482
1547
  cfgScale: 0.5,
1483
1548
  negativePrompt: NEGATIVE_PROMPT
1484
1549
  },
1485
- usage: { ...VIDEO_USAGE },
1550
+ usage: { ...VIDEO_USAGE, slug: "grok" },
1486
1551
  pricingKind: "video_per_second",
1487
1552
  display: {
1488
1553
  provider: "kuaishou",
@@ -1933,6 +1998,40 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
1933
1998
  model: model.id
1934
1999
  });
1935
2000
  }
2001
+ if (merged.sourceVideo !== void 0 && !model.capabilities?.acceptsSourceVideo) {
2002
+ if (onUnsupported === "error") {
2003
+ throw new ModelKitError({
2004
+ code: "unsupported_option",
2005
+ message: `${model.id} does not take a source video`,
2006
+ model: model.id
2007
+ });
2008
+ }
2009
+ warnings.push({
2010
+ code: "option_ignored",
2011
+ field: "sourceVideo",
2012
+ message: `${model.id} does not take a source video; dropped`
2013
+ });
2014
+ delete merged.sourceVideo;
2015
+ }
2016
+ const hasFrames = merged.firstFrame !== void 0 || merged.lastFrame !== void 0;
2017
+ const hasRefs = compact(merged.referenceImages).length + compact(merged.referenceVideos).length + compact(merged.referenceAudios).length > 0;
2018
+ if (hasFrames && hasRefs && model.capabilities?.framesExcludeReferences) {
2019
+ if (onUnsupported === "error") {
2020
+ throw new ModelKitError({
2021
+ code: "unsupported_option",
2022
+ message: `${model.id} takes frames or references, not both`,
2023
+ model: model.id
2024
+ });
2025
+ }
2026
+ warnings.push({
2027
+ code: "option_ignored",
2028
+ field: "referenceImages",
2029
+ message: `${model.id} takes frames or references, not both; references dropped`
2030
+ });
2031
+ delete merged.referenceImages;
2032
+ delete merged.referenceVideos;
2033
+ delete merged.referenceAudios;
2034
+ }
1936
2035
  for (const input of c.ratioIgnoredWith ?? []) {
1937
2036
  if (merged[input] !== void 0 && merged.aspectRatio !== void 0) {
1938
2037
  if (request.aspectRatio !== void 0) {