chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
import rootConfig from '../../eslint.config.mjs'
|
||||
|
||||
export default [
|
||||
...rootConfig,
|
||||
{
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
project: ['./tsconfig.json'],
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -0,0 +1,5 @@
|
||||
# Groq Integration
|
||||
|
||||
This integration allows your bot to choose from a curated list of models from [Groq](https://groq.com/) for content generation and chat completions (LLM) and audio transcription (speech-to-text).
|
||||
|
||||
Usage is charged to the AI Spend of your workspace in Botpress Cloud at the [same pricing](https://wow.groq.com/) (at cost) as directly with Groq.
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="201" height="201">
|
||||
<path d="M0 0 C66.33 0 132.66 0 201 0 C201 66.33 201 132.66 201 201 C134.67 201 68.34 201 0 201 C0 134.67 0 68.34 0 0 Z " fill="#F54F35" transform="translate(0,0)"/>
|
||||
<path d="M0 0 C0.93779297 0.75216797 0.93779297 0.75216797 1.89453125 1.51953125 C8.33639184 7.28773322 12.6023833 15.48965542 14 24 C14.09738126 25.82273518 14.14785758 27.64834642 14.16113281 29.47363281 C14.17074036 30.54534729 14.1803479 31.61706177 14.19024658 32.72125244 C14.19449646 33.87027039 14.19874634 35.01928833 14.203125 36.203125 C14.20882507 37.39548767 14.21452515 38.58785034 14.22039795 39.81634521 C14.22983588 42.3380037 14.23637713 44.85967446 14.24023438 47.38134766 C14.24992907 51.22190086 14.2809605 55.0619163 14.3125 58.90234375 C14.31903167 61.35676767 14.32428149 63.8111954 14.328125 66.265625 C14.3404718 67.40654602 14.3528186 68.54746704 14.36553955 69.72296143 C14.33311138 81.43954401 10.99252261 91.55248956 2.890625 100.26953125 C-1.66120262 104.49959175 -6.25671611 107.64198507 -12 110 C-12.78761719 110.34804687 -13.57523438 110.69609375 -14.38671875 111.0546875 C-23.66203561 114.40988433 -34.68691913 113.45211475 -43.765625 109.92578125 C-48.78168448 107.54540572 -52.92239216 104.75569143 -57 101 C-53.32167983 96.47384007 -49.58913637 92.60575001 -45 89 C-43.989375 89.78375 -42.97875 90.5675 -41.9375 91.375 C-36.36462944 95.33319579 -30.8023444 96.586409 -24 96 C-17.04056152 94.61566323 -11.54460551 91.49829147 -7 86 C-2.82603872 79.21578252 -2.41043479 73.77764288 -2.46875 65.90625 C-2.4649231 64.76015259 -2.46109619 63.61405518 -2.45715332 62.43322754 C-2.45444148 60.01944089 -2.46175137 57.60562449 -2.47851562 55.19189453 C-2.49993381 51.51137352 -2.47868717 47.83280453 -2.453125 44.15234375 C-2.4557684 41.79947489 -2.46089364 39.44660723 -2.46875 37.09375 C-2.46065308 36.00082642 -2.45255615 34.90790283 -2.44421387 33.78186035 C-2.54164791 25.78635396 -4.17568469 20.57192819 -9.125 14.3125 C-15.91094631 8.85423884 -22.22973717 6.10057876 -31.0390625 6.51953125 C-38.36558014 7.70839889 -44.3167643 11.21929709 -48.81640625 17.12109375 C-52.52753946 23.01236462 -54.13875057 29.0698894 -53 36 C-50.80897616 43.54685988 -47.9814321 49.94755953 -41 54 C-35.15229374 57.06131509 -30.10781754 57.52257119 -23.5625 57.6875 C-22.64017578 57.72166016 -21.71785156 57.75582031 -20.76757812 57.79101562 C-18.51212643 57.87281957 -16.25608573 57.93810172 -14 58 C-14 63.28 -14 68.56 -14 74 C-30.68235034 74.67327871 -43.61483255 74.6541625 -56.8515625 63.15234375 C-65.1324364 54.85641372 -70.18998583 43.60277378 -70.5625 31.875 C-70.16772512 22.00562801 -66.63225848 13.98056169 -61 6 C-60.443125 5.154375 -59.88625 4.30875 -59.3125 3.4375 C-43.30278865 -13.43760116 -17.9493234 -14.56398932 0 0 Z " fill="#FEFBFB" transform="translate(128,49)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
@@ -0,0 +1,36 @@
|
||||
import { IntegrationDefinition, z } from '@botpress/sdk'
|
||||
import { modelId } from 'src/schemas'
|
||||
import llm from './bp_modules/llm'
|
||||
import stt from './bp_modules/speech-to-text'
|
||||
|
||||
export default new IntegrationDefinition({
|
||||
name: 'groq',
|
||||
title: 'Groq',
|
||||
description: 'Gain access to Groq models for content generation, chat responses, and audio transcription.',
|
||||
version: '16.0.0',
|
||||
readme: 'hub.md',
|
||||
icon: 'icon.svg',
|
||||
entities: {
|
||||
modelRef: {
|
||||
schema: z.object({
|
||||
id: modelId,
|
||||
}),
|
||||
},
|
||||
speechToTextModelRef: {
|
||||
schema: z.object({
|
||||
id: z.string(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
secrets: {
|
||||
GROQ_API_KEY: {
|
||||
description: 'Groq API key',
|
||||
},
|
||||
},
|
||||
attributes: {
|
||||
category: 'AI Models',
|
||||
repo: 'botpress',
|
||||
},
|
||||
})
|
||||
.extend(llm, ({ entities: { modelRef } }) => ({ entities: { modelRef } }))
|
||||
.extend(stt, ({ entities: { speechToTextModelRef } }) => ({ entities: { speechToTextModelRef } }))
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "@botpresshub/groq",
|
||||
"scripts": {
|
||||
"build": "bp add -y && bp build",
|
||||
"check:type": "tsc --noEmit",
|
||||
"check:bplint": "bp lint",
|
||||
"test": "vitest --run"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@botpress/client": "workspace:*",
|
||||
"@botpress/common": "workspace:*",
|
||||
"@botpress/sdk": "workspace:*",
|
||||
"openai": "^5.12.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@botpress/cli": "workspace:*",
|
||||
"@botpress/sdk": "workspace:*",
|
||||
"@botpresshub/llm": "workspace:*",
|
||||
"@botpresshub/speech-to-text": "workspace:*"
|
||||
},
|
||||
"bpDependencies": {
|
||||
"llm": "../../interfaces/llm",
|
||||
"speech-to-text": "../../interfaces/speech-to-text"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
import { llm, speechToText } from '@botpress/common'
|
||||
import { validateGptOssReasoningEffort } from '@botpress/common/src/llm/openai'
|
||||
import OpenAI from 'openai'
|
||||
import { ModelId, SpeechToTextModelId } from './schemas'
|
||||
import * as bp from '.botpress'
|
||||
|
||||
const groqClient = new OpenAI({
|
||||
baseURL: 'https://api.groq.com/openai/v1',
|
||||
apiKey: bp.secrets.GROQ_API_KEY,
|
||||
})
|
||||
|
||||
const languageModels: Record<ModelId, llm.ModelDetails> = {
|
||||
// Reference:
|
||||
// https://console.groq.com/docs/models
|
||||
// https://groq.com/pricing/
|
||||
'openai/gpt-oss-20b': {
|
||||
name: 'GPT-OSS 20B',
|
||||
description:
|
||||
'gpt-oss-20b is a compact, open-weight language model optimized for low-latency. It shares the same training foundation and capabilities as the GPT-OSS 120B model, with faster responses and lower cost.',
|
||||
tags: ['general-purpose', 'reasoning', 'low-cost'],
|
||||
input: {
|
||||
costPer1MTokens: 0.1,
|
||||
maxTokens: 131_000,
|
||||
},
|
||||
output: {
|
||||
costPer1MTokens: 0.5,
|
||||
maxTokens: 32_000,
|
||||
},
|
||||
},
|
||||
'openai/gpt-oss-120b': {
|
||||
name: 'GPT-OSS 120B',
|
||||
description:
|
||||
'gpt-oss-120b is a high-performance, open-weight language model designed for production-grade, general-purpose use cases. It excels at complex reasoning and supports configurable reasoning effort, full chain-of-thought transparency for easier debugging and trust, and native agentic capabilities for function calling, tool use, and structured outputs.',
|
||||
tags: ['general-purpose', 'reasoning'],
|
||||
|
||||
input: {
|
||||
costPer1MTokens: 0.15,
|
||||
maxTokens: 131_000,
|
||||
},
|
||||
output: {
|
||||
costPer1MTokens: 0.75,
|
||||
maxTokens: 32_000,
|
||||
},
|
||||
},
|
||||
'llama-3.3-70b-versatile': {
|
||||
name: 'LLaMA 3.3 70B',
|
||||
description:
|
||||
'The Meta Llama 3.3 multilingual large language model (LLM) is a pretrained and instruction tuned generative model in 70B (text in/text out). The Llama 3.3 instruction tuned text only model is optimized for multilingual dialogue use cases and outperforms many of the available open source and closed chat models on common industry benchmarks.',
|
||||
tags: ['recommended', 'general-purpose', 'coding'],
|
||||
input: {
|
||||
costPer1MTokens: 0.59,
|
||||
maxTokens: 128_000,
|
||||
},
|
||||
output: {
|
||||
costPer1MTokens: 0.79,
|
||||
maxTokens: 32_768,
|
||||
},
|
||||
},
|
||||
'llama-3.1-8b-instant': {
|
||||
name: 'LLaMA 3.1 8B',
|
||||
description: 'The Llama 3.1 instruction-tuned, text-only models are optimized for multilingual dialogue use cases.',
|
||||
tags: ['low-cost', 'general-purpose'],
|
||||
input: {
|
||||
costPer1MTokens: 0.05,
|
||||
maxTokens: 128_000,
|
||||
},
|
||||
output: {
|
||||
costPer1MTokens: 0.08,
|
||||
maxTokens: 8192,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const speechToTextModels: Record<SpeechToTextModelId, speechToText.SpeechToTextModelDetails> = {
|
||||
'whisper-large-v3': {
|
||||
name: 'Whisper V3',
|
||||
costPerMinute: 0.00185,
|
||||
},
|
||||
'whisper-large-v3-turbo': {
|
||||
name: 'Whisper V3 Turbo',
|
||||
costPerMinute: 0.000666666666667,
|
||||
},
|
||||
'distil-whisper-large-v3-en': {
|
||||
name: 'Whisper V3 English-only',
|
||||
costPerMinute: 0.000333333333333,
|
||||
},
|
||||
}
|
||||
|
||||
const provider = 'Groq'
|
||||
|
||||
export default new bp.Integration({
|
||||
register: async () => {},
|
||||
unregister: async () => {},
|
||||
actions: {
|
||||
generateContent: async ({ input, logger, metadata }) => {
|
||||
const output = await llm.openai.generateContent<ModelId>(
|
||||
<llm.GenerateContentInput>input,
|
||||
groqClient as any, // TODO: fix mismatch of openai version
|
||||
logger,
|
||||
{
|
||||
provider,
|
||||
models: languageModels,
|
||||
defaultModel: 'llama-3.3-70b-versatile',
|
||||
overrideRequest: (request) => {
|
||||
if (input.model?.id === 'openai/gpt-oss-20b' || input.model?.id === 'openai/gpt-oss-120b') {
|
||||
request.reasoning_effort = validateGptOssReasoningEffort(input, logger)
|
||||
|
||||
// GPT-OSS models don't work well with a stop sequence, so we have to remove it from the request.
|
||||
delete request.stop
|
||||
|
||||
// Reasoning models don't support temperature
|
||||
delete request.temperature
|
||||
}
|
||||
|
||||
return request
|
||||
},
|
||||
}
|
||||
)
|
||||
metadata.setCost(output.botpress.cost)
|
||||
return output
|
||||
},
|
||||
transcribeAudio: async ({ input, logger, metadata }) => {
|
||||
const output = await speechToText.openai.transcribeAudio(
|
||||
input,
|
||||
groqClient as any, // TODO: fix mismatch of openai version
|
||||
logger,
|
||||
{
|
||||
provider,
|
||||
models: speechToTextModels,
|
||||
defaultModel: 'whisper-large-v3',
|
||||
}
|
||||
)
|
||||
metadata.setCost(output.botpress.cost)
|
||||
return output
|
||||
},
|
||||
listLanguageModels: async ({}) => {
|
||||
return {
|
||||
models: Object.entries(languageModels).map(([id, model]) => ({ id: <ModelId>id, ...model })),
|
||||
}
|
||||
},
|
||||
listSpeechToTextModels: async ({}) => {
|
||||
return {
|
||||
models: [
|
||||
{
|
||||
id: 'whisper-1',
|
||||
name: 'Whisper V2',
|
||||
costPerMinute: 0.006,
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
},
|
||||
channels: {},
|
||||
handler: async () => {},
|
||||
})
|
||||
@@ -0,0 +1,11 @@
|
||||
import { z } from '@botpress/sdk'
|
||||
|
||||
export const modelId = z
|
||||
.enum(['openai/gpt-oss-20b', 'openai/gpt-oss-120b', 'llama-3.3-70b-versatile', 'llama-3.1-8b-instant'])
|
||||
.describe('Model to use for content generation')
|
||||
.placeholder('openai/gpt-oss-120b')
|
||||
|
||||
export type ModelId = z.infer<typeof modelId>
|
||||
|
||||
export const speechToTextModelId = z.enum(['whisper-large-v3', 'whisper-large-v3-turbo', 'distil-whisper-large-v3-en'])
|
||||
export type SpeechToTextModelId = z.infer<typeof speechToTextModelId>
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"paths": { "*": ["./*"] },
|
||||
"outDir": "dist"
|
||||
},
|
||||
"include": [".botpress/**/*", "definitions/**/*", "src/**/*", "*.ts"]
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
import config from '../../vitest.config'
|
||||
export default config
|
||||
Reference in New Issue
Block a user