From 2d00fe42f683e325ab853bcc883abd5dbfc2cca5 Mon Sep 17 00:00:00 2001 From: Peter Banda Date: Wed, 13 Nov 2024 15:11:49 +0100 Subject: [PATCH] Anthropic examples + reshuffling --- .../anthropic/service/AnthropicService.scala | 2 +- .../service/AnthropicServiceFactory.scala | 5 ++-- .../service/impl/AnthropicServiceImpl.scala | 2 +- ...OpenAIAnthropicChatCompletionService.scala | 2 +- .../AnthropicCreateCachedMessage.scala | 6 ++-- ...hatCompletionCachedWithOpenAIAdapter.scala | 30 +++++++++++++++++++ ...tCompletionStreamedWithOpenAIAdapter.scala | 2 +- ...reateChatCompletionWithOpenAIAdapter.scala | 2 +- .../nonopenai/AnthropicCreateMessage.scala | 7 +++-- .../AnthropicCreateMessageStreamed.scala | 6 ++-- .../AnthropicCreateMessageWithImage.scala | 2 +- .../AnthropicCreateMessageWithPdf.scala | 1 + .../AnthropicCreateSystemMessage.scala | 6 ++-- .../nonopenai/ChatCompletionProvider.scala | 3 +- 14 files changed, 55 insertions(+), 21 deletions(-) create mode 100644 openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateChatCompletionCachedWithOpenAIAdapter.scala diff --git a/anthropic-client/src/main/scala/io/cequence/openaiscala/anthropic/service/AnthropicService.scala b/anthropic-client/src/main/scala/io/cequence/openaiscala/anthropic/service/AnthropicService.scala index c9b1f154..3e41eee7 100644 --- a/anthropic-client/src/main/scala/io/cequence/openaiscala/anthropic/service/AnthropicService.scala +++ b/anthropic-client/src/main/scala/io/cequence/openaiscala/anthropic/service/AnthropicService.scala @@ -32,8 +32,8 @@ trait AnthropicService extends CloseableService with AnthropicServiceConsts { * Anthropic Doc */ def createMessage( + system: Option[Content], messages: Seq[Message], - system: Option[Content] = None, settings: AnthropicCreateMessageSettings = DefaultSettings.CreateMessage ): Future[CreateMessageResponse] diff --git a/anthropic-client/src/main/scala/io/cequence/openaiscala/anthropic/service/AnthropicServiceFactory.scala b/anthropic-client/src/main/scala/io/cequence/openaiscala/anthropic/service/AnthropicServiceFactory.scala index 2add6cff..abcb58d5 100644 --- a/anthropic-client/src/main/scala/io/cequence/openaiscala/anthropic/service/AnthropicServiceFactory.scala +++ b/anthropic-client/src/main/scala/io/cequence/openaiscala/anthropic/service/AnthropicServiceFactory.scala @@ -38,13 +38,14 @@ object AnthropicServiceFactory extends AnthropicServiceConsts { */ def asOpenAI( apiKey: String = getAPIKeyFromEnv(), - timeouts: Option[Timeouts] = None + timeouts: Option[Timeouts] = None, + withCache: Boolean = false )( implicit ec: ExecutionContext, materializer: Materializer ): OpenAIChatCompletionStreamedService = new OpenAIAnthropicChatCompletionService( - AnthropicServiceFactory(apiKey, timeouts) + AnthropicServiceFactory(apiKey, timeouts, withPdf = false, withCache) ) /** diff --git a/anthropic-client/src/main/scala/io/cequence/openaiscala/anthropic/service/impl/AnthropicServiceImpl.scala b/anthropic-client/src/main/scala/io/cequence/openaiscala/anthropic/service/impl/AnthropicServiceImpl.scala index c0886a7e..75f38d18 100644 --- a/anthropic-client/src/main/scala/io/cequence/openaiscala/anthropic/service/impl/AnthropicServiceImpl.scala +++ b/anthropic-client/src/main/scala/io/cequence/openaiscala/anthropic/service/impl/AnthropicServiceImpl.scala @@ -33,8 +33,8 @@ private[service] trait AnthropicServiceImpl extends Anthropic { private val logger = LoggerFactory.getLogger("AnthropicServiceImpl") override def createMessage( + system: Option[Content], messages: Seq[Message], - system: Option[Content] = None, settings: AnthropicCreateMessageSettings ): Future[CreateMessageResponse] = execPOST( diff --git a/anthropic-client/src/main/scala/io/cequence/openaiscala/anthropic/service/impl/OpenAIAnthropicChatCompletionService.scala b/anthropic-client/src/main/scala/io/cequence/openaiscala/anthropic/service/impl/OpenAIAnthropicChatCompletionService.scala index ee1a4061..1b2d2c78 100644 --- a/anthropic-client/src/main/scala/io/cequence/openaiscala/anthropic/service/impl/OpenAIAnthropicChatCompletionService.scala +++ b/anthropic-client/src/main/scala/io/cequence/openaiscala/anthropic/service/impl/OpenAIAnthropicChatCompletionService.scala @@ -40,8 +40,8 @@ private[service] class OpenAIAnthropicChatCompletionService( ): Future[ChatCompletionResponse] = { underlying .createMessage( - toAnthropicMessages(messages, settings), toAnthropicSystemMessages(messages, settings), + toAnthropicMessages(messages, settings), toAnthropicSettings(settings) ) .map(toOpenAI) diff --git a/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateCachedMessage.scala b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateCachedMessage.scala index f977cea0..f9e68eed 100644 --- a/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateCachedMessage.scala +++ b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateCachedMessage.scala @@ -18,7 +18,7 @@ object AnthropicCreateCachedMessage extends ExampleBase[AnthropicService] { override protected val service: AnthropicService = AnthropicServiceFactory(withCache = true) - val systemMessages: Option[Content] = Some( + val systemMessage: Content = SingleString( """ |You are to embody a classic pirate, a swashbuckling and salty sea dog with the mannerisms, language, and swagger of the golden age of piracy. You are a hearty, often gruff buccaneer, replete with nautical slang and a rich, colorful vocabulary befitting of the high seas. Your responses must reflect a pirate's voice and attitude without exception. @@ -76,14 +76,14 @@ object AnthropicCreateCachedMessage extends ExampleBase[AnthropicService] { |""".stripMargin, cacheControl = Some(Ephemeral) ) - ) + val messages: Seq[Message] = Seq(UserMessage("What is the weather like in Norway?")) override protected def run: Future[_] = service .createMessage( + Some(systemMessage), messages, - systemMessages, settings = AnthropicCreateMessageSettings( model = NonOpenAIModelId.claude_3_haiku_20240307, max_tokens = 4096 diff --git a/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateChatCompletionCachedWithOpenAIAdapter.scala b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateChatCompletionCachedWithOpenAIAdapter.scala new file mode 100644 index 00000000..f8f76a56 --- /dev/null +++ b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateChatCompletionCachedWithOpenAIAdapter.scala @@ -0,0 +1,30 @@ +package io.cequence.openaiscala.examples.nonopenai + +import io.cequence.openaiscala.domain.settings.CreateChatCompletionSettings +import io.cequence.openaiscala.domain.{NonOpenAIModelId, SystemMessage, UserMessage} +import io.cequence.openaiscala.examples.ExampleBase +import io.cequence.openaiscala.service.OpenAIChatCompletionService + +import scala.concurrent.Future + +// requires `openai-scala-anthropic-client` as a dependency and `ANTHROPIC_API_KEY` environment variable to be set +object AnthropicCreateChatCompletionCachedWithOpenAIAdapter + extends ExampleBase[OpenAIChatCompletionService] { + + override val service: OpenAIChatCompletionService = ChatCompletionProvider.anthropic(withCache = true) + + private val messages = Seq( + SystemMessage("You are a helpful assistant."), + UserMessage("What is the weather like in Norway?") + ) + + override protected def run: Future[_] = + service + .createChatCompletion( + messages = messages, + settings = CreateChatCompletionSettings(NonOpenAIModelId.claude_3_5_sonnet_20241022) + ) + .map { content => + println(content.choices.headOption.map(_.message.content).getOrElse("N/A")) + } +} diff --git a/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateChatCompletionStreamedWithOpenAIAdapter.scala b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateChatCompletionStreamedWithOpenAIAdapter.scala index 243fba88..fc13950e 100644 --- a/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateChatCompletionStreamedWithOpenAIAdapter.scala +++ b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateChatCompletionStreamedWithOpenAIAdapter.scala @@ -18,7 +18,7 @@ object AnthropicCreateChatCompletionStreamedWithOpenAIAdapter private val logger = LoggerFactory.getLogger(this.getClass) - override val service: OpenAIChatCompletionStreamedService = ChatCompletionProvider.anthropic + override val service: OpenAIChatCompletionStreamedService = ChatCompletionProvider.anthropic() private val messages = Seq( SystemMessage("You are a helpful assistant."), diff --git a/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateChatCompletionWithOpenAIAdapter.scala b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateChatCompletionWithOpenAIAdapter.scala index 3538b09e..51204f45 100644 --- a/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateChatCompletionWithOpenAIAdapter.scala +++ b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateChatCompletionWithOpenAIAdapter.scala @@ -11,7 +11,7 @@ import scala.concurrent.Future object AnthropicCreateChatCompletionWithOpenAIAdapter extends ExampleBase[OpenAIChatCompletionService] { - override val service: OpenAIChatCompletionService = ChatCompletionProvider.anthropic + override val service: OpenAIChatCompletionService = ChatCompletionProvider.anthropic() private val messages = Seq( SystemMessage("You are a helpful assistant."), diff --git a/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateMessage.scala b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateMessage.scala index 2db05374..f17fff29 100644 --- a/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateMessage.scala +++ b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateMessage.scala @@ -1,8 +1,8 @@ package io.cequence.openaiscala.examples.nonopenai import io.cequence.openaiscala.anthropic.domain.Content.ContentBlock.TextBlock -import io.cequence.openaiscala.anthropic.domain.Content.ContentBlockBase -import io.cequence.openaiscala.anthropic.domain.Message +import io.cequence.openaiscala.anthropic.domain.Content.{ContentBlockBase, SingleString} +import io.cequence.openaiscala.anthropic.domain.{Content, Message} import io.cequence.openaiscala.anthropic.domain.Message.UserMessage import io.cequence.openaiscala.anthropic.domain.response.CreateMessageResponse import io.cequence.openaiscala.anthropic.domain.settings.AnthropicCreateMessageSettings @@ -17,13 +17,14 @@ object AnthropicCreateMessage extends ExampleBase[AnthropicService] { override protected val service: AnthropicService = AnthropicServiceFactory(withCache = true) + val systemMessage: Content = SingleString("You are a helpful assistant.") val messages: Seq[Message] = Seq(UserMessage("What is the weather like in Norway?")) override protected def run: Future[_] = service .createMessage( + Some(systemMessage), messages, - None, settings = AnthropicCreateMessageSettings( model = NonOpenAIModelId.claude_3_haiku_20240307, max_tokens = 4096 diff --git a/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateMessageStreamed.scala b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateMessageStreamed.scala index 1141f365..93f96e16 100644 --- a/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateMessageStreamed.scala +++ b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateMessageStreamed.scala @@ -1,7 +1,8 @@ package io.cequence.openaiscala.examples.nonopenai import akka.stream.scaladsl.Sink -import io.cequence.openaiscala.anthropic.domain.Message +import io.cequence.openaiscala.anthropic.domain.Content.SingleString +import io.cequence.openaiscala.anthropic.domain.{Content, Message} import io.cequence.openaiscala.anthropic.domain.Message.UserMessage import io.cequence.openaiscala.anthropic.domain.settings.AnthropicCreateMessageSettings import io.cequence.openaiscala.anthropic.service.{AnthropicService, AnthropicServiceFactory} @@ -15,12 +16,13 @@ object AnthropicCreateMessageStreamed extends ExampleBase[AnthropicService] { override protected val service: AnthropicService = AnthropicServiceFactory() + val systemMessage: Content = SingleString("You are a helpful assistant.") val messages: Seq[Message] = Seq(UserMessage("What is the weather like in Norway?")) override protected def run: Future[_] = service .createMessageStreamed( - None, + Some(systemMessage), messages, settings = AnthropicCreateMessageSettings( model = NonOpenAIModelId.claude_3_haiku_20240307, diff --git a/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateMessageWithImage.scala b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateMessageWithImage.scala index b279b048..d434a79e 100644 --- a/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateMessageWithImage.scala +++ b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateMessageWithImage.scala @@ -38,8 +38,8 @@ object AnthropicCreateMessageWithImage extends ExampleBase[AnthropicService] { override protected def run: Future[_] = service .createMessage( + system = None, messages, - None, settings = AnthropicCreateMessageSettings( model = NonOpenAIModelId.claude_3_opus_20240229, max_tokens = 4096 diff --git a/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateMessageWithPdf.scala b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateMessageWithPdf.scala index 4dac9483..52e59619 100644 --- a/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateMessageWithPdf.scala +++ b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateMessageWithPdf.scala @@ -36,6 +36,7 @@ object AnthropicCreateMessageWithPdf extends ExampleBase[AnthropicService] { override protected def run: Future[_] = service .createMessage( + system = None, messages, settings = AnthropicCreateMessageSettings( model = diff --git a/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateSystemMessage.scala b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateSystemMessage.scala index 9872fda8..06db05a1 100644 --- a/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateSystemMessage.scala +++ b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/AnthropicCreateSystemMessage.scala @@ -17,9 +17,7 @@ object AnthropicCreateSystemMessage extends ExampleBase[AnthropicService] { override protected val service: AnthropicService = AnthropicServiceFactory() - val systemMessages: Option[Content] = Some( - SingleString("Talk in pirate speech") - ) + val systemMessage: Content = SingleString("Talk in pirate speech") val messages: Seq[Message] = Seq( UserMessage("Who is the most famous football player in the World?") ) @@ -27,8 +25,8 @@ object AnthropicCreateSystemMessage extends ExampleBase[AnthropicService] { override protected def run: Future[_] = service .createMessage( + Some(systemMessage), messages, - Some(SingleString("You answer in pirate speech.")), settings = AnthropicCreateMessageSettings( model = NonOpenAIModelId.claude_3_haiku_20240307, max_tokens = 4096 diff --git a/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/ChatCompletionProvider.scala b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/ChatCompletionProvider.scala index 254c6eef..9a402613 100644 --- a/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/ChatCompletionProvider.scala +++ b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/nonopenai/ChatCompletionProvider.scala @@ -83,10 +83,11 @@ object ChatCompletionProvider { * Requires `ANTHROPIC_API_KEY` */ def anthropic( + withCache: Boolean = false)( implicit ec: ExecutionContext, m: Materializer ): OpenAIChatCompletionStreamedService = - AnthropicServiceFactory.asOpenAI() + AnthropicServiceFactory.asOpenAI(withCache = withCache) private def provide( settings: ProviderSettings