Skip to content

Commit 23aa3eb

Browse files
committed
README - adapters usage
1 parent 90be46f commit 23aa3eb

File tree

1 file changed

+82
-40
lines changed

1 file changed

+82
-40
lines changed

README.md

Lines changed: 82 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Also, we aimed the lib to be self-contained with the fewest dependencies possibl
3333
- [Ollama](https://ollama.com/) - runs locally, serves as an umbrella for open-source LLMs including LLaMA3, dbrx, and Command-R
3434
- [FastChat](https://github.com/lm-sys/FastChat) - runs locally, serves as an umbrella for open-source LLMs such as Vicuna, Alpaca, LLaMA2, and FastChat-T5
3535

36-
See [examples](https://github.com/cequence-io/openai-scala-client/tree/master/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai) for more details.
36+
See [examples](./openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai) for more details.
3737

3838
---
3939

@@ -176,7 +176,7 @@ Then you can obtain a service in one of the following ways.
176176
val service: OpenAIStreamedService = OpenAIServiceFactory.withStreaming()
177177
```
178178

179-
for similarly for a chat-completion service
179+
similarly for a chat-completion service
180180

181181
```scala
182182
import io.cequence.openaiscala.service.OpenAIStreamedServiceImplicits._
@@ -187,7 +187,7 @@ for similarly for a chat-completion service
187187
)
188188
```
189189

190-
or if only streaming is required
190+
or only if streaming is required
191191

192192
```scala
193193
val service: OpenAIChatCompletionStreamedServiceExtra =
@@ -208,9 +208,8 @@ or if only streaming is required
208208
**II. Calling functions**
209209

210210
Full documentation of each call with its respective inputs and settings is provided in [OpenAIService](./openai-core/src/main/scala/io/cequence/openaiscala/service/OpenAIService.scala). Since all the calls are async they return responses wrapped in `Future`.
211-
🔥 **New**: There is a new project [openai-scala-client-examples](./openai-examples/src/main/scala/io/cequence/openaiscala/examples) where you can find a lot of ready-to-use examples!
212211

213-
Examples:
212+
🔥 **New**: There is a new project [openai-scala-client-examples](./openai-examples/src/main/scala/io/cequence/openaiscala/examples) where you can find a lot of ready-to-use examples!
214213

215214
- List models
216215

@@ -384,50 +383,63 @@ class MyCompletionService extends OpenAICountTokensHelper {
384383

385384
---
386385

387-
**III. Using multiple services**
386+
**III. Using adapters**
387+
388+
Adapters for OpenAI services (chat completion, core, or full) are provided by [OpenAIServiceAdapters](./openai-core/src/main/scala/io/cequence/openaiscala/service/adapter/OpenAIServiceAdapters). The adapters are used to distribute the load between multiple services, retry on transient errors, route, or provide additional functionality. See [examples](./openai-examples/src/main/scala/io/cequence/openaiscala/examples/adapter) for more details.
389+
Note that adapters can be arbitrarily combined/stacked.
388390

389-
- Load distribution with `OpenAIMultiServiceAdapter` - _round robin_ (_rotation_) type
391+
- **Round robin** load distribution
390392

391393
```scala
394+
val adapters = OpenAIServiceAdapters.forFullService
395+
392396
val service1 = OpenAIServiceFactory("your-api-key1")
393397
val service2 = OpenAIServiceFactory("your-api-key2")
394-
val service3 = OpenAIServiceFactory("your-api-key3")
395-
396-
val service = OpenAIMultiServiceAdapter.ofRoundRobinType(service1, service2, service3)
397398

398-
service.listModels.map { models =>
399-
models.foreach(println)
400-
service.close()
401-
}
399+
val service = adapters.roundRobin(service1, service2)
402400
```
403401

404-
- Load distribution with `OpenAIMultiServiceAdapter` - _random order_ type
402+
- **Random order** load distribution
405403

406404
```scala
405+
val adapters = OpenAIServiceAdapters.forFullService
406+
407407
val service1 = OpenAIServiceFactory("your-api-key1")
408408
val service2 = OpenAIServiceFactory("your-api-key2")
409-
val service3 = OpenAIServiceFactory("your-api-key3")
410409

411-
val service = OpenAIMultiServiceAdapter.ofRandomOrderType(service1, service2, service3)
410+
val service = adapters.randomOrder(service1, service2)
411+
```
412+
413+
- **Logging** function calls
412414

413-
service.listModels.map { models =>
414-
models.foreach(println)
415-
service.close()
416-
}
415+
```scala
416+
val adapters = OpenAIServiceAdapters.forFullService
417+
418+
val rawService = OpenAIServiceFactory()
419+
420+
val service = adapters.log(
421+
rawService,
422+
"openAIService",
423+
logger.log
424+
)
417425
```
418426

419-
- Create completion and retry on transient errors (e.g. rate limit error)
427+
- **Retry** on transient errors (e.g. rate limit error)
428+
420429
```scala
421-
import akka.actor.{ActorSystem, Scheduler}
422-
import io.cequence.openaiscala.RetryHelpers
423-
import io.cequence.openaiscala.RetryHelpers.RetrySettings
424-
import io.cequence.openaiscala.domain.{ChatRole, MessageSpec}
425-
import io.cequence.openaiscala.service.{OpenAIService, OpenAIServiceFactory}
430+
val adapters = OpenAIServiceAdapters.forFullService
431+
432+
implicit val retrySettings: RetrySettings = RetrySettings(maxRetries = 10).constantInterval(10.seconds)
426433

427-
import javax.inject.Inject
428-
import scala.concurrent.duration.DurationInt
429-
import scala.concurrent.{ExecutionContext, Future}
434+
val service = adapters.retry(
435+
OpenAIServiceFactory(),
436+
Some(println(_)) // simple logging
437+
)
438+
```
430439

440+
- **Retry** on a specific function using [RetryHelpers](./openai-core/src/main/scala/io/cequence/openaiscala/RetryHelpers.scala) directly
441+
442+
```scala
431443
class MyCompletionService @Inject() (
432444
val actorSystem: ActorSystem,
433445
implicit val ec: ExecutionContext,
@@ -449,20 +461,50 @@ class MyCompletionService @Inject() (
449461
}
450462
```
451463

452-
- Retries with `OpenAIRetryServiceAdapter`
464+
- **Route** chat completion calls based on models
453465

454466
```scala
455-
val serviceAux = ... // your service
467+
val adapters = OpenAIServiceAdapters.forFullService
456468

457-
implicit val retrySettings: RetrySettings =
458-
RetrySettings(maxRetries = 10).constantInterval(10.seconds)
459-
// wrap it with the retry adapter
460-
val service = OpenAIRetryServiceAdapter(serviceAux)
469+
// OctoAI
470+
val octoMLService = OpenAIChatCompletionServiceFactory(
471+
coreUrl = "https://text.octoai.run/v1/",
472+
authHeaders = Seq(("Authorization", s"Bearer ${sys.env("OCTOAI_TOKEN")}"))
473+
)
461474

462-
service.listModels.map { models =>
463-
models.foreach(println)
464-
service.close
465-
}
475+
476+
// Anthropic
477+
val anthropicService = AnthropicServiceFactory.asOpenAI()
478+
479+
// OpenAI
480+
val openAIService = OpenAIServiceFactory()
481+
482+
val service: OpenAIService =
483+
adapters.chatCompletionRouter(
484+
// OpenAI service is default so no need to specify its models here
485+
serviceModels = Map(
486+
octoMLService -> Seq(NonOpenAIModelId.mixtral_8x22b_instruct),
487+
anthropicService -> Seq(
488+
NonOpenAIModelId.claude_2_1,
489+
NonOpenAIModelId.claude_3_opus_20240229,
490+
NonOpenAIModelId.claude_3_haiku_20240307
491+
)
492+
),
493+
openAIService
494+
)
495+
```
496+
497+
- **Chat-to-completion** adapter
498+
499+
```scala
500+
val adapters = OpenAIServiceAdapters.forCoreService
501+
502+
val service = adapters.chatToCompletion(
503+
OpenAICoreServiceFactory(
504+
coreUrl = "https://api.fireworks.ai/inference/v1/",
505+
authHeaders = Seq(("Authorization", s"Bearer ${sys.env("FIREWORKS_API_KEY")}"))
506+
)
507+
)
466508
```
467509

468510
## FAQ 🤔

0 commit comments

Comments
 (0)