@openclaw/baseten-provider 2026.11.3 → 2026.11.5-beta.2

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,6 +1,5 @@
1
- import { resolveDefaultModelMaxTokens } from "openclaw/plugin-sdk/provider-model-shared";
2
- import { buildManifestModelProviderConfig, readManifestProviderDefaultModelRef } from "openclaw/plugin-sdk/provider-catalog-shared";
3
1
  import { asNonArrayRecord, asOptionalRecord, asPositiveSafeInteger, filterStringEntries, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
2
+ import { buildManifestModelProviderConfig, readManifestProviderDefaultModelRef } from "openclaw/plugin-sdk/provider-catalog-shared";
4
3
  //#region extensions/baseten/openclaw.plugin.json
5
4
  var openclaw_plugin_default = {
6
5
  id: "baseten",
@@ -9,6 +8,7 @@ var openclaw_plugin_default = {
9
8
  description: "OpenClaw Baseten provider plugin.",
10
9
  activation: { "onStartup": false },
11
10
  enabledByDefault: true,
11
+ contracts: { "decisionProviders": ["baseten"] },
12
12
  providers: ["baseten"],
13
13
  providerRequest: { "providers": { "baseten": {
14
14
  "family": "baseten",
@@ -21,6 +21,64 @@ var openclaw_plugin_default = {
21
21
  "api": "openai-completions",
22
22
  "defaultModel": "deepseek-ai/DeepSeek-V4.1-Flash",
23
23
  "models": [
24
+ {
25
+ "id": "decision-models/baseten-elephant-9b-latest",
26
+ "name": "elephant-1 (9B)",
27
+ "inference": {
28
+ "chat": false,
29
+ "decision": {
30
+ "protocol": "baseten-systemone",
31
+ "input": ["text"],
32
+ "reasoning": { "modes": ["auto"] },
33
+ "questions": {
34
+ "boolean": {
35
+ "probabilities": "boolean",
36
+ "abstention": false
37
+ },
38
+ "choice": {
39
+ "probabilities": "categorical",
40
+ "abstention": false,
41
+ "minOptions": 2
42
+ },
43
+ "score": {
44
+ "probabilities": "categorical",
45
+ "abstention": false,
46
+ "minOptions": 2
47
+ }
48
+ },
49
+ "confidence": "provider-specific"
50
+ }
51
+ }
52
+ },
53
+ {
54
+ "id": "decision-models/baseten-mammoth-27b-latest",
55
+ "name": "mammoth-1 (27B)",
56
+ "inference": {
57
+ "chat": false,
58
+ "decision": {
59
+ "protocol": "baseten-systemone",
60
+ "input": ["text"],
61
+ "reasoning": { "modes": ["auto"] },
62
+ "questions": {
63
+ "boolean": {
64
+ "probabilities": "boolean",
65
+ "abstention": false
66
+ },
67
+ "choice": {
68
+ "probabilities": "categorical",
69
+ "abstention": false,
70
+ "minOptions": 2
71
+ },
72
+ "score": {
73
+ "probabilities": "categorical",
74
+ "abstention": false,
75
+ "minOptions": 2
76
+ }
77
+ },
78
+ "confidence": "provider-specific"
79
+ }
80
+ }
81
+ },
24
82
  {
25
83
  "id": "deepseek-ai/DeepSeek-V4.1-Flash",
26
84
  "name": "DeepSeek V4.1 Flash",
@@ -46,7 +104,8 @@ var openclaw_plugin_default = {
46
104
  "off": "none",
47
105
  "none": "none",
48
106
  "adaptive": "max"
49
- }
107
+ },
108
+ "codeMode": "capable"
50
109
  }
51
110
  },
52
111
  {
@@ -215,12 +274,18 @@ var openclaw_plugin_default = {
215
274
  };
216
275
  //#endregion
217
276
  //#region extensions/baseten/models.ts
218
- const BASETEN_MANIFEST_CATALOG = openclaw_plugin_default.modelCatalog.providers.baseten;
277
+ const declaredCatalog = openclaw_plugin_default.modelCatalog.providers.baseten;
278
+ const BASETEN_DECISION_MODEL_IDS = new Set(declaredCatalog.models.filter((model) => model.inference?.chat === false).map((model) => model.id));
279
+ const BASETEN_MANIFEST_CATALOG = {
280
+ ...declaredCatalog,
281
+ models: declaredCatalog.models.filter((model) => model.inference?.chat !== false)
282
+ };
219
283
  const BASETEN_MODEL_COMPAT = new Map(buildManifestModelProviderConfig({
220
284
  providerId: "baseten",
221
285
  catalog: BASETEN_MANIFEST_CATALOG
222
286
  }).models.map(({ id, compat }) => [id, compat]));
223
287
  const DEFAULT_CONTEXT_WINDOW = 128e3;
288
+ const DEFAULT_MAX_TOKENS = 8192;
224
289
  const CHAT_TEMPLATE_THINKING_MODEL_IDS = /* @__PURE__ */ new Set([
225
290
  "zai-org/glm-4.7",
226
291
  "zai-org/glm-5.2",
@@ -248,7 +313,7 @@ function usesBasetenChatTemplateThinking(modelId) {
248
313
  function buildBasetenModelCompat(modelId) {
249
314
  return {
250
315
  ...BASE_COMPAT,
251
- ...structuredClone(BASETEN_MODEL_COMPAT.get(modelId))
316
+ ...BASETEN_MODEL_COMPAT.get(modelId)
252
317
  };
253
318
  }
254
319
  function buildStaticBasetenModels() {
@@ -262,28 +327,16 @@ function readPerTokenPrice(value) {
262
327
  const number = typeof value === "number" ? value : Number(value);
263
328
  return Number.isFinite(number) && number >= 0 ? Number((number * 1e6).toFixed(9)) : void 0;
264
329
  }
265
- function applyLiveReasoningEffortCompat(fallbackCompat, supportsReasoningEffort) {
266
- const compat = {
267
- ...fallbackCompat,
268
- supportsReasoningEffort
269
- };
270
- if (!supportsReasoningEffort) {
271
- delete compat.supportedReasoningEfforts;
272
- delete compat.reasoningEffortMap;
273
- }
274
- return compat;
275
- }
276
330
  function projectLiveModel(row, fallback) {
277
331
  if (row.object !== void 0 && row.object !== "model") return;
278
332
  const id = normalizeOptionalString(row.id);
279
- if (!id) return;
333
+ if (!id || id.startsWith("decision-models/")) return;
280
334
  const hasLiveFeatures = Array.isArray(row.supported_features);
281
335
  const features = new Set(filterStringEntries(row.supported_features));
282
336
  const pricing = asNonArrayRecord(row.pricing);
283
337
  const inputPrice = readPerTokenPrice(pricing.prompt);
284
338
  const outputPrice = readPerTokenPrice(pricing.completion);
285
339
  const cacheReadPrice = readPerTokenPrice(pricing.input_cache_read);
286
- const contextWindow = asPositiveSafeInteger(Number(row.context_length)) ?? fallback?.contextWindow ?? DEFAULT_CONTEXT_WINDOW;
287
340
  const hasDocumentedSparseFeatures = ["deepseek-ai/DeepSeek-V4.1-Flash", "deepseek-ai/DeepSeek-V4-Pro-0813"].includes(id) && [
288
341
  "tools",
289
342
  "reasoning",
@@ -292,7 +345,17 @@ function projectLiveModel(row, fallback) {
292
345
  ].every((feature) => features.has(feature));
293
346
  const fallbackCompat = fallback?.compat ?? buildBasetenModelCompat(id);
294
347
  const supportsReasoningEffort = features.has("reasoning_effort") || hasDocumentedSparseFeatures && fallbackCompat.supportsReasoningEffort === true;
295
- const compat = hasLiveFeatures ? applyLiveReasoningEffortCompat(fallbackCompat, supportsReasoningEffort) : fallbackCompat;
348
+ let compat = fallbackCompat;
349
+ if (hasLiveFeatures) {
350
+ compat = {
351
+ ...fallbackCompat,
352
+ supportsReasoningEffort
353
+ };
354
+ if (!supportsReasoningEffort) {
355
+ delete compat.supportedReasoningEfforts;
356
+ delete compat.reasoningEffortMap;
357
+ }
358
+ }
296
359
  return {
297
360
  id,
298
361
  name: normalizeOptionalString(row.name) ?? fallback?.name ?? id,
@@ -304,8 +367,8 @@ function projectLiveModel(row, fallback) {
304
367
  cacheRead: cacheReadPrice ?? fallback?.cost.cacheRead ?? 0,
305
368
  cacheWrite: fallback?.cost.cacheWrite ?? 0
306
369
  },
307
- contextWindow,
308
- maxTokens: asPositiveSafeInteger(Number(row.max_completion_tokens)) ?? fallback?.maxTokens ?? resolveDefaultModelMaxTokens(contextWindow),
370
+ contextWindow: asPositiveSafeInteger(Number(row.context_length)) ?? fallback?.contextWindow ?? DEFAULT_CONTEXT_WINDOW,
371
+ maxTokens: asPositiveSafeInteger(Number(row.max_completion_tokens)) ?? fallback?.maxTokens ?? DEFAULT_MAX_TOKENS,
309
372
  compat
310
373
  };
311
374
  }
@@ -327,7 +390,7 @@ function projectBasetenLiveModels(rows) {
327
390
  /** Resolves a forward-compatible Baseten model id not yet in the bundled catalog. */
328
391
  function resolveBasetenDynamicModel(modelId) {
329
392
  const id = modelId.trim();
330
- if (!id || BASETEN_MODEL_CATALOG.some((model) => model.id === id)) return;
393
+ if (!id || id.startsWith("decision-models/") || BASETEN_MODEL_CATALOG.some((model) => model.id === id)) return;
331
394
  return {
332
395
  id,
333
396
  name: id,
@@ -343,9 +406,9 @@ function resolveBasetenDynamicModel(modelId) {
343
406
  cacheWrite: 0
344
407
  },
345
408
  contextWindow: DEFAULT_CONTEXT_WINDOW,
346
- maxTokens: resolveDefaultModelMaxTokens(DEFAULT_CONTEXT_WINDOW),
409
+ maxTokens: DEFAULT_MAX_TOKENS,
347
410
  compat: buildBasetenModelCompat(id)
348
411
  };
349
412
  }
350
413
  //#endregion
351
- export { buildBasetenModelCompat as a, resolveBasetenDynamicModel as c, BASETEN_MODEL_CATALOG as i, usesBasetenChatTemplateThinking as l, BASETEN_DEFAULT_MODEL_ID as n, buildStaticBasetenModels as o, BASETEN_DEFAULT_MODEL_REF as r, projectBasetenLiveModels as s, BASETEN_BASE_URL as t, openclaw_plugin_default as u };
414
+ export { BASETEN_MODEL_CATALOG as a, projectBasetenLiveModels as c, openclaw_plugin_default as d, BASETEN_DEFAULT_MODEL_REF as i, resolveBasetenDynamicModel as l, BASETEN_DECISION_MODEL_IDS as n, buildBasetenModelCompat as o, BASETEN_DEFAULT_MODEL_ID as r, buildStaticBasetenModels as s, BASETEN_BASE_URL as t, usesBasetenChatTemplateThinking as u };
@@ -0,0 +1 @@
1
+ {"version":3,"entries":[{"output":"api.js","source":"extensions/baseten/api.ts"},{"output":"decision-provider.js","source":"extensions/baseten/decision-provider.ts"},{"output":"decision-provider.runtime.js","source":"extensions/baseten/decision-provider.runtime.ts"},{"output":"index.js","source":"extensions/baseten/index.ts"},{"output":"models.js","source":"extensions/baseten/models.ts"},{"output":"onboard.js","source":"extensions/baseten/onboard.ts"},{"output":"provider-catalog.js","source":"extensions/baseten/provider-catalog.ts"}],"chunks":[{"output":".setup/models-BIkKHeH8.mjs","sha256":"9cb803e1a14be9b7eef7147d9c264f50a259a5bb7aa5431adb913d6251c70b9d","facadeSource":null,"sources":["extensions/baseten/models.ts","extensions/baseten/openclaw.plugin.json"]},{"output":"api.js","sha256":"d10c3f0ac816db46c8774cae38084d2af761699e6758a81e7f14a82dab7ad7fb","facadeSource":"extensions/baseten/api.ts","sources":[]},{"output":"decision-provider.js","sha256":"789c840380ca5aa016cea147172177ba2ee12ee8d89cc37b0f10fab65ea10903","facadeSource":"extensions/baseten/decision-provider.ts","sources":["extensions/baseten/decision-provider.ts"]},{"output":"decision-provider.runtime.js","sha256":"2ed08e17a739c2a92a0c4c04029d3d5fb357c5d95b75247e54fbb35abcedf09a","facadeSource":"extensions/baseten/decision-provider.runtime.ts","sources":["extensions/baseten/decision-provider.runtime.ts"]},{"output":"index.js","sha256":"6232022bca0ac2c8dc17f2f19938bcde62055d94999f7febf82396611507e2cc","facadeSource":"extensions/baseten/index.ts","sources":["extensions/baseten/index.ts"]},{"output":"models.js","sha256":"c93c4c47cb5f67eaec1c1b39706b7b545864ed0bdf426408b28091eb06306812","facadeSource":"extensions/baseten/models.ts","sources":[]},{"output":"onboard.js","sha256":"dfe9631c3aed4265aad7ae29a0691d3087585fb1628fc123ce879635193d34be","facadeSource":"extensions/baseten/onboard.ts","sources":["extensions/baseten/onboard.ts"]},{"output":"provider-catalog.js","sha256":"e165ce143981f1f09f4eee96a26709fbde16ab5fc6e5d585a87f839f3737c5b5","facadeSource":"extensions/baseten/provider-catalog.ts","sources":["extensions/baseten/provider-catalog.ts"]}],"unrenderedSources":["extensions/baseten/api.ts"]}
package/dist/api.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as buildBasetenModelCompat, c as resolveBasetenDynamicModel, i as BASETEN_MODEL_CATALOG, l as usesBasetenChatTemplateThinking, n as BASETEN_DEFAULT_MODEL_ID, o as buildStaticBasetenModels, r as BASETEN_DEFAULT_MODEL_REF, t as BASETEN_BASE_URL } from "./.setup/models-wG5xIuOb.mjs";
1
+ import { a as BASETEN_MODEL_CATALOG, i as BASETEN_DEFAULT_MODEL_REF, l as resolveBasetenDynamicModel, o as buildBasetenModelCompat, r as BASETEN_DEFAULT_MODEL_ID, s as buildStaticBasetenModels, t as BASETEN_BASE_URL, u as usesBasetenChatTemplateThinking } from "./.setup/models-BIkKHeH8.mjs";
2
2
  import { applyBasetenConfig } from "./onboard.js";
3
3
  import { buildStaticBasetenProvider } from "./provider-catalog.js";
4
4
  export { BASETEN_BASE_URL, BASETEN_DEFAULT_MODEL_ID, BASETEN_DEFAULT_MODEL_REF, BASETEN_MODEL_CATALOG, applyBasetenConfig, buildBasetenModelCompat, buildStaticBasetenModels, buildStaticBasetenProvider, resolveBasetenDynamicModel, usesBasetenChatTemplateThinking };
@@ -0,0 +1,17 @@
1
+ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
2
+ //#region extensions/baseten/decision-provider.ts
3
+ const loadRuntime = createLazyRuntimeModule(() => import("./decision-provider.runtime.js"));
4
+ function buildBasetenDecisionProvider() {
5
+ return {
6
+ id: "baseten",
7
+ contractVersion: 2,
8
+ async evaluate(batch, context) {
9
+ context.signal.throwIfAborted();
10
+ const { evaluateBasetenDecision } = await loadRuntime();
11
+ context.signal.throwIfAborted();
12
+ return evaluateBasetenDecision(batch, context);
13
+ }
14
+ };
15
+ }
16
+ //#endregion
17
+ export { buildBasetenDecisionProvider };
@@ -0,0 +1,218 @@
1
+ import { n as BASETEN_DECISION_MODEL_IDS, t as BASETEN_BASE_URL } from "./.setup/models-BIkKHeH8.mjs";
2
+ import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
3
+ import { getModelProviderRequestTransport } from "openclaw/plugin-sdk/agent-harness-runtime";
4
+ import { validateDecisionResultV2 } from "openclaw/plugin-sdk/decisions";
5
+ import { buildTimeoutAbortSignal } from "openclaw/plugin-sdk/extension-shared";
6
+ import { shouldUseEnvHttpProxyForUrl, withTrustedEnvProxyGuardedFetchMode } from "openclaw/plugin-sdk/fetch-runtime";
7
+ import { createProviderCredentialMatcher, fetchWithProviderHttpGuard, readProviderJsonObjectResponse, resolveProviderHttpRequestConfig } from "openclaw/plugin-sdk/provider-http";
8
+ import { parseRetryAfterHeaderSeconds } from "openclaw/plugin-sdk/retry-runtime";
9
+ //#region extensions/baseten/decision-provider.runtime.ts
10
+ function text(value) {
11
+ return typeof value === "string" ? value : value === void 0 ? "" : JSON.stringify(value);
12
+ }
13
+ function questions(batch) {
14
+ return Object.fromEntries(Object.entries(batch.questions).map(([id, q]) => {
15
+ const instructions = text(q.instructions);
16
+ if (q.type === "boolean") return [id, {
17
+ type: "noul",
18
+ instructions: q.criteria ? `${instructions}\nTrue criterion: ${text(q.criteria.true)}\nFalse criterion: ${text(q.criteria.false)}` : instructions
19
+ }];
20
+ if (q.type === "choice") return [id, {
21
+ type: "choice",
22
+ instructions,
23
+ criteria: Object.fromEntries(Object.entries(q.criteria).map(([key, value]) => [key, text(value)]))
24
+ }];
25
+ if (q.type === "score") return [id, {
26
+ type: "score",
27
+ instructions,
28
+ criteria: q.criteria.map(text)
29
+ }];
30
+ throw new Error("Unsupported Baseten decision question");
31
+ }));
32
+ }
33
+ function parseResult(batch, payload) {
34
+ const invalid = {
35
+ status: "unavailable",
36
+ reason: "invalid-response"
37
+ };
38
+ if (!isRecord(payload.answers) || Object.keys(payload.answers).length !== Object.keys(batch.questions).length || !isRecord(payload.usage)) return invalid;
39
+ const usage = payload.usage;
40
+ if (!Number.isSafeInteger(usage.input_tokens) || typeof usage.input_tokens !== "number" || usage.input_tokens < 0 || usage.output_tokens !== Object.keys(batch.questions).length) return invalid;
41
+ const answers = Object.create(null);
42
+ for (const [id, q] of Object.entries(batch.questions)) {
43
+ const answer = payload.answers[id];
44
+ if (!isRecord(answer)) return invalid;
45
+ if (q.type === "boolean") {
46
+ if (answer.type !== "noul") return invalid;
47
+ answers[id] = {
48
+ type: "boolean",
49
+ probabilityTrue: answer.noul
50
+ };
51
+ continue;
52
+ }
53
+ if (answer.type !== q.type || !isRecord(answer.probabilities) || typeof answer.confidence !== "number" || answer.confidence < 0 || answer.confidence > 1) return invalid;
54
+ if (q.type === "choice") answers[id] = {
55
+ type: "choice",
56
+ choice: answer.choice,
57
+ probabilities: answer.probabilities,
58
+ confidence: answer.confidence
59
+ };
60
+ else if (q.type === "score") {
61
+ const legend = answer.legend;
62
+ const probabilities = answer.probabilities;
63
+ if (!isRecord(legend) || Object.keys(legend).length !== q.criteria.length || Object.keys(probabilities).length !== q.criteria.length || q.criteria.some((value, index) => legend[String(index)] !== text(value))) return invalid;
64
+ answers[id] = {
65
+ type: "score",
66
+ score: answer.score,
67
+ probabilities: q.criteria.map((_, index) => probabilities[String(index)]),
68
+ confidence: answer.confidence
69
+ };
70
+ } else return invalid;
71
+ }
72
+ const result = {
73
+ model: payload.model,
74
+ answers,
75
+ usage: {
76
+ inputTokens: usage.input_tokens,
77
+ outputTokens: usage.output_tokens
78
+ }
79
+ };
80
+ return validateDecisionResultV2(batch, result) ? {
81
+ status: "ok",
82
+ result
83
+ } : invalid;
84
+ }
85
+ async function evaluateBasetenDecision(batch, context) {
86
+ context.signal.throwIfAborted();
87
+ if (context.model.provider !== "baseten" || !BASETEN_DECISION_MODEL_IDS.has(context.model.id) || !["text", "json"].includes(batch.state.type) || Object.values(batch.questions).some((q) => ![
88
+ "boolean",
89
+ "choice",
90
+ "score"
91
+ ].includes(q.type)) || context.reasoning !== void 0 && context.reasoning !== "auto") return {
92
+ status: "unavailable",
93
+ reason: "unsupported-input"
94
+ };
95
+ const auth = context.auth;
96
+ if (auth.mode !== "api-key" || !auth.apiKey) return {
97
+ status: "unavailable",
98
+ reason: "credentials-unavailable"
99
+ };
100
+ const timeoutMs = context.deadlineMonotonicMs - performance.now();
101
+ if (timeoutMs <= 0) return {
102
+ status: "unavailable",
103
+ reason: "transport"
104
+ };
105
+ const { signal: timeoutSignal, cleanup } = buildTimeoutAbortSignal({
106
+ signal: context.signal,
107
+ timeoutMs,
108
+ operation: "Baseten decision"
109
+ });
110
+ const signal = timeoutSignal ?? context.signal;
111
+ let admissionError;
112
+ const assertActive = () => {
113
+ signal.throwIfAborted();
114
+ let admitted;
115
+ try {
116
+ admitted = context.isAdmissible();
117
+ } catch (error) {
118
+ admissionError = { error };
119
+ throw error;
120
+ }
121
+ if (!admitted || performance.now() >= context.deadlineMonotonicMs) throw new Error("Baseten decision is no longer admitted.");
122
+ };
123
+ try {
124
+ const preparedRequest = getModelProviderRequestTransport(context.model);
125
+ const { baseUrl, headers, dispatcherPolicy, allowPrivateNetwork } = resolveProviderHttpRequestConfig({
126
+ provider: "baseten",
127
+ capability: "other",
128
+ transport: "http",
129
+ baseUrl: context.model.baseUrl ?? BASETEN_BASE_URL,
130
+ defaultBaseUrl: BASETEN_BASE_URL,
131
+ headers: context.model.headers,
132
+ defaultHeaders: {
133
+ ...!preparedRequest?.auth || preparedRequest.auth.mode === "provider-default" ? { Authorization: `Bearer ${auth.apiKey}` } : {},
134
+ "Content-Type": "application/json",
135
+ Accept: "application/json"
136
+ },
137
+ request: preparedRequest ? {
138
+ proxy: preparedRequest.proxy,
139
+ tls: preparedRequest.tls,
140
+ allowPrivateNetwork: preparedRequest.allowPrivateNetwork
141
+ } : void 0
142
+ });
143
+ const url = baseUrl.replace(/\/$/, "") + "/systemone";
144
+ const request = {
145
+ url,
146
+ signal,
147
+ beforeRequest: assertActive,
148
+ maxRedirects: 0,
149
+ dispatcherPolicy,
150
+ policy: { allowPrivateNetwork },
151
+ init: {
152
+ method: "POST",
153
+ headers,
154
+ body: JSON.stringify({
155
+ model: context.model.id,
156
+ state: batch.state.type === "text" ? batch.state.text : batch.state.type === "json" ? JSON.stringify(batch.state.value) : "",
157
+ questions: questions(batch)
158
+ })
159
+ }
160
+ };
161
+ const { response, release } = await fetchWithProviderHttpGuard(!dispatcherPolicy && shouldUseEnvHttpProxyForUrl(url) ? withTrustedEnvProxyGuardedFetchMode(request) : request);
162
+ try {
163
+ if (!response.ok) {
164
+ await response.body?.cancel();
165
+ const seconds = parseRetryAfterHeaderSeconds(response.headers.get("retry-after"));
166
+ return {
167
+ status: "unavailable",
168
+ reason: response.status === 401 || response.status === 403 ? "authentication" : response.status === 429 ? "rate-limited" : [
169
+ 400,
170
+ 413,
171
+ 422
172
+ ].includes(response.status) ? "unsupported-input" : "transport",
173
+ ...response.status === 429 && seconds !== void 0 ? { retryAfterMs: seconds * 1e3 } : {}
174
+ };
175
+ }
176
+ let payload;
177
+ try {
178
+ payload = await readProviderJsonObjectResponse(response, "Baseten decision", {
179
+ maxBytes: 1048576,
180
+ signal,
181
+ requestHeaders: headers
182
+ });
183
+ } catch {
184
+ signal.throwIfAborted();
185
+ return {
186
+ status: "unavailable",
187
+ reason: "invalid-response"
188
+ };
189
+ }
190
+ assertActive();
191
+ const serialized = JSON.stringify(payload);
192
+ if (serialized.includes(auth.apiKey) || createProviderCredentialMatcher({
193
+ headers,
194
+ request: preparedRequest,
195
+ configuredHeaderNames: Object.keys(context.model.headers ?? {}),
196
+ defaultAuthHeader: "Authorization",
197
+ defaultAuthPrefix: "Bearer "
198
+ })(serialized)) return {
199
+ status: "unavailable",
200
+ reason: "invalid-response"
201
+ };
202
+ return parseResult(batch, payload);
203
+ } finally {
204
+ await release();
205
+ }
206
+ } catch {
207
+ context.signal.throwIfAborted();
208
+ if (admissionError) throw admissionError.error;
209
+ return {
210
+ status: "unavailable",
211
+ reason: "transport"
212
+ };
213
+ } finally {
214
+ cleanup();
215
+ }
216
+ }
217
+ //#endregion
218
+ export { evaluateBasetenDecision };
package/dist/index.js CHANGED
@@ -1,18 +1,87 @@
1
- import { c as resolveBasetenDynamicModel, s as projectBasetenLiveModels, u as openclaw_plugin_default } from "./.setup/models-wG5xIuOb.mjs";
1
+ import { buildBasetenDecisionProvider } from "./decision-provider.js";
2
+ import { c as projectBasetenLiveModels, d as openclaw_plugin_default, l as resolveBasetenDynamicModel, t as BASETEN_BASE_URL, u as usesBasetenChatTemplateThinking } from "./.setup/models-BIkKHeH8.mjs";
2
3
  import { applyBasetenSetupConfig } from "./onboard.js";
3
4
  import { buildStaticBasetenProvider } from "./provider-catalog.js";
4
- import { createBasetenThinkingWrapper } from "./stream.js";
5
- import { resolveBasetenThinkingProfile } from "./thinking.js";
5
+ import { streamSimple } from "openclaw/plugin-sdk/llm";
6
6
  import { buildOpenAICompatibleLiveProviderCatalog } from "openclaw/plugin-sdk/provider-catalog-live-runtime";
7
7
  import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
8
8
  import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared";
9
+ import { normalizeOpenAICompatibleReasoningReplay, streamWithPayloadPatch } from "openclaw/plugin-sdk/provider-stream-shared";
10
+ import { asNonArrayRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
9
11
  //#region extensions/baseten/index.ts
10
12
  const PROVIDER_ID = "baseten";
13
+ function createBasetenThinkingWrapper(ctx) {
14
+ const underlying = ctx.streamFn ?? streamSimple;
15
+ return (model, context, options) => {
16
+ if (model.provider !== "baseten" || (ctx.sourceApi ?? model.api) !== "openai-completions") return underlying(model, context, options);
17
+ const affinity = options?.promptCacheKey ?? options?.sessionId;
18
+ const cacheRetention = options?.cacheRetention ?? ctx.extraParams?.cacheRetention;
19
+ let streamOptions = options;
20
+ if (affinity && cacheRetention !== "none" && model.baseUrl?.trim().replace(/\/+$/u, "") === BASETEN_BASE_URL && !Object.keys({
21
+ ...model.headers,
22
+ ...options?.headers
23
+ }).some((name) => name.toLowerCase() === "x-session-affinity")) streamOptions = {
24
+ ...options,
25
+ headers: {
26
+ ...options?.headers,
27
+ "x-session-affinity": affinity
28
+ }
29
+ };
30
+ const optIn = usesBasetenChatTemplateThinking(model.id);
31
+ const thinkingLevel = options?.reasoning ?? (ctx.thinkingLevel === "adaptive" ? "max" : ctx.thinkingLevel) ?? (optIn ? "off" : void 0);
32
+ return streamWithPayloadPatch(underlying, model, context, thinkingLevel === void 0 ? streamOptions : {
33
+ ...streamOptions,
34
+ reasoning: thinkingLevel
35
+ }, (payload) => {
36
+ const normalizedModelId = model.id.trim().toLowerCase();
37
+ if (normalizedModelId === "deepseek-ai/deepseek-v4-pro" || normalizedModelId === "deepseek-ai/deepseek-v4-pro-0813") {
38
+ normalizeOpenAICompatibleReasoningReplay(payload, {
39
+ thinkingEnabled: thinkingLevel !== "off",
40
+ stripAssistantMessagesOnly: true,
41
+ replaceNullReasoningContent: true
42
+ });
43
+ if (normalizedModelId === "deepseek-ai/deepseek-v4-pro-0813" && payload.reasoning_effort !== void 0) payload.thinking = { type: payload.reasoning_effort === "none" ? "disabled" : "enabled" };
44
+ }
45
+ if (optIn) payload.chat_template_args = {
46
+ ...asNonArrayRecord(payload.chat_template_args),
47
+ enable_thinking: thinkingLevel !== "off"
48
+ };
49
+ });
50
+ };
51
+ }
52
+ const BASETEN_BINARY_THINKING_PROFILE = {
53
+ levels: [{ id: "off" }, {
54
+ id: "low",
55
+ label: "on"
56
+ }],
57
+ defaultLevel: "off"
58
+ };
59
+ const BASETEN_GLM_52_THINKING_PROFILE = {
60
+ levels: [
61
+ { id: "off" },
62
+ { id: "high" },
63
+ { id: "max" }
64
+ ],
65
+ defaultLevel: "off"
66
+ };
67
+ const BASETEN_DEEPSEEK_THINKING_PROFILE = { levels: [
68
+ { id: "off" },
69
+ { id: "low" },
70
+ { id: "high" },
71
+ { id: "max" }
72
+ ] };
73
+ const BASETEN_DEEPSEEK_V41_THINKING_PROFILE = {
74
+ ...BASETEN_DEEPSEEK_THINKING_PROFILE,
75
+ defaultLevel: "high"
76
+ };
11
77
  var baseten_default = defineSingleProviderPluginEntry({
12
78
  id: PROVIDER_ID,
13
79
  name: "Baseten Provider",
14
80
  description: "Official Baseten Model APIs provider plugin",
15
81
  manifest: openclaw_plugin_default,
82
+ register(api) {
83
+ api.registerDecisionProvider(buildBasetenDecisionProvider());
84
+ },
16
85
  provider: {
17
86
  label: "Baseten",
18
87
  docsPath: "/providers/baseten",
@@ -54,7 +123,13 @@ var baseten_default = defineSingleProviderPluginEntry({
54
123
  }),
55
124
  wrapStreamFn: createBasetenThinkingWrapper,
56
125
  wrapSimpleCompletionStreamFn: createBasetenThinkingWrapper,
57
- resolveThinkingProfile: ({ modelId }) => resolveBasetenThinkingProfile(modelId),
126
+ resolveThinkingProfile: ({ modelId }) => {
127
+ const normalized = modelId.trim().toLowerCase();
128
+ if (normalized === "deepseek-ai/deepseek-v4.1-flash") return BASETEN_DEEPSEEK_V41_THINKING_PROFILE;
129
+ if (normalized === "deepseek-ai/deepseek-v4-pro-0813") return BASETEN_DEEPSEEK_THINKING_PROFILE;
130
+ if (normalized === "zai-org/glm-5.2" || normalized === "zai-org/glm-5.2-fast") return BASETEN_GLM_52_THINKING_PROFILE;
131
+ return usesBasetenChatTemplateThinking(normalized) ? BASETEN_BINARY_THINKING_PROFILE : void 0;
132
+ },
58
133
  isModernModelRef: () => true
59
134
  }
60
135
  });
package/dist/models.js CHANGED
@@ -1,2 +1 @@
1
- import { a as buildBasetenModelCompat, c as resolveBasetenDynamicModel, i as BASETEN_MODEL_CATALOG, l as usesBasetenChatTemplateThinking, n as BASETEN_DEFAULT_MODEL_ID, o as buildStaticBasetenModels, r as BASETEN_DEFAULT_MODEL_REF, s as projectBasetenLiveModels, t as BASETEN_BASE_URL } from "./.setup/models-wG5xIuOb.mjs";
2
- export { BASETEN_BASE_URL, BASETEN_DEFAULT_MODEL_ID, BASETEN_DEFAULT_MODEL_REF, BASETEN_MODEL_CATALOG, buildBasetenModelCompat, buildStaticBasetenModels, projectBasetenLiveModels, resolveBasetenDynamicModel, usesBasetenChatTemplateThinking };
1
+ export { t as BASETEN_BASE_URL, n as BASETEN_DECISION_MODEL_IDS, r as BASETEN_DEFAULT_MODEL_ID, i as BASETEN_DEFAULT_MODEL_REF, a as BASETEN_MODEL_CATALOG, o as buildBasetenModelCompat, s as buildStaticBasetenModels, c as projectBasetenLiveModels, l as resolveBasetenDynamicModel, u as usesBasetenChatTemplateThinking } from "./.setup/models-BIkKHeH8.mjs";
package/dist/onboard.js CHANGED
@@ -1,4 +1,4 @@
1
- import { o as buildStaticBasetenModels, r as BASETEN_DEFAULT_MODEL_REF, t as BASETEN_BASE_URL } from "./.setup/models-wG5xIuOb.mjs";
1
+ import { i as BASETEN_DEFAULT_MODEL_REF, s as buildStaticBasetenModels, t as BASETEN_BASE_URL } from "./.setup/models-BIkKHeH8.mjs";
2
2
  import { createModelCatalogPresetAppliers } from "openclaw/plugin-sdk/provider-onboard";
3
3
  //#region extensions/baseten/onboard.ts
4
4
  const { applyConfig } = createModelCatalogPresetAppliers({
@@ -1,4 +1,4 @@
1
- import { o as buildStaticBasetenModels, t as BASETEN_BASE_URL } from "./.setup/models-wG5xIuOb.mjs";
1
+ import { s as buildStaticBasetenModels, t as BASETEN_BASE_URL } from "./.setup/models-BIkKHeH8.mjs";
2
2
  //#region extensions/baseten/provider-catalog.ts
3
3
  function buildStaticBasetenProvider() {
4
4
  return {
@@ -7,6 +7,7 @@
7
7
  "onStartup": false
8
8
  },
9
9
  "enabledByDefault": true,
10
+ "contracts": { "decisionProviders": ["baseten"] },
10
11
  "providers": [
11
12
  "baseten"
12
13
  ],
@@ -30,6 +31,76 @@
30
31
  "api": "openai-completions",
31
32
  "defaultModel": "deepseek-ai/DeepSeek-V4.1-Flash",
32
33
  "models": [
34
+ {
35
+ "id": "decision-models/baseten-elephant-9b-latest",
36
+ "name": "elephant-1 (9B)",
37
+ "inference": {
38
+ "chat": false,
39
+ "decision": {
40
+ "protocol": "baseten-systemone",
41
+ "input": [
42
+ "text"
43
+ ],
44
+ "reasoning": {
45
+ "modes": [
46
+ "auto"
47
+ ]
48
+ },
49
+ "questions": {
50
+ "boolean": {
51
+ "probabilities": "boolean",
52
+ "abstention": false
53
+ },
54
+ "choice": {
55
+ "probabilities": "categorical",
56
+ "abstention": false,
57
+ "minOptions": 2
58
+ },
59
+ "score": {
60
+ "probabilities": "categorical",
61
+ "abstention": false,
62
+ "minOptions": 2
63
+ }
64
+ },
65
+ "confidence": "provider-specific"
66
+ }
67
+ }
68
+ },
69
+ {
70
+ "id": "decision-models/baseten-mammoth-27b-latest",
71
+ "name": "mammoth-1 (27B)",
72
+ "inference": {
73
+ "chat": false,
74
+ "decision": {
75
+ "protocol": "baseten-systemone",
76
+ "input": [
77
+ "text"
78
+ ],
79
+ "reasoning": {
80
+ "modes": [
81
+ "auto"
82
+ ]
83
+ },
84
+ "questions": {
85
+ "boolean": {
86
+ "probabilities": "boolean",
87
+ "abstention": false
88
+ },
89
+ "choice": {
90
+ "probabilities": "categorical",
91
+ "abstention": false,
92
+ "minOptions": 2
93
+ },
94
+ "score": {
95
+ "probabilities": "categorical",
96
+ "abstention": false,
97
+ "minOptions": 2
98
+ }
99
+ },
100
+ "confidence": "provider-specific"
101
+ }
102
+ }
103
+ },
33
104
  {
34
105
  "id": "deepseek-ai/DeepSeek-V4.1-Flash",
35
106
  "name": "DeepSeek V4.1 Flash",
@@ -46,7 +117,8 @@
46
117
  "compat": {
47
118
  "supportsReasoningEffort": true,
48
119
  "supportedReasoningEfforts": ["none", "low", "high", "max"],
49
- "reasoningEffortMap": { "off": "none", "none": "none", "adaptive": "max" }
120
+ "reasoningEffortMap": { "off": "none", "none": "none", "adaptive": "max" },
121
+ "codeMode": "capable"
50
122
  }
51
123
  },
52
124
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/baseten-provider",
3
- "version": "2026.11.3",
3
+ "version": "2026.11.5-beta.2",
4
4
  "description": "OpenClaw Baseten provider plugin.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -18,10 +18,10 @@
18
18
  "minHostVersion": ">=2026.7.2"
19
19
  },
20
20
  "compat": {
21
- "pluginApi": ">=2026.11.3"
21
+ "pluginApi": ">=2026.11.5-beta.2"
22
22
  },
23
23
  "build": {
24
- "openclawVersion": "2026.11.3",
24
+ "openclawVersion": "2026.11.5-beta.2",
25
25
  "bundledDist": false
26
26
  },
27
27
  "release": {
@@ -40,7 +40,7 @@
40
40
  "assets/activity.svg"
41
41
  ],
42
42
  "peerDependencies": {
43
- "openclaw": ">=2026.11.3"
43
+ "openclaw": ">=2026.11.5-beta.2"
44
44
  },
45
45
  "peerDependenciesMeta": {
46
46
  "openclaw": {
package/dist/stream.js DELETED
@@ -1,47 +0,0 @@
1
- import { l as usesBasetenChatTemplateThinking, t as BASETEN_BASE_URL } from "./.setup/models-wG5xIuOb.mjs";
2
- import { asNonArrayRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
3
- import { streamSimple } from "openclaw/plugin-sdk/llm";
4
- import { normalizeOpenAICompatibleReasoningReplay, streamWithPayloadPatch } from "openclaw/plugin-sdk/provider-stream-shared";
5
- //#region extensions/baseten/stream.ts
6
- /** Baseten session affinity and model-specific thinking policy. */
7
- function createBasetenThinkingWrapper(ctx) {
8
- const underlying = ctx.streamFn ?? streamSimple;
9
- return (model, context, options) => {
10
- if (model.provider !== "baseten" || (ctx.sourceApi ?? model.api) !== "openai-completions") return underlying(model, context, options);
11
- const affinity = options?.promptCacheKey ?? options?.sessionId;
12
- const cacheRetention = options?.cacheRetention ?? ctx.extraParams?.cacheRetention;
13
- let streamOptions = options;
14
- if (affinity && cacheRetention !== "none" && model.baseUrl?.trim().replace(/\/+$/u, "") === BASETEN_BASE_URL && !Object.keys({
15
- ...model.headers,
16
- ...options?.headers
17
- }).some((name) => name.toLowerCase() === "x-session-affinity")) streamOptions = {
18
- ...options,
19
- headers: {
20
- ...options?.headers,
21
- "x-session-affinity": affinity
22
- }
23
- };
24
- const optIn = usesBasetenChatTemplateThinking(model.id);
25
- const thinkingLevel = options?.reasoning ?? (ctx.thinkingLevel === "adaptive" ? "max" : ctx.thinkingLevel) ?? (optIn ? "off" : void 0);
26
- return streamWithPayloadPatch(underlying, model, context, thinkingLevel === void 0 ? streamOptions : {
27
- ...streamOptions,
28
- reasoning: thinkingLevel
29
- }, (payload) => {
30
- const normalizedModelId = model.id.trim().toLowerCase();
31
- if (normalizedModelId === "deepseek-ai/deepseek-v4-pro" || normalizedModelId === "deepseek-ai/deepseek-v4-pro-0813") {
32
- normalizeOpenAICompatibleReasoningReplay(payload, {
33
- thinkingEnabled: thinkingLevel !== "off",
34
- stripAssistantMessagesOnly: true,
35
- replaceNullReasoningContent: true
36
- });
37
- if (normalizedModelId === "deepseek-ai/deepseek-v4-pro-0813" && payload.reasoning_effort !== void 0) payload.thinking = { type: payload.reasoning_effort === "none" ? "disabled" : "enabled" };
38
- }
39
- if (optIn) payload.chat_template_args = {
40
- ...asNonArrayRecord(payload.chat_template_args),
41
- enable_thinking: thinkingLevel !== "off"
42
- };
43
- });
44
- };
45
- }
46
- //#endregion
47
- export { createBasetenThinkingWrapper };
package/dist/thinking.js DELETED
@@ -1,37 +0,0 @@
1
- import { l as usesBasetenChatTemplateThinking } from "./.setup/models-wG5xIuOb.mjs";
2
- //#region extensions/baseten/thinking.ts
3
- const BASETEN_BINARY_THINKING_PROFILE = {
4
- levels: [{ id: "off" }, {
5
- id: "low",
6
- label: "on"
7
- }],
8
- defaultLevel: "off"
9
- };
10
- const BASETEN_GLM_52_THINKING_PROFILE = {
11
- levels: [
12
- { id: "off" },
13
- { id: "high" },
14
- { id: "max" }
15
- ],
16
- defaultLevel: "off"
17
- };
18
- const BASETEN_DEEPSEEK_THINKING_PROFILE = { levels: [
19
- { id: "off" },
20
- { id: "low" },
21
- { id: "high" },
22
- { id: "max" }
23
- ] };
24
- const BASETEN_DEEPSEEK_V41_THINKING_PROFILE = {
25
- ...BASETEN_DEEPSEEK_THINKING_PROFILE,
26
- defaultLevel: "high"
27
- };
28
- /** Exposes only the thinking levels that Baseten actually accepts for opt-in models. */
29
- function resolveBasetenThinkingProfile(modelId) {
30
- const normalized = modelId.trim().toLowerCase();
31
- if (normalized === "deepseek-ai/deepseek-v4.1-flash") return BASETEN_DEEPSEEK_V41_THINKING_PROFILE;
32
- if (normalized === "deepseek-ai/deepseek-v4-pro-0813") return BASETEN_DEEPSEEK_THINKING_PROFILE;
33
- if (normalized === "zai-org/glm-5.2" || normalized === "zai-org/glm-5.2-fast") return BASETEN_GLM_52_THINKING_PROFILE;
34
- return usesBasetenChatTemplateThinking(normalized) ? BASETEN_BINARY_THINKING_PROFILE : void 0;
35
- }
36
- //#endregion
37
- export { resolveBasetenThinkingProfile };