Skip to content

Commit cbc4f54

Browse files
committed
README updated - prep for the release
1 parent b639b27 commit cbc4f54

File tree

1 file changed

+117
-93
lines changed

1 file changed

+117
-93
lines changed

README.md

Lines changed: 117 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# OpenAI Scala Client 🤖
22
[![version](https://img.shields.io/badge/version-1.1.2-green.svg)](https://cequence.io) [![License](https://img.shields.io/badge/License-MIT-lightgrey.svg)](https://opensource.org/licenses/MIT) ![GitHub Stars](https://img.shields.io/github/stars/cequence-io/openai-scala-client?style=social) [![Twitter Follow](https://img.shields.io/twitter/follow/0xbnd?style=social)](https://twitter.com/0xbnd) ![GitHub CI](https://github.com/cequence-io/openai-scala-client/actions/workflows/continuous-integration.yml/badge.svg)
33

4-
This is a no-nonsense async Scala client for OpenAI API supporting all the available endpoints and params **including streaming**, the newest **chat completion**, **vision**, and **voice routines** (as defined [here](https://beta.openai.com/docs/api-reference)), provided in a single, convenient service called [OpenAIService](./openai-core/src/main/scala/io/cequence/openaiscala/service/OpenAIService.scala). The supported calls are:
4+
This is a no-nonsense async Scala client for OpenAI API supporting all the available endpoints and params **including streaming**, the newest **chat completion**, **responses API**, **assistants API**, **tools**, **vision**, and **voice routines** (as defined [here](https://platform.openai.com/docs/api-reference)), provided in a single, convenient service called [OpenAIService](./openai-core/src/main/scala/io/cequence/openaiscala/service/OpenAIService.scala). The supported calls are:
55

66
* **Models**: [listModels](https://platform.openai.com/docs/api-reference/models/list), and [retrieveModel](https://platform.openai.com/docs/api-reference/models/retrieve)
77
* **Completions**: [createCompletion](https://platform.openai.com/docs/api-reference/completions/create)
@@ -22,37 +22,46 @@ This is a no-nonsense async Scala client for OpenAI API supporting all the avail
2222
* **Vector Stores**: [createVectorStore](https://platform.openai.com/docs/api-reference/vector-stores/create), [listVectorStores](https://platform.openai.com/docs/api-reference/vector-stores/list), [retrieveVectorStore](https://platform.openai.com/docs/api-reference/vector-stores/retrieve), [modifyVectorStore](https://platform.openai.com/docs/api-reference/vector-stores/modify), and [deleteVectorStore](https://platform.openai.com/docs/api-reference/vector-stores/delete)
2323
* **Vector Store Files**: [createVectorStoreFile](https://platform.openai.com/docs/api-reference/vector-stores-files/createFile), [listVectorStoreFiles](https://platform.openai.com/docs/api-reference/vector-stores-files/listFiles), [retrieveVectorStoreFile](https://platform.openai.com/docs/api-reference/vector-stores-files/getFile), and [deleteVectorStoreFile](https://platform.openai.com/docs/api-reference/vector-stores-files/deleteFile)
2424
* **Vector Store File Batches**: [createVectorStoreFileBatch](https://platform.openai.com/docs/api-reference/vector-stores-file-batches/createBatch), [retrieveVectorStoreFileBatch](https://platform.openai.com/docs/api-reference/vector-stores-file-batches/getBatch), [cancelVectorStoreFileBatch](https://platform.openai.com/docs/api-reference/vector-stores-file-batches/cancelBatch), and [listVectorStoreBatchFiles](https://platform.openai.com/docs/api-reference/vector-stores-file-batches/listBatchFiles)
25+
* **Responses** (🔥 **New**): [createModelResponse](https://platform.openai.com/docs/api-reference/responses/create), [getModelResponse](https://platform.openai.com/docs/api-reference/responses/get), [deleteModelResponse](https://platform.openai.com/docs/api-reference/responses/delete), and [listModelResponseInputItems](https://platform.openai.com/docs/api-reference/responses/input-items)
2526

26-
Note that in order to be consistent with the OpenAI API naming, the service function names match exactly the API endpoint titles/descriptions with camelcase.
27-
Also, we aimed the lib to be self-contained with the fewest dependencies possible therefore we ended up using only two libs `play-ahc-ws-standalone` and `play-ws-standalone-json` (at the top level). Additionally, if dependency injection is required we use `scala-guice` lib as well.
27+
28+
Note that in order to be consistent with the OpenAI API naming, the service function names match exactly the API endpoint titles/descriptions in camelCase.
29+
Also, we aimed for the library to be self-contained with the fewest dependencies possible. Therefore, we implemented our own generic WS client (currently with Play WS backend, which can be swapped for other engines in the future). Additionally, if dependency injection is required, we use the `scala-guice` library.
2830

2931
---
3032

3133
👉 **No time to read a lengthy tutorial? Sure, we hear you! Check out the [examples](./openai-examples/src/main/scala/io/cequence/openaiscala/examples) to see how to use the lib in practice.**
3234

3335
---
3436

35-
In addition to the OpenAI API, this library also supports API-compatible providers (see [examples](./openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai)) such as:
36-
- [Azure OpenAI](https://azure.microsoft.com/en-us/products/ai-services/openai-service) - cloud-based, utilizes OpenAI models but with lower latency
37-
- [Azure AI](https://azure.microsoft.com/en-us/products/ai-studio) - cloud-based, offers a vast selection of open-source models
38-
- [Anthropic](https://www.anthropic.com/api) - cloud-based, a major competitor to OpenAI, features proprietary/closed-source models such as Claude3 - Haiku, Sonnet, and Opus. 🔥 **New**: now also through Bedrock!
39-
- [Google Vertex AI](https://cloud.google.com/vertex-ai) - cloud-based, features proprietary/closed-source models such as Gemini 1.5 Pro and flash
40-
- [Groq](https://wow.groq.com/) - cloud-based provider, known for its superfast inference with LPUs
41-
- [Grok](https://x.ai/) - cloud-based provider from x.AI
42-
- [Fireworks AI](https://fireworks.ai/) - cloud-based provider
43-
- [OctoAI](https://octo.ai/) - cloud-based provider
44-
- [TogetherAI](https://www.together.ai/) - cloud-based provider
45-
- [Cerebras](https://cerebras.ai/) - cloud-based provider, superfast (akin to Groq)
46-
- [Mistral](https://mistral.ai/) - cloud-based, leading open-source LLM company
47-
- [Deepseek](https://deepseek.com/) - cloud-based provider from China
48-
- [Ollama](https://ollama.com/) - runs locally, serves as an umbrella for open-source LLMs including LLaMA3, dbrx, and Command-R
49-
- [FastChat](https://github.com/lm-sys/FastChat) - runs locally, serves as an umbrella for open-source LLMs such as Vicuna, Alpaca, and FastChat-T5
37+
In addition to OpenAI, this library supports many other LLM providers. For providers that aren't natively compatible with the chat completion API, we've implemented adapters to streamline integration (see [examples](./openai-examples/src/main/scala/io/cequence/openaiscala/examples)).
38+
39+
| Provider | JSON/Structured Output | Tools Support | Description |
40+
|----------|------------------------|---------------|-------------|
41+
| [OpenAI](https://platform.openai.com) | Full | Standard + Responses API | Full API support |
42+
| [Azure OpenAI](https://azure.microsoft.com/en-us/products/ai-services/openai-service) | Full | Standard + Responses API | OpenAI on Azure|
43+
| [Azure AI](https://azure.microsoft.com/en-us/products/ai-studio) | Varies | | Open-source models |
44+
| [Anthropic](https://www.anthropic.com/api) | Implied | | Claude models |
45+
| [Google Vertex AI](https://cloud.google.com/vertex-ai) | Full | Yes | Gemini models |
46+
| [Google Gemini](https://ai.google.dev/) (🔥 **New**) | Full | Yes | Google's models |
47+
| [Groq](https://wow.groq.com/) | Only JSON object mode | Yes | Fast inference |
48+
| [Grok](https://x.ai/) | Full | | x.AI models |
49+
| [Fireworks AI](https://fireworks.ai/) | Only JSON object mode | | Cloud provider |
50+
| [Octo AI](https://octo.ai/) | Only JSON object mode | | Cloud provider (obsolete) |
51+
| [TogetherAI](https://www.together.ai/) | Only JSON object mode | | Cloud provider |
52+
| [Cerebras](https://cerebras.ai/) | Only JSON object mode | | Fast inference |
53+
| [Mistral](https://mistral.ai/) | Only JSON object mode | | Open-source leader |
54+
| [Deepseek](https://deepseek.com/) | Only JSON object mode | | Chinese provider |
55+
| [Ollama](https://ollama.com/) | Varies | | Local LLMs |
56+
| [FastChat](https://github.com/lm-sys/FastChat) | Varies | | Local LLMs |
57+
| [Novita](https://novita.ai/) (🔥 **New**) | Only JSON object mode | | Cloud provider |
58+
| [Perplexity Sonar](https://www.perplexity.ai/) (🔥 **New**) | Only implied | | Search-based AI |
5059

5160
---
5261

53-
👉 For background information read an article about the lib/client on [Medium](https://medium.com/@0xbnd/openai-scala-client-is-out-d7577de934ad).
62+
👉 For background information how the project started read an article about the lib/client on [Medium](https://medium.com/@0xbnd/openai-scala-client-is-out-d7577de934ad).
5463

55-
Also try out our [Scala client for Pinecone vector database](https://github.com/cequence-io/pinecone-scala), or use both clients together! [This demo project](https://github.com/cequence-io/pinecone-openai-scala-demo) shows how to generate and store OpenAI embeddings (with `text-embedding-ada-002` model) into Pinecone and query them afterward. The OpenAI + Pinecone combo is commonly used for autonomous AI agents, such as [babyAGI](https://github.com/yoheinakajima/babyagi) and [AutoGPT](https://github.com/Significant-Gravitas/Auto-GPT).
64+
Also try out our [Scala client for Pinecone vector database](https://github.com/cequence-io/pinecone-scala), or use both clients together! [This demo project](https://github.com/cequence-io/pinecone-openai-scala-demo) shows how to generate and store OpenAI embeddings into Pinecone and query them afterward. The OpenAI + Pinecone combo is commonly used for autonomous AI agents, such as [babyAGI](https://github.com/yoheinakajima/babyagi) and [AutoGPT](https://github.com/Significant-Gravitas/Auto-GPT).
5665

5766
**✔️ Important**: this is a "community-maintained" library and, as such, has no relation to OpenAI company.
5867

@@ -154,56 +163,73 @@ Then you can obtain a service in one of the following ways.
154163
val service = VertexAIServiceFactory.asOpenAI()
155164
```
156165

157-
4. [Groq](https://wow.groq.com/) - requires `GROQ_API_KEY"`
166+
4. [Google Gemini](https://ai.google.dev/) - requires `openai-scala-google-gemini-client` lib and `GOOGLE_API_KEY`
167+
```scala
168+
val service = GeminiServiceFactory.asOpenAI()
169+
```
170+
171+
5. [Perplexity Sonar](https://www.perplexity.ai/) - requires `openai-scala-perplexity-client` lib and `SONAR_API_KEY`
172+
```scala
173+
val service = SonarServiceFactory.asOpenAI()
174+
```
175+
176+
6. [Novita](https://novita.ai/) - requires `NOVITA_API_KEY`
177+
```scala
178+
val service = OpenAIChatCompletionServiceFactory(ChatProviderSettings.novita)
179+
// or with streaming
180+
val service = OpenAIChatCompletionServiceFactory.withStreaming(ChatProviderSettings.novita)
181+
```
182+
183+
7. [Groq](https://wow.groq.com/) - requires `GROQ_API_KEY"`
158184
```scala
159185
val service = OpenAIChatCompletionServiceFactory(ChatProviderSettings.groq)
160186
// or with streaming
161187
val service = OpenAIChatCompletionServiceFactory.withStreaming(ChatProviderSettings.groq)
162188
```
163189

164-
5. [Grok](https://x.ai) - requires `GROK_API_KEY"`
190+
8. [Grok](https://x.ai) - requires `GROK_API_KEY"`
165191
```scala
166192
val service = OpenAIChatCompletionServiceFactory(ChatProviderSettings.grok)
167193
// or with streaming
168194
val service = OpenAIChatCompletionServiceFactory.withStreaming(ChatProviderSettings.grok)
169195
```
170196

171-
6. [Fireworks AI](https://fireworks.ai/) - requires `FIREWORKS_API_KEY"`
197+
9. [Fireworks AI](https://fireworks.ai/) - requires `FIREWORKS_API_KEY"`
172198
```scala
173199
val service = OpenAIChatCompletionServiceFactory(ChatProviderSettings.fireworks)
174200
// or with streaming
175201
val service = OpenAIChatCompletionServiceFactory.withStreaming(ChatProviderSettings.fireworks)
176202
```
177203

178-
7. [Octo AI](https://octo.ai/) - requires `OCTOAI_TOKEN`
204+
10. [Octo AI](https://octo.ai/) - requires `OCTOAI_TOKEN`
179205
```scala
180206
val service = OpenAIChatCompletionServiceFactory(ChatProviderSettings.octoML)
181207
// or with streaming
182208
val service = OpenAIChatCompletionServiceFactory.withStreaming(ChatProviderSettings.octoML)
183209
```
184210

185-
8. [TogetherAI](https://www.together.ai/) requires `TOGETHERAI_API_KEY`
211+
11. [TogetherAI](https://www.together.ai/) requires `TOGETHERAI_API_KEY`
186212
```scala
187213
val service = OpenAIChatCompletionServiceFactory(ChatProviderSettings.togetherAI)
188214
// or with streaming
189215
val service = OpenAIChatCompletionServiceFactory.withStreaming(ChatProviderSettings.togetherAI)
190216
```
191217

192-
9. [Cerebras](https://cerebras.ai/) requires `CEREBRAS_API_KEY`
218+
12. [Cerebras](https://cerebras.ai/) requires `CEREBRAS_API_KEY`
193219
```scala
194220
val service = OpenAIChatCompletionServiceFactory(ChatProviderSettings.cerebras)
195221
// or with streaming
196222
val service = OpenAIChatCompletionServiceFactory.withStreaming(ChatProviderSettings.cerebras)
197223
```
198224

199-
10. [Mistral](https://mistral.ai/) requires `MISTRAL_API_KEY`
225+
13. [Mistral](https://mistral.ai/) requires `MISTRAL_API_KEY`
200226
```scala
201227
val service = OpenAIChatCompletionServiceFactory(ChatProviderSettings.mistral)
202228
// or with streaming
203229
val service = OpenAIChatCompletionServiceFactory.withStreaming(ChatProviderSettings.mistral)
204230
```
205231

206-
11. [Ollama](https://ollama.com/)
232+
14. [Ollama](https://ollama.com/)
207233
```scala
208234
val service = OpenAIChatCompletionServiceFactory(
209235
coreUrl = "http://localhost:11434/v1/"
@@ -275,66 +301,6 @@ There is a new project [openai-scala-client-examples](./openai-examples/src/main
275301
)
276302
```
277303

278-
- Create completion
279-
```scala
280-
val text = """Extract the name and mailing address from this email:
281-
|Dear Kelly,
282-
|It was great to talk to you at the seminar. I thought Jane's talk was quite good.
283-
|Thank you for the book. Here's my address 2111 Ash Lane, Crestview CA 92002
284-
|Best,
285-
|Maya
286-
""".stripMargin
287-
288-
service.createCompletion(text).map(completion =>
289-
println(completion.choices.head.text)
290-
)
291-
```
292-
293-
- Create completion with a custom setting
294-
295-
```scala
296-
val text = """Extract the name and mailing address from this email:
297-
|Dear Kelly,
298-
|It was great to talk to you at the seminar. I thought Jane's talk was quite good.
299-
|Thank you for the book. Here's my address 2111 Ash Lane, Crestview CA 92002
300-
|Best,
301-
|Maya
302-
""".stripMargin
303-
304-
service.createCompletion(
305-
text,
306-
settings = CreateCompletionSettings(
307-
model = ModelId.gpt_4o,
308-
max_tokens = Some(1500),
309-
temperature = Some(0.9),
310-
presence_penalty = Some(0.2),
311-
frequency_penalty = Some(0.2)
312-
)
313-
).map(completion =>
314-
println(completion.choices.head.text)
315-
)
316-
```
317-
318-
- Create completion with streaming and a custom setting
319-
320-
```scala
321-
val source = service.createCompletionStreamed(
322-
prompt = "Write me a Shakespeare poem about two cats playing baseball in Russia using at least 2 pages",
323-
settings = CreateCompletionSettings(
324-
model = ModelId.text_davinci_003,
325-
max_tokens = Some(1500),
326-
temperature = Some(0.9),
327-
presence_penalty = Some(0.2),
328-
frequency_penalty = Some(0.2)
329-
)
330-
)
331-
332-
source.map(completion =>
333-
println(completion.choices.head.text)
334-
).runWith(Sink.ignore)
335-
```
336-
For this to work you need to use `OpenAIServiceStreamedFactory` from `openai-scala-client-stream` lib.
337-
338304
- Create chat completion
339305

340306
```scala
@@ -353,7 +319,7 @@ For this to work you need to use `OpenAIServiceStreamedFactory` from `openai-sca
353319
messages = messages,
354320
settings = createChatCompletionSettings
355321
).map { chatCompletion =>
356-
println(chatCompletion.choices.head.message.content)
322+
println(chatCompletion.contentHead)
357323
}
358324
```
359325

@@ -393,7 +359,7 @@ For this to work you need to use `OpenAIServiceStreamedFactory` from `openai-sca
393359
messages = messages,
394360
tools = tools,
395361
responseToolChoice = None, // means "auto"
396-
settings = CreateChatCompletionSettings(ModelId.gpt_3_5_turbo_1106)
362+
settings = CreateChatCompletionSettings(ModelId.gpt_4o)
397363
).map { response =>
398364
val chatFunCompletionMessage = response.choices.head.message
399365
val toolCalls = chatFunCompletionMessage.tool_calls.collect {
@@ -412,7 +378,7 @@ For this to work you need to use `OpenAIServiceStreamedFactory` from `openai-sca
412378
}
413379
```
414380

415-
- Create chat completion with json output
381+
- Create chat completion with json/structured output
416382

417383
```scala
418384
val messages = Seq(
@@ -448,14 +414,72 @@ For this to work you need to use `OpenAIServiceStreamedFactory` from `openai-sca
448414
service
449415
.createChatCompletion(
450416
messages = messages,
451-
settings = DefaultSettings.createJsonChatCompletion(jsonSchemaDef)
417+
settings = CreateChatCompletionSettings(
418+
model = ModelId.o3_mini,
419+
max_tokens = Some(1000),
420+
response_format_type = Some(ChatCompletionResponseFormatType.json_schema),
421+
jsonSchema = Some(jsonSchemaDef)
422+
)
452423
)
453424
.map { response =>
454-
val json = Json.parse(messageContent(response))
425+
val json = Json.parse(response.contentHead)
455426
println(Json.prettyPrint(json))
456427
}
457428
```
458429

430+
- Create chat completion with json/structured output using a handly implicit function (`createChatCompletionWithJSON[T]`) that handles JSON extraction with a potential repair, as well as deserialization to an object T.
431+
432+
```scala
433+
import io.cequence.openaiscala.service.OpenAIChatCompletionExtra._
434+
435+
...
436+
437+
service
438+
.createChatCompletionWithJSON[JsObject](
439+
messages = messages,
440+
settings = CreateChatCompletionSettings(
441+
model = ModelId.o3_mini,
442+
max_tokens = Some(1000),
443+
response_format_type = Some(ChatCompletionResponseFormatType.json_schema),
444+
jsonSchema = Some(jsonSchemaDef)
445+
)
446+
)
447+
.map { json =>
448+
println(Json.prettyPrint(json))
449+
}
450+
```
451+
452+
- Failover
453+
454+
```
455+
private val messages = Seq(
456+
SystemMessage("You are a helpful weather assistant."),
457+
UserMessage("What is the weather like in Norway?")
458+
)
459+
460+
service
461+
.createChatCompletionWithFailover(
462+
messages = messages,
463+
settings = CreateChatCompletionSettings(
464+
model = ModelId.o3_mini
465+
),
466+
failoverModels = Seq(ModelId.gpt_4_5_preview, ModelId.gpt_4o),
467+
retryOnAnyError = true,
468+
failureMessage = "Weather assistant failed to provide a response."
469+
)
470+
.map { response =>
471+
print(response.contentHead)
472+
}
473+
```
474+
- Failover with JSON/structred outuput
475+
476+
- Responses API (basic)
477+
478+
- Responses API (tool use)
479+
480+
481+
482+
459483
- Count expected used tokens before calling `createChatCompletions` or `createChatFunCompletions`, this helps you select proper model and reduce costs. This is an experimental feature and it may not work for all models. Requires `openai-scala-count-tokens` lib.
460484

461485
An example how to count message tokens:

0 commit comments

Comments
 (0)