on main help sign in
feat(groq): add support for Groq using the OpenAI provider
7a62ab7Hunter Casten
README.md+12
@@ -91,6 +91,10 @@ You can configure OpenCode using environment variables:
91 "anthropic": {
91 "anthropic": {
92 "apiKey": "your-api-key",
92 "apiKey": "your-api-key",
93 "disabled": false
93 "disabled": false
94+ },
95+ "groq": {
96+ "apiKey": "your-api-key",
97+ "disabled": false
94 }
98 }
95 },
99 },
96 "agents": {
100 "agents": {
@@ -158,6 +162,14 @@ OpenCode supports a variety of AI models from different providers:
158
162
159- Claude 3.7 Sonnet
163- Claude 3.7 Sonnet
160
164
165+### Groq
166+
167+- Llama 4 Maverick (17b-128e-instruct)
168+- Llama 4 Scout (17b-16e-instruct)
169+- QWEN QWQ-32b
170+- Deepseek R1 distill Llama 70b
171+- Llama 3.3 70b Versatile
172+
161## Usage
173## Usage
162
174
163```bash
175```bash
internal/llm/models/groq.gonew file+82
@@ -0,0 +1,82 @@
1+package models
2+
3+const (
4+ ProviderGROQ ModelProvider = "groq"
5+
6+ // GROQ
7+ QWENQwq ModelID = "qwen-qwq"
8+
9+ // GROQ preview models
10+ Llama4Scout ModelID = "meta-llama/llama-4-scout-17b-16e-instruct"
11+ Llama4Maverick ModelID = "meta-llama/llama-4-maverick-17b-128e-instruct"
12+ Llama3_3_70BVersatile ModelID = "llama-3.3-70b-versatile"
13+ DeepseekR1DistillLlama70b ModelID = "deepseek-r1-distill-llama-70b"
14+)
15+
16+var GroqModels = map[ModelID]Model{
17+ //
18+ // GROQ
19+ QWENQwq: {
20+ ID: QWENQwq,
21+ Name: "Qwen Qwq",
22+ Provider: ProviderGROQ,
23+ APIModel: "qwen-qwq-32b",
24+ CostPer1MIn: 0.29,
25+ CostPer1MInCached: 0.275,
26+ CostPer1MOutCached: 0.0,
27+ CostPer1MOut: 0.39,
28+ ContextWindow: 128_000,
29+ DefaultMaxTokens: 50000,
30+ // for some reason, the groq api doesn't like the reasoningEffort parameter
31+ CanReason: false,
32+ },
33+
34+ Llama4Scout: {
35+ ID: Llama4Scout,
36+ Name: "Llama4Scout",
37+ Provider: ProviderGROQ,
38+ APIModel: "meta-llama/llama-4-scout-17b-16e-instruct",
39+ CostPer1MIn: 0.11,
40+ CostPer1MInCached: 0,
41+ CostPer1MOutCached: 0,
42+ CostPer1MOut: 0.34,
43+ ContextWindow: 128_000, // 10M when?
44+ },
45+
46+ Llama4Maverick: {
47+ ID: Llama4Maverick,
48+ Name: "Llama4Maverick",
49+ Provider: ProviderGROQ,
50+ APIModel: "meta-llama/llama-4-maverick-17b-128e-instruct",
51+ CostPer1MIn: 0.20,
52+ CostPer1MInCached: 0,
53+ CostPer1MOutCached: 0,
54+ CostPer1MOut: 0.20,
55+ ContextWindow: 128_000,
56+ },
57+
58+ Llama3_3_70BVersatile: {
59+ ID: Llama3_3_70BVersatile,
60+ Name: "Llama3_3_70BVersatile",
61+ Provider: ProviderGROQ,
62+ APIModel: "llama-3.3-70b-versatile",
63+ CostPer1MIn: 0.59,
64+ CostPer1MInCached: 0,
65+ CostPer1MOutCached: 0,
66+ CostPer1MOut: 0.79,
67+ ContextWindow: 128_000,
68+ },
69+
70+ DeepseekR1DistillLlama70b: {
71+ ID: DeepseekR1DistillLlama70b,
72+ Name: "DeepseekR1DistillLlama70b",
73+ Provider: ProviderGROQ,
74+ APIModel: "deepseek-r1-distill-llama-70b",
75+ CostPer1MIn: 0.75,
76+ CostPer1MInCached: 0,
77+ CostPer1MOutCached: 0,
78+ CostPer1MOut: 0.99,
79+ ContextWindow: 128_000,
80+ CanReason: true,
81+ },
82+}
internal/llm/models/models.go+1−17
@@ -23,17 +23,12 @@ type Model struct {
23
23
24// Model IDs
24// Model IDs
25const ( // GEMINI
25const ( // GEMINI
26− // GROQ
27− QWENQwq ModelID = "qwen-qwq"
28−
29 // Bedrock
26 // Bedrock
30 BedrockClaude37Sonnet ModelID = "bedrock.claude-3.7-sonnet"
27 BedrockClaude37Sonnet ModelID = "bedrock.claude-3.7-sonnet"
31)
28)
32
29
33const (
30const (
34 ProviderBedrock ModelProvider = "bedrock"
31 ProviderBedrock ModelProvider = "bedrock"
35− ProviderGROQ ModelProvider = "groq"
36−
37 // ForTests
32 // ForTests
38 ProviderMock ModelProvider = "__mock"
33 ProviderMock ModelProvider = "__mock"
39)
34)
@@ -63,18 +58,6 @@ var SupportedModels = map[ModelID]Model{
63 // CostPer1MOut: 0.4,
58 // CostPer1MOut: 0.4,
64 // },
59 // },
65 //
60 //
66− // // GROQ
67− // QWENQwq: {
68− // ID: QWENQwq,
69− // Name: "Qwen Qwq",
70− // Provider: ProviderGROQ,
71− // APIModel: "qwen-qwq-32b",
72− // CostPer1MIn: 0,
73− // CostPer1MInCached: 0,
74− // CostPer1MOutCached: 0,
75− // CostPer1MOut: 0,
76− // },
77− //
78 // // Bedrock
61 // // Bedrock
79 BedrockClaude37Sonnet: {
62 BedrockClaude37Sonnet: {
80 ID: BedrockClaude37Sonnet,
63 ID: BedrockClaude37Sonnet,
@@ -92,4 +75,5 @@ func init() {
92 maps.Copy(SupportedModels, AnthropicModels)
75 maps.Copy(SupportedModels, AnthropicModels)
93 maps.Copy(SupportedModels, OpenAIModels)
76 maps.Copy(SupportedModels, OpenAIModels)
94 maps.Copy(SupportedModels, GeminiModels)
77 maps.Copy(SupportedModels, GeminiModels)
78+ maps.Copy(SupportedModels, GroqModels)
95}
79}
internal/llm/provider/provider.go+8
@@ -107,6 +107,14 @@ func NewProvider(providerName models.ModelProvider, opts ...ProviderClientOption
107 options: clientOptions,
107 options: clientOptions,
108 client: newBedrockClient(clientOptions),
108 client: newBedrockClient(clientOptions),
109 }, nil
109 }, nil
110+ case models.ProviderGROQ:
111+ clientOptions.openaiOptions = append(clientOptions.openaiOptions,
112+ WithOpenAIBaseURL("https://api.groq.com/openai/v1"),
113+ )
114+ return &baseProvider[OpenAIClient]{
115+ options: clientOptions,
116+ client: newOpenAIClient(clientOptions),
117+ }, nil
110 case models.ProviderMock:
118 case models.ProviderMock:
111 // TODO: implement mock client for test
119 // TODO: implement mock client for test
112 panic("not implemented")
120 panic("not implemented")
opencode-schema.json+40−30
@@ -12,28 +12,33 @@
12 "model": {
12 "model": {
13 "description": "Model ID for the agent",
13 "description": "Model ID for the agent",
14 "enum": [
14 "enum": [
15− "gemini-2.0-flash",
16− "bedrock.claude-3.7-sonnet",
15+ "claude-3.7-sonnet",
17 "claude-3-opus",
16 "claude-3-opus",
18− "claude-3.5-sonnet",
17+ "gpt-4.1-mini",
18+ "gpt-4o",
19 "gpt-4o-mini",
19 "gpt-4o-mini",
20+ "gemini-2.0-flash-lite",
21+ "meta-llama/llama-4-maverick-17b-128e-instruct",
22+ "gpt-4.1",
23+ "gpt-4.5-preview",
20 "o1",
24 "o1",
25+ "gpt-4.1-nano",
21 "o3-mini",
26 "o3-mini",
27+ "gemini-2.5-flash",
28+ "gemini-2.0-flash",
29+ "meta-llama/llama-4-scout-17b-16e-instruct",
30+ "bedrock.claude-3.7-sonnet",
22 "o1-pro",
31 "o1-pro",
23− "o4-mini",
24− "claude-3-haiku",
25− "gpt-4o",
26 "o3",
32 "o3",
27− "gpt-4.1-mini",
28− "gpt-4.5-preview",
29− "gemini-2.5-flash",
33+ "gemini-2.5",
34+ "qwen-qwq",
35+ "llama-3.3-70b-versatile",
36+ "deepseek-r1-distill-llama-70b",
37+ "claude-3.5-sonnet",
38+ "claude-3-haiku",
30 "claude-3.5-haiku",
39 "claude-3.5-haiku",
31− "gpt-4.1",
40+ "o4-mini",
32− "gemini-2.0-flash-lite",
33− "claude-3.7-sonnet",
34− "o1-mini",
41+ "o1-mini"
35− "gpt-4.1-nano",
36− "gemini-2.5"
37 ],
42 ],
38 "type": "string"
43 "type": "string"
39 },
44 },
@@ -67,28 +72,33 @@
67 "model": {
72 "model": {
68 "description": "Model ID for the agent",
73 "description": "Model ID for the agent",
69 "enum": [
74 "enum": [
70− "gemini-2.0-flash",
71− "bedrock.claude-3.7-sonnet",
75+ "claude-3.7-sonnet",
72 "claude-3-opus",
76 "claude-3-opus",
73− "claude-3.5-sonnet",
77+ "gpt-4.1-mini",
78+ "gpt-4o",
74 "gpt-4o-mini",
79 "gpt-4o-mini",
80+ "gemini-2.0-flash-lite",
81+ "meta-llama/llama-4-maverick-17b-128e-instruct",
82+ "gpt-4.1",
83+ "gpt-4.5-preview",
75 "o1",
84 "o1",
85+ "gpt-4.1-nano",
76 "o3-mini",
86 "o3-mini",
87+ "gemini-2.5-flash",
88+ "gemini-2.0-flash",
89+ "meta-llama/llama-4-scout-17b-16e-instruct",
90+ "bedrock.claude-3.7-sonnet",
77 "o1-pro",
91 "o1-pro",
78− "o4-mini",
79− "claude-3-haiku",
80− "gpt-4o",
81 "o3",
92 "o3",
82− "gpt-4.1-mini",
83− "gpt-4.5-preview",
84− "gemini-2.5-flash",
93+ "gemini-2.5",
94+ "qwen-qwq",
95+ "llama-3.3-70b-versatile",
96+ "deepseek-r1-distill-llama-70b",
97+ "claude-3.5-sonnet",
98+ "claude-3-haiku",
85 "claude-3.5-haiku",
99 "claude-3.5-haiku",
86− "gpt-4.1",
100+ "o4-mini",
87− "gemini-2.0-flash-lite",
88− "claude-3.7-sonnet",
89− "o1-mini",
101+ "o1-mini"
90− "gpt-4.1-nano",
91− "gemini-2.5"
92 ],
102 ],
93 "type": "string"
103 "type": "string"
94 },
104 },