boxcars 0.7.6 → 0.8.0
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -3
- data/.ruby-version +1 -1
- data/CHANGELOG.md +41 -0
- data/Gemfile +3 -13
- data/Gemfile.lock +29 -25
- data/POSTHOG_TEST_README.md +118 -0
- data/README.md +305 -0
- data/boxcars.gemspec +1 -2
- data/lib/boxcars/boxcar/active_record.rb +9 -10
- data/lib/boxcars/boxcar/calculator.rb +2 -2
- data/lib/boxcars/boxcar/engine_boxcar.rb +4 -4
- data/lib/boxcars/boxcar/google_search.rb +2 -2
- data/lib/boxcars/boxcar/json_engine_boxcar.rb +1 -1
- data/lib/boxcars/boxcar/ruby_calculator.rb +1 -1
- data/lib/boxcars/boxcar/sql_base.rb +4 -4
- data/lib/boxcars/boxcar/swagger.rb +3 -3
- data/lib/boxcars/boxcar/vector_answer.rb +3 -3
- data/lib/boxcars/boxcar/xml_engine_boxcar.rb +1 -1
- data/lib/boxcars/boxcar.rb +6 -6
- data/lib/boxcars/conversation_prompt.rb +3 -3
- data/lib/boxcars/engine/anthropic.rb +121 -23
- data/lib/boxcars/engine/cerebras.rb +2 -2
- data/lib/boxcars/engine/cohere.rb +135 -9
- data/lib/boxcars/engine/gemini_ai.rb +151 -76
- data/lib/boxcars/engine/google.rb +2 -2
- data/lib/boxcars/engine/gpt4all_eng.rb +92 -34
- data/lib/boxcars/engine/groq.rb +124 -73
- data/lib/boxcars/engine/intelligence_base.rb +52 -17
- data/lib/boxcars/engine/ollama.rb +127 -47
- data/lib/boxcars/engine/openai.rb +186 -103
- data/lib/boxcars/engine/perplexityai.rb +116 -136
- data/lib/boxcars/engine/together.rb +2 -2
- data/lib/boxcars/engine/unified_observability.rb +430 -0
- data/lib/boxcars/engine.rb +4 -3
- data/lib/boxcars/engines.rb +74 -0
- data/lib/boxcars/observability.rb +44 -0
- data/lib/boxcars/observability_backend.rb +17 -0
- data/lib/boxcars/observability_backends/multi_backend.rb +42 -0
- data/lib/boxcars/observability_backends/posthog_backend.rb +89 -0
- data/lib/boxcars/observation.rb +8 -8
- data/lib/boxcars/prompt.rb +16 -4
- data/lib/boxcars/result.rb +7 -12
- data/lib/boxcars/ruby_repl.rb +1 -1
- data/lib/boxcars/train/train_action.rb +1 -1
- data/lib/boxcars/train/xml_train.rb +3 -3
- data/lib/boxcars/train/xml_zero_shot.rb +1 -1
- data/lib/boxcars/train/zero_shot.rb +3 -3
- data/lib/boxcars/train.rb +1 -1
- data/lib/boxcars/vector_search.rb +5 -5
- data/lib/boxcars/vector_store/pgvector/build_from_array.rb +116 -88
- data/lib/boxcars/vector_store/pgvector/build_from_files.rb +106 -80
- data/lib/boxcars/vector_store/pgvector/save_to_database.rb +148 -122
- data/lib/boxcars/vector_store/pgvector/search.rb +157 -131
- data/lib/boxcars/vector_store.rb +4 -4
- data/lib/boxcars/version.rb +1 -1
- data/lib/boxcars.rb +31 -20
- metadata +11 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 27e2420c9339daf37e4eb0c63f86fede297cf48931398a33b2a73054900b5288
|
4
|
+
data.tar.gz: f6fd74d8381fa7905715706d51fafdd179f47c4b021cb57caeacbadb9fdb40a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3844edd3c676e68aead5f2a461b401a11a7094d944b66f5b560d03f55a5ca49c936d0ddd8e4f58ac44a32300895c2d34fd5c52adc45fdfc489653b3cf5de2c78
|
7
|
+
data.tar.gz: f8844a5a5977a7769a495bc16b3bc1d6204501a42106fe2528ec6d60be559c08419eae242a1d3ed8b73c1dc9ff44e94c7f2e4e7dd06413483f4db3a66e299711
|
data/.rubocop.yml
CHANGED
@@ -6,7 +6,7 @@ plugins:
|
|
6
6
|
|
7
7
|
|
8
8
|
AllCops:
|
9
|
-
TargetRubyVersion: 3
|
9
|
+
TargetRubyVersion: 3.2
|
10
10
|
Exclude:
|
11
11
|
- 'bin/{rails,rake}'
|
12
12
|
- 'node_modules/**/*'
|
@@ -72,7 +72,7 @@ Metrics/BlockLength:
|
|
72
72
|
- 'spec/**/*'
|
73
73
|
|
74
74
|
Metrics/MethodLength:
|
75
|
-
Max:
|
75
|
+
Max: 40
|
76
76
|
Exclude:
|
77
77
|
- 'spec/**/*'
|
78
78
|
|
@@ -95,7 +95,7 @@ Naming/AccessorMethodName:
|
|
95
95
|
Enabled: false
|
96
96
|
|
97
97
|
Metrics/PerceivedComplexity:
|
98
|
-
Max:
|
98
|
+
Max: 20
|
99
99
|
|
100
100
|
Style/RescueStandardError:
|
101
101
|
Enabled: false
|
@@ -171,3 +171,6 @@ RSpec/ExampleLength:
|
|
171
171
|
|
172
172
|
RSpec/MultipleExpectations:
|
173
173
|
Enabled: false
|
174
|
+
|
175
|
+
RSpec/BeforeAfterAll:
|
176
|
+
Enabled: false
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.4.4
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,46 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v0.7.6](https://github.com/BoxcarsAI/boxcars/tree/v0.7.6) (2025-04-22)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/BoxcarsAI/boxcars/compare/v0.7.5...v0.7.6)
|
6
|
+
|
7
|
+
## [v0.7.5](https://github.com/BoxcarsAI/boxcars/tree/v0.7.5) (2025-04-21)
|
8
|
+
|
9
|
+
[Full Changelog](https://github.com/BoxcarsAI/boxcars/compare/v0.7.4...v0.7.5)
|
10
|
+
|
11
|
+
**Merged pull requests:**
|
12
|
+
|
13
|
+
- Together AI Engine [\#250](https://github.com/BoxcarsAI/boxcars/pull/250) ([francis](https://github.com/francis))
|
14
|
+
|
15
|
+
## [v0.7.4](https://github.com/BoxcarsAI/boxcars/tree/v0.7.4) (2025-04-16)
|
16
|
+
|
17
|
+
[Full Changelog](https://github.com/BoxcarsAI/boxcars/compare/v0.7.3...v0.7.4)
|
18
|
+
|
19
|
+
## [v0.7.3](https://github.com/BoxcarsAI/boxcars/tree/v0.7.3) (2025-01-20)
|
20
|
+
|
21
|
+
[Full Changelog](https://github.com/BoxcarsAI/boxcars/compare/v0.7.2...v0.7.3)
|
22
|
+
|
23
|
+
**Merged pull requests:**
|
24
|
+
|
25
|
+
- add cerebras tests [\#246](https://github.com/BoxcarsAI/boxcars/pull/246) ([francis](https://github.com/francis))
|
26
|
+
|
27
|
+
## [v0.7.2](https://github.com/BoxcarsAI/boxcars/tree/v0.7.2) (2025-01-17)
|
28
|
+
|
29
|
+
[Full Changelog](https://github.com/BoxcarsAI/boxcars/compare/v0.7.1...v0.7.2)
|
30
|
+
|
31
|
+
**Merged pull requests:**
|
32
|
+
|
33
|
+
- cerebras bug fixes [\#245](https://github.com/BoxcarsAI/boxcars/pull/245) ([francis](https://github.com/francis))
|
34
|
+
|
35
|
+
## [v0.7.1](https://github.com/BoxcarsAI/boxcars/tree/v0.7.1) (2025-01-17)
|
36
|
+
|
37
|
+
[Full Changelog](https://github.com/BoxcarsAI/boxcars/compare/v0.6.9...v0.7.1)
|
38
|
+
|
39
|
+
**Merged pull requests:**
|
40
|
+
|
41
|
+
- add Cerebras [\#244](https://github.com/BoxcarsAI/boxcars/pull/244) ([francis](https://github.com/francis))
|
42
|
+
- \[infra\] Bump pg from 1.5.8 to 1.5.9 [\#231](https://github.com/BoxcarsAI/boxcars/pull/231) ([dependabot[bot]](https://github.com/apps/dependabot))
|
43
|
+
|
3
44
|
## [v0.6.9](https://github.com/BoxcarsAI/boxcars/tree/v0.6.9) (2024-12-19)
|
4
45
|
|
5
46
|
[Full Changelog](https://github.com/BoxcarsAI/boxcars/compare/v0.6.8...v0.6.9)
|
data/Gemfile
CHANGED
@@ -5,36 +5,26 @@ source "https://rubygems.org"
|
|
5
5
|
# Specify your gem's dependencies in boxcars.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
-
gem "debug", "~> 1.9"
|
9
|
-
|
10
8
|
gem "dotenv", "~> 3.1"
|
11
|
-
|
12
9
|
gem "rake", "~> 13.2"
|
13
|
-
|
14
10
|
gem "sqlite3", "~> 2.0"
|
15
|
-
|
16
11
|
gem "async", "~>1.32.1"
|
17
|
-
|
18
12
|
gem "activerecord", "~> 7.1"
|
19
|
-
|
20
|
-
gem "github_changelog_generator", "~> 1.16"
|
21
|
-
|
22
13
|
gem "faraday-retry", "~> 2.0"
|
23
|
-
|
24
14
|
gem "activesupport", "~> 7.1"
|
25
|
-
|
26
15
|
gem "rest-client", "~> 2.1"
|
27
|
-
|
28
16
|
gem "hnswlib", "~> 0.9.0"
|
29
|
-
|
30
17
|
gem "pg", "~> 1.5"
|
31
18
|
gem "pgvector", "~> 0.2.2"
|
32
19
|
|
33
20
|
group :development, :test do
|
21
|
+
gem "debug", "~> 1.9"
|
34
22
|
gem "rspec", "~> 3.13"
|
35
23
|
gem "rubocop", "~> 1.67"
|
36
24
|
gem "vcr", "~> 6.3.1"
|
37
25
|
gem "webmock", "~> 3.24.0"
|
38
26
|
gem "rubocop-rake", "~> 0.6.0"
|
39
27
|
gem "rubocop-rspec", "~> 3.2"
|
28
|
+
gem "posthog-ruby", require: false
|
29
|
+
gem "github_changelog_generator", "~> 1.16", require: false
|
40
30
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
boxcars (0.
|
4
|
+
boxcars (0.8.0)
|
5
5
|
google_search_results (~> 2.2)
|
6
6
|
gpt4all (~> 0.0.5)
|
7
7
|
hnswlib (~> 0.9)
|
8
8
|
intelligence (>= 0.8)
|
9
9
|
nokogiri (~> 1.18)
|
10
|
-
pgvector (~> 0.2)
|
11
10
|
ruby-anthropic (~> 0.4)
|
12
11
|
ruby-openai (>= 7.3)
|
13
12
|
|
@@ -54,11 +53,11 @@ GEM
|
|
54
53
|
async
|
55
54
|
async-pool (0.10.3)
|
56
55
|
async (>= 1.25)
|
57
|
-
base64 (0.
|
58
|
-
benchmark (0.4.
|
59
|
-
bigdecimal (3.1
|
56
|
+
base64 (0.3.0)
|
57
|
+
benchmark (0.4.1)
|
58
|
+
bigdecimal (3.2.1)
|
60
59
|
concurrent-ruby (1.3.5)
|
61
|
-
connection_pool (2.5.
|
60
|
+
connection_pool (2.5.3)
|
62
61
|
console (1.30.2)
|
63
62
|
fiber-annotation
|
64
63
|
fiber-local (~> 1.1)
|
@@ -70,13 +69,14 @@ GEM
|
|
70
69
|
debug (1.10.0)
|
71
70
|
irb (~> 1.10)
|
72
71
|
reline (>= 0.3.8)
|
73
|
-
diff-lcs (1.6.
|
72
|
+
diff-lcs (1.6.2)
|
74
73
|
domain_name (0.6.20240107)
|
75
74
|
dotenv (3.1.8)
|
76
|
-
drb (2.2.
|
75
|
+
drb (2.2.3)
|
77
76
|
dynamicschema (1.0.0.beta04)
|
77
|
+
erb (5.0.1)
|
78
78
|
event_stream_parser (1.0.0)
|
79
|
-
faraday (2.13.
|
79
|
+
faraday (2.13.1)
|
80
80
|
faraday-net_http (>= 2.0, < 3.5)
|
81
81
|
json
|
82
82
|
logger
|
@@ -106,7 +106,7 @@ GEM
|
|
106
106
|
faraday (~> 2.7)
|
107
107
|
os (~> 1.1)
|
108
108
|
tty-progressbar (~> 0.18.2)
|
109
|
-
hashdiff (1.
|
109
|
+
hashdiff (1.2.0)
|
110
110
|
hnswlib (0.9.0)
|
111
111
|
http-accept (1.7.0)
|
112
112
|
http-cookie (1.0.8)
|
@@ -123,15 +123,15 @@ GEM
|
|
123
123
|
pp (>= 0.6.0)
|
124
124
|
rdoc (>= 4.0.0)
|
125
125
|
reline (>= 0.4.2)
|
126
|
-
json (2.
|
126
|
+
json (2.12.2)
|
127
127
|
json-repair (0.2.0)
|
128
|
-
language_server-protocol (3.17.0.
|
128
|
+
language_server-protocol (3.17.0.5)
|
129
129
|
lint_roller (1.1.0)
|
130
130
|
logger (1.7.0)
|
131
|
-
mime-types (3.
|
131
|
+
mime-types (3.7.0)
|
132
132
|
logger
|
133
|
-
mime-types-data (~> 3.
|
134
|
-
mime-types-data (3.2025.
|
133
|
+
mime-types-data (~> 3.2025, >= 3.2025.0507)
|
134
|
+
mime-types-data (3.2025.0527)
|
135
135
|
minitest (5.25.5)
|
136
136
|
multi_json (1.15.0)
|
137
137
|
multipart-post (2.4.1)
|
@@ -165,6 +165,8 @@ GEM
|
|
165
165
|
racc
|
166
166
|
pg (1.5.9)
|
167
167
|
pgvector (0.2.2)
|
168
|
+
posthog-ruby (3.0.1)
|
169
|
+
concurrent-ruby (~> 1)
|
168
170
|
pp (0.6.2)
|
169
171
|
prettyprint
|
170
172
|
prettyprint (0.2.0)
|
@@ -176,14 +178,15 @@ GEM
|
|
176
178
|
protocol-http2 (0.16.0)
|
177
179
|
protocol-hpack (~> 1.4)
|
178
180
|
protocol-http (~> 0.18)
|
179
|
-
psych (5.2.
|
181
|
+
psych (5.2.6)
|
180
182
|
date
|
181
183
|
stringio
|
182
|
-
public_suffix (6.0.
|
184
|
+
public_suffix (6.0.2)
|
183
185
|
racc (1.8.1)
|
184
186
|
rainbow (3.1.1)
|
185
|
-
rake (13.
|
186
|
-
rdoc (6.
|
187
|
+
rake (13.3.0)
|
188
|
+
rdoc (6.14.0)
|
189
|
+
erb
|
187
190
|
psych (>= 4.0.0)
|
188
191
|
regexp_parser (2.10.0)
|
189
192
|
reline (0.6.1)
|
@@ -194,20 +197,20 @@ GEM
|
|
194
197
|
mime-types (>= 1.16, < 4.0)
|
195
198
|
netrc (~> 0.8)
|
196
199
|
rexml (3.4.1)
|
197
|
-
rspec (3.13.
|
200
|
+
rspec (3.13.1)
|
198
201
|
rspec-core (~> 3.13.0)
|
199
202
|
rspec-expectations (~> 3.13.0)
|
200
203
|
rspec-mocks (~> 3.13.0)
|
201
|
-
rspec-core (3.13.
|
204
|
+
rspec-core (3.13.4)
|
202
205
|
rspec-support (~> 3.13.0)
|
203
|
-
rspec-expectations (3.13.
|
206
|
+
rspec-expectations (3.13.5)
|
204
207
|
diff-lcs (>= 1.2.0, < 2.0)
|
205
208
|
rspec-support (~> 3.13.0)
|
206
|
-
rspec-mocks (3.13.
|
209
|
+
rspec-mocks (3.13.5)
|
207
210
|
diff-lcs (>= 1.2.0, < 2.0)
|
208
211
|
rspec-support (~> 3.13.0)
|
209
|
-
rspec-support (3.13.
|
210
|
-
rubocop (1.75.
|
212
|
+
rspec-support (3.13.4)
|
213
|
+
rubocop (1.75.8)
|
211
214
|
json (~> 2.3)
|
212
215
|
language_server-protocol (~> 3.17.0.2)
|
213
216
|
lint_roller (~> 1.1.0)
|
@@ -292,6 +295,7 @@ DEPENDENCIES
|
|
292
295
|
hnswlib (~> 0.9.0)
|
293
296
|
pg (~> 1.5)
|
294
297
|
pgvector (~> 0.2.2)
|
298
|
+
posthog-ruby
|
295
299
|
rake (~> 13.2)
|
296
300
|
rest-client (~> 2.1)
|
297
301
|
rspec (~> 3.13)
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# Boxcars Engines PostHog Observability Test
|
2
|
+
|
3
|
+
This test program demonstrates how to use the Boxcars library with PostHog observability backend to track AI engine usage.
|
4
|
+
|
5
|
+
## Prerequisites
|
6
|
+
|
7
|
+
1. **PostHog Ruby Gem**: Install the required gem
|
8
|
+
```bash
|
9
|
+
gem install posthog-ruby
|
10
|
+
```
|
11
|
+
|
12
|
+
2. **Environment Variables**: Ensure your `.env` file contains:
|
13
|
+
```
|
14
|
+
POSTHOG_API_KEY=your_posthog_project_api_key
|
15
|
+
POSTHOG_HOST=https://app.posthog.com # or your self-hosted instance
|
16
|
+
```
|
17
|
+
|
18
|
+
3. **AI Provider API Keys**: For testing different engines, you'll need:
|
19
|
+
```
|
20
|
+
openai_access_token=your_openai_token
|
21
|
+
GOOGLE_API_KEY=your_google_api_key
|
22
|
+
ANTHROPIC_API_KEY=your_anthropic_key
|
23
|
+
GROQ_API_KEY=your_groq_key
|
24
|
+
```
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
### Method 1: IRB Interactive Session (Recommended)
|
29
|
+
|
30
|
+
Start IRB with the required dependencies:
|
31
|
+
|
32
|
+
```bash
|
33
|
+
irb -r dotenv/load -r boxcars -r debug -r boxcars/observability_backends/posthog_backend
|
34
|
+
```
|
35
|
+
|
36
|
+
Then in the IRB session:
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
# Load and run the test
|
40
|
+
load 'test_engines_with_posthog.rb'
|
41
|
+
|
42
|
+
# Or set up PostHog backend manually:
|
43
|
+
Boxcars::Observability.backend = Boxcars::PosthogBackend.new(
|
44
|
+
api_key: ENV['POSTHOG_API_KEY'],
|
45
|
+
host: ENV['POSTHOG_HOST']
|
46
|
+
)
|
47
|
+
|
48
|
+
# Run manual tests
|
49
|
+
manual_test(model: 'gpt-4o', prompt: 'What is machine learning?')
|
50
|
+
manual_test(model: 'flash', prompt: 'Explain Ruby in one sentence')
|
51
|
+
manual_test(model: 'sonnet', prompt: 'Write a short poem about coding')
|
52
|
+
```
|
53
|
+
|
54
|
+
### Method 2: Direct Ruby Execution
|
55
|
+
|
56
|
+
```bash
|
57
|
+
ruby test_engines_with_posthog.rb
|
58
|
+
```
|
59
|
+
|
60
|
+
## What the Test Does
|
61
|
+
|
62
|
+
1. **Initializes PostHog Backend**: Sets up the PostHog observability backend with your API credentials
|
63
|
+
2. **Tests Multiple Engines**: Runs tests against various AI engines:
|
64
|
+
- Gemini Flash (Default)
|
65
|
+
- GPT-4o (OpenAI)
|
66
|
+
- Claude Sonnet (Anthropic)
|
67
|
+
- Groq Llama
|
68
|
+
3. **Tracks Observability Events**: Each API call generates PostHog events with AI-specific properties
|
69
|
+
4. **Provides Manual Testing**: Includes a `manual_test` function for interactive testing
|
70
|
+
|
71
|
+
## PostHog Events
|
72
|
+
|
73
|
+
The test will generate events in PostHog with properties like:
|
74
|
+
|
75
|
+
- `$ai_model`: The AI model used (e.g., "gpt-4o", "gemini-2.5-flash")
|
76
|
+
- `$ai_provider`: The provider (e.g., "openai", "google", "anthropic")
|
77
|
+
- `$ai_input_tokens`: Number of input tokens
|
78
|
+
- `$ai_output_tokens`: Number of output tokens
|
79
|
+
- `$ai_latency`: Response time in seconds
|
80
|
+
- `$ai_http_status`: HTTP status code
|
81
|
+
- `$ai_trace_id`: Unique trace identifier
|
82
|
+
- `$ai_is_error`: Boolean indicating if there was an error
|
83
|
+
|
84
|
+
## Viewing Results
|
85
|
+
|
86
|
+
After running the test:
|
87
|
+
|
88
|
+
1. Go to your PostHog dashboard
|
89
|
+
2. Navigate to Events or Live Events
|
90
|
+
3. Look for events with AI-related properties
|
91
|
+
4. You can create insights and dashboards to analyze AI usage patterns
|
92
|
+
|
93
|
+
## Troubleshooting
|
94
|
+
|
95
|
+
- **Missing PostHog gem**: Install with `gem install posthog-ruby`
|
96
|
+
- **Missing API keys**: Check your `.env` file has the required keys
|
97
|
+
- **Engine errors**: Some engines may fail if you don't have valid API keys for those providers
|
98
|
+
- **No events in PostHog**: Check your PostHog API key and host configuration
|
99
|
+
|
100
|
+
## Available Models
|
101
|
+
|
102
|
+
You can test with these model aliases:
|
103
|
+
|
104
|
+
- `flash` - Gemini 2.5 Flash
|
105
|
+
- `gpt-4o` - OpenAI GPT-4o
|
106
|
+
- `sonnet` - Claude Sonnet
|
107
|
+
- `groq` - Groq Llama
|
108
|
+
- `online` - Perplexity Sonar
|
109
|
+
- And many more (see `lib/boxcars/engines.rb`)
|
110
|
+
|
111
|
+
## Example Manual Tests
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
# Test different models
|
115
|
+
manual_test(model: 'flash', prompt: 'Explain quantum computing')
|
116
|
+
manual_test(model: 'gpt-4o', prompt: 'Write a Python function to sort a list')
|
117
|
+
manual_test(model: 'sonnet', prompt: 'What are the benefits of functional programming?')
|
118
|
+
manual_test(model: 'groq', prompt: 'Describe the difference between AI and ML')
|