@openclaw/chutes-provider 2026.7.2-beta.5 → 2026.8.1-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.
package/dist/api.js CHANGED
@@ -1,4 +1,4 @@
1
- import { n as CHUTES_MODEL_CATALOG, r as discoverChutesModels, t as CHUTES_BASE_URL } from "./models-BEC8VGou.js";
1
+ import { n as CHUTES_MODEL_CATALOG, r as discoverChutesModels, t as CHUTES_BASE_URL } from "./models-CuOVDO2U.js";
2
2
  import { CHUTES_DEFAULT_MODEL_ID, CHUTES_DEFAULT_MODEL_REF, applyChutesApiKeyConfig, applyChutesConfig, applyChutesProviderConfig } from "./onboard.js";
3
3
  import { buildChutesProvider } from "./provider-catalog.js";
4
4
  export { CHUTES_BASE_URL, CHUTES_DEFAULT_MODEL_ID, CHUTES_DEFAULT_MODEL_REF, CHUTES_MODEL_CATALOG, applyChutesApiKeyConfig, applyChutesConfig, applyChutesProviderConfig, buildChutesProvider, discoverChutesModels };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { loginChutes } from "./oauth.js";
1
+ import { loginChutes, refreshChutesOAuthCredential } from "./oauth.js";
2
2
  import { CHUTES_DEFAULT_MODEL_REF, applyChutesApiKeyConfig, applyChutesProviderConfig } from "./onboard.js";
3
3
  import { buildChutesProvider, buildStaticChutesProvider } from "./provider-catalog.js";
4
4
  import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
@@ -141,7 +141,8 @@ var chutes_default = definePluginEntry({
141
141
  staticCatalog: {
142
142
  order: "profile",
143
143
  run: async () => ({ provider: buildStaticChutesProvider() })
144
- }
144
+ },
145
+ refreshOAuth: refreshChutesOAuthCredential
145
146
  });
146
147
  }
147
148
  });
@@ -1,4 +1,3 @@
1
- import { isChutesModelDiscoveryTestEnvironment } from "./model-discovery-env.js";
2
1
  import { asPositiveSafeInteger, normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
3
2
  import { buildManifestModelDefinition } from "openclaw/plugin-sdk/provider-catalog-shared";
4
3
  import { withTrustedEnvProxyGuardedFetchMode } from "openclaw/plugin-sdk/fetch-runtime";
@@ -209,7 +208,7 @@ function projectChutesModels(rows) {
209
208
  cacheRead: entry.pricing?.input_cache_read || 0,
210
209
  cacheWrite: 0
211
210
  },
212
- contextWindow: asPositiveSafeInteger(entry.context_length) ?? CHUTES_DEFAULT_CONTEXT_WINDOW,
211
+ contextWindow: asPositiveSafeInteger(entry.context_length) ?? asPositiveSafeInteger(entry.max_model_len) ?? CHUTES_DEFAULT_CONTEXT_WINDOW,
213
212
  maxTokens: asPositiveSafeInteger(entry.max_output_length) ?? CHUTES_DEFAULT_MAX_TOKENS,
214
213
  compat: { supportsUsageInStreaming: false }
215
214
  });
@@ -218,7 +217,6 @@ function projectChutesModels(rows) {
218
217
  }
219
218
  /** Discovers Chutes models dynamically, falling back to the bundled static catalog. */
220
219
  async function discoverChutesModels(accessToken) {
221
- if (isChutesModelDiscoveryTestEnvironment()) return structuredClone(CHUTES_MODEL_CATALOG);
222
220
  return (await buildLiveModelProviderConfig({
223
221
  providerId: "chutes",
224
222
  endpoint: `${CHUTES_BASE_URL}/models`,
package/dist/models.js CHANGED
@@ -1,2 +1,2 @@
1
- import { n as CHUTES_MODEL_CATALOG, r as discoverChutesModels, t as CHUTES_BASE_URL } from "./models-BEC8VGou.js";
1
+ import { n as CHUTES_MODEL_CATALOG, r as discoverChutesModels, t as CHUTES_BASE_URL } from "./models-CuOVDO2U.js";
2
2
  export { CHUTES_BASE_URL, CHUTES_MODEL_CATALOG, discoverChutesModels };
package/dist/oauth.js CHANGED
@@ -1,4 +1,4 @@
1
- import { generatePkceVerifierChallenge, toFormUrlEncoded } from "openclaw/plugin-sdk/provider-auth";
1
+ import { generatePkceVerifierChallenge } from "openclaw/plugin-sdk/provider-auth";
2
2
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  import { randomBytes } from "node:crypto";
4
4
  import { resolveExpiresAtMsFromDurationSeconds } from "openclaw/plugin-sdk/number-runtime";
@@ -52,6 +52,28 @@ function resolveChutesExpiresAt(value, now) {
52
52
  minRemainingMs: 3e4
53
53
  });
54
54
  }
55
+ async function requestChutesTokenGrant(params) {
56
+ const response = await (params.fetchFn ?? fetch)(CHUTES_TOKEN_ENDPOINT, {
57
+ method: "POST",
58
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
59
+ body: params.body,
60
+ signal: buildOAuthRequestSignal({
61
+ timeoutMs: CHUTES_OAUTH_REQUEST_TIMEOUT_MS,
62
+ ...params.signal ? { signal: params.signal } : {}
63
+ })
64
+ });
65
+ await assertOkOrThrowProviderError(response, `${params.responseLabel} failed`);
66
+ const data = await readProviderJsonResponse(response, params.responseLabel);
67
+ const access = normalizeOptionalString(data.access_token);
68
+ const expires = resolveChutesExpiresAt(data.expires_in, params.now ?? Date.now());
69
+ if (!access) throw new Error(`${params.responseLabel} returned no access_token`);
70
+ if (expires === void 0) throw new Error(`${params.responseLabel} returned invalid expires_in`);
71
+ return {
72
+ access,
73
+ refresh: normalizeOptionalString(data.refresh_token),
74
+ expires
75
+ };
76
+ }
55
77
  async function fetchChutesUserInfo(params) {
56
78
  const response = await (params.fetchFn ?? fetch)(CHUTES_USERINFO_ENDPOINT, {
57
79
  headers: { Authorization: `Bearer ${params.accessToken}` },
@@ -70,35 +92,26 @@ async function fetchChutesUserInfo(params) {
70
92
  async function exchangeChutesCodeForTokens(params) {
71
93
  const fetchFn = params.fetchFn ?? fetch;
72
94
  const now = params.now ?? Date.now();
73
- const body = new URLSearchParams(toFormUrlEncoded({
95
+ const body = new URLSearchParams({
74
96
  grant_type: "authorization_code",
75
97
  client_id: params.app.clientId,
76
98
  code: params.code,
77
99
  redirect_uri: params.app.redirectUri,
78
100
  code_verifier: params.codeVerifier
79
- }));
101
+ });
80
102
  if (params.app.clientSecret) body.set("client_secret", params.app.clientSecret);
81
- const response = await fetchFn(CHUTES_TOKEN_ENDPOINT, {
82
- method: "POST",
83
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
103
+ const token = await requestChutesTokenGrant({
84
104
  body,
85
- signal: buildOAuthRequestSignal({
86
- timeoutMs: CHUTES_OAUTH_REQUEST_TIMEOUT_MS,
87
- ...params.signal ? { signal: params.signal } : {}
88
- })
105
+ responseLabel: "Chutes token exchange",
106
+ fetchFn,
107
+ now,
108
+ ...params.signal ? { signal: params.signal } : {}
89
109
  });
90
- await assertOkOrThrowProviderError(response, "Chutes token exchange failed");
91
- const data = await readProviderJsonResponse(response, "Chutes token exchange");
92
- const access = normalizeOptionalString(data.access_token);
93
- const refresh = normalizeOptionalString(data.refresh_token);
94
- const expires = resolveChutesExpiresAt(data.expires_in, now);
95
- if (!access) throw new Error("Chutes token exchange returned no access_token");
96
- if (!refresh) throw new Error("Chutes token exchange returned no refresh_token");
97
- if (expires === void 0) throw new Error("Chutes token exchange returned invalid expires_in");
110
+ if (!token.refresh) throw new Error("Chutes token exchange returned no refresh_token");
98
111
  let info = null;
99
112
  try {
100
113
  info = await fetchChutesUserInfo({
101
- accessToken: access,
114
+ accessToken: token.access,
102
115
  fetchFn,
103
116
  ...params.signal ? { signal: params.signal } : {}
104
117
  });
@@ -106,14 +119,41 @@ async function exchangeChutesCodeForTokens(params) {
106
119
  if (params.signal?.aborted) throw error;
107
120
  }
108
121
  return {
109
- access,
110
- refresh,
111
- expires,
122
+ access: token.access,
123
+ refresh: token.refresh,
124
+ expires: token.expires,
112
125
  email: info?.username,
113
126
  accountId: info?.sub,
114
127
  clientId: params.app.clientId
115
128
  };
116
129
  }
130
+ /** Refreshes a stored Chutes OAuth credential through the provider token endpoint. */
131
+ async function refreshChutesOAuthCredential(credential, options = {}) {
132
+ const refreshToken = normalizeOptionalString(credential.refresh);
133
+ if (!refreshToken) throw new Error("Chutes OAuth credential is missing refresh token");
134
+ const clientId = normalizeOptionalString(credential.clientId ?? process.env.CHUTES_CLIENT_ID);
135
+ if (!clientId) throw new Error("Missing CHUTES_CLIENT_ID for Chutes OAuth refresh (set env var or re-auth).");
136
+ const clientSecret = normalizeOptionalString(process.env.CHUTES_CLIENT_SECRET);
137
+ const body = new URLSearchParams({
138
+ grant_type: "refresh_token",
139
+ client_id: clientId,
140
+ refresh_token: refreshToken
141
+ });
142
+ if (clientSecret) body.set("client_secret", clientSecret);
143
+ const token = await requestChutesTokenGrant({
144
+ body,
145
+ responseLabel: "Chutes token refresh",
146
+ fetchFn: options.fetchFn,
147
+ now: options.now
148
+ });
149
+ return {
150
+ ...credential,
151
+ access: token.access,
152
+ refresh: token.refresh ?? refreshToken,
153
+ expires: token.expires,
154
+ clientId
155
+ };
156
+ }
117
157
  /** Runs Chutes OAuth and returns refreshable stored credentials. */
118
158
  async function loginChutes(params) {
119
159
  const { verifier, challenge } = generatePkceVerifierChallenge();
@@ -167,4 +207,4 @@ async function loginChutes(params) {
167
207
  });
168
208
  }
169
209
  //#endregion
170
- export { loginChutes };
210
+ export { loginChutes, refreshChutesOAuthCredential };
package/dist/onboard.js CHANGED
@@ -1,4 +1,4 @@
1
- import { i as openclaw_plugin_default, n as CHUTES_MODEL_CATALOG, t as CHUTES_BASE_URL } from "./models-BEC8VGou.js";
1
+ import { i as openclaw_plugin_default, n as CHUTES_MODEL_CATALOG, t as CHUTES_BASE_URL } from "./models-CuOVDO2U.js";
2
2
  import { readManifestProviderDefaultModelRef } from "openclaw/plugin-sdk/provider-catalog-shared";
3
3
  import { applyAgentDefaultModelPrimary, createModelCatalogPresetAppliers } from "openclaw/plugin-sdk/provider-onboard";
4
4
  //#region extensions/chutes/onboard.ts
@@ -1,4 +1,4 @@
1
- import { n as CHUTES_MODEL_CATALOG, r as discoverChutesModels, t as CHUTES_BASE_URL } from "./models-BEC8VGou.js";
1
+ import { n as CHUTES_MODEL_CATALOG, r as discoverChutesModels, t as CHUTES_BASE_URL } from "./models-CuOVDO2U.js";
2
2
  //#region extensions/chutes/provider-catalog.ts
3
3
  /** Builds the static Chutes provider catalog from bundled model metadata. */
4
4
  function buildStaticChutesProvider() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/chutes-provider",
3
- "version": "2026.7.2-beta.5",
3
+ "version": "2026.8.1-beta.2",
4
4
  "description": "OpenClaw Chutes.ai 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.7.2-beta.5"
21
+ "pluginApi": ">=2026.8.1-beta.2"
22
22
  },
23
23
  "build": {
24
- "openclawVersion": "2026.7.2-beta.5",
24
+ "openclawVersion": "2026.8.1-beta.2",
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.7.2-beta.5"
41
+ "openclaw": ">=2026.8.1-beta.2"
42
42
  },
43
43
  "peerDependenciesMeta": {
44
44
  "openclaw": {
@@ -1,10 +0,0 @@
1
- //#region extensions/chutes/model-discovery-env.ts
2
- /**
3
- * Environment helper for Chutes model discovery behavior in tests.
4
- */
5
- /** Returns whether dynamic Chutes model discovery should use test behavior. */
6
- function isChutesModelDiscoveryTestEnvironment(env = process.env) {
7
- return env.NODE_ENV === "test" || env.VITEST === "true";
8
- }
9
- //#endregion
10
- export { isChutesModelDiscoveryTestEnvironment };