foobara-ai 0.0.11 → 0.0.13

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bc15c8346f2afa89586829dba2c16741e63838012af8120b790018941cda79b4
4
- data.tar.gz: 942a26bfe13bdc7d51deeb800bcbdd6d7ee1b7ccbe696ff26b233ff27bbbe256
3
+ metadata.gz: f95051eb1f729d1c5d7d9222c057bb9b3482b943514cec30169d873e48357db9
4
+ data.tar.gz: 02d3b9173387a1dc0e75b711604fb437eb4139e65b6143244edb4d1789fe6a53
5
5
  SHA512:
6
- metadata.gz: 8664935bc503f4531bdbe7a801e3c6d7968cf25a1a1b2ac2cf7a1c6edef9c06c51119499fe8a3e59e41d3afda1662766049cd49a43d1c0d3fc8d581e8877b9d5
7
- data.tar.gz: 10bb054e4e6d56c9fa69e30aa5b18f49bf660dd6795f51d03bf362b3efdabbca9a62810a2958eb3eaebaa897225b0900aa494da7787c255248cacfb357bca84a
6
+ metadata.gz: e023eadbdc74d8ba0625cb3ad69dcdb19b024412cbaadcf79e07b5a1ebcd9854921bfcc67f796441070a6b2a7a832803abdd4cc4755a038a5049e59895257841
7
+ data.tar.gz: 37316615e1c52161e88b79a864ef20eb5d7487544f478f7703ba4168ceb703a7762f348921378c64b52b94103886ffce94a0ee2c5531466826f2e3aaaa850c05
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## [0.0.13] - 2025-06-27
2
+
3
+ - Add GenerateChatCompletion command
4
+
5
+ ## [0.0.12] - 2025-05-27
6
+
7
+ - Do not load service models in parallel due to undiagnosed race condition somewhere
8
+
1
9
  ## [0.0.11] - 2025-03-06
2
10
 
3
11
  - Fix bug that broke ListModels
@@ -43,7 +43,10 @@ module Foobara
43
43
  inputs[:instructions] = instructions
44
44
  end
45
45
 
46
- self.answer = run_mapped_subcommand!(ai_command, inputs)
46
+ inputs = domain_map!(inputs, to: ai_command)
47
+ answer = run_subcommand!(ai_command, inputs)
48
+
49
+ self.answer = domain_map!(answer, to: :string)
47
50
  end
48
51
  end
49
52
  end
@@ -0,0 +1,56 @@
1
+ require_relative "../../types/model_enum"
2
+
3
+ module Foobara
4
+ module Ai
5
+ module AnswerBot
6
+ module DomainMappers
7
+ module AnthropicApi
8
+ class ChatToCreateMessage < Foobara::DomainMapper
9
+ from do
10
+ chat Types::Chat, :required
11
+ temperature :float
12
+ model :model_enum
13
+ end
14
+ to Foobara::Ai::AnthropicApi::CreateMessage
15
+
16
+ def map
17
+ system_messages, non_system_messages = chat.messages.partition(&:system?)
18
+
19
+ inputs = {
20
+ messages: non_system_messages.map do |message|
21
+ { role: message.role, content: message.content }
22
+ end
23
+ }
24
+
25
+ unless system_messages.empty?
26
+ inputs[:system] = system_messages.map(&:content).join("\n")
27
+ end
28
+
29
+ if temperature
30
+ inputs[:temperature] = temperature
31
+ end
32
+
33
+ if model
34
+ inputs[:model] = model
35
+ end
36
+
37
+ inputs
38
+ end
39
+
40
+ def chat
41
+ from[:chat]
42
+ end
43
+
44
+ def temperature
45
+ from[:temperature]
46
+ end
47
+
48
+ def model
49
+ from[:model]
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,23 @@
1
+ module Foobara
2
+ module Ai
3
+ module AnswerBot
4
+ module DomainMappers
5
+ module AnthropicApi
6
+ class MessageResultToMessage < Foobara::DomainMapper
7
+ from Foobara::Ai::AnthropicApi::Types::MessageResult
8
+ to Types::Message
9
+
10
+ def map
11
+ {
12
+ content: message_result.content.last.text,
13
+ role: message_result.role
14
+ }
15
+ end
16
+
17
+ alias message_result from
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ module Foobara
2
+ module Ai
3
+ module AnswerBot
4
+ module DomainMappers
5
+ module OllamaApi
6
+ class ChatCompletionResultToMessage < Foobara::DomainMapper
7
+ from Foobara::Ai::OllamaApi::Types::ChatCompletion
8
+ to Types::Message
9
+
10
+ def map
11
+ message = chat_completion.message
12
+
13
+ {
14
+ content: message.content,
15
+ role: message.role
16
+ }
17
+ end
18
+
19
+ alias chat_completion from
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,52 @@
1
+ require_relative "../../types/model_enum"
2
+
3
+ module Foobara
4
+ module Ai
5
+ module AnswerBot
6
+ module DomainMappers
7
+ module OllamaApi
8
+ class ChatToGenerateChatCompletion < Foobara::DomainMapper
9
+ from do
10
+ chat Types::Chat, :required
11
+ temperature :float
12
+ model :model_enum
13
+ end
14
+ to Foobara::Ai::OllamaApi::GenerateChatCompletion
15
+
16
+ def map
17
+ inputs = {
18
+ messages: chat.messages.map do |message|
19
+ { role: message.role, content: message.content }
20
+ end
21
+ }
22
+
23
+ if temperature
24
+ inputs[:options] = {
25
+ temperature:
26
+ }
27
+ end
28
+
29
+ if model
30
+ inputs[:model] = model
31
+ end
32
+
33
+ inputs
34
+ end
35
+
36
+ def chat
37
+ from[:chat]
38
+ end
39
+
40
+ def temperature
41
+ from[:temperature]
42
+ end
43
+
44
+ def model
45
+ from[:model]
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,25 @@
1
+ module Foobara
2
+ module Ai
3
+ module AnswerBot
4
+ module DomainMappers
5
+ module OpenAiApi
6
+ class ChatCompletionResultToMessage < Foobara::DomainMapper
7
+ from Foobara::Ai::OpenAiApi::Types::ChatCompletion
8
+ to Types::Message
9
+
10
+ def map
11
+ message = chat_completion.choices.first.message
12
+
13
+ {
14
+ content: message.content,
15
+ role: message.role
16
+ }
17
+ end
18
+
19
+ alias chat_completion from
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,50 @@
1
+ require_relative "../../types/model_enum"
2
+
3
+ module Foobara
4
+ module Ai
5
+ module AnswerBot
6
+ module DomainMappers
7
+ module OpenAiApi
8
+ class ChatToGenerateChatCompletion < Foobara::DomainMapper
9
+ from do
10
+ chat Types::Chat, :required
11
+ temperature :float
12
+ model :model_enum
13
+ end
14
+ to Foobara::Ai::OpenAiApi::CreateChatCompletion
15
+
16
+ def map
17
+ inputs = {
18
+ messages: chat.messages.map do |message|
19
+ { role: message.role, content: message.content }
20
+ end
21
+ }
22
+
23
+ if temperature
24
+ inputs[:temperature] = temperature
25
+ end
26
+
27
+ if model
28
+ inputs[:model] = model
29
+ end
30
+
31
+ inputs
32
+ end
33
+
34
+ def chat
35
+ from[:chat]
36
+ end
37
+
38
+ def temperature
39
+ from[:temperature]
40
+ end
41
+
42
+ def model
43
+ from[:model]
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,49 @@
1
+ module Foobara
2
+ module Ai
3
+ module AnswerBot
4
+ class GenerateNextMessage < Foobara::Command
5
+ description "Takes a chat and generates the next message using the model of your choice."
6
+
7
+ inputs do
8
+ chat Types::Chat, :required
9
+ service :service_enum, "If two services expose the same model, you can specify which one to use."
10
+ model :model_enum, default: "claude-3-7-sonnet-20250219", description: "The model to use."
11
+ temperature :float
12
+ end
13
+
14
+ result Types::Message
15
+
16
+ AI_SERVICES.each_key do |service|
17
+ command = Foobara::Ai::AnswerBot::DomainMappers::ServiceToChatCompletionCommand.map!(service)
18
+ depends_on command
19
+ end
20
+
21
+ def execute
22
+ determine_ai_service
23
+ determine_ai_command
24
+ run_ai_service
25
+
26
+ next_message
27
+ end
28
+
29
+ attr_accessor :ai_command, :response, :ai_service, :next_message
30
+
31
+ def determine_ai_service
32
+ self.ai_service = service || domain_map!(model, from: :model_enum)
33
+ end
34
+
35
+ def determine_ai_command
36
+ self.ai_command = Foobara::Ai::AnswerBot::DomainMappers::ServiceToChatCompletionCommand.map!(ai_service)
37
+ end
38
+
39
+ def run_ai_service
40
+ inputs = { chat:, temperature:, model: }
41
+ inputs = domain_map!(inputs, to: ai_command)
42
+ next_message = run_subcommand!(ai_command, inputs)
43
+
44
+ self.next_message = domain_map!(next_message, to: Types::Message)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,13 @@
1
+ module Foobara
2
+ module Ai
3
+ module AnswerBot
4
+ module Types
5
+ class Chat < Foobara::Model
6
+ attributes do
7
+ messages [Message]
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+ module Foobara
2
+ module Ai
3
+ module AnswerBot
4
+ module Types
5
+ class Message < Foobara::Model
6
+ attributes do
7
+ role :symbol, one_of: [:assistant, :user, :system]
8
+ content :string
9
+ end
10
+
11
+ def system?
12
+ role == :system
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -5,16 +5,27 @@ module Foobara
5
5
  module Ai
6
6
  module AnswerBot
7
7
  module Types
8
- threads = AI_SERVICES.keys.map do |service|
9
- Thread.new do
10
- service_models = AnswerBot.foobara_domain_map!(service).run!
11
- service_models.map do |model|
12
- AnswerBot.foobara_domain_map!(model, to: :string)
13
- end
8
+ models = []
9
+ AI_SERVICES.each_key do |service|
10
+ service_models = AnswerBot.foobara_domain_map!(service).run!
11
+ service_models.map do |model|
12
+ models << AnswerBot.foobara_domain_map!(model, to: :string)
14
13
  end
15
14
  end
16
15
 
17
- models = threads.each(&:join).map(&:value).flatten
16
+ # Doing this in a threaded fashion creates a race condition somewhere for some unidentified reason
17
+ # so commenting this all out for now.
18
+ #
19
+ # threads = AI_SERVICES.keys.map do |service|
20
+ # Thread.new do
21
+ # service_models = AnswerBot.foobara_domain_map!(service).run!
22
+ # service_models.map do |model|
23
+ # AnswerBot.foobara_domain_map!(model, to: :string)
24
+ # end
25
+ # end
26
+ # end
27
+ #
28
+ # models = threads.each(&:join).map(&:value).flatten
18
29
 
19
30
  unless models.uniq == models
20
31
  # :nocov:
@@ -2,10 +2,10 @@ module Foobara
2
2
  module Ai
3
3
  module AnswerBot
4
4
  module Types
5
- services = %w[
6
- open-ai
7
- anthropic
8
- ollama
5
+ services = [
6
+ "open-ai",
7
+ "anthropic",
8
+ "ollama"
9
9
  ]
10
10
 
11
11
  ServiceEnum = Foobara::Enumerated.make_module(services)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foobara-ai
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 0.0.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miles Georgi
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-03-06 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  email:
13
13
  - azimux@gmail.com
@@ -21,22 +21,31 @@ files:
21
21
  - README.md
22
22
  - lib/foobara/ai.rb
23
23
  - src/foobara/ai/answer_bot/ask.rb
24
+ - src/foobara/ai/answer_bot/domain_mappers/anthropic_api/chat_to_create_message.rb
24
25
  - src/foobara/ai/answer_bot/domain_mappers/anthropic_api/message_result_to_answer.rb
26
+ - src/foobara/ai/answer_bot/domain_mappers/anthropic_api/message_result_to_message.rb
25
27
  - src/foobara/ai/answer_bot/domain_mappers/anthropic_api/model_to_foobara_model.rb
26
28
  - src/foobara/ai/answer_bot/domain_mappers/anthropic_api/model_to_model_enum_string.rb
27
29
  - src/foobara/ai/answer_bot/domain_mappers/anthropic_api/question_to_create_message.rb
28
30
  - src/foobara/ai/answer_bot/domain_mappers/model_to_ai_service.rb
31
+ - src/foobara/ai/answer_bot/domain_mappers/ollama_api/chat_completion_result_to_message.rb
29
32
  - src/foobara/ai/answer_bot/domain_mappers/ollama_api/chat_completion_to_answer.rb
33
+ - src/foobara/ai/answer_bot/domain_mappers/ollama_api/chat_to_generate_chat_completion.rb
30
34
  - src/foobara/ai/answer_bot/domain_mappers/ollama_api/model_to_foobara_model.rb
31
35
  - src/foobara/ai/answer_bot/domain_mappers/ollama_api/model_to_model_enum_string.rb
32
36
  - src/foobara/ai/answer_bot/domain_mappers/ollama_api/question_to_generate_chat_completion.rb
37
+ - src/foobara/ai/answer_bot/domain_mappers/open_ai_api/chat_completion_result_to_message.rb
33
38
  - src/foobara/ai/answer_bot/domain_mappers/open_ai_api/chat_completion_to_answer.rb
39
+ - src/foobara/ai/answer_bot/domain_mappers/open_ai_api/chat_to_generate_chat_completion.rb
34
40
  - src/foobara/ai/answer_bot/domain_mappers/open_ai_api/model_to_foobara_model.rb
35
41
  - src/foobara/ai/answer_bot/domain_mappers/open_ai_api/model_to_model_enum_string.rb
36
42
  - src/foobara/ai/answer_bot/domain_mappers/open_ai_api/question_to_create_chat_completion.rb
37
43
  - src/foobara/ai/answer_bot/domain_mappers/service_to_command.rb
38
44
  - src/foobara/ai/answer_bot/domain_mappers/service_to_list_models_command.rb
45
+ - src/foobara/ai/answer_bot/generate_next_message.rb
39
46
  - src/foobara/ai/answer_bot/list_models.rb
47
+ - src/foobara/ai/answer_bot/types/chat.rb
48
+ - src/foobara/ai/answer_bot/types/message.rb
40
49
  - src/foobara/ai/answer_bot/types/model.rb
41
50
  - src/foobara/ai/answer_bot/types/model_enum.rb
42
51
  - src/foobara/ai/answer_bot/types/service_enum.rb
@@ -62,7 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
62
71
  - !ruby/object:Gem::Version
63
72
  version: '0'
64
73
  requirements: []
65
- rubygems_version: 3.6.5
74
+ rubygems_version: 3.6.9
66
75
  specification_version: 4
67
76
  summary: No description. Add one.
68
77
  test_files: []