@openclaw/deepinfra-provider 2026.9.2 → 2026.9.3

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.
@@ -1,9 +1,19 @@
1
- import { applyAnthropicEphemeralCacheControlMarkers, createPayloadPatchStreamWrapper } from "openclaw/plugin-sdk/provider-stream-shared";
1
+ import { applyAnthropicEphemeralCacheControlMarkers, applyCompletionsAnthropicCacheControl, createPayloadPatchStreamWrapper } from "openclaw/plugin-sdk/provider-stream-shared";
2
2
  //#region extensions/deepinfra/cache-wrapper.ts
3
- function createDeepInfraAnthropicCacheWrapper(baseStreamFn) {
4
- return createPayloadPatchStreamWrapper(baseStreamFn, ({ payload }) => {
5
- applyAnthropicEphemeralCacheControlMarkers(payload);
6
- }, { shouldPatch: ({ model }) => model.id.toLowerCase().startsWith("anthropic/") });
3
+ function createDeepInfraAnthropicCacheWrapper(baseStreamFn, extraParams) {
4
+ return (model, context, options) => {
5
+ if (!model.id.toLowerCase().startsWith("anthropic/")) return baseStreamFn(model, context, options);
6
+ const isCompletions = model.api === "openai-completions";
7
+ const configured = options?.cacheRetention ?? extraParams?.cacheRetention;
8
+ const cacheRetention = configured === "none" || configured === "long" ? configured : "short";
9
+ return createPayloadPatchStreamWrapper(baseStreamFn, ({ payload }) => {
10
+ if (isCompletions) applyCompletionsAnthropicCacheControl(payload, cacheRetention === "none" ? null : { type: "ephemeral" });
11
+ else applyAnthropicEphemeralCacheControlMarkers(payload);
12
+ })(model, context, isCompletions ? {
13
+ ...options,
14
+ cacheRetention
15
+ } : options);
16
+ };
7
17
  }
8
18
  //#endregion
9
19
  export { createDeepInfraAnthropicCacheWrapper };
package/dist/index.js CHANGED
@@ -2,13 +2,12 @@ import { createDeepInfraAnthropicCacheWrapper } from "./cache-wrapper.js";
2
2
  import { buildDeepInfraEmbeddingAdapter } from "./embedding-adapter.js";
3
3
  import { buildDeepInfraImageGenerationProvider } from "./image-generation-provider.js";
4
4
  import { buildDeepInfraMediaUnderstandingProvider } from "./media-understanding-provider.js";
5
- import { DEEPINFRA_DEFAULT_MODEL_REF, discoverDeepInfraModels, getDeepInfraSurfaceFallbackCatalog, hasDeepInfraApiKey } from "./provider-models.js";
5
+ import { DEEPINFRA_DEFAULT_MODEL_REF, getDeepInfraSurfaceFallbackCatalog } from "./provider-models.js";
6
6
  import { applyDeepInfraConfig } from "./onboard.js";
7
7
  import { buildDeepInfraApiKeyCatalog, buildStaticDeepInfraProvider } from "./provider-catalog.js";
8
8
  import { buildDeepInfraSpeechProvider } from "./speech-provider.js";
9
9
  import { listDeepInfraImageGenCatalog, listDeepInfraVideoGenCatalog } from "./surface-model-catalogs.js";
10
10
  import { buildDeepInfraVideoGenerationProvider } from "./video-generation-provider.js";
11
- import { readConfiguredProviderCatalogEntries } from "openclaw/plugin-sdk/provider-catalog-shared";
12
11
  import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
13
12
  import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared";
14
13
  import { createOpenRouterWrapper, isProxyReasoningUnsupported } from "openclaw/plugin-sdk/provider-stream";
@@ -47,38 +46,6 @@ var deepinfra_default = defineSingleProviderPluginEntry({
47
46
  run: (ctx) => buildDeepInfraApiKeyCatalog(ctx),
48
47
  staticRun: async () => ({ provider: buildStaticDeepInfraProvider() })
49
48
  },
50
- augmentModelCatalog: async ({ config, env, agentDir }) => {
51
- const configured = readConfiguredProviderCatalogEntries({
52
- config,
53
- providerId: PROVIDER_ID
54
- });
55
- const hasApiKey = hasDeepInfraApiKey({
56
- env,
57
- agentDir,
58
- config
59
- });
60
- const seen = new Set(configured.map((entry) => entry.id));
61
- const discovered = await discoverDeepInfraModels({
62
- hasApiKey,
63
- env,
64
- agentDir
65
- });
66
- const merged = [...configured];
67
- for (const model of discovered) {
68
- if (seen.has(model.id)) continue;
69
- seen.add(model.id);
70
- const input = model.input;
71
- merged.push({
72
- provider: PROVIDER_ID,
73
- id: model.id,
74
- name: model.name ?? model.id,
75
- ...typeof model.contextWindow === "number" && model.contextWindow > 0 ? { contextWindow: model.contextWindow } : {},
76
- ...typeof model.reasoning === "boolean" ? { reasoning: model.reasoning } : {},
77
- ...input && input.length > 0 ? { input } : {}
78
- });
79
- }
80
- return merged;
81
- },
82
49
  normalizeConfig: ({ providerConfig }) => providerConfig,
83
50
  normalizeTransport: ({ api, baseUrl }) => baseUrl === "https://api.deepinfra.com/v1/openai" ? {
84
51
  api,
@@ -87,7 +54,7 @@ var deepinfra_default = defineSingleProviderPluginEntry({
87
54
  ...buildProviderReplayFamilyHooks({ family: "passthrough-gemini" }),
88
55
  wrapStreamFn: (ctx) => {
89
56
  const thinkingLevel = isProxyReasoningUnsupported(ctx.modelId) ? void 0 : ctx.thinkingLevel;
90
- return createDeepInfraAnthropicCacheWrapper(createOpenRouterWrapper(ctx.streamFn, thinkingLevel));
57
+ return createDeepInfraAnthropicCacheWrapper(createOpenRouterWrapper(ctx.streamFn, thinkingLevel), ctx.extraParams);
91
58
  },
92
59
  isModernModelRef: () => true,
93
60
  isCacheTtlEligible: (ctx) => ctx.modelId.toLowerCase().startsWith("anthropic/")
@@ -1,5 +1,6 @@
1
1
  import { DEEPINFRA_BASE_URL } from "./media-models.js";
2
2
  import { DEEPINFRA_MODEL_CATALOG, buildDeepInfraModelDefinition, discoverDeepInfraModels } from "./provider-models.js";
3
+ import { runLiveProviderCatalog } from "openclaw/plugin-sdk/provider-catalog-live-runtime";
3
4
  import { buildSingleProviderApiKeyCatalog } from "openclaw/plugin-sdk/provider-catalog-shared";
4
5
  //#region extensions/deepinfra/provider-catalog.ts
5
6
  function buildStaticDeepInfraProvider() {
@@ -10,7 +11,10 @@ function buildStaticDeepInfraProvider() {
10
11
  };
11
12
  }
12
13
  async function buildDeepInfraProvider(options) {
13
- const models = await discoverDeepInfraModels(options);
14
+ const models = await discoverDeepInfraModels({
15
+ ...options,
16
+ discoveryMode: options?.discoveryMode ?? "advisory"
17
+ });
14
18
  return {
15
19
  baseUrl: DEEPINFRA_BASE_URL,
16
20
  api: "openai-completions",
@@ -18,13 +22,17 @@ async function buildDeepInfraProvider(options) {
18
22
  };
19
23
  }
20
24
  function buildDeepInfraApiKeyCatalog(ctx) {
21
- return buildSingleProviderApiKeyCatalog({
22
- ctx,
25
+ return runLiveProviderCatalog({
23
26
  providerId: "deepinfra",
24
- buildProvider: () => buildDeepInfraProvider({
25
- hasApiKey: true,
26
- env: ctx.env,
27
- agentDir: ctx.agentDir
27
+ run: () => buildSingleProviderApiKeyCatalog({
28
+ ctx,
29
+ providerId: "deepinfra",
30
+ buildProvider: () => buildDeepInfraProvider({
31
+ hasApiKey: true,
32
+ discoveryMode: "strict",
33
+ env: ctx.env,
34
+ agentDir: ctx.agentDir
35
+ })
28
36
  })
29
37
  });
30
38
  }
@@ -1,13 +1,12 @@
1
1
  import { t as modelCatalog } from "./openclaw.plugin-BRaVociw.js";
2
2
  import { DEEPINFRA_BASE_URL, DEEPINFRA_TTS_FALLBACK_CATALOG } from "./media-models.js";
3
3
  import { parseDeepInfraPricingCatalog } from "./pricing-api.js";
4
- import { buildManifestModelProviderConfig, getCachedLiveCatalogValue } from "openclaw/plugin-sdk/provider-catalog-shared";
5
- import { asPositiveSafeInteger } from "openclaw/plugin-sdk/string-coerce-runtime";
4
+ import { asPositiveSafeInteger, isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
6
5
  import { withTrustedEnvProxyGuardedFetchMode } from "openclaw/plugin-sdk/fetch-runtime";
7
6
  import { isProviderApiKeyConfigured } from "openclaw/plugin-sdk/provider-auth";
8
- import { LiveModelCatalogHttpError, fetchLiveProviderModelRows, getCachedLiveProviderModelRows } from "openclaw/plugin-sdk/provider-catalog-live-runtime";
7
+ import { fetchLiveProviderModelRows } from "openclaw/plugin-sdk/provider-catalog-live-runtime";
8
+ import { buildManifestModelProviderConfig, getCachedLiveCatalogValue } from "openclaw/plugin-sdk/provider-catalog-shared";
9
9
  import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
10
- import { hasConfiguredSecretInput } from "openclaw/plugin-sdk/secret-input";
11
10
  import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
12
11
  //#region extensions/deepinfra/provider-models.ts
13
12
  const log = createSubsystemLogger("deepinfra-models");
@@ -36,14 +35,14 @@ function entryToSurfaceModel(entry) {
36
35
  const id = typeof entry?.id === "string" ? entry.id.trim() : "";
37
36
  if (!id) return null;
38
37
  const metadata = entry.metadata;
39
- if (!metadata) return null;
40
- const tags = Array.isArray(metadata.tags) ? metadata.tags.filter((t) => typeof t === "string") : [];
38
+ if (metadata === null) return null;
39
+ if (!isRecord(metadata) || !Array.isArray(metadata.tags) || metadata.tags.some((tag) => typeof tag !== "string")) throw new Error("DeepInfra model metadata discovery unavailable.");
41
40
  const pricing = metadata.pricing ?? {};
42
41
  return {
43
42
  id,
44
43
  name: id,
45
- description: metadata.description ?? void 0,
46
- tags,
44
+ description: typeof metadata.description === "string" ? metadata.description : void 0,
45
+ tags: metadata.tags,
47
46
  contextWindow: asPositiveSafeInteger(metadata.context_length),
48
47
  maxTokens: asPositiveSafeInteger(metadata.max_tokens),
49
48
  pricing,
@@ -84,9 +83,6 @@ function bucketBySurface(models) {
84
83
  }
85
84
  return catalog;
86
85
  }
87
- function hasDeepInfraSurfaceModelRows(rows) {
88
- return rows.some((entry) => entryToSurfaceModel(entry) !== null);
89
- }
90
86
  function manifestChatEntryToSurfaceModel(entry) {
91
87
  const cost = entry.cost ?? {};
92
88
  const pricing = {};
@@ -194,109 +190,99 @@ function chatSurfaceModelToModelDefinition(model) {
194
190
  maxTokens: model.maxTokens ?? DEEPINFRA_DEFAULT_MAX_TOKENS
195
191
  };
196
192
  }
197
- function hasDeepInfraApiKey(options) {
193
+ function canDiscoverDeepInfra(options) {
194
+ if (options?.hasApiKey !== void 0) return options.hasApiKey;
198
195
  const fromEnv = (options?.env ?? process.env).DEEPINFRA_API_KEY;
199
- if (typeof fromEnv === "string" && fromEnv.trim() !== "") return true;
200
- const providers = options?.config?.models?.providers;
201
- for (const [providerId, provider] of Object.entries(providers ?? {})) if (providerId.trim().toLowerCase() === "deepinfra" && hasConfiguredSecretInput(provider?.apiKey, options?.config?.secrets?.defaults)) return true;
202
- return isProviderApiKeyConfigured({
196
+ return typeof fromEnv === "string" && fromEnv.trim() !== "" || isProviderApiKeyConfigured({
203
197
  provider: "deepinfra",
204
198
  agentDir: options?.agentDir
205
199
  });
206
200
  }
207
- function canDiscoverDeepInfra(options) {
208
- const env = options?.env ?? process.env;
209
- if (env.NODE_ENV === "test" || env.VITEST) return false;
210
- return options?.hasApiKey ?? hasDeepInfraApiKey({
211
- env,
212
- agentDir: options?.agentDir
213
- });
214
- }
215
201
  async function discoverDeepInfraSurfaces(options) {
216
- return canDiscoverDeepInfra(options) ? loadDeepInfraSurfaces() : manifestFallbackCatalog();
202
+ if (canDiscoverDeepInfra(options)) try {
203
+ return await loadDeepInfraSurfaces();
204
+ } catch (error) {
205
+ log.warn(`Model metadata discovery unavailable: ${String(error)}`);
206
+ }
207
+ return manifestFallbackCatalog();
217
208
  }
218
209
  async function loadDeepInfraSurfaces() {
219
- try {
220
- const data = await getCachedLiveProviderModelRows({
221
- providerId: "deepinfra",
222
- endpoint: DEEPINFRA_MODELS_URL,
223
- timeoutMs: DISCOVERY_TIMEOUT_MS,
224
- ttlMs: DISCOVERY_CACHE_TTL_MS,
225
- buildRequestHeaders: () => ({ Accept: "application/json" }),
226
- auditContext: "deepinfra-model-discovery",
227
- shouldCacheRows: hasDeepInfraSurfaceModelRows,
228
- fetchGuard: (params) => fetchWithSsrFGuard(withTrustedEnvProxyGuardedFetchMode(params))
229
- });
230
- if (data.length === 0) {
231
- log.warn("No models found from DeepInfra agent-projection endpoint, using static catalog");
232
- return manifestFallbackCatalog();
233
- }
234
- const seenIds = /* @__PURE__ */ new Set();
235
- const surfaceModels = [];
236
- for (const entry of data) {
237
- const model = entryToSurfaceModel(entry);
238
- if (!model || seenIds.has(model.id)) continue;
239
- seenIds.add(model.id);
240
- surfaceModels.push(model);
241
- }
242
- if (surfaceModels.length === 0) return manifestFallbackCatalog();
243
- return bucketBySurface(surfaceModels);
244
- } catch (error) {
245
- if (error instanceof LiveModelCatalogHttpError) {
246
- log.warn(`Failed to discover models: HTTP ${error.status}, using static catalog`);
247
- return manifestFallbackCatalog();
210
+ return getCachedLiveCatalogValue({
211
+ keyParts: [
212
+ "deepinfra",
213
+ "surfaces",
214
+ DEEPINFRA_MODELS_URL
215
+ ],
216
+ ttlMs: DISCOVERY_CACHE_TTL_MS,
217
+ load: async () => {
218
+ const data = await fetchLiveProviderModelRows({
219
+ providerId: "deepinfra",
220
+ endpoint: DEEPINFRA_MODELS_URL,
221
+ timeoutMs: DISCOVERY_TIMEOUT_MS,
222
+ buildRequestHeaders: () => ({ Accept: "application/json" }),
223
+ auditContext: "deepinfra-model-discovery",
224
+ fetchGuard: (params) => fetchWithSsrFGuard(withTrustedEnvProxyGuardedFetchMode(params))
225
+ });
226
+ const seenIds = /* @__PURE__ */ new Set();
227
+ const surfaceModels = [];
228
+ for (const entry of data) {
229
+ const model = entryToSurfaceModel(entry);
230
+ if (!model || seenIds.has(model.id)) continue;
231
+ seenIds.add(model.id);
232
+ surfaceModels.push(model);
233
+ }
234
+ if (data.length > 0 && surfaceModels.length === 0) throw new Error("DeepInfra model metadata discovery unavailable.");
235
+ return bucketBySurface(surfaceModels);
248
236
  }
249
- log.warn(`Discovery failed: ${String(error)}, using static catalog`);
250
- return manifestFallbackCatalog();
251
- }
237
+ });
252
238
  }
253
239
  async function discoverDeepInfraPricing() {
254
- try {
255
- return await getCachedLiveCatalogValue({
256
- keyParts: [
257
- "deepinfra",
258
- "native-pricing",
259
- DEEPINFRA_PRICING_URL
260
- ],
261
- ttlMs: DISCOVERY_CACHE_TTL_MS,
262
- load: async () => {
263
- const rows = await fetchLiveProviderModelRows({
264
- providerId: "deepinfra",
265
- endpoint: DEEPINFRA_PRICING_URL,
266
- timeoutMs: DISCOVERY_TIMEOUT_MS,
267
- buildRequestHeaders: () => ({ Accept: "application/json" }),
268
- auditContext: "deepinfra-pricing-discovery",
269
- fetchGuard: (params) => fetchWithSsrFGuard(withTrustedEnvProxyGuardedFetchMode(params)),
270
- readRows: (body) => {
271
- if (!Array.isArray(body)) throw new Error("Native DeepInfra pricing response must be an array");
272
- return body;
273
- }
274
- });
275
- const prices = parseDeepInfraPricingCatalog(rows);
276
- if (!prices) throw new Error("Native DeepInfra pricing is malformed or has no usable schedules");
277
- return prices;
278
- }
279
- });
280
- } catch (error) {
281
- log.warn(`Native pricing unavailable: ${String(error)}. Keeping model metadata with unknown estimates; retry discovery or configure explicit model costs.`);
282
- return;
283
- }
240
+ return await getCachedLiveCatalogValue({
241
+ keyParts: [
242
+ "deepinfra",
243
+ "native-pricing",
244
+ DEEPINFRA_PRICING_URL
245
+ ],
246
+ ttlMs: DISCOVERY_CACHE_TTL_MS,
247
+ load: async () => {
248
+ const rows = await fetchLiveProviderModelRows({
249
+ providerId: "deepinfra",
250
+ endpoint: DEEPINFRA_PRICING_URL,
251
+ timeoutMs: DISCOVERY_TIMEOUT_MS,
252
+ buildRequestHeaders: () => ({ Accept: "application/json" }),
253
+ auditContext: "deepinfra-pricing-discovery",
254
+ fetchGuard: (params) => fetchWithSsrFGuard(withTrustedEnvProxyGuardedFetchMode(params)),
255
+ readRows: (body) => {
256
+ if (!Array.isArray(body)) throw new Error("Native DeepInfra pricing response must be an array");
257
+ return body;
258
+ }
259
+ });
260
+ const prices = parseDeepInfraPricingCatalog(rows);
261
+ if (!prices) throw new Error("Native DeepInfra pricing is malformed or has no usable schedules");
262
+ return prices;
263
+ }
264
+ });
284
265
  }
285
266
  async function discoverDeepInfraModels(options) {
286
267
  if (!canDiscoverDeepInfra(options)) return DEEPINFRA_MODEL_CATALOG.map(buildDeepInfraModelDefinition);
287
- const [catalog, prices] = await Promise.all([loadDeepInfraSurfaces(), discoverDeepInfraPricing()]);
288
- if (!catalog.live && !prices) return DEEPINFRA_MODEL_CATALOG.map(buildDeepInfraModelDefinition);
289
- const chatModels = catalog.chat.length > 0 ? catalog.chat : [...catalog.chat, ...catalog.vlm];
290
- const liveModels = catalog.live ? chatModels.map(chatSurfaceModelToModelDefinition) : [];
291
- const seen = new Set(liveModels.map((model) => model.id));
292
- const manifestModels = DEEPINFRA_MODEL_CATALOG.filter((model) => {
293
- const unseen = !seen.has(model.id);
294
- seen.add(model.id);
295
- return unseen;
296
- });
297
- const models = [...liveModels, ...manifestModels];
268
+ const strict = options?.discoveryMode !== "advisory";
269
+ const [metadata, pricing] = await Promise.allSettled([loadDeepInfraSurfaces(), discoverDeepInfraPricing()]);
270
+ if (metadata.status === "rejected") {
271
+ if (strict) throw metadata.reason;
272
+ if (pricing.status === "rejected") return DEEPINFRA_MODEL_CATALOG.map(buildDeepInfraModelDefinition);
273
+ }
274
+ const catalog = metadata.status === "fulfilled" ? metadata.value : void 0;
275
+ const chatModels = catalog ? catalog.chat.length > 0 ? catalog.chat : catalog.vlm : [];
276
+ if (strict && chatModels.length === 0) return [];
277
+ if (strict && pricing.status === "rejected") throw pricing.reason;
278
+ const prices = pricing.status === "fulfilled" ? pricing.value : void 0;
279
+ const models = chatModels.map(chatSurfaceModelToModelDefinition);
280
+ if (!strict) {
281
+ const discovered = new Set(models.map((model) => model.id));
282
+ models.push(...DEEPINFRA_MODEL_CATALOG.filter((model) => !discovered.has(model.id)));
283
+ }
298
284
  const unknownPrices = models.filter((model) => !prices?.has(model.id)).length;
299
- if (prices && unknownPrices > 0) log.warn(`Native pricing unavailable or qualified for ${unknownPrices} models; keeping metadata with unknown estimates. Configure explicit model costs if needed.`);
285
+ if (unknownPrices > 0) log.warn(`Native pricing unavailable or qualified for ${unknownPrices} models; keeping metadata with unknown estimates. Configure explicit model costs if needed.`);
300
286
  return models.map((model) => buildDeepInfraModelDefinition({
301
287
  ...model,
302
288
  cost: prices?.get(model.id) ?? {
@@ -308,4 +294,4 @@ async function discoverDeepInfraModels(options) {
308
294
  }));
309
295
  }
310
296
  //#endregion
311
- export { DEEPINFRA_DEFAULT_MODEL_REF, DEEPINFRA_MODEL_CATALOG, buildDeepInfraModelDefinition, discoverDeepInfraModels, discoverDeepInfraSurfaces, getDeepInfraSurfaceFallbackCatalog, hasDeepInfraApiKey };
297
+ export { DEEPINFRA_DEFAULT_MODEL_REF, DEEPINFRA_MODEL_CATALOG, buildDeepInfraModelDefinition, discoverDeepInfraModels, discoverDeepInfraSurfaces, getDeepInfraSurfaceFallbackCatalog };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/deepinfra-provider",
3
- "version": "2026.9.2",
3
+ "version": "2026.9.3",
4
4
  "description": "OpenClaw DeepInfra provider plugin.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -18,10 +18,10 @@
18
18
  "minHostVersion": ">=2026.6.8"
19
19
  },
20
20
  "compat": {
21
- "pluginApi": ">=2026.9.2"
21
+ "pluginApi": ">=2026.9.3"
22
22
  },
23
23
  "build": {
24
- "openclawVersion": "2026.9.2",
24
+ "openclawVersion": "2026.9.3",
25
25
  "bundledDist": false
26
26
  },
27
27
  "release": {
@@ -38,7 +38,7 @@
38
38
  "README.md"
39
39
  ],
40
40
  "peerDependencies": {
41
- "openclaw": ">=2026.9.2"
41
+ "openclaw": ">=2026.9.3"
42
42
  },
43
43
  "peerDependenciesMeta": {
44
44
  "openclaw": {