@openclaw/groq-provider 2026.7.2-beta.2 → 2026.7.2-beta.4
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 +260 -1
- package/npm-shrinkwrap.json +2 -2
- package/openclaw.plugin.json +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,8 +1,254 @@
|
|
|
1
1
|
import { groqMediaUnderstandingProvider } from "./media-understanding-provider.js";
|
|
2
|
+
import { createAssistantMessageEventStream, streamSimple } from "openclaw/plugin-sdk/llm";
|
|
2
3
|
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
3
4
|
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth-api-key";
|
|
5
|
+
import { buildOpenAICompatibleProviderCatalog } from "openclaw/plugin-sdk/provider-catalog-live-runtime";
|
|
6
|
+
import { buildManifestModelProviderConfig } from "openclaw/plugin-sdk/provider-catalog-shared";
|
|
7
|
+
//#region extensions/groq/openclaw.plugin.json
|
|
8
|
+
var modelCatalog = {
|
|
9
|
+
"providers": { "groq": {
|
|
10
|
+
"baseUrl": "https://api.groq.com/openai/v1",
|
|
11
|
+
"api": "openai-completions",
|
|
12
|
+
"models": [
|
|
13
|
+
{
|
|
14
|
+
"id": "groq/compound",
|
|
15
|
+
"name": "Compound",
|
|
16
|
+
"reasoning": true,
|
|
17
|
+
"input": ["text"],
|
|
18
|
+
"contextWindow": 131072,
|
|
19
|
+
"maxTokens": 8192,
|
|
20
|
+
"cost": {
|
|
21
|
+
"input": 0,
|
|
22
|
+
"output": 0,
|
|
23
|
+
"cacheRead": 0,
|
|
24
|
+
"cacheWrite": 0
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"id": "groq/compound-mini",
|
|
29
|
+
"name": "Compound Mini",
|
|
30
|
+
"reasoning": true,
|
|
31
|
+
"input": ["text"],
|
|
32
|
+
"contextWindow": 131072,
|
|
33
|
+
"maxTokens": 8192,
|
|
34
|
+
"cost": {
|
|
35
|
+
"input": 0,
|
|
36
|
+
"output": 0,
|
|
37
|
+
"cacheRead": 0,
|
|
38
|
+
"cacheWrite": 0
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"id": "llama-3.1-8b-instant",
|
|
43
|
+
"name": "Llama 3.1 8B Instant",
|
|
44
|
+
"reasoning": false,
|
|
45
|
+
"input": ["text"],
|
|
46
|
+
"contextWindow": 131072,
|
|
47
|
+
"maxTokens": 131072,
|
|
48
|
+
"cost": {
|
|
49
|
+
"input": .05,
|
|
50
|
+
"output": .08,
|
|
51
|
+
"cacheRead": 0,
|
|
52
|
+
"cacheWrite": 0
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"id": "llama-3.3-70b-versatile",
|
|
57
|
+
"name": "Llama 3.3 70B Versatile",
|
|
58
|
+
"reasoning": false,
|
|
59
|
+
"input": ["text"],
|
|
60
|
+
"contextWindow": 131072,
|
|
61
|
+
"maxTokens": 32768,
|
|
62
|
+
"cost": {
|
|
63
|
+
"input": .59,
|
|
64
|
+
"output": .79,
|
|
65
|
+
"cacheRead": 0,
|
|
66
|
+
"cacheWrite": 0
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"id": "meta-llama/llama-4-scout-17b-16e-instruct",
|
|
71
|
+
"name": "Llama 4 Scout 17B",
|
|
72
|
+
"reasoning": false,
|
|
73
|
+
"input": ["text", "image"],
|
|
74
|
+
"mediaInput": { "image": {
|
|
75
|
+
"maxPixels": 33177600,
|
|
76
|
+
"preferredSidePx": 2048,
|
|
77
|
+
"tokenMode": "provider"
|
|
78
|
+
} },
|
|
79
|
+
"contextWindow": 131072,
|
|
80
|
+
"maxTokens": 8192,
|
|
81
|
+
"cost": {
|
|
82
|
+
"input": .11,
|
|
83
|
+
"output": .34,
|
|
84
|
+
"cacheRead": 0,
|
|
85
|
+
"cacheWrite": 0
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"id": "openai/gpt-oss-120b",
|
|
90
|
+
"name": "GPT OSS 120B",
|
|
91
|
+
"reasoning": true,
|
|
92
|
+
"input": ["text"],
|
|
93
|
+
"contextWindow": 131072,
|
|
94
|
+
"maxTokens": 65536,
|
|
95
|
+
"cost": {
|
|
96
|
+
"input": .15,
|
|
97
|
+
"output": .6,
|
|
98
|
+
"cacheRead": 0,
|
|
99
|
+
"cacheWrite": 0
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"id": "openai/gpt-oss-20b",
|
|
104
|
+
"name": "GPT OSS 20B",
|
|
105
|
+
"reasoning": true,
|
|
106
|
+
"input": ["text"],
|
|
107
|
+
"contextWindow": 131072,
|
|
108
|
+
"maxTokens": 65536,
|
|
109
|
+
"cost": {
|
|
110
|
+
"input": .075,
|
|
111
|
+
"output": .3,
|
|
112
|
+
"cacheRead": 0,
|
|
113
|
+
"cacheWrite": 0
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"id": "openai/gpt-oss-safeguard-20b",
|
|
118
|
+
"name": "Safety GPT OSS 20B",
|
|
119
|
+
"reasoning": true,
|
|
120
|
+
"input": ["text"],
|
|
121
|
+
"contextWindow": 131072,
|
|
122
|
+
"maxTokens": 65536,
|
|
123
|
+
"cost": {
|
|
124
|
+
"input": .075,
|
|
125
|
+
"output": .3,
|
|
126
|
+
"cacheRead": .037,
|
|
127
|
+
"cacheWrite": 0
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"id": "qwen/qwen3-32b",
|
|
132
|
+
"name": "Qwen3 32B",
|
|
133
|
+
"reasoning": true,
|
|
134
|
+
"input": ["text"],
|
|
135
|
+
"contextWindow": 131072,
|
|
136
|
+
"maxTokens": 40960,
|
|
137
|
+
"cost": {
|
|
138
|
+
"input": .29,
|
|
139
|
+
"output": .59,
|
|
140
|
+
"cacheRead": 0,
|
|
141
|
+
"cacheWrite": 0
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
} },
|
|
146
|
+
"discovery": { "groq": "refreshable" }
|
|
147
|
+
};
|
|
148
|
+
//#endregion
|
|
4
149
|
//#region extensions/groq/index.ts
|
|
5
150
|
const GROQ_DEFAULT_MODEL_REF = "groq/llama-3.3-70b-versatile";
|
|
151
|
+
const GROQ_DEFAULT_MODEL_ID = "llama-3.3-70b-versatile";
|
|
152
|
+
const GROQ_FALLBACK_MAX_TOKENS = 1024;
|
|
153
|
+
function buildGroqCatalogProvider() {
|
|
154
|
+
return buildManifestModelProviderConfig({
|
|
155
|
+
providerId: "groq",
|
|
156
|
+
catalog: modelCatalog.providers.groq
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
function hasWireMaxTokens(value) {
|
|
160
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
161
|
+
const record = value;
|
|
162
|
+
return record.max_completion_tokens !== void 0 || record.max_tokens !== void 0;
|
|
163
|
+
}
|
|
164
|
+
function hasExplicitMaxTokens(extraParams) {
|
|
165
|
+
return extraParams?.maxTokens !== void 0 || hasWireMaxTokens(extraParams) || hasWireMaxTokens(extraParams?.extra_body) || hasWireMaxTokens(extraParams?.extraBody);
|
|
166
|
+
}
|
|
167
|
+
function isGroqTpmRequestTooLargeEvent(event) {
|
|
168
|
+
if (event.type !== "error") return false;
|
|
169
|
+
const message = event.error.errorMessage?.toLowerCase() ?? "";
|
|
170
|
+
return message.includes("413 request too large for model") && message.includes("tokens per minute (tpm)") && message.includes("limit ") && message.includes("requested ");
|
|
171
|
+
}
|
|
172
|
+
function wrapGroqOversizedRequestRecovery(streamFn, enabled) {
|
|
173
|
+
const underlying = streamFn ?? streamSimple;
|
|
174
|
+
if (!enabled) return underlying;
|
|
175
|
+
const withoutTools = (model, context, options) => {
|
|
176
|
+
const originalOnPayload = options?.onPayload;
|
|
177
|
+
return underlying(model, context, {
|
|
178
|
+
...options,
|
|
179
|
+
async onPayload(payload, payloadModel) {
|
|
180
|
+
const replacement = await originalOnPayload?.(payload, payloadModel);
|
|
181
|
+
const finalPayload = replacement && typeof replacement === "object" ? replacement : payload;
|
|
182
|
+
const record = finalPayload;
|
|
183
|
+
delete record.tools;
|
|
184
|
+
delete record.tool_choice;
|
|
185
|
+
delete record.parallel_tool_calls;
|
|
186
|
+
delete record.parallelToolCalls;
|
|
187
|
+
delete record.max_tokens;
|
|
188
|
+
delete record.max_completion_tokens;
|
|
189
|
+
record.max_completion_tokens = GROQ_FALLBACK_MAX_TOKENS;
|
|
190
|
+
return finalPayload;
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
};
|
|
194
|
+
return (model, context, options) => {
|
|
195
|
+
if (options?.maxTokens !== void 0) return underlying(model, context, options);
|
|
196
|
+
const initial = underlying(model, context, options);
|
|
197
|
+
const output = createAssistantMessageEventStream();
|
|
198
|
+
const writable = output;
|
|
199
|
+
(async () => {
|
|
200
|
+
try {
|
|
201
|
+
const resolvedInitial = await Promise.resolve(initial);
|
|
202
|
+
let forwarded = false;
|
|
203
|
+
let retryWithoutTools = false;
|
|
204
|
+
for await (const event of resolvedInitial) {
|
|
205
|
+
if (!forwarded && !options?.signal?.aborted && isGroqTpmRequestTooLargeEvent(event)) {
|
|
206
|
+
retryWithoutTools = true;
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
writable.push(event);
|
|
210
|
+
forwarded = true;
|
|
211
|
+
}
|
|
212
|
+
if (retryWithoutTools) {
|
|
213
|
+
const fallback = await Promise.resolve(withoutTools(model, context, options));
|
|
214
|
+
for await (const event of fallback) writable.push(event);
|
|
215
|
+
}
|
|
216
|
+
} catch (error) {
|
|
217
|
+
writable.push({
|
|
218
|
+
type: "error",
|
|
219
|
+
reason: "error",
|
|
220
|
+
error: {
|
|
221
|
+
role: "assistant",
|
|
222
|
+
content: [],
|
|
223
|
+
api: model.api,
|
|
224
|
+
provider: model.provider,
|
|
225
|
+
model: model.id,
|
|
226
|
+
usage: {
|
|
227
|
+
input: 0,
|
|
228
|
+
output: 0,
|
|
229
|
+
cacheRead: 0,
|
|
230
|
+
cacheWrite: 0,
|
|
231
|
+
totalTokens: 0,
|
|
232
|
+
cost: {
|
|
233
|
+
input: 0,
|
|
234
|
+
output: 0,
|
|
235
|
+
cacheRead: 0,
|
|
236
|
+
cacheWrite: 0,
|
|
237
|
+
total: 0
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
stopReason: "error",
|
|
241
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
242
|
+
timestamp: Date.now()
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
} finally {
|
|
246
|
+
writable.end();
|
|
247
|
+
}
|
|
248
|
+
})();
|
|
249
|
+
return output;
|
|
250
|
+
};
|
|
251
|
+
}
|
|
6
252
|
var groq_default = definePluginEntry({
|
|
7
253
|
id: "groq",
|
|
8
254
|
name: "Groq Provider",
|
|
@@ -31,7 +277,20 @@ var groq_default = definePluginEntry({
|
|
|
31
277
|
groupLabel: "Groq",
|
|
32
278
|
groupHint: "Fast OpenAI-compatible inference"
|
|
33
279
|
}
|
|
34
|
-
})]
|
|
280
|
+
})],
|
|
281
|
+
catalog: {
|
|
282
|
+
order: "simple",
|
|
283
|
+
run: (ctx) => buildOpenAICompatibleProviderCatalog({
|
|
284
|
+
ctx,
|
|
285
|
+
providerId: "groq",
|
|
286
|
+
buildProvider: buildGroqCatalogProvider
|
|
287
|
+
})
|
|
288
|
+
},
|
|
289
|
+
staticCatalog: {
|
|
290
|
+
order: "simple",
|
|
291
|
+
run: async () => ({ provider: buildGroqCatalogProvider() })
|
|
292
|
+
},
|
|
293
|
+
wrapStreamFn: (ctx) => wrapGroqOversizedRequestRecovery(ctx.streamFn, ctx.modelId === GROQ_DEFAULT_MODEL_ID && !hasExplicitMaxTokens(ctx.extraParams) && !hasExplicitMaxTokens(ctx.model?.params) && ctx.model?.maxTokensSource === "discovered")
|
|
35
294
|
});
|
|
36
295
|
api.registerMediaUnderstandingProvider(groqMediaUnderstandingProvider);
|
|
37
296
|
}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/groq-provider",
|
|
3
|
-
"version": "2026.7.2-beta.
|
|
3
|
+
"version": "2026.7.2-beta.4",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/groq-provider",
|
|
9
|
-
"version": "2026.7.2-beta.
|
|
9
|
+
"version": "2026.7.2-beta.4"
|
|
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/groq-provider",
|
|
3
|
-
"version": "2026.7.2-beta.
|
|
3
|
+
"version": "2026.7.2-beta.4",
|
|
4
4
|
"description": "OpenClaw Groq media-understanding provider.",
|
|
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.
|
|
21
|
+
"pluginApi": ">=2026.7.2-beta.4"
|
|
22
22
|
},
|
|
23
23
|
"build": {
|
|
24
|
-
"openclawVersion": "2026.7.2-beta.
|
|
24
|
+
"openclawVersion": "2026.7.2-beta.4",
|
|
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.2-beta.
|
|
42
|
+
"openclaw": ">=2026.7.2-beta.4"
|
|
43
43
|
},
|
|
44
44
|
"peerDependenciesMeta": {
|
|
45
45
|
"openclaw": {
|