@openclaw/chutes-provider 2026.7.1 → 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 +2 -1
- package/dist/oauth.js +32 -15
- package/npm-shrinkwrap.json +2 -2
- package/openclaw.plugin.json +1 -0
- package/package.json +4 -4
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 {
|
|
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
|
|
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, {
|
|
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
|
-
|
|
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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
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
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/chutes-provider",
|
|
3
|
-
"version": "2026.7.1",
|
|
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"
|
|
9
|
+
"version": "2026.7.2-beta.1"
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
}
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/chutes-provider",
|
|
3
|
-
"version": "2026.7.1",
|
|
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"
|
|
21
|
+
"pluginApi": ">=2026.7.2-beta.1"
|
|
22
22
|
},
|
|
23
23
|
"build": {
|
|
24
|
-
"openclawVersion": "2026.7.1",
|
|
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"
|
|
42
|
+
"openclaw": ">=2026.7.2-beta.1"
|
|
43
43
|
},
|
|
44
44
|
"peerDependenciesMeta": {
|
|
45
45
|
"openclaw": {
|