@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,147 @@
1
+ import {
2
+ LanguageModelV3Prompt,
3
+ UnsupportedFunctionalityError,
4
+ } from '@ai-sdk/provider';
5
+ import { GroqChatPrompt } from './groq-api-types';
6
+ import { convertToBase64 } from '@ai-sdk/provider-utils';
7
+
8
+ export function convertToGroqChatMessages(
9
+ prompt: LanguageModelV3Prompt,
10
+ ): GroqChatPrompt {
11
+ const messages: GroqChatPrompt = [];
12
+
13
+ for (const { role, content } of prompt) {
14
+ switch (role) {
15
+ case 'system': {
16
+ messages.push({ role: 'system', content });
17
+ break;
18
+ }
19
+
20
+ case 'user': {
21
+ if (content.length === 1 && content[0].type === 'text') {
22
+ messages.push({ role: 'user', content: content[0].text });
23
+ break;
24
+ }
25
+
26
+ messages.push({
27
+ role: 'user',
28
+ content: content.map(part => {
29
+ switch (part.type) {
30
+ case 'text': {
31
+ return { type: 'text', text: part.text };
32
+ }
33
+ case 'file': {
34
+ if (!part.mediaType.startsWith('image/')) {
35
+ throw new UnsupportedFunctionalityError({
36
+ functionality: 'Non-image file content parts',
37
+ });
38
+ }
39
+
40
+ const mediaType =
41
+ part.mediaType === 'image/*' ? 'image/jpeg' : part.mediaType;
42
+
43
+ return {
44
+ type: 'image_url',
45
+ image_url: {
46
+ url:
47
+ part.data instanceof URL
48
+ ? part.data.toString()
49
+ : `data:${mediaType};base64,${convertToBase64(part.data)}`,
50
+ },
51
+ };
52
+ }
53
+ }
54
+ }),
55
+ });
56
+
57
+ break;
58
+ }
59
+
60
+ case 'assistant': {
61
+ let text = '';
62
+ let reasoning = '';
63
+ const toolCalls: Array<{
64
+ id: string;
65
+ type: 'function';
66
+ function: { name: string; arguments: string };
67
+ }> = [];
68
+
69
+ for (const part of content) {
70
+ switch (part.type) {
71
+ // groq supports reasoning for tool-calls in multi-turn conversations
72
+ // https://github.com/vercel/ai/issues/7860
73
+ case 'reasoning': {
74
+ reasoning += part.text;
75
+ break;
76
+ }
77
+
78
+ case 'text': {
79
+ text += part.text;
80
+ break;
81
+ }
82
+
83
+ case 'tool-call': {
84
+ toolCalls.push({
85
+ id: part.toolCallId,
86
+ type: 'function',
87
+ function: {
88
+ name: part.toolName,
89
+ arguments: JSON.stringify(part.input),
90
+ },
91
+ });
92
+ break;
93
+ }
94
+ }
95
+ }
96
+
97
+ messages.push({
98
+ role: 'assistant',
99
+ content: text,
100
+ ...(reasoning.length > 0 ? { reasoning } : null),
101
+ ...(toolCalls.length > 0 ? { tool_calls: toolCalls } : null),
102
+ });
103
+
104
+ break;
105
+ }
106
+
107
+ case 'tool': {
108
+ for (const toolResponse of content) {
109
+ if (toolResponse.type === 'tool-approval-response') {
110
+ continue;
111
+ }
112
+ const output = toolResponse.output;
113
+
114
+ let contentValue: string;
115
+ switch (output.type) {
116
+ case 'text':
117
+ case 'error-text':
118
+ contentValue = output.value;
119
+ break;
120
+ case 'execution-denied':
121
+ contentValue = output.reason ?? 'Tool execution denied.';
122
+ break;
123
+ case 'content':
124
+ case 'json':
125
+ case 'error-json':
126
+ contentValue = JSON.stringify(output.value);
127
+ break;
128
+ }
129
+
130
+ messages.push({
131
+ role: 'tool',
132
+ tool_call_id: toolResponse.toolCallId,
133
+ content: contentValue,
134
+ });
135
+ }
136
+ break;
137
+ }
138
+
139
+ default: {
140
+ const _exhaustiveCheck: never = role;
141
+ throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
142
+ }
143
+ }
144
+ }
145
+
146
+ return messages;
147
+ }
@@ -0,0 +1,15 @@
1
+ export function getResponseMetadata({
2
+ id,
3
+ model,
4
+ created,
5
+ }: {
6
+ id?: string | undefined | null;
7
+ created?: number | undefined | null;
8
+ model?: string | undefined | null;
9
+ }) {
10
+ return {
11
+ id: id ?? undefined,
12
+ modelId: model ?? undefined,
13
+ timestamp: created != null ? new Date(created * 1000) : undefined,
14
+ };
15
+ }
@@ -0,0 +1,100 @@
1
+ export type GroqChatPrompt = Array<GroqMessage>;
2
+
3
+ export type GroqMessage =
4
+ | GroqSystemMessage
5
+ | GroqUserMessage
6
+ | GroqAssistantMessage
7
+ | GroqToolMessage;
8
+
9
+ export interface GroqSystemMessage {
10
+ role: 'system';
11
+ content: string;
12
+ }
13
+
14
+ export interface GroqUserMessage {
15
+ role: 'user';
16
+ content: string | Array<GroqContentPart>;
17
+ }
18
+
19
+ export type GroqContentPart = GroqContentPartText | GroqContentPartImage;
20
+
21
+ export interface GroqContentPartImage {
22
+ type: 'image_url';
23
+ image_url: { url: string };
24
+ }
25
+
26
+ export interface GroqContentPartText {
27
+ type: 'text';
28
+ text: string;
29
+ }
30
+
31
+ export interface GroqAssistantMessage {
32
+ role: 'assistant';
33
+ content?: string | null;
34
+ reasoning?: string;
35
+ tool_calls?: Array<GroqMessageToolCall>;
36
+ }
37
+
38
+ export interface GroqMessageToolCall {
39
+ type: 'function';
40
+ id: string;
41
+ function: {
42
+ arguments: string;
43
+ name: string;
44
+ };
45
+ }
46
+
47
+ export interface GroqToolMessage {
48
+ role: 'tool';
49
+ content: string;
50
+ tool_call_id: string;
51
+ }
52
+
53
+ export interface GroqTranscriptionAPITypes {
54
+ /**
55
+ * The audio file object for direct upload to translate/transcribe.
56
+ * Required unless using url instead.
57
+ */
58
+ file?: string;
59
+
60
+ /**
61
+ * The audio URL to translate/transcribe (supports Base64URL).
62
+ * Required unless using file instead.
63
+ */
64
+ url?: string;
65
+
66
+ /**
67
+ * The language of the input audio. Supplying the input language in ISO-639-1 (i.e. en, tr`) format will improve accuracy and latency.
68
+ * The translations endpoint only supports 'en' as a parameter option.
69
+ */
70
+ language?: string;
71
+
72
+ /**
73
+ * ID of the model to use.
74
+ */
75
+ model: string;
76
+
77
+ /**
78
+ * Prompt to guide the model's style or specify how to spell unfamiliar words. (limited to 224 tokens)
79
+ */
80
+ prompt?: string;
81
+
82
+ /**
83
+ * Define the output response format.
84
+ * Set to verbose_json to receive timestamps for audio segments.
85
+ * Set to text to return a text response.
86
+ */
87
+ response_format?: string;
88
+
89
+ /**
90
+ * The temperature between 0 and 1. For translations and transcriptions, we recommend the default value of 0.
91
+ */
92
+ temperature?: number;
93
+
94
+ /**
95
+ * The timestamp granularities to populate for this transcription. response_format must be set verbose_json to use timestamp granularities.
96
+ * Either or both of word and segment are supported.
97
+ * segment returns full metadata and word returns only word, start, and end timestamps. To get both word-level timestamps and full segment metadata, include both values in the array.
98
+ */
99
+ timestamp_granularities?: Array<string>;
100
+ }
@@ -0,0 +1,26 @@
1
+ import { GroqChatModelId } from './groq-chat-options';
2
+
3
+ /**
4
+ * Models that support browser search functionality.
5
+ * Based on: https://console.groq.com/docs/browser-search
6
+ */
7
+ export const BROWSER_SEARCH_SUPPORTED_MODELS: readonly GroqChatModelId[] = [
8
+ 'openai/gpt-oss-20b',
9
+ 'openai/gpt-oss-120b',
10
+ ] as const;
11
+
12
+ /**
13
+ * Check if a model supports browser search functionality.
14
+ */
15
+ export function isBrowserSearchSupportedModel(
16
+ modelId: GroqChatModelId,
17
+ ): boolean {
18
+ return BROWSER_SEARCH_SUPPORTED_MODELS.includes(modelId);
19
+ }
20
+
21
+ /**
22
+ * Get a formatted list of supported models for error messages.
23
+ */
24
+ export function getSupportedModelsString(): string {
25
+ return BROWSER_SEARCH_SUPPORTED_MODELS.join(', ');
26
+ }