@openclaw/chutes-provider 2026.7.1-beta.6 → 2026.7.2-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -53,7 +53,8 @@ async function runChutesOAuth(ctx) {
53
53
  manual: isRemote,
54
54
  onAuth,
55
55
  onPrompt,
56
- onProgress: (message) => progress.update(message)
56
+ onProgress: (message) => progress.update(message),
57
+ ...ctx.signal ? { signal: ctx.signal } : {}
57
58
  });
58
59
  progress.stop("Chutes OAuth complete");
59
60
  return buildOauthProviderAuthResult({
package/dist/oauth.js CHANGED
@@ -3,7 +3,8 @@ import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runti
3
3
  import { randomBytes } from "node:crypto";
4
4
  import { resolveExpiresAtMsFromDurationSeconds } from "openclaw/plugin-sdk/number-runtime";
5
5
  import { parseOAuthCallbackInput, waitForLocalOAuthCallback } from "openclaw/plugin-sdk/provider-auth-runtime";
6
- import { readProviderJsonResponse, readResponseTextLimited } from "openclaw/plugin-sdk/provider-http";
6
+ import { assertOkOrThrowProviderError, readProviderJsonResponse } from "openclaw/plugin-sdk/provider-http";
7
+ import { buildOAuthRequestSignal } from "openclaw/plugin-sdk/provider-oauth-runtime";
7
8
  //#region extensions/chutes/oauth.ts
8
9
  /**
9
10
  * Chutes OAuth PKCE login flow.
@@ -11,7 +12,7 @@ import { readProviderJsonResponse, readResponseTextLimited } from "openclaw/plug
11
12
  const CHUTES_AUTHORIZE_ENDPOINT = "https://api.chutes.ai/idp/authorize";
12
13
  const CHUTES_TOKEN_ENDPOINT = "https://api.chutes.ai/idp/token";
13
14
  const CHUTES_USERINFO_ENDPOINT = "https://api.chutes.ai/idp/userinfo";
14
- const CHUTES_TOKEN_ERROR_BODY_LIMIT_BYTES = 8 * 1024;
15
+ const CHUTES_OAUTH_REQUEST_TIMEOUT_MS = 3e4;
15
16
  function parseRedirectUri(redirectUri) {
16
17
  const url = new URL(redirectUri);
17
18
  if (url.protocol !== "http:") throw new Error(`Chutes OAuth redirect URI must be http:// (got ${redirectUri})`);
@@ -52,7 +53,13 @@ function resolveChutesExpiresAt(value, now) {
52
53
  });
53
54
  }
54
55
  async function fetchChutesUserInfo(params) {
55
- const response = await (params.fetchFn ?? fetch)(CHUTES_USERINFO_ENDPOINT, { headers: { Authorization: `Bearer ${params.accessToken}` } });
56
+ const response = await (params.fetchFn ?? fetch)(CHUTES_USERINFO_ENDPOINT, {
57
+ headers: { Authorization: `Bearer ${params.accessToken}` },
58
+ signal: buildOAuthRequestSignal({
59
+ timeoutMs: CHUTES_OAUTH_REQUEST_TIMEOUT_MS,
60
+ ...params.signal ? { signal: params.signal } : {}
61
+ })
62
+ });
56
63
  if (!response.ok) return null;
57
64
  const data = await readProviderJsonResponse(response, "Chutes userinfo");
58
65
  return data && typeof data === "object" ? data : null;
@@ -71,12 +78,13 @@ async function exchangeChutesCodeForTokens(params) {
71
78
  const response = await fetchFn(CHUTES_TOKEN_ENDPOINT, {
72
79
  method: "POST",
73
80
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
74
- body
81
+ body,
82
+ signal: buildOAuthRequestSignal({
83
+ timeoutMs: CHUTES_OAUTH_REQUEST_TIMEOUT_MS,
84
+ ...params.signal ? { signal: params.signal } : {}
85
+ })
75
86
  });
76
- if (!response.ok) {
77
- const detail = await readResponseTextLimited(response, CHUTES_TOKEN_ERROR_BODY_LIMIT_BYTES).catch(() => "");
78
- throw new Error(`Chutes token exchange failed: ${detail}`);
79
- }
87
+ await assertOkOrThrowProviderError(response, "Chutes token exchange failed");
80
88
  const data = await readProviderJsonResponse(response, "Chutes token exchange");
81
89
  const access = normalizeOptionalString(data.access_token);
82
90
  const refresh = normalizeOptionalString(data.refresh_token);
@@ -84,10 +92,16 @@ async function exchangeChutesCodeForTokens(params) {
84
92
  if (!access) throw new Error("Chutes token exchange returned no access_token");
85
93
  if (!refresh) throw new Error("Chutes token exchange returned no refresh_token");
86
94
  if (expires === void 0) throw new Error("Chutes token exchange returned invalid expires_in");
87
- const info = await fetchChutesUserInfo({
88
- accessToken: access,
89
- fetchFn
90
- });
95
+ let info = null;
96
+ try {
97
+ info = await fetchChutesUserInfo({
98
+ accessToken: access,
99
+ fetchFn,
100
+ ...params.signal ? { signal: params.signal } : {}
101
+ });
102
+ } catch (error) {
103
+ if (params.signal?.aborted) throw error;
104
+ }
91
105
  return {
92
106
  access,
93
107
  refresh,
@@ -127,8 +141,10 @@ async function loginChutes(params) {
127
141
  redirectUri: params.app.redirectUri,
128
142
  successTitle: "Chutes OAuth complete",
129
143
  hostname: redirect.hostname,
130
- onProgress: params.onProgress
131
- }).catch(async () => {
144
+ onProgress: params.onProgress,
145
+ ...params.signal ? { signal: params.signal } : {}
146
+ }).catch(async (error) => {
147
+ if (params.signal?.aborted) throw error;
132
148
  params.onProgress?.("OAuth callback not detected; paste redirect URL...");
133
149
  return parseManualOAuthInput(await params.onPrompt({
134
150
  message: "Paste the redirect URL",
@@ -143,7 +159,8 @@ async function loginChutes(params) {
143
159
  app: params.app,
144
160
  code: codeAndState.code,
145
161
  codeVerifier: verifier,
146
- fetchFn: params.fetchFn
162
+ fetchFn: params.fetchFn,
163
+ ...params.signal ? { signal: params.signal } : {}
147
164
  });
148
165
  }
149
166
  //#endregion
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@openclaw/chutes-provider",
3
- "version": "2026.7.1-beta.6",
3
+ "version": "2026.7.2-beta.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/chutes-provider",
9
- "version": "2026.7.1-beta.6"
9
+ "version": "2026.7.2-beta.1"
10
10
  }
11
11
  }
12
12
  }
@@ -31,6 +31,7 @@
31
31
  "provider": "chutes",
32
32
  "method": "oauth",
33
33
  "choiceId": "chutes",
34
+ "appGuidedAuth": "oauth",
34
35
  "choiceLabel": "Chutes (OAuth)",
35
36
  "choiceHint": "Browser sign-in",
36
37
  "groupId": "chutes",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/chutes-provider",
3
- "version": "2026.7.1-beta.6",
3
+ "version": "2026.7.2-beta.1",
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.1-beta.6"
21
+ "pluginApi": ">=2026.7.2-beta.1"
22
22
  },
23
23
  "build": {
24
- "openclawVersion": "2026.7.1-beta.6",
24
+ "openclawVersion": "2026.7.2-beta.1",
25
25
  "bundledDist": false
26
26
  },
27
27
  "release": {
@@ -39,7 +39,7 @@
39
39
  "README.md"
40
40
  ],
41
41
  "peerDependencies": {
42
- "openclaw": ">=2026.7.1-beta.6"
42
+ "openclaw": ">=2026.7.2-beta.1"
43
43
  },
44
44
  "peerDependenciesMeta": {
45
45
  "openclaw": {