@openclaw/chutes-provider 2026.7.2-beta.5 → 2026.7.33
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 +3 -3
- package/dist/index.js +3 -3
- package/dist/models.js +766 -2
- package/dist/oauth.js +18 -38
- package/dist/onboard.js +26 -18
- package/dist/provider-catalog.js +3 -3
- package/openclaw.plugin.json +597 -37
- package/package.json +4 -4
- package/dist/models-BEC8VGou.js +0 -245
package/dist/oauth.js
CHANGED
|
@@ -3,8 +3,7 @@ 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 {
|
|
7
|
-
import { buildOAuthRequestSignal } from "openclaw/plugin-sdk/provider-oauth-runtime";
|
|
6
|
+
import { readProviderJsonResponse, readResponseTextLimited } from "openclaw/plugin-sdk/provider-http";
|
|
8
7
|
//#region extensions/chutes/oauth.ts
|
|
9
8
|
/**
|
|
10
9
|
* Chutes OAuth PKCE login flow.
|
|
@@ -12,7 +11,7 @@ import { buildOAuthRequestSignal } from "openclaw/plugin-sdk/provider-oauth-runt
|
|
|
12
11
|
const CHUTES_AUTHORIZE_ENDPOINT = "https://api.chutes.ai/idp/authorize";
|
|
13
12
|
const CHUTES_TOKEN_ENDPOINT = "https://api.chutes.ai/idp/token";
|
|
14
13
|
const CHUTES_USERINFO_ENDPOINT = "https://api.chutes.ai/idp/userinfo";
|
|
15
|
-
const
|
|
14
|
+
const CHUTES_TOKEN_ERROR_BODY_LIMIT_BYTES = 8192;
|
|
16
15
|
function parseRedirectUri(redirectUri) {
|
|
17
16
|
const url = new URL(redirectUri);
|
|
18
17
|
if (url.protocol !== "http:") throw new Error(`Chutes OAuth redirect URI must be http:// (got ${redirectUri})`);
|
|
@@ -48,22 +47,13 @@ function buildAuthorizeUrl(params) {
|
|
|
48
47
|
function resolveChutesExpiresAt(value, now) {
|
|
49
48
|
return resolveExpiresAtMsFromDurationSeconds(value, {
|
|
50
49
|
nowMs: now,
|
|
51
|
-
bufferMs:
|
|
50
|
+
bufferMs: 3e5,
|
|
52
51
|
minRemainingMs: 3e4
|
|
53
52
|
});
|
|
54
53
|
}
|
|
55
54
|
async function fetchChutesUserInfo(params) {
|
|
56
|
-
const response = await (params.fetchFn ?? fetch)(CHUTES_USERINFO_ENDPOINT, {
|
|
57
|
-
|
|
58
|
-
signal: buildOAuthRequestSignal({
|
|
59
|
-
timeoutMs: CHUTES_OAUTH_REQUEST_TIMEOUT_MS,
|
|
60
|
-
...params.signal ? { signal: params.signal } : {}
|
|
61
|
-
})
|
|
62
|
-
});
|
|
63
|
-
if (!response.ok) {
|
|
64
|
-
await response.body?.cancel().catch(() => void 0);
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
55
|
+
const response = await (params.fetchFn ?? fetch)(CHUTES_USERINFO_ENDPOINT, { headers: { Authorization: `Bearer ${params.accessToken}` } });
|
|
56
|
+
if (!response.ok) return null;
|
|
67
57
|
const data = await readProviderJsonResponse(response, "Chutes userinfo");
|
|
68
58
|
return data && typeof data === "object" ? data : null;
|
|
69
59
|
}
|
|
@@ -81,13 +71,12 @@ async function exchangeChutesCodeForTokens(params) {
|
|
|
81
71
|
const response = await fetchFn(CHUTES_TOKEN_ENDPOINT, {
|
|
82
72
|
method: "POST",
|
|
83
73
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
84
|
-
body
|
|
85
|
-
signal: buildOAuthRequestSignal({
|
|
86
|
-
timeoutMs: CHUTES_OAUTH_REQUEST_TIMEOUT_MS,
|
|
87
|
-
...params.signal ? { signal: params.signal } : {}
|
|
88
|
-
})
|
|
74
|
+
body
|
|
89
75
|
});
|
|
90
|
-
|
|
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
|
+
}
|
|
91
80
|
const data = await readProviderJsonResponse(response, "Chutes token exchange");
|
|
92
81
|
const access = normalizeOptionalString(data.access_token);
|
|
93
82
|
const refresh = normalizeOptionalString(data.refresh_token);
|
|
@@ -95,16 +84,10 @@ async function exchangeChutesCodeForTokens(params) {
|
|
|
95
84
|
if (!access) throw new Error("Chutes token exchange returned no access_token");
|
|
96
85
|
if (!refresh) throw new Error("Chutes token exchange returned no refresh_token");
|
|
97
86
|
if (expires === void 0) throw new Error("Chutes token exchange returned invalid expires_in");
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
fetchFn,
|
|
103
|
-
...params.signal ? { signal: params.signal } : {}
|
|
104
|
-
});
|
|
105
|
-
} catch (error) {
|
|
106
|
-
if (params.signal?.aborted) throw error;
|
|
107
|
-
}
|
|
87
|
+
const info = await fetchChutesUserInfo({
|
|
88
|
+
accessToken: access,
|
|
89
|
+
fetchFn
|
|
90
|
+
});
|
|
108
91
|
return {
|
|
109
92
|
access,
|
|
110
93
|
refresh,
|
|
@@ -118,7 +101,7 @@ async function exchangeChutesCodeForTokens(params) {
|
|
|
118
101
|
async function loginChutes(params) {
|
|
119
102
|
const { verifier, challenge } = generatePkceVerifierChallenge();
|
|
120
103
|
const state = params.createState?.() ?? randomBytes(16).toString("hex");
|
|
121
|
-
const timeoutMs = params.timeoutMs ??
|
|
104
|
+
const timeoutMs = params.timeoutMs ?? 18e4;
|
|
122
105
|
const url = buildAuthorizeUrl({
|
|
123
106
|
clientId: params.app.clientId,
|
|
124
107
|
redirectUri: params.app.redirectUri,
|
|
@@ -144,10 +127,8 @@ async function loginChutes(params) {
|
|
|
144
127
|
redirectUri: params.app.redirectUri,
|
|
145
128
|
successTitle: "Chutes OAuth complete",
|
|
146
129
|
hostname: redirect.hostname,
|
|
147
|
-
onProgress: params.onProgress
|
|
148
|
-
|
|
149
|
-
}).catch(async (error) => {
|
|
150
|
-
if (params.signal?.aborted) throw error;
|
|
130
|
+
onProgress: params.onProgress
|
|
131
|
+
}).catch(async () => {
|
|
151
132
|
params.onProgress?.("OAuth callback not detected; paste redirect URL...");
|
|
152
133
|
return parseManualOAuthInput(await params.onPrompt({
|
|
153
134
|
message: "Paste the redirect URL",
|
|
@@ -162,8 +143,7 @@ async function loginChutes(params) {
|
|
|
162
143
|
app: params.app,
|
|
163
144
|
code: codeAndState.code,
|
|
164
145
|
codeVerifier: verifier,
|
|
165
|
-
fetchFn: params.fetchFn
|
|
166
|
-
...params.signal ? { signal: params.signal } : {}
|
|
146
|
+
fetchFn: params.fetchFn
|
|
167
147
|
});
|
|
168
148
|
}
|
|
169
149
|
//#endregion
|
package/dist/onboard.js
CHANGED
|
@@ -1,32 +1,39 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { applyAgentDefaultModelPrimary, createModelCatalogPresetAppliers } from "openclaw/plugin-sdk/provider-onboard";
|
|
1
|
+
import { CHUTES_BASE_URL, CHUTES_DEFAULT_MODEL_REF, CHUTES_MODEL_CATALOG, buildChutesModelDefinition } from "./models.js";
|
|
2
|
+
import { applyAgentDefaultModelPrimary, applyProviderConfigWithModelCatalogPreset } from "openclaw/plugin-sdk/provider-onboard";
|
|
4
3
|
//#region extensions/chutes/onboard.ts
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Chutes onboarding config helpers for OAuth and API-key setup.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Apply Chutes provider configuration without changing the default model.
|
|
9
|
+
* Registers all catalog models and sets provider aliases (chutes-fast, etc.).
|
|
10
|
+
*/
|
|
11
|
+
function applyChutesProviderConfig(cfg) {
|
|
12
|
+
return applyProviderConfigWithModelCatalogPreset(cfg, {
|
|
10
13
|
providerId: "chutes",
|
|
11
14
|
api: "openai-completions",
|
|
12
15
|
baseUrl: CHUTES_BASE_URL,
|
|
13
|
-
catalogModels:
|
|
16
|
+
catalogModels: CHUTES_MODEL_CATALOG.map(buildChutesModelDefinition),
|
|
14
17
|
aliases: [
|
|
15
18
|
...CHUTES_MODEL_CATALOG.map((model) => `chutes/${model.id}`),
|
|
19
|
+
{
|
|
20
|
+
modelRef: "chutes-fast",
|
|
21
|
+
alias: "chutes/zai-org/GLM-4.7-FP8"
|
|
22
|
+
},
|
|
16
23
|
{
|
|
17
24
|
modelRef: "chutes-vision",
|
|
18
|
-
alias: "chutes/
|
|
25
|
+
alias: "chutes/chutesai/Mistral-Small-3.2-24B-Instruct-2506"
|
|
19
26
|
},
|
|
20
27
|
{
|
|
21
28
|
modelRef: "chutes-pro",
|
|
22
29
|
alias: "chutes/deepseek-ai/DeepSeek-V3.2-TEE"
|
|
23
30
|
}
|
|
24
31
|
]
|
|
25
|
-
})
|
|
26
|
-
});
|
|
27
|
-
function applyChutesProviderConfig(cfg) {
|
|
28
|
-
return chutesPresetAppliers.applyProviderConfig(cfg);
|
|
32
|
+
});
|
|
29
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Apply Chutes provider configuration AND set Chutes as the default model.
|
|
36
|
+
*/
|
|
30
37
|
function applyChutesConfig(cfg) {
|
|
31
38
|
const next = applyChutesProviderConfig(cfg);
|
|
32
39
|
return {
|
|
@@ -37,18 +44,19 @@ function applyChutesConfig(cfg) {
|
|
|
37
44
|
...next.agents?.defaults,
|
|
38
45
|
model: {
|
|
39
46
|
primary: CHUTES_DEFAULT_MODEL_REF,
|
|
40
|
-
fallbacks: ["chutes/deepseek-ai/DeepSeek-V3.2-TEE", "chutes/
|
|
47
|
+
fallbacks: ["chutes/deepseek-ai/DeepSeek-V3.2-TEE", "chutes/Qwen/Qwen3-32B"]
|
|
41
48
|
},
|
|
42
49
|
imageModel: {
|
|
43
|
-
primary: "chutes/
|
|
44
|
-
fallbacks: ["chutes/
|
|
50
|
+
primary: "chutes/chutesai/Mistral-Small-3.2-24B-Instruct-2506",
|
|
51
|
+
fallbacks: ["chutes/chutesai/Mistral-Small-3.1-24B-Instruct-2503"]
|
|
45
52
|
}
|
|
46
53
|
}
|
|
47
54
|
}
|
|
48
55
|
};
|
|
49
56
|
}
|
|
57
|
+
/** Applies Chutes provider config and sets the default model for API-key auth. */
|
|
50
58
|
function applyChutesApiKeyConfig(cfg) {
|
|
51
59
|
return applyAgentDefaultModelPrimary(applyChutesProviderConfig(cfg), CHUTES_DEFAULT_MODEL_REF);
|
|
52
60
|
}
|
|
53
61
|
//#endregion
|
|
54
|
-
export {
|
|
62
|
+
export { CHUTES_DEFAULT_MODEL_REF, applyChutesApiKeyConfig, applyChutesConfig, applyChutesProviderConfig };
|
package/dist/provider-catalog.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CHUTES_BASE_URL, CHUTES_MODEL_CATALOG, buildChutesModelDefinition, discoverChutesModels } from "./models.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() {
|
|
5
5
|
return {
|
|
6
6
|
baseUrl: CHUTES_BASE_URL,
|
|
7
7
|
api: "openai-completions",
|
|
8
|
-
models:
|
|
8
|
+
models: CHUTES_MODEL_CATALOG.map(buildChutesModelDefinition)
|
|
9
9
|
};
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
@@ -18,7 +18,7 @@ async function buildChutesProvider(accessToken) {
|
|
|
18
18
|
return {
|
|
19
19
|
baseUrl: CHUTES_BASE_URL,
|
|
20
20
|
api: "openai-completions",
|
|
21
|
-
models: models.length > 0 ? models :
|
|
21
|
+
models: models.length > 0 ? models : CHUTES_MODEL_CATALOG.map(buildChutesModelDefinition)
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
24
|
//#endregion
|