@shop-os/modelkit 0.2.12 → 0.2.14
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/CHANGELOG.md +19 -0
- package/README.md +43 -2
- package/dist/catalog.cjs +422 -148
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.d.cts +294 -1
- package/dist/catalog.d.ts +294 -1
- package/dist/catalog.js +422 -148
- package/dist/catalog.js.map +1 -1
- package/dist/index.cjs +5835 -5126
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +371 -38
- package/dist/index.d.ts +371 -38
- package/dist/index.js +4195 -3495
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/catalog.js
CHANGED
|
@@ -126,7 +126,9 @@ function normalizeExposure(value) {
|
|
|
126
126
|
if (value === "catalog") return ["cowork", "space_builder"];
|
|
127
127
|
if (value === "internal") return [];
|
|
128
128
|
if (Array.isArray(value)) {
|
|
129
|
-
if (value.every(
|
|
129
|
+
if (value.every(
|
|
130
|
+
(entry) => SURFACES.includes(entry)
|
|
131
|
+
)) {
|
|
130
132
|
const present = new Set(value);
|
|
131
133
|
return SURFACES.filter((surface) => present.has(surface));
|
|
132
134
|
}
|
|
@@ -1824,7 +1826,215 @@ var MODELS = [
|
|
|
1824
1826
|
];
|
|
1825
1827
|
|
|
1826
1828
|
// src/catalog/schema.ts
|
|
1829
|
+
import { z as z2 } from "zod";
|
|
1830
|
+
|
|
1831
|
+
// src/catalog/collisions.ts
|
|
1832
|
+
function collisionIssues(rows) {
|
|
1833
|
+
const issues = [];
|
|
1834
|
+
const seenIds = /* @__PURE__ */ new Map();
|
|
1835
|
+
const seenAliases = /* @__PURE__ */ new Map();
|
|
1836
|
+
rows.forEach((row, index) => {
|
|
1837
|
+
if (seenIds.has(row.id)) {
|
|
1838
|
+
issues.push({
|
|
1839
|
+
index,
|
|
1840
|
+
path: ["id"],
|
|
1841
|
+
message: `Duplicate model id "${row.id}"`
|
|
1842
|
+
});
|
|
1843
|
+
} else {
|
|
1844
|
+
const aliasOwner = seenAliases.get(row.id);
|
|
1845
|
+
if (aliasOwner !== void 0) {
|
|
1846
|
+
issues.push({
|
|
1847
|
+
index: aliasOwner.index,
|
|
1848
|
+
path: ["aliases", aliasOwner.aliasIndex],
|
|
1849
|
+
message: `Alias "${row.id}" collides with a model id`
|
|
1850
|
+
});
|
|
1851
|
+
}
|
|
1852
|
+
seenIds.set(row.id, index);
|
|
1853
|
+
}
|
|
1854
|
+
const local = /* @__PURE__ */ new Set();
|
|
1855
|
+
for (const [aliasIndex, alias] of row.aliases.entries()) {
|
|
1856
|
+
if (alias === row.id || seenIds.has(alias)) {
|
|
1857
|
+
issues.push({
|
|
1858
|
+
index,
|
|
1859
|
+
path: ["aliases", aliasIndex],
|
|
1860
|
+
message: `Alias "${alias}" collides with a model id`
|
|
1861
|
+
});
|
|
1862
|
+
} else if (local.has(alias) || seenAliases.has(alias)) {
|
|
1863
|
+
issues.push({
|
|
1864
|
+
index,
|
|
1865
|
+
path: ["aliases", aliasIndex],
|
|
1866
|
+
message: `Duplicate alias "${alias}"`
|
|
1867
|
+
});
|
|
1868
|
+
}
|
|
1869
|
+
local.add(alias);
|
|
1870
|
+
if (!seenAliases.has(alias)) seenAliases.set(alias, { index, aliasIndex });
|
|
1871
|
+
}
|
|
1872
|
+
});
|
|
1873
|
+
return issues;
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1876
|
+
// src/catalog/input-spec.ts
|
|
1827
1877
|
import { z } from "zod";
|
|
1878
|
+
var VIDEO_INPUT_SPEC_KEYS = [
|
|
1879
|
+
"prompt",
|
|
1880
|
+
"durationSeconds",
|
|
1881
|
+
"aspectRatio",
|
|
1882
|
+
"resolution",
|
|
1883
|
+
"firstFrame",
|
|
1884
|
+
"lastFrame",
|
|
1885
|
+
"seed",
|
|
1886
|
+
"negativePrompt",
|
|
1887
|
+
"generateAudio",
|
|
1888
|
+
"cfgScale",
|
|
1889
|
+
"promptExpansion",
|
|
1890
|
+
"referenceImages"
|
|
1891
|
+
];
|
|
1892
|
+
var AUDIO_INPUT_SPEC_KEYS = [
|
|
1893
|
+
"prompt",
|
|
1894
|
+
"durationSeconds",
|
|
1895
|
+
"seed",
|
|
1896
|
+
"negativePrompt",
|
|
1897
|
+
"references",
|
|
1898
|
+
"sourceVideo",
|
|
1899
|
+
"instrumental"
|
|
1900
|
+
];
|
|
1901
|
+
var INPUT_SPEC_SUPPORTS_KEYS = [
|
|
1902
|
+
"lastFrame",
|
|
1903
|
+
"seed",
|
|
1904
|
+
"negativePrompt",
|
|
1905
|
+
"generateAudio",
|
|
1906
|
+
"cfgScale",
|
|
1907
|
+
"promptExpansion",
|
|
1908
|
+
"instrumental"
|
|
1909
|
+
];
|
|
1910
|
+
var VIDEO_KEY_SET = new Set(VIDEO_INPUT_SPEC_KEYS);
|
|
1911
|
+
var AUDIO_KEY_SET = new Set(AUDIO_INPUT_SPEC_KEYS);
|
|
1912
|
+
var ALL_KEY_SET = /* @__PURE__ */ new Set([
|
|
1913
|
+
...VIDEO_INPUT_SPEC_KEYS,
|
|
1914
|
+
...AUDIO_INPUT_SPEC_KEYS
|
|
1915
|
+
]);
|
|
1916
|
+
var ProviderScalarSchema = z.union([z.string(), z.number(), z.boolean()]);
|
|
1917
|
+
var FieldsSchema = z.record(z.string(), z.string().min(1)).superRefine((fields, ctx) => {
|
|
1918
|
+
const keys = Object.keys(fields);
|
|
1919
|
+
if (keys.length === 0) {
|
|
1920
|
+
ctx.addIssue({
|
|
1921
|
+
code: "custom",
|
|
1922
|
+
message: "inputSpec.fields must name at least one field"
|
|
1923
|
+
});
|
|
1924
|
+
return;
|
|
1925
|
+
}
|
|
1926
|
+
for (const key of keys) {
|
|
1927
|
+
if (!ALL_KEY_SET.has(key)) {
|
|
1928
|
+
ctx.addIssue({
|
|
1929
|
+
code: "custom",
|
|
1930
|
+
message: `inputSpec.fields has unknown canonical key "${key}"`
|
|
1931
|
+
});
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
});
|
|
1935
|
+
var ValuesSchema = z.record(z.string(), z.record(z.string(), ProviderScalarSchema)).superRefine((values, ctx) => {
|
|
1936
|
+
for (const key of Object.keys(values)) {
|
|
1937
|
+
if (!ALL_KEY_SET.has(key)) {
|
|
1938
|
+
ctx.addIssue({
|
|
1939
|
+
code: "custom",
|
|
1940
|
+
message: `inputSpec.values has unknown canonical key "${key}"`
|
|
1941
|
+
});
|
|
1942
|
+
}
|
|
1943
|
+
}
|
|
1944
|
+
});
|
|
1945
|
+
var StaticSchema = z.record(z.string(), ProviderScalarSchema);
|
|
1946
|
+
var InputSpecSchema = z.strictObject({
|
|
1947
|
+
fields: FieldsSchema,
|
|
1948
|
+
values: ValuesSchema.optional(),
|
|
1949
|
+
static: StaticSchema.optional()
|
|
1950
|
+
}).superRefine((spec, ctx) => {
|
|
1951
|
+
const mappedNames = new Set(Object.values(spec.fields));
|
|
1952
|
+
for (const key of Object.keys(spec.static ?? {})) {
|
|
1953
|
+
if (mappedNames.has(key)) {
|
|
1954
|
+
ctx.addIssue({
|
|
1955
|
+
code: "custom",
|
|
1956
|
+
path: ["static", key],
|
|
1957
|
+
message: `inputSpec.static "${key}" collides with a mapped field name`
|
|
1958
|
+
});
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
});
|
|
1962
|
+
function validateInputSpec(raw, row) {
|
|
1963
|
+
const parsed = InputSpecSchema.safeParse(raw);
|
|
1964
|
+
if (!parsed.success) {
|
|
1965
|
+
return {
|
|
1966
|
+
ok: false,
|
|
1967
|
+
issues: parsed.error.issues.map((issue) => ({
|
|
1968
|
+
path: issue.path,
|
|
1969
|
+
message: issue.message
|
|
1970
|
+
}))
|
|
1971
|
+
};
|
|
1972
|
+
}
|
|
1973
|
+
const spec = parsed.data;
|
|
1974
|
+
if (row.adapter !== "replicate") {
|
|
1975
|
+
return {
|
|
1976
|
+
ok: false,
|
|
1977
|
+
issues: [{ path: [], message: "inputSpec is only supported on replicate rows" }]
|
|
1978
|
+
};
|
|
1979
|
+
}
|
|
1980
|
+
const issues = [];
|
|
1981
|
+
if (row.type !== "video" && row.type !== "audio") {
|
|
1982
|
+
issues.push({
|
|
1983
|
+
path: [],
|
|
1984
|
+
message: `inputSpec is not supported for "${row.type}" rows`
|
|
1985
|
+
});
|
|
1986
|
+
} else {
|
|
1987
|
+
const allowed = row.type === "video" ? VIDEO_KEY_SET : AUDIO_KEY_SET;
|
|
1988
|
+
for (const key of Object.keys(spec.fields)) {
|
|
1989
|
+
if (!allowed.has(key)) {
|
|
1990
|
+
issues.push({
|
|
1991
|
+
path: ["fields", key],
|
|
1992
|
+
message: `inputSpec.fields "${key}" is not supported for ${row.type} rows`
|
|
1993
|
+
});
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
for (const key of Object.keys(spec.values ?? {})) {
|
|
1997
|
+
if (!allowed.has(key)) {
|
|
1998
|
+
issues.push({
|
|
1999
|
+
path: ["values", key],
|
|
2000
|
+
message: `inputSpec.values "${key}" is not supported for ${row.type} rows`
|
|
2001
|
+
});
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
const seenNames = /* @__PURE__ */ new Map();
|
|
2006
|
+
for (const [key, name] of Object.entries(spec.fields)) {
|
|
2007
|
+
const first = seenNames.get(name);
|
|
2008
|
+
if (first === void 0) seenNames.set(name, key);
|
|
2009
|
+
else {
|
|
2010
|
+
issues.push({
|
|
2011
|
+
path: ["fields", key],
|
|
2012
|
+
message: `inputSpec.fields "${first}" and "${key}" both map to "${name}"`
|
|
2013
|
+
});
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
for (const key of Object.keys(spec.values ?? {})) {
|
|
2017
|
+
if (!(key in spec.fields)) {
|
|
2018
|
+
issues.push({
|
|
2019
|
+
path: ["values", key],
|
|
2020
|
+
message: `inputSpec.values "${key}" has no matching fields entry`
|
|
2021
|
+
});
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
const supports = row.constraints.supports ?? [];
|
|
2025
|
+
for (const key of INPUT_SPEC_SUPPORTS_KEYS) {
|
|
2026
|
+
if (key in spec.fields && !supports.includes(key)) {
|
|
2027
|
+
issues.push({
|
|
2028
|
+
path: ["fields", key],
|
|
2029
|
+
message: `inputSpec.fields "${key}" needs "${key}" in constraints.supports`
|
|
2030
|
+
});
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
if (issues.length > 0) return { ok: false, issues };
|
|
2034
|
+
return { ok: true, spec };
|
|
2035
|
+
}
|
|
2036
|
+
|
|
2037
|
+
// src/catalog/schema.ts
|
|
1828
2038
|
var ADAPTER_IDS = [
|
|
1829
2039
|
"ai-sdk-text",
|
|
1830
2040
|
"google-image",
|
|
@@ -1837,16 +2047,16 @@ var ADAPTER_IDS = [
|
|
|
1837
2047
|
"higgsfield",
|
|
1838
2048
|
"xai-video"
|
|
1839
2049
|
];
|
|
1840
|
-
var ModelTypeSchema =
|
|
1841
|
-
var LifecycleSchema =
|
|
1842
|
-
var SurfaceSchema =
|
|
2050
|
+
var ModelTypeSchema = z2.enum(["text", "image", "video", "audio", "upscale", "bg-remove"]);
|
|
2051
|
+
var LifecycleSchema = z2.enum(["active", "deprecated", "retired"]);
|
|
2052
|
+
var SurfaceSchema = z2.enum(["cowork", "space_builder"]);
|
|
1843
2053
|
var SURFACES2 = SurfaceSchema.options;
|
|
1844
|
-
var ExposureSchema =
|
|
2054
|
+
var ExposureSchema = z2.preprocess(
|
|
1845
2055
|
normalizeExposure,
|
|
1846
|
-
|
|
2056
|
+
z2.array(SurfaceSchema)
|
|
1847
2057
|
);
|
|
1848
|
-
var AdapterSchema =
|
|
1849
|
-
var AspectRatioSchema =
|
|
2058
|
+
var AdapterSchema = z2.enum(ADAPTER_IDS);
|
|
2059
|
+
var AspectRatioSchema = z2.enum([
|
|
1850
2060
|
"1:1",
|
|
1851
2061
|
"16:9",
|
|
1852
2062
|
"9:16",
|
|
@@ -1861,12 +2071,12 @@ var AspectRatioSchema = z.enum([
|
|
|
1861
2071
|
"97:30",
|
|
1862
2072
|
"adaptive"
|
|
1863
2073
|
]);
|
|
1864
|
-
var ImageSizeSchema =
|
|
1865
|
-
var VideoResolutionSchema =
|
|
1866
|
-
var ImageQualitySchema =
|
|
1867
|
-
var OutputFormatSchema =
|
|
1868
|
-
var RequiredInputSchema =
|
|
1869
|
-
var SupportedOptionSchema =
|
|
2074
|
+
var ImageSizeSchema = z2.enum(["512", "1K", "2K", "4K"]);
|
|
2075
|
+
var VideoResolutionSchema = z2.enum(["360p", "480p", "720p", "768p", "1080p", "2k", "4k"]);
|
|
2076
|
+
var ImageQualitySchema = z2.enum(["auto", "low", "medium", "high", "xhigh", "max"]);
|
|
2077
|
+
var OutputFormatSchema = z2.enum(["png", "jpeg", "webp"]);
|
|
2078
|
+
var RequiredInputSchema = z2.enum(["firstFrame", "sourceVideo", "references"]);
|
|
2079
|
+
var SupportedOptionSchema = z2.enum([
|
|
1870
2080
|
"seed",
|
|
1871
2081
|
"quality",
|
|
1872
2082
|
"negativePrompt",
|
|
@@ -1885,128 +2095,128 @@ var SupportedOptionSchema = z.enum([
|
|
|
1885
2095
|
"taskType",
|
|
1886
2096
|
"instrumental"
|
|
1887
2097
|
]);
|
|
1888
|
-
var UsageUnitSchema =
|
|
2098
|
+
var UsageUnitSchema = z2.enum([
|
|
1889
2099
|
"tokens",
|
|
1890
2100
|
"images",
|
|
1891
2101
|
"seconds",
|
|
1892
2102
|
"reported_cost_usd",
|
|
1893
2103
|
"compute_seconds"
|
|
1894
2104
|
]);
|
|
1895
|
-
var PricingKindSchema =
|
|
1896
|
-
var ProviderOptionValueSchema =
|
|
1897
|
-
() =>
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
2105
|
+
var PricingKindSchema = z2.enum(["token", "image_size", "video_per_second", "flat"]);
|
|
2106
|
+
var ProviderOptionValueSchema = z2.lazy(
|
|
2107
|
+
() => z2.union([
|
|
2108
|
+
z2.string(),
|
|
2109
|
+
z2.number(),
|
|
2110
|
+
z2.boolean(),
|
|
2111
|
+
z2.array(ProviderOptionValueSchema),
|
|
2112
|
+
z2.record(z2.string(), ProviderOptionValueSchema)
|
|
1903
2113
|
])
|
|
1904
2114
|
);
|
|
1905
|
-
var ProviderOptionsSchema =
|
|
1906
|
-
var ReferenceLimitsSchema =
|
|
1907
|
-
images:
|
|
1908
|
-
imagesWithVideo:
|
|
1909
|
-
videos:
|
|
1910
|
-
audios:
|
|
1911
|
-
total:
|
|
1912
|
-
audioOnly:
|
|
2115
|
+
var ProviderOptionsSchema = z2.record(z2.string(), z2.record(z2.string(), ProviderOptionValueSchema));
|
|
2116
|
+
var ReferenceLimitsSchema = z2.looseObject({
|
|
2117
|
+
images: z2.number().optional(),
|
|
2118
|
+
imagesWithVideo: z2.number().optional(),
|
|
2119
|
+
videos: z2.number().optional(),
|
|
2120
|
+
audios: z2.number().optional(),
|
|
2121
|
+
total: z2.number().optional(),
|
|
2122
|
+
audioOnly: z2.boolean().optional()
|
|
1913
2123
|
});
|
|
1914
|
-
var ModelConstraintsSchema =
|
|
1915
|
-
aspectRatios:
|
|
1916
|
-
sizes:
|
|
1917
|
-
resolutions:
|
|
1918
|
-
durations:
|
|
1919
|
-
durationPresets:
|
|
1920
|
-
qualityOptions:
|
|
1921
|
-
exactSizes:
|
|
2124
|
+
var ModelConstraintsSchema = z2.looseObject({
|
|
2125
|
+
aspectRatios: z2.array(AspectRatioSchema).optional(),
|
|
2126
|
+
sizes: z2.array(ImageSizeSchema).optional(),
|
|
2127
|
+
resolutions: z2.array(VideoResolutionSchema).optional(),
|
|
2128
|
+
durations: z2.union([z2.looseObject({ min: z2.number(), max: z2.number() }), z2.array(z2.number())]).optional(),
|
|
2129
|
+
durationPresets: z2.array(z2.number()).optional(),
|
|
2130
|
+
qualityOptions: z2.array(z2.string()).optional(),
|
|
2131
|
+
exactSizes: z2.record(z2.string(), z2.string()).optional(),
|
|
1922
2132
|
references: ReferenceLimitsSchema.optional(),
|
|
1923
|
-
requires:
|
|
1924
|
-
supports:
|
|
1925
|
-
ratioIgnoredWith:
|
|
2133
|
+
requires: z2.array(RequiredInputSchema).optional(),
|
|
2134
|
+
supports: z2.array(SupportedOptionSchema).optional(),
|
|
2135
|
+
ratioIgnoredWith: z2.array(z2.enum(["firstFrame", "sourceVideo"])).optional()
|
|
1926
2136
|
});
|
|
1927
|
-
var MediaRefSchema =
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
bytes:
|
|
1931
|
-
mime:
|
|
1932
|
-
label:
|
|
2137
|
+
var MediaRefSchema = z2.union([
|
|
2138
|
+
z2.looseObject({ url: z2.string(), label: z2.string().optional() }),
|
|
2139
|
+
z2.looseObject({
|
|
2140
|
+
bytes: z2.instanceof(Uint8Array),
|
|
2141
|
+
mime: z2.string(),
|
|
2142
|
+
label: z2.string().optional()
|
|
1933
2143
|
})
|
|
1934
2144
|
]);
|
|
1935
|
-
var ImageSafetySettingSchema =
|
|
1936
|
-
var UpscaleOptionsSchema =
|
|
1937
|
-
enhanceModel:
|
|
1938
|
-
subjectDetection:
|
|
1939
|
-
faceEnhancement:
|
|
1940
|
-
faceEnhancementCreativity:
|
|
1941
|
-
faceEnhancementStrength:
|
|
2145
|
+
var ImageSafetySettingSchema = z2.looseObject({ category: z2.string(), threshold: z2.string() });
|
|
2146
|
+
var UpscaleOptionsSchema = z2.looseObject({
|
|
2147
|
+
enhanceModel: z2.string().optional(),
|
|
2148
|
+
subjectDetection: z2.string().optional(),
|
|
2149
|
+
faceEnhancement: z2.boolean().optional(),
|
|
2150
|
+
faceEnhancementCreativity: z2.number().optional(),
|
|
2151
|
+
faceEnhancementStrength: z2.number().optional()
|
|
1942
2152
|
});
|
|
1943
|
-
var DefaultsSchema =
|
|
1944
|
-
references:
|
|
2153
|
+
var DefaultsSchema = z2.looseObject({
|
|
2154
|
+
references: z2.array(MediaRefSchema).optional(),
|
|
1945
2155
|
aspectRatio: AspectRatioSchema.optional(),
|
|
1946
2156
|
size: ImageSizeSchema.optional(),
|
|
1947
|
-
exactSize:
|
|
2157
|
+
exactSize: z2.string().optional(),
|
|
1948
2158
|
quality: ImageQualitySchema.optional(),
|
|
1949
|
-
seed:
|
|
1950
|
-
count:
|
|
2159
|
+
seed: z2.number().optional(),
|
|
2160
|
+
count: z2.number().optional(),
|
|
1951
2161
|
outputFormat: OutputFormatSchema.optional(),
|
|
1952
|
-
scaleFactor:
|
|
1953
|
-
safetySettings:
|
|
1954
|
-
temperature:
|
|
2162
|
+
scaleFactor: z2.number().optional(),
|
|
2163
|
+
safetySettings: z2.array(ImageSafetySettingSchema).optional(),
|
|
2164
|
+
temperature: z2.number().optional(),
|
|
1955
2165
|
upscale: UpscaleOptionsSchema.optional(),
|
|
1956
2166
|
firstFrame: MediaRefSchema.optional(),
|
|
1957
2167
|
lastFrame: MediaRefSchema.optional(),
|
|
1958
2168
|
sourceVideo: MediaRefSchema.optional(),
|
|
1959
|
-
referenceImages:
|
|
1960
|
-
referenceVideos:
|
|
1961
|
-
referenceAudios:
|
|
2169
|
+
referenceImages: z2.array(MediaRefSchema).optional(),
|
|
2170
|
+
referenceVideos: z2.array(MediaRefSchema).optional(),
|
|
2171
|
+
referenceAudios: z2.array(MediaRefSchema).optional(),
|
|
1962
2172
|
resolution: VideoResolutionSchema.optional(),
|
|
1963
|
-
durationSeconds:
|
|
1964
|
-
generateAudio:
|
|
1965
|
-
negativePrompt:
|
|
1966
|
-
cfgScale:
|
|
1967
|
-
promptExpansion:
|
|
1968
|
-
watermark:
|
|
1969
|
-
safetyChecker:
|
|
1970
|
-
taskType:
|
|
1971
|
-
mode:
|
|
1972
|
-
instrumental:
|
|
2173
|
+
durationSeconds: z2.number().optional(),
|
|
2174
|
+
generateAudio: z2.boolean().optional(),
|
|
2175
|
+
negativePrompt: z2.string().optional(),
|
|
2176
|
+
cfgScale: z2.number().optional(),
|
|
2177
|
+
promptExpansion: z2.enum(["fast", "balanced", "quality"]).optional(),
|
|
2178
|
+
watermark: z2.boolean().optional(),
|
|
2179
|
+
safetyChecker: z2.boolean().optional(),
|
|
2180
|
+
taskType: z2.enum(["reference", "edit", "extend"]).optional(),
|
|
2181
|
+
mode: z2.enum(["standard", "pro"]).optional(),
|
|
2182
|
+
instrumental: z2.boolean().optional()
|
|
1973
2183
|
});
|
|
1974
|
-
var CatalogDisplaySchema =
|
|
1975
|
-
provider:
|
|
1976
|
-
description:
|
|
1977
|
-
logo:
|
|
1978
|
-
costTier:
|
|
1979
|
-
recommended:
|
|
1980
|
-
sortOrder:
|
|
1981
|
-
chat:
|
|
2184
|
+
var CatalogDisplaySchema = z2.looseObject({
|
|
2185
|
+
provider: z2.string(),
|
|
2186
|
+
description: z2.string(),
|
|
2187
|
+
logo: z2.string().optional(),
|
|
2188
|
+
costTier: z2.union([z2.literal(1), z2.literal(2), z2.literal(3)]).optional(),
|
|
2189
|
+
recommended: z2.boolean().optional(),
|
|
2190
|
+
sortOrder: z2.number().optional(),
|
|
2191
|
+
chat: z2.looseObject({
|
|
1982
2192
|
providerOptions: ProviderOptionsSchema.optional(),
|
|
1983
|
-
temperature:
|
|
2193
|
+
temperature: z2.number().optional()
|
|
1984
2194
|
}).optional()
|
|
1985
2195
|
});
|
|
1986
|
-
var CatalogCapabilitiesSchema =
|
|
1987
|
-
acceptsSourceVideo:
|
|
1988
|
-
framesExcludeReferences:
|
|
1989
|
-
reasoning:
|
|
1990
|
-
vision:
|
|
1991
|
-
contextWindow:
|
|
2196
|
+
var CatalogCapabilitiesSchema = z2.looseObject({
|
|
2197
|
+
acceptsSourceVideo: z2.boolean().optional(),
|
|
2198
|
+
framesExcludeReferences: z2.boolean().optional(),
|
|
2199
|
+
reasoning: z2.boolean().optional(),
|
|
2200
|
+
vision: z2.boolean().optional(),
|
|
2201
|
+
contextWindow: z2.number().optional()
|
|
1992
2202
|
});
|
|
1993
|
-
var CatalogModelSchemaBase =
|
|
1994
|
-
id:
|
|
1995
|
-
aliases:
|
|
1996
|
-
label:
|
|
2203
|
+
var CatalogModelSchemaBase = z2.looseObject({
|
|
2204
|
+
id: z2.string().min(1),
|
|
2205
|
+
aliases: z2.array(z2.string()).default([]),
|
|
2206
|
+
label: z2.string().min(1),
|
|
1997
2207
|
type: ModelTypeSchema,
|
|
1998
2208
|
adapter: AdapterSchema,
|
|
1999
|
-
providerModelId:
|
|
2209
|
+
providerModelId: z2.string().min(1),
|
|
2000
2210
|
lifecycle: LifecycleSchema,
|
|
2001
|
-
replacedBy:
|
|
2211
|
+
replacedBy: z2.string().optional(),
|
|
2002
2212
|
exposure: ExposureSchema,
|
|
2003
2213
|
constraints: ModelConstraintsSchema,
|
|
2004
2214
|
defaults: DefaultsSchema,
|
|
2005
2215
|
providerOptions: ProviderOptionsSchema.optional(),
|
|
2006
|
-
usage:
|
|
2216
|
+
usage: z2.looseObject({
|
|
2007
2217
|
unit: UsageUnitSchema,
|
|
2008
|
-
slug:
|
|
2009
|
-
providerLabel:
|
|
2218
|
+
slug: z2.string().optional(),
|
|
2219
|
+
providerLabel: z2.string().optional()
|
|
2010
2220
|
}),
|
|
2011
2221
|
pricingKind: PricingKindSchema,
|
|
2012
2222
|
display: CatalogDisplaySchema.optional(),
|
|
@@ -2044,44 +2254,29 @@ var CatalogModelSchema = CatalogModelSchemaBase.superRefine(
|
|
|
2044
2254
|
message: 'transport must be "direct" or "bedrock"'
|
|
2045
2255
|
});
|
|
2046
2256
|
}
|
|
2257
|
+
const inputSpecRaw = row.providerOptions?.["modelkit"]?.["inputSpec"];
|
|
2258
|
+
if (inputSpecRaw !== void 0) {
|
|
2259
|
+
const result = validateInputSpec(inputSpecRaw, row);
|
|
2260
|
+
if (!result.ok) {
|
|
2261
|
+
for (const issue of result.issues) {
|
|
2262
|
+
ctx.addIssue({
|
|
2263
|
+
code: "custom",
|
|
2264
|
+
path: ["providerOptions", "modelkit", "inputSpec", ...issue.path],
|
|
2265
|
+
message: issue.message
|
|
2266
|
+
});
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2047
2270
|
}
|
|
2048
2271
|
);
|
|
2049
|
-
var CatalogSchema =
|
|
2050
|
-
const
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
path: [index, "id"],
|
|
2056
|
-
message: `Duplicate model id "${row.id}"`
|
|
2057
|
-
});
|
|
2058
|
-
} else {
|
|
2059
|
-
seenIds.set(row.id, index);
|
|
2060
|
-
}
|
|
2061
|
-
});
|
|
2062
|
-
const seenAliases = /* @__PURE__ */ new Map();
|
|
2063
|
-
rows.forEach((row, index) => {
|
|
2064
|
-
row.aliases.forEach((alias, aliasIndex) => {
|
|
2065
|
-
const path = [index, "aliases", aliasIndex];
|
|
2066
|
-
if (alias === row.id || seenIds.has(alias)) {
|
|
2067
|
-
ctx.addIssue({
|
|
2068
|
-
code: "custom",
|
|
2069
|
-
path,
|
|
2070
|
-
message: `Alias "${alias}" collides with a model id`
|
|
2071
|
-
});
|
|
2072
|
-
return;
|
|
2073
|
-
}
|
|
2074
|
-
if (seenAliases.has(alias)) {
|
|
2075
|
-
ctx.addIssue({
|
|
2076
|
-
code: "custom",
|
|
2077
|
-
path,
|
|
2078
|
-
message: `Duplicate alias "${alias}"`
|
|
2079
|
-
});
|
|
2080
|
-
} else {
|
|
2081
|
-
seenAliases.set(alias, index);
|
|
2082
|
-
}
|
|
2272
|
+
var CatalogSchema = z2.array(CatalogModelSchemaBase).superRefine((rows, ctx) => {
|
|
2273
|
+
for (const issue of collisionIssues(rows)) {
|
|
2274
|
+
ctx.addIssue({
|
|
2275
|
+
code: "custom",
|
|
2276
|
+
path: [issue.index, ...issue.path],
|
|
2277
|
+
message: issue.message
|
|
2083
2278
|
});
|
|
2084
|
-
}
|
|
2279
|
+
}
|
|
2085
2280
|
});
|
|
2086
2281
|
|
|
2087
2282
|
// src/catalog/live.ts
|
|
@@ -2096,26 +2291,102 @@ var liveState = store[KEY] ??= {
|
|
|
2096
2291
|
};
|
|
2097
2292
|
var liveCatalog = liveState.catalog;
|
|
2098
2293
|
|
|
2294
|
+
// src/json.ts
|
|
2295
|
+
import { z as z3 } from "zod";
|
|
2296
|
+
var JsonValueSchema = z3.lazy(
|
|
2297
|
+
() => z3.union([
|
|
2298
|
+
z3.string(),
|
|
2299
|
+
z3.number(),
|
|
2300
|
+
z3.boolean(),
|
|
2301
|
+
z3.null(),
|
|
2302
|
+
z3.array(JsonValueSchema),
|
|
2303
|
+
z3.record(z3.string(), JsonValueSchema)
|
|
2304
|
+
])
|
|
2305
|
+
);
|
|
2306
|
+
var JsonObjectSchema = z3.record(z3.string(), JsonValueSchema);
|
|
2307
|
+
var thrownErrorSchema = z3.object({
|
|
2308
|
+
message: z3.string().optional(),
|
|
2309
|
+
status: z3.number().optional(),
|
|
2310
|
+
statusCode: z3.number().optional(),
|
|
2311
|
+
responseBody: z3.string().optional()
|
|
2312
|
+
});
|
|
2313
|
+
|
|
2099
2314
|
// src/catalog/load.ts
|
|
2100
|
-
import { z as
|
|
2315
|
+
import { z as z4 } from "zod";
|
|
2101
2316
|
function rowCount() {
|
|
2102
2317
|
return liveCatalog.list({ lifecycle: ["active", "deprecated", "retired"] }).length;
|
|
2103
2318
|
}
|
|
2104
2319
|
function authHeaders(auth) {
|
|
2105
2320
|
return "bearer" in auth ? { Authorization: `Bearer ${auth.bearer}` } : { "x-api-key": auth.apiKey };
|
|
2106
2321
|
}
|
|
2107
|
-
var EnvelopeSchema =
|
|
2108
|
-
rows:
|
|
2109
|
-
revision:
|
|
2322
|
+
var EnvelopeSchema = z4.object({
|
|
2323
|
+
rows: z4.array(JsonValueSchema),
|
|
2324
|
+
revision: z4.string().optional()
|
|
2110
2325
|
});
|
|
2111
|
-
function
|
|
2112
|
-
|
|
2113
|
-
|
|
2326
|
+
function dropReason(path, message) {
|
|
2327
|
+
return path.length === 0 ? message : `${path.map((part) => String(part)).join(".")} ${message}`;
|
|
2328
|
+
}
|
|
2329
|
+
function rowId(raw) {
|
|
2330
|
+
const parsed = z4.object({ id: z4.string().min(1) }).loose().safeParse(raw);
|
|
2331
|
+
if (!parsed.success) return "?";
|
|
2332
|
+
return parsed.data.id;
|
|
2333
|
+
}
|
|
2334
|
+
function quarantine(rawRows, logger) {
|
|
2335
|
+
const valid = [];
|
|
2336
|
+
let dropped = 0;
|
|
2337
|
+
for (const raw of rawRows) {
|
|
2338
|
+
const parsed = CatalogModelSchemaBase.safeParse(raw);
|
|
2339
|
+
if (!parsed.success) {
|
|
2340
|
+
const first = parsed.error.issues[0];
|
|
2341
|
+
const reason = first ? dropReason(first.path, first.message) : "invalid row";
|
|
2342
|
+
logger.warn(`[modelkit] catalog row dropped id=${rowId(raw)} reason=${reason}`);
|
|
2343
|
+
dropped += 1;
|
|
2344
|
+
continue;
|
|
2345
|
+
}
|
|
2346
|
+
const row = parsed.data;
|
|
2347
|
+
const inputSpecRaw = row.providerOptions?.["modelkit"]?.["inputSpec"];
|
|
2348
|
+
if (inputSpecRaw !== void 0) {
|
|
2349
|
+
const result = validateInputSpec(inputSpecRaw, row);
|
|
2350
|
+
if (!result.ok) {
|
|
2351
|
+
const first = result.issues[0];
|
|
2352
|
+
const detail = first ? dropReason(first.path, first.message) : "invalid inputSpec";
|
|
2353
|
+
logger.warn(
|
|
2354
|
+
`[modelkit] catalog row ${row.id} has an invalid providerOptions.modelkit.inputSpec: ${detail}; calls fail until it is fixed`
|
|
2355
|
+
);
|
|
2356
|
+
}
|
|
2357
|
+
}
|
|
2358
|
+
valid.push(row);
|
|
2359
|
+
}
|
|
2360
|
+
let kept = valid;
|
|
2361
|
+
for (; ; ) {
|
|
2362
|
+
const issues = collisionIssues(kept);
|
|
2363
|
+
if (issues.length === 0) break;
|
|
2364
|
+
const firstByIndex = /* @__PURE__ */ new Map();
|
|
2365
|
+
for (const issue of issues) {
|
|
2366
|
+
if (!firstByIndex.has(issue.index)) firstByIndex.set(issue.index, issue);
|
|
2367
|
+
}
|
|
2368
|
+
for (const [index, issue] of [...firstByIndex.entries()].sort((a, b) => a[0] - b[0])) {
|
|
2369
|
+
const row = kept[index];
|
|
2370
|
+
if (!row) continue;
|
|
2371
|
+
logger.warn(
|
|
2372
|
+
`[modelkit] catalog row dropped id=${row.id} reason=${String(issue.path[0] ?? "")} ${issue.message}`
|
|
2373
|
+
);
|
|
2374
|
+
}
|
|
2375
|
+
const dropSet = new Set(firstByIndex.keys());
|
|
2376
|
+
kept = kept.filter((_, index) => !dropSet.has(index));
|
|
2377
|
+
dropped += dropSet.size;
|
|
2378
|
+
}
|
|
2379
|
+
return { rows: kept, dropped };
|
|
2380
|
+
}
|
|
2381
|
+
function toEnvelope(data, logger) {
|
|
2382
|
+
const { rows, dropped } = quarantine(data.rows, logger);
|
|
2383
|
+
if (rows.length === 0) throw new Error("invalid catalog response: no rows");
|
|
2384
|
+
const envelope = { rows, dropped };
|
|
2114
2385
|
if (data.revision !== void 0) envelope.revision = data.revision;
|
|
2115
2386
|
return envelope;
|
|
2116
2387
|
}
|
|
2117
|
-
function describeError(
|
|
2118
|
-
return
|
|
2388
|
+
function describeError(cause) {
|
|
2389
|
+
return cause instanceof Error ? cause.message : String(cause);
|
|
2119
2390
|
}
|
|
2120
2391
|
function logPrimed(logger, result) {
|
|
2121
2392
|
const revision = result.revision === void 0 ? "" : ` revision=${result.revision}`;
|
|
@@ -2136,9 +2407,9 @@ async function fetchRemote(source, logger) {
|
|
|
2136
2407
|
const json = await res.json();
|
|
2137
2408
|
const parsed = EnvelopeSchema.safeParse(json);
|
|
2138
2409
|
if (!parsed.success) throw new Error("invalid catalog response: missing rows");
|
|
2139
|
-
const { rows, revision: rev } = toEnvelope(parsed.data);
|
|
2140
|
-
if (rev === void 0) return { rows, fromCache: false };
|
|
2141
|
-
return { rows, revision: rev, fromCache: false };
|
|
2410
|
+
const { rows, revision: rev, dropped } = toEnvelope(parsed.data, logger);
|
|
2411
|
+
if (rev === void 0) return { rows, fromCache: false, dropped };
|
|
2412
|
+
return { rows, revision: rev, fromCache: false, dropped };
|
|
2142
2413
|
}
|
|
2143
2414
|
async function writeCache(source, logger, rows, rev) {
|
|
2144
2415
|
if (!source.cache) return;
|
|
@@ -2163,6 +2434,7 @@ async function prime(source, logger) {
|
|
|
2163
2434
|
await writeCache(source, logger, fetched.rows, fetched.revision);
|
|
2164
2435
|
const result = { origin: liveState.origin, rowCount: rowCount() };
|
|
2165
2436
|
if (fetched.revision !== void 0) result.revision = fetched.revision;
|
|
2437
|
+
if (fetched.dropped > 0) result.droppedRows = fetched.dropped;
|
|
2166
2438
|
logPrimed(logger, result);
|
|
2167
2439
|
return result;
|
|
2168
2440
|
} catch (err) {
|
|
@@ -2173,7 +2445,7 @@ async function prime(source, logger) {
|
|
|
2173
2445
|
if (!cached) throw new Error("no cached catalog");
|
|
2174
2446
|
const cachedParsed = EnvelopeSchema.safeParse(JSON.parse(cached));
|
|
2175
2447
|
if (!cachedParsed.success) throw new Error("invalid catalog response: missing rows");
|
|
2176
|
-
const { rows, revision: rev } = toEnvelope(cachedParsed.data);
|
|
2448
|
+
const { rows, revision: rev, dropped } = toEnvelope(cachedParsed.data, logger);
|
|
2177
2449
|
liveCatalog.replace(rows);
|
|
2178
2450
|
liveState.origin = "last-good";
|
|
2179
2451
|
liveState.revision = rev;
|
|
@@ -2183,6 +2455,7 @@ async function prime(source, logger) {
|
|
|
2183
2455
|
error
|
|
2184
2456
|
};
|
|
2185
2457
|
if (rev !== void 0) result.revision = rev;
|
|
2458
|
+
if (dropped > 0) result.droppedRows = dropped;
|
|
2186
2459
|
logPrimed(logger, result);
|
|
2187
2460
|
return result;
|
|
2188
2461
|
} catch (cacheErr) {
|
|
@@ -2630,6 +2903,7 @@ export {
|
|
|
2630
2903
|
ADAPTER_IDS,
|
|
2631
2904
|
Catalog,
|
|
2632
2905
|
CatalogModelSchema,
|
|
2906
|
+
CatalogModelSchemaBase,
|
|
2633
2907
|
CatalogSchema,
|
|
2634
2908
|
ExposureSchema,
|
|
2635
2909
|
IMAGE_MODELS,
|