UNPKG

@copilotkit/runtime

Version:

<img src="https://github.com/user-attachments/assets/0a6b64d9-e193-4940-a3f6-60334ac34084" alt="banner" style="border-radius: 12px; border: 2px solid #d6d4fa;" />

1 lines 9.72 kB
{"version":3,"file":"groq-adapter.mjs","names":[],"sources":["../../../src/service-adapters/groq/groq-adapter.ts"],"sourcesContent":["/**\n * Copilot Runtime adapter for Groq.\n *\n * ## Example\n *\n * ```ts\n * import { CopilotRuntime, GroqAdapter } from \"@copilotkit/runtime\";\n * import { Groq } from \"groq-sdk\";\n *\n * const groq = new Groq({ apiKey: process.env[\"GROQ_API_KEY\"] });\n *\n * const copilotKit = new CopilotRuntime();\n *\n * return new GroqAdapter({ groq, model: \"<model-name>\" });\n * ```\n */\nimport type { LanguageModel } from \"ai\";\nimport { createOpenAI } from \"@ai-sdk/openai\";\nimport type { Groq } from \"groq-sdk\";\nimport type { ChatCompletionMessageParam } from \"groq-sdk/resources/chat\";\nimport {\n CopilotServiceAdapter,\n CopilotRuntimeChatCompletionRequest,\n CopilotRuntimeChatCompletionResponse,\n} from \"../service-adapter\";\nimport {\n convertActionInputToOpenAITool,\n convertMessageToOpenAIMessage,\n limitMessagesToTokenCount,\n} from \"../openai/utils\";\nimport { randomUUID } from \"@copilotkit/shared\";\nimport { convertServiceAdapterError, getSdkClientOptions } from \"../shared\";\n\nconst DEFAULT_MODEL = \"llama-3.3-70b-versatile\";\n\nexport interface GroqAdapterParams {\n /**\n * An optional Groq instance to use.\n */\n groq?: Groq;\n\n /**\n * The model to use.\n */\n model?: string;\n\n /**\n * Whether to disable parallel tool calls.\n * You can disable parallel tool calls to force the model to execute tool calls sequentially.\n * This is useful if you want to execute tool calls in a specific order so that the state changes\n * introduced by one tool call are visible to the next tool call. (i.e. new actions or readables)\n *\n * @default false\n */\n disableParallelToolCalls?: boolean;\n}\n\nexport class GroqAdapter implements CopilotServiceAdapter {\n public model: string = DEFAULT_MODEL;\n public provider = \"groq\";\n\n private disableParallelToolCalls: boolean = false;\n private _groq: Groq;\n public get groq(): Groq {\n return this._groq;\n }\n public get name() {\n return \"GroqAdapter\";\n }\n\n constructor(params?: GroqAdapterParams) {\n if (params?.groq) {\n this._groq = params.groq;\n }\n // If no instance provided, we'll lazy-load in ensureGroq()\n if (params?.model) {\n this.model = params.model;\n }\n this.disableParallelToolCalls = params?.disableParallelToolCalls || false;\n }\n\n getLanguageModel(): LanguageModel {\n const groq = this.ensureGroq();\n const options = getSdkClientOptions(groq);\n const provider = createOpenAI({\n baseURL: groq.baseURL,\n apiKey: groq.apiKey,\n headers: options.defaultHeaders,\n fetch: options.fetch,\n name: \"groq\",\n });\n return provider(this.model);\n }\n\n private ensureGroq(): Groq {\n if (!this._groq) {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { Groq } = require(\"groq-sdk\");\n this._groq = new Groq({});\n }\n return this._groq;\n }\n\n async process(\n request: CopilotRuntimeChatCompletionRequest,\n ): Promise<CopilotRuntimeChatCompletionResponse> {\n const {\n threadId,\n model = this.model,\n messages,\n actions,\n eventSource,\n forwardedParameters,\n } = request;\n const tools = actions.map(convertActionInputToOpenAITool);\n\n let openaiMessages = messages.map((m) =>\n convertMessageToOpenAIMessage(m, { keepSystemRole: true }),\n );\n openaiMessages = limitMessagesToTokenCount(openaiMessages, tools, model);\n\n let toolChoice: any = forwardedParameters?.toolChoice;\n if (forwardedParameters?.toolChoice === \"function\") {\n toolChoice = {\n type: \"function\",\n function: { name: forwardedParameters.toolChoiceFunctionName },\n };\n }\n let stream;\n try {\n const groq = this.ensureGroq();\n stream = await groq.chat.completions.create({\n model: model,\n stream: true,\n messages: openaiMessages as unknown as ChatCompletionMessageParam[],\n ...(tools.length > 0 && { tools }),\n ...(forwardedParameters?.maxTokens && {\n max_tokens: forwardedParameters.maxTokens,\n }),\n ...(forwardedParameters?.stop && { stop: forwardedParameters.stop }),\n ...(toolChoice && { tool_choice: toolChoice }),\n ...(this.disableParallelToolCalls && { parallel_tool_calls: false }),\n ...(forwardedParameters?.temperature && {\n temperature: forwardedParameters.temperature,\n }),\n });\n } catch (error) {\n throw convertServiceAdapterError(error, \"Groq\");\n }\n\n eventSource.stream(async (eventStream$) => {\n let mode: \"function\" | \"message\" | null = null;\n let currentMessageId: string;\n let currentToolCallId: string;\n\n try {\n for await (const chunk of stream) {\n const toolCall = chunk.choices[0].delta.tool_calls?.[0];\n const content = chunk.choices[0].delta.content;\n\n // When switching from message to function or vice versa,\n // send the respective end event.\n // If toolCall?.id is defined, it means a new tool call starts.\n if (mode === \"message\" && toolCall?.id) {\n mode = null;\n eventStream$.sendTextMessageEnd({ messageId: currentMessageId });\n } else if (\n mode === \"function\" &&\n (toolCall === undefined || toolCall?.id)\n ) {\n mode = null;\n eventStream$.sendActionExecutionEnd({\n actionExecutionId: currentToolCallId,\n });\n }\n\n // If we send a new message type, send the appropriate start event.\n if (mode === null) {\n if (toolCall?.id) {\n mode = \"function\";\n currentToolCallId = toolCall!.id;\n eventStream$.sendActionExecutionStart({\n actionExecutionId: currentToolCallId,\n actionName: toolCall!.function!.name,\n parentMessageId: chunk.id,\n });\n } else if (content) {\n mode = \"message\";\n currentMessageId = chunk.id;\n eventStream$.sendTextMessageStart({\n messageId: currentMessageId,\n });\n }\n }\n\n // send the content events\n if (mode === \"message\" && content) {\n eventStream$.sendTextMessageContent({\n messageId: currentMessageId,\n content,\n });\n } else if (mode === \"function\" && toolCall?.function?.arguments) {\n eventStream$.sendActionExecutionArgs({\n actionExecutionId: currentToolCallId,\n args: toolCall.function.arguments,\n });\n }\n }\n\n // send the end events\n if (mode === \"message\") {\n eventStream$.sendTextMessageEnd({ messageId: currentMessageId });\n } else if (mode === \"function\") {\n eventStream$.sendActionExecutionEnd({\n actionExecutionId: currentToolCallId,\n });\n }\n } catch (error) {\n throw convertServiceAdapterError(error, \"Groq\");\n }\n\n eventStream$.complete();\n });\n\n return {\n threadId: request.threadId || randomUUID(),\n };\n }\n}\n"],"mappings":"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"}