@ai-sdk/groq 0.0.0-013d7476-20250808163325 → 0.0.0-4115c213-20260122152721

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.
@@ -0,0 +1,78 @@
1
+ import { z } from 'zod/v4';
2
+
3
+ // https://console.groq.com/docs/models
4
+ export type GroqChatModelId =
5
+ // production models
6
+ | 'gemma2-9b-it'
7
+ | 'llama-3.1-8b-instant'
8
+ | 'llama-3.3-70b-versatile'
9
+ | 'meta-llama/llama-guard-4-12b'
10
+ | 'openai/gpt-oss-120b'
11
+ | 'openai/gpt-oss-20b'
12
+ // preview models (selection)
13
+ | 'deepseek-r1-distill-llama-70b'
14
+ | 'meta-llama/llama-4-maverick-17b-128e-instruct'
15
+ | 'meta-llama/llama-4-scout-17b-16e-instruct'
16
+ | 'meta-llama/llama-prompt-guard-2-22m'
17
+ | 'meta-llama/llama-prompt-guard-2-86m'
18
+ | 'moonshotai/kimi-k2-instruct-0905'
19
+ | 'qwen/qwen3-32b'
20
+ | 'llama-guard-3-8b'
21
+ | 'llama3-70b-8192'
22
+ | 'llama3-8b-8192'
23
+ | 'mixtral-8x7b-32768'
24
+ | 'qwen-qwq-32b'
25
+ | 'qwen-2.5-32b'
26
+ | 'deepseek-r1-distill-qwen-32b'
27
+ | (string & {});
28
+
29
+ export const groqProviderOptions = z.object({
30
+ reasoningFormat: z.enum(['parsed', 'raw', 'hidden']).optional(),
31
+
32
+ /**
33
+ * Specifies the reasoning effort level for model inference.
34
+ * @see https://console.groq.com/docs/reasoning#reasoning-effort
35
+ */
36
+ reasoningEffort: z
37
+ .enum(['none', 'default', 'low', 'medium', 'high'])
38
+ .optional(),
39
+
40
+ /**
41
+ * Whether to enable parallel function calling during tool use. Default to true.
42
+ */
43
+ parallelToolCalls: z.boolean().optional(),
44
+
45
+ /**
46
+ * A unique identifier representing your end-user, which can help OpenAI to
47
+ * monitor and detect abuse. Learn more.
48
+ */
49
+ user: z.string().optional(),
50
+
51
+ /**
52
+ * Whether to use structured outputs.
53
+ *
54
+ * @default true
55
+ */
56
+ structuredOutputs: z.boolean().optional(),
57
+
58
+ /**
59
+ * Whether to use strict JSON schema validation.
60
+ * When true, the model uses constrained decoding to guarantee schema compliance.
61
+ * Only used when structured outputs are enabled and a schema is provided.
62
+ *
63
+ * @default true
64
+ */
65
+ strictJsonSchema: z.boolean().optional(),
66
+
67
+ /**
68
+ * Service tier for the request.
69
+ * - 'on_demand': Default tier with consistent performance and fairness
70
+ * - 'flex': Higher throughput tier optimized for workloads that can handle occasional request failures
71
+ * - 'auto': Uses on_demand rate limits, then falls back to flex tier if exceeded
72
+ *
73
+ * @default 'on_demand'
74
+ */
75
+ serviceTier: z.enum(['on_demand', 'flex', 'auto']).optional(),
76
+ });
77
+
78
+ export type GroqProviderOptions = z.infer<typeof groqProviderOptions>;
@@ -0,0 +1,9 @@
1
+ import { FetchFunction } from '@ai-sdk/provider-utils';
2
+
3
+ export type GroqConfig = {
4
+ provider: string;
5
+ url: (options: { modelId: string; path: string }) => string;
6
+ headers: () => Record<string, string | undefined>;
7
+ fetch?: FetchFunction;
8
+ generateId?: () => string;
9
+ };
@@ -0,0 +1,16 @@
1
+ import { z } from 'zod/v4';
2
+ import { createJsonErrorResponseHandler } from '@ai-sdk/provider-utils';
3
+
4
+ export const groqErrorDataSchema = z.object({
5
+ error: z.object({
6
+ message: z.string(),
7
+ type: z.string(),
8
+ }),
9
+ });
10
+
11
+ export type GroqErrorData = z.infer<typeof groqErrorDataSchema>;
12
+
13
+ export const groqFailedResponseHandler = createJsonErrorResponseHandler({
14
+ errorSchema: groqErrorDataSchema,
15
+ errorToMessage: data => data.error.message,
16
+ });
@@ -0,0 +1,128 @@
1
+ import {
2
+ LanguageModelV3CallOptions,
3
+ SharedV3Warning,
4
+ UnsupportedFunctionalityError,
5
+ } from '@ai-sdk/provider';
6
+ import {
7
+ getSupportedModelsString,
8
+ isBrowserSearchSupportedModel,
9
+ } from './groq-browser-search-models';
10
+ import { GroqChatModelId } from './groq-chat-options';
11
+
12
+ export function prepareTools({
13
+ tools,
14
+ toolChoice,
15
+ modelId,
16
+ }: {
17
+ tools: LanguageModelV3CallOptions['tools'];
18
+ toolChoice?: LanguageModelV3CallOptions['toolChoice'];
19
+ modelId: GroqChatModelId;
20
+ }): {
21
+ tools:
22
+ | undefined
23
+ | Array<
24
+ | {
25
+ type: 'function';
26
+ function: {
27
+ name: string;
28
+ description: string | undefined;
29
+ parameters: unknown;
30
+ };
31
+ }
32
+ | {
33
+ type: 'browser_search';
34
+ }
35
+ >;
36
+ toolChoice:
37
+ | { type: 'function'; function: { name: string } }
38
+ | 'auto'
39
+ | 'none'
40
+ | 'required'
41
+ | undefined;
42
+ toolWarnings: SharedV3Warning[];
43
+ } {
44
+ // when the tools array is empty, change it to undefined to prevent errors:
45
+ tools = tools?.length ? tools : undefined;
46
+
47
+ const toolWarnings: SharedV3Warning[] = [];
48
+
49
+ if (tools == null) {
50
+ return { tools: undefined, toolChoice: undefined, toolWarnings };
51
+ }
52
+
53
+ const groqTools: Array<
54
+ | {
55
+ type: 'function';
56
+ function: {
57
+ name: string;
58
+ description: string | undefined;
59
+ parameters: unknown;
60
+ };
61
+ }
62
+ | {
63
+ type: 'browser_search';
64
+ }
65
+ > = [];
66
+
67
+ for (const tool of tools) {
68
+ if (tool.type === 'provider') {
69
+ if (tool.id === 'groq.browser_search') {
70
+ if (!isBrowserSearchSupportedModel(modelId)) {
71
+ toolWarnings.push({
72
+ type: 'unsupported',
73
+ feature: `provider-defined tool ${tool.id}`,
74
+ details: `Browser search is only supported on the following models: ${getSupportedModelsString()}. Current model: ${modelId}`,
75
+ });
76
+ } else {
77
+ groqTools.push({
78
+ type: 'browser_search',
79
+ });
80
+ }
81
+ } else {
82
+ toolWarnings.push({
83
+ type: 'unsupported',
84
+ feature: `provider-defined tool ${tool.id}`,
85
+ });
86
+ }
87
+ } else {
88
+ groqTools.push({
89
+ type: 'function',
90
+ function: {
91
+ name: tool.name,
92
+ description: tool.description,
93
+ parameters: tool.inputSchema,
94
+ },
95
+ });
96
+ }
97
+ }
98
+
99
+ if (toolChoice == null) {
100
+ return { tools: groqTools, toolChoice: undefined, toolWarnings };
101
+ }
102
+
103
+ const type = toolChoice.type;
104
+
105
+ switch (type) {
106
+ case 'auto':
107
+ case 'none':
108
+ case 'required':
109
+ return { tools: groqTools, toolChoice: type, toolWarnings };
110
+ case 'tool':
111
+ return {
112
+ tools: groqTools,
113
+ toolChoice: {
114
+ type: 'function',
115
+ function: {
116
+ name: toolChoice.toolName,
117
+ },
118
+ },
119
+ toolWarnings,
120
+ };
121
+ default: {
122
+ const _exhaustiveCheck: never = type;
123
+ throw new UnsupportedFunctionalityError({
124
+ functionality: `tool choice type: ${_exhaustiveCheck}`,
125
+ });
126
+ }
127
+ }
128
+ }
@@ -0,0 +1,143 @@
1
+ import {
2
+ LanguageModelV3,
3
+ NoSuchModelError,
4
+ ProviderV3,
5
+ TranscriptionModelV3,
6
+ } from '@ai-sdk/provider';
7
+ import {
8
+ FetchFunction,
9
+ loadApiKey,
10
+ withoutTrailingSlash,
11
+ withUserAgentSuffix,
12
+ } from '@ai-sdk/provider-utils';
13
+ import { GroqChatLanguageModel } from './groq-chat-language-model';
14
+ import { GroqChatModelId } from './groq-chat-options';
15
+ import { GroqTranscriptionModelId } from './groq-transcription-options';
16
+ import { GroqTranscriptionModel } from './groq-transcription-model';
17
+
18
+ import { groqTools } from './groq-tools';
19
+ import { VERSION } from './version';
20
+ export interface GroqProvider extends ProviderV3 {
21
+ /**
22
+ Creates a model for text generation.
23
+ */
24
+ (modelId: GroqChatModelId): LanguageModelV3;
25
+
26
+ /**
27
+ Creates an Groq chat model for text generation.
28
+ */
29
+ languageModel(modelId: GroqChatModelId): LanguageModelV3;
30
+
31
+ /**
32
+ Creates a model for transcription.
33
+ */
34
+ transcription(modelId: GroqTranscriptionModelId): TranscriptionModelV3;
35
+
36
+ /**
37
+ * Tools provided by Groq.
38
+ */
39
+ tools: typeof groqTools;
40
+
41
+ /**
42
+ * @deprecated Use `embeddingModel` instead.
43
+ */
44
+ textEmbeddingModel(modelId: string): never;
45
+ }
46
+
47
+ export interface GroqProviderSettings {
48
+ /**
49
+ Base URL for the Groq API calls.
50
+ */
51
+ baseURL?: string;
52
+
53
+ /**
54
+ API key for authenticating requests.
55
+ */
56
+ apiKey?: string;
57
+
58
+ /**
59
+ Custom headers to include in the requests.
60
+ */
61
+ headers?: Record<string, string>;
62
+
63
+ /**
64
+ Custom fetch implementation. You can use it as a middleware to intercept requests,
65
+ or to provide a custom fetch implementation for e.g. testing.
66
+ */
67
+ fetch?: FetchFunction;
68
+ }
69
+
70
+ /**
71
+ Create an Groq provider instance.
72
+ */
73
+ export function createGroq(options: GroqProviderSettings = {}): GroqProvider {
74
+ const baseURL =
75
+ withoutTrailingSlash(options.baseURL) ?? 'https://api.groq.com/openai/v1';
76
+
77
+ const getHeaders = () =>
78
+ withUserAgentSuffix(
79
+ {
80
+ Authorization: `Bearer ${loadApiKey({
81
+ apiKey: options.apiKey,
82
+ environmentVariableName: 'GROQ_API_KEY',
83
+ description: 'Groq',
84
+ })}`,
85
+ ...options.headers,
86
+ },
87
+ `ai-sdk/groq/${VERSION}`,
88
+ );
89
+
90
+ const createChatModel = (modelId: GroqChatModelId) =>
91
+ new GroqChatLanguageModel(modelId, {
92
+ provider: 'groq.chat',
93
+ url: ({ path }) => `${baseURL}${path}`,
94
+ headers: getHeaders,
95
+ fetch: options.fetch,
96
+ });
97
+
98
+ const createLanguageModel = (modelId: GroqChatModelId) => {
99
+ if (new.target) {
100
+ throw new Error(
101
+ 'The Groq model function cannot be called with the new keyword.',
102
+ );
103
+ }
104
+
105
+ return createChatModel(modelId);
106
+ };
107
+
108
+ const createTranscriptionModel = (modelId: GroqTranscriptionModelId) => {
109
+ return new GroqTranscriptionModel(modelId, {
110
+ provider: 'groq.transcription',
111
+ url: ({ path }) => `${baseURL}${path}`,
112
+ headers: getHeaders,
113
+ fetch: options.fetch,
114
+ });
115
+ };
116
+
117
+ const provider = function (modelId: GroqChatModelId) {
118
+ return createLanguageModel(modelId);
119
+ };
120
+
121
+ provider.specificationVersion = 'v3' as const;
122
+ provider.languageModel = createLanguageModel;
123
+ provider.chat = createChatModel;
124
+
125
+ provider.embeddingModel = (modelId: string) => {
126
+ throw new NoSuchModelError({ modelId, modelType: 'embeddingModel' });
127
+ };
128
+ provider.textEmbeddingModel = provider.embeddingModel;
129
+ provider.imageModel = (modelId: string) => {
130
+ throw new NoSuchModelError({ modelId, modelType: 'imageModel' });
131
+ };
132
+ provider.transcription = createTranscriptionModel;
133
+ provider.transcriptionModel = createTranscriptionModel;
134
+
135
+ provider.tools = groqTools;
136
+
137
+ return provider;
138
+ }
139
+
140
+ /**
141
+ Default Groq provider instance.
142
+ */
143
+ export const groq = createGroq();
@@ -0,0 +1,5 @@
1
+ import { browserSearch } from './tool/browser-search';
2
+
3
+ export const groqTools = {
4
+ browserSearch,
5
+ };
@@ -0,0 +1,184 @@
1
+ import { TranscriptionModelV3, SharedV3Warning } from '@ai-sdk/provider';
2
+ import {
3
+ combineHeaders,
4
+ convertBase64ToUint8Array,
5
+ createJsonResponseHandler,
6
+ mediaTypeToExtension,
7
+ parseProviderOptions,
8
+ postFormDataToApi,
9
+ } from '@ai-sdk/provider-utils';
10
+ import { z } from 'zod/v4';
11
+ import { GroqConfig } from './groq-config';
12
+ import { groqFailedResponseHandler } from './groq-error';
13
+ import { GroqTranscriptionModelId } from './groq-transcription-options';
14
+ import { GroqTranscriptionAPITypes } from './groq-api-types';
15
+
16
+ // https://console.groq.com/docs/speech-to-text
17
+ const groqProviderOptionsSchema = z.object({
18
+ language: z.string().nullish(),
19
+ prompt: z.string().nullish(),
20
+ responseFormat: z.string().nullish(),
21
+ temperature: z.number().min(0).max(1).nullish(),
22
+ timestampGranularities: z.array(z.string()).nullish(),
23
+ });
24
+
25
+ export type GroqTranscriptionCallOptions = z.infer<
26
+ typeof groqProviderOptionsSchema
27
+ >;
28
+
29
+ interface GroqTranscriptionModelConfig extends GroqConfig {
30
+ _internal?: {
31
+ currentDate?: () => Date;
32
+ };
33
+ }
34
+
35
+ export class GroqTranscriptionModel implements TranscriptionModelV3 {
36
+ readonly specificationVersion = 'v3';
37
+
38
+ get provider(): string {
39
+ return this.config.provider;
40
+ }
41
+
42
+ constructor(
43
+ readonly modelId: GroqTranscriptionModelId,
44
+ private readonly config: GroqTranscriptionModelConfig,
45
+ ) {}
46
+
47
+ private async getArgs({
48
+ audio,
49
+ mediaType,
50
+ providerOptions,
51
+ }: Parameters<TranscriptionModelV3['doGenerate']>[0]) {
52
+ const warnings: SharedV3Warning[] = [];
53
+
54
+ // Parse provider options
55
+ const groqOptions = await parseProviderOptions({
56
+ provider: 'groq',
57
+ providerOptions,
58
+ schema: groqProviderOptionsSchema,
59
+ });
60
+
61
+ // Create form data with base fields
62
+ const formData = new FormData();
63
+ const blob =
64
+ audio instanceof Uint8Array
65
+ ? new Blob([audio])
66
+ : new Blob([convertBase64ToUint8Array(audio)]);
67
+
68
+ formData.append('model', this.modelId);
69
+ const fileExtension = mediaTypeToExtension(mediaType);
70
+ formData.append(
71
+ 'file',
72
+ new File([blob], 'audio', { type: mediaType }),
73
+ `audio.${fileExtension}`,
74
+ );
75
+
76
+ // Add provider-specific options
77
+ if (groqOptions) {
78
+ const transcriptionModelOptions: Omit<
79
+ GroqTranscriptionAPITypes,
80
+ 'model'
81
+ > = {
82
+ language: groqOptions.language ?? undefined,
83
+ prompt: groqOptions.prompt ?? undefined,
84
+ response_format: groqOptions.responseFormat ?? undefined,
85
+ temperature: groqOptions.temperature ?? undefined,
86
+ timestamp_granularities:
87
+ groqOptions.timestampGranularities ?? undefined,
88
+ };
89
+
90
+ for (const key in transcriptionModelOptions) {
91
+ const value =
92
+ transcriptionModelOptions[
93
+ key as keyof Omit<GroqTranscriptionAPITypes, 'model'>
94
+ ];
95
+ if (value !== undefined) {
96
+ if (Array.isArray(value)) {
97
+ for (const item of value) {
98
+ formData.append(`${key}[]`, String(item));
99
+ }
100
+ } else {
101
+ formData.append(key, String(value));
102
+ }
103
+ }
104
+ }
105
+ }
106
+
107
+ return {
108
+ formData,
109
+ warnings,
110
+ };
111
+ }
112
+
113
+ async doGenerate(
114
+ options: Parameters<TranscriptionModelV3['doGenerate']>[0],
115
+ ): Promise<Awaited<ReturnType<TranscriptionModelV3['doGenerate']>>> {
116
+ const currentDate = this.config._internal?.currentDate?.() ?? new Date();
117
+ const { formData, warnings } = await this.getArgs(options);
118
+
119
+ const {
120
+ value: response,
121
+ responseHeaders,
122
+ rawValue: rawResponse,
123
+ } = await postFormDataToApi({
124
+ url: this.config.url({
125
+ path: '/audio/transcriptions',
126
+ modelId: this.modelId,
127
+ }),
128
+ headers: combineHeaders(this.config.headers(), options.headers),
129
+ formData,
130
+ failedResponseHandler: groqFailedResponseHandler,
131
+ successfulResponseHandler: createJsonResponseHandler(
132
+ groqTranscriptionResponseSchema,
133
+ ),
134
+ abortSignal: options.abortSignal,
135
+ fetch: this.config.fetch,
136
+ });
137
+
138
+ return {
139
+ text: response.text,
140
+ segments:
141
+ response.segments?.map(segment => ({
142
+ text: segment.text,
143
+ startSecond: segment.start,
144
+ endSecond: segment.end,
145
+ })) ?? [],
146
+ language: response.language ?? undefined,
147
+ durationInSeconds: response.duration ?? undefined,
148
+ warnings,
149
+ response: {
150
+ timestamp: currentDate,
151
+ modelId: this.modelId,
152
+ headers: responseHeaders,
153
+ body: rawResponse,
154
+ },
155
+ };
156
+ }
157
+ }
158
+
159
+ const groqTranscriptionResponseSchema = z.object({
160
+ text: z.string(),
161
+ x_groq: z.object({
162
+ id: z.string(),
163
+ }),
164
+ // additional properties are returned when `response_format: 'verbose_json'` is
165
+ task: z.string().nullish(),
166
+ language: z.string().nullish(),
167
+ duration: z.number().nullish(),
168
+ segments: z
169
+ .array(
170
+ z.object({
171
+ id: z.number(),
172
+ seek: z.number(),
173
+ start: z.number(),
174
+ end: z.number(),
175
+ text: z.string(),
176
+ tokens: z.array(z.number()),
177
+ temperature: z.number(),
178
+ avg_logprob: z.number(),
179
+ compression_ratio: z.number(),
180
+ no_speech_prob: z.number(),
181
+ }),
182
+ )
183
+ .nullish(),
184
+ });
@@ -0,0 +1,4 @@
1
+ export type GroqTranscriptionModelId =
2
+ | 'whisper-large-v3-turbo'
3
+ | 'whisper-large-v3'
4
+ | (string & {});
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ export { createGroq, groq } from './groq-provider';
2
+ export type { GroqProvider, GroqProviderSettings } from './groq-provider';
3
+ export type { GroqProviderOptions } from './groq-chat-options';
4
+ export { browserSearch } from './tool/browser-search';
5
+ export { VERSION } from './version';
@@ -0,0 +1,19 @@
1
+ import { LanguageModelV3FinishReason } from '@ai-sdk/provider';
2
+
3
+ export function mapGroqFinishReason(
4
+ finishReason: string | null | undefined,
5
+ ): LanguageModelV3FinishReason['unified'] {
6
+ switch (finishReason) {
7
+ case 'stop':
8
+ return 'stop';
9
+ case 'length':
10
+ return 'length';
11
+ case 'content_filter':
12
+ return 'content-filter';
13
+ case 'function_call':
14
+ case 'tool_calls':
15
+ return 'tool-calls';
16
+ default:
17
+ return 'other';
18
+ }
19
+ }
@@ -0,0 +1,28 @@
1
+ import { createProviderToolFactory } from '@ai-sdk/provider-utils';
2
+ import { z } from 'zod/v4';
3
+
4
+ /**
5
+ * Browser search tool for Groq models.
6
+ *
7
+ * Provides interactive browser search capabilities that go beyond traditional web search
8
+ * by navigating websites interactively and providing more detailed results.
9
+ *
10
+ * Currently supported on:
11
+ * - openai/gpt-oss-20b
12
+ * - openai/gpt-oss-120b
13
+ *
14
+ * @see https://console.groq.com/docs/browser-search
15
+ */
16
+ export const browserSearch = createProviderToolFactory<
17
+ {
18
+ // Browser search doesn't take input parameters - it's controlled by the prompt
19
+ // The tool is activated automatically when included in the tools array
20
+ },
21
+ {
22
+ // No configuration options needed - the tool works automatically
23
+ // when included in the tools array for supported models
24
+ }
25
+ >({
26
+ id: 'groq.browser_search',
27
+ inputSchema: z.object({}),
28
+ });
Binary file
package/src/version.ts ADDED
@@ -0,0 +1,6 @@
1
+ // Version string of this package injected at build time.
2
+ declare const __PACKAGE_VERSION__: string | undefined;
3
+ export const VERSION: string =
4
+ typeof __PACKAGE_VERSION__ !== 'undefined'
5
+ ? __PACKAGE_VERSION__
6
+ : '0.0.0-test';