roseflow 0.0.1 → 0.1.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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.standard.yml +3 -1
  3. data/CHANGELOG.md +2 -2
  4. data/Gemfile +2 -0
  5. data/examples/github-repo-chat/lib/actions/clone_and_load_repository.rb +52 -0
  6. data/examples/github-repo-chat/lib/actions/create_prompt.rb +15 -0
  7. data/examples/github-repo-chat/lib/actions/embed_repository.rb +35 -0
  8. data/examples/github-repo-chat/lib/actions/initialize_vector_store.rb +40 -0
  9. data/examples/github-repo-chat/lib/actions/interact_with_model.rb +29 -0
  10. data/examples/github-repo-chat/lib/actions/load_documents_to_database.rb +0 -0
  11. data/examples/github-repo-chat/lib/actions/split_files_to_documents.rb +55 -0
  12. data/examples/github-repo-chat/lib/document_database.rb +0 -0
  13. data/examples/github-repo-chat/lib/github_chat_prompt.rb +24 -0
  14. data/examples/github-repo-chat/lib/github_repository_chat.rb +12 -0
  15. data/examples/github-repo-chat/lib/interactions/ask_llm.rb +31 -0
  16. data/examples/github-repo-chat/lib/interactions/github_repository_chat.rb +36 -0
  17. data/examples/github-repo-chat/lib/interactions/load_files_to_document_database.rb +18 -0
  18. data/examples/github-repo-chat/lib/interactions/load_repository.rb +20 -0
  19. data/examples/github-repo-chat/lib/interactions/prepare_vector_store.rb +21 -0
  20. data/examples/github-repo-chat/lib/repository.rb +9 -0
  21. data/examples/github-repo-chat/lib/repository_file.rb +31 -0
  22. data/examples/github-repo-chat/spec/actions/clone_and_load_repository_spec.rb +28 -0
  23. data/examples/github-repo-chat/spec/actions/embed_repository_spec.rb +24 -0
  24. data/examples/github-repo-chat/spec/actions/initialize_vector_store_spec.rb +20 -0
  25. data/examples/github-repo-chat/spec/actions/load_files_to_document_database_spec.rb +23 -0
  26. data/examples/github-repo-chat/spec/fixtures/ulid-ruby.zip +0 -0
  27. data/examples/github-repo-chat/spec/github_repository_chat_spec.rb +16 -0
  28. data/examples/github-repo-chat/spec/interactions/prepare_vector_store_spec.rb +4 -0
  29. data/examples/github-repo-chat/spec/spec_helper.rb +12 -0
  30. data/lib/roseflow/action.rb +13 -0
  31. data/lib/roseflow/actions/ai/resolve_model.rb +27 -0
  32. data/lib/roseflow/actions/ai/resolve_provider.rb +31 -0
  33. data/lib/roseflow/ai/model.rb +19 -0
  34. data/lib/roseflow/ai/provider.rb +30 -0
  35. data/lib/roseflow/chat/dialogue.rb +80 -0
  36. data/lib/roseflow/chat/exchange.rb +12 -0
  37. data/lib/roseflow/chat/message.rb +39 -0
  38. data/lib/roseflow/chat/personality.rb +10 -0
  39. data/lib/roseflow/embeddings/embedding.rb +26 -0
  40. data/lib/roseflow/finite_machine.rb +298 -0
  41. data/lib/roseflow/interaction/with_http_api.rb +10 -0
  42. data/lib/roseflow/interaction.rb +14 -0
  43. data/lib/roseflow/interaction_context.rb +10 -0
  44. data/lib/roseflow/interactions/ai/initialize_llm.rb +26 -0
  45. data/lib/roseflow/primitives/vector.rb +19 -0
  46. data/lib/roseflow/prompt.rb +17 -0
  47. data/lib/roseflow/text/completion.rb +16 -0
  48. data/lib/roseflow/text/recursive_character_splitter.rb +43 -0
  49. data/lib/roseflow/text/sentence_splitter.rb +42 -0
  50. data/lib/roseflow/text/splitter.rb +18 -0
  51. data/lib/roseflow/text/tokenized_text.rb +20 -0
  52. data/lib/roseflow/text/word_splitter.rb +14 -0
  53. data/lib/roseflow/tokenizer.rb +13 -0
  54. data/lib/roseflow/types.rb +9 -0
  55. data/lib/roseflow/vector_stores/base.rb +39 -0
  56. data/lib/roseflow/vector_stores/hnsw.proto +18 -0
  57. data/lib/roseflow/vector_stores/hnsw_memory_store.rb +442 -0
  58. data/lib/roseflow/vector_stores/hnsw_pb.rb +27 -0
  59. data/lib/roseflow/vector_stores/type/vector.rb +38 -0
  60. data/lib/roseflow/vector_stores/vector.rb +19 -0
  61. data/lib/roseflow/version.rb +12 -1
  62. data/lib/roseflow.rb +10 -1
  63. data/roseflow.gemspec +53 -0
  64. metadata +274 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5332eb49fa51fee8d237a7201b36694c5a09851e2bfab8cbc2f2f53a941f6ff1
4
- data.tar.gz: 44b0b895bf1000c3cecf77c5e09f00001a03bd9600232bc52bf75508f858d0ff
3
+ metadata.gz: b8b7f5c7688debc9bb3b2e804dfcc45671ca670cc3114fabeb8ceff1169b5098
4
+ data.tar.gz: cb9d12161f611bf90738c2459e0700698e3443a8fe7b0d3f98c8d6268b315c0f
5
5
  SHA512:
6
- metadata.gz: f5ee95217a4ea9e7af38942d003299354cf47ddd77af2aaca7d0fc3bc8a9047d76dd95a8c7b390305858285ad40cc9c0ac3d985ce6ff1533a759a09a9a2ed98e
7
- data.tar.gz: '08c4e29bb46765709f0698a9b1212cfb9e0d1a636bf2bcf9feac03d7da4d683c99e83bea3c23eb988cd6a02fb2e7e153bc88a17d2774c344b75520b1fd85dbea'
6
+ metadata.gz: dcb00909e24bf283c2f901f680e86995bbe0fe5060eb9fb243e1e6435c1b1c39735ae918609eb89f81a40c48196861e4a2de8881f5c1c71b86e4fb996adff2af
7
+ data.tar.gz: 89415e4d06ef6b421da5be3a9a214752dfaa959258082ad09c9321d9f9d47703ea8d17ac7eaf26da9bb18ca4b291e1ca982c5f0a98b4c86b324f697b25446f20
data/.standard.yml CHANGED
@@ -1,3 +1,5 @@
1
1
  # For available configuration options, see:
2
2
  # https://github.com/testdouble/standard
3
- ruby_version: 2.6
3
+ ruby_version: 3.2
4
+ ignore:
5
+ - "Gemfile"
data/CHANGELOG.md CHANGED
@@ -1,5 +1,5 @@
1
- ## [Unreleased]
1
+ ## [0.1.0] - 2023-05-10
2
2
 
3
- ## [0.1.0] - 2023-04-22
3
+ "La petite fille de la mer"
4
4
 
5
5
  - Initial release
data/Gemfile CHANGED
@@ -8,3 +8,5 @@ gemspec
8
8
  gem "rake", "~> 13.0"
9
9
  gem "rspec", "~> 3.0"
10
10
  gem "standard", "~> 1.3"
11
+
12
+ eval_gemfile "Gemfile.local" if File.exist?("Gemfile.local")
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This class represents an action that clones and loads a repository from a
4
+ # given URL. The action expects a repository URL as input and returns a
5
+ # Repository object containing the repository's data.
6
+ #
7
+ # Example usage:
8
+ # repository = Actions::CloneAndLoadRepository.call(
9
+ # repository_url: "https://github.com/ljuti/roseflow.git"
10
+ # )
11
+
12
+ require "roseflow/action"
13
+ require "rugged"
14
+ require "tmpdir"
15
+
16
+ require_relative "../repository"
17
+
18
+ class Actions::CloneAndLoadRepository
19
+ extend Roseflow::Action
20
+
21
+ # Define the inputs and outputs of the action
22
+ expects :repository_url # Input: The URL of the repository to clone
23
+ promises :repository # Output: a Repository object
24
+
25
+ executed do |ctx|
26
+ ctx[:repository] = clone_repository(ctx.repository_url)
27
+ end
28
+
29
+ # Clone a repository from a given URL, load its data, and create a Repository object.
30
+ #
31
+ # @param repository_url [String] The URL of the repository to clone
32
+ # @return [Repository] A Repository object containing the repository's data
33
+ def self.clone_repository(repository_url)
34
+ files = {}
35
+ Dir.mktmpdir do |dir|
36
+ # Clone the repository into a temporary directory
37
+ repository = Rugged::Repository.clone_at(repository_url, dir)
38
+ head_commit = repository.head.target
39
+ tree = repository.lookup(head_commit.tree.oid)
40
+
41
+ # Collect the content of each file in the repository
42
+ tree.walk_blobs(:preorder) do |root, entry|
43
+ file_path = "#{root}#{entry[:name]}"
44
+ files[file_path] = repository.lookup(entry[:oid]).content
45
+ end
46
+
47
+ # Extract the repository's name from the URL and create a Repository object
48
+ name = repository_url.split("/").last.gsub(".git", "")
49
+ return Repository.new(name, repository_url, files)
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "roseflow/action"
4
+ require_relative "../github_chat_prompt"
5
+
6
+ class Actions::CreatePrompt
7
+ extend Roseflow::Action
8
+
9
+ expects :input
10
+ promises :prompt
11
+
12
+ executed do |ctx|
13
+ ctx[:prompt] = GithubChatPrompt.new(input)
14
+ end
15
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "roseflow/action"
4
+ require "roseflow/vector_stores/base"
5
+ require_relative "../repository_file"
6
+
7
+ class Actions::EmbedRepository
8
+ extend Roseflow::Action
9
+
10
+ expects :repository
11
+ expects :vector_store
12
+
13
+ executed do |ctx|
14
+ # Check if the vector store already has embeddings for given repository
15
+ # If so, we can skip this action
16
+ next if ctx.vector_store.has_embeddings?(ctx.repository)
17
+
18
+ # Otherwise, we need to embed the repository
19
+ embed_repository(ctx.repository, ctx.vector_store)
20
+ end
21
+
22
+ def self.embed_repository(repository, vector_store)
23
+ repository.files.each do |file_path, content|
24
+ unless file_is_embedded?(vector_store, file_path, repository.name)
25
+ embedding = RepositoryFile.new(file_path, content)
26
+ vector = vector_store.build_vector(file_path.to_s, embedding.embedding.vector)
27
+ vector_store.create_vector("github", vector, namespace: repository.name)
28
+ end
29
+ end
30
+ end
31
+
32
+ def self.file_is_embedded?(vector_store, file_path, repository_name)
33
+ vector_store.find("github", file_path.to_s, namespace: repository_name)
34
+ end
35
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This class represents an action that initializes a vector store based on a
4
+ # given provider. The action expects a provider as input and returns a
5
+ # VectorStore object.
6
+ #
7
+ # Example usage:
8
+ # vector_store = Actions::InitializeVectorStore.execute(provider: :pinecone)
9
+
10
+ require "roseflow/action"
11
+
12
+ class Actions::InitializeVectorStore
13
+ # Make it a Roseflow action
14
+ extend Roseflow::Action
15
+
16
+ # Define the inputs and outputs of the action
17
+ expects :provider # Input: The vector store provider to use
18
+ promises :vector_store # Output: a VectorStore object
19
+
20
+ executed do |ctx|
21
+ ctx[:vector_store] = initialize_vector_store(ctx.provider)
22
+ end
23
+
24
+ # Initialize a vector store based on the given provider.
25
+ #
26
+ # @param provider [Symbol] The symbol representing the vector store provider
27
+ # @return [Object] A VectorStore object corresponding to the given provider
28
+ # @raise [ArgumentError] If the provider is unknown
29
+ def self.initialize_vector_store(provider)
30
+ case provider
31
+ when :pinecone
32
+ # Initialize a Pinecone vector store
33
+ require "roseflow/pinecone/vector_store"
34
+ Roseflow::Pinecone::VectorStore.new
35
+ else
36
+ # Raise an error if the provider is unknown
37
+ raise ArgumentError, "Unknown provider: #{provider}"
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This class represents an action that interacts with a given model using a
4
+ # provided prompt. The action expects both a prompt and a model as input, and
5
+ # returns a response generated by the model.
6
+ #
7
+ # Example usage:
8
+ # response = Actions::InteractWithModel.execute(prompt: "What is the capital of France?", model: my_model)
9
+
10
+ require "roseflow/action"
11
+
12
+ class Actions::InteractWithModel
13
+ # Make it a Roseflow action
14
+ extend Roseflow::Action
15
+
16
+ # Define the inputs and outputs of the action
17
+ expects :prompt # Input: The prompt to use
18
+ expects :model # Input: The model to interact with
19
+
20
+ promises :response # Output: The response generated by the model
21
+
22
+ executed do |ctx|
23
+ # Interact with the model using the provided prompt
24
+ chat = ctx.model.chat(ctx.prompt)
25
+
26
+ # Store the response in the context
27
+ context[:response] = chat.response
28
+ end
29
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This action splits the content of source code files into smaller chunks
4
+ # and tokenizing them into documents.
5
+ #
6
+ # It takes a repository as an input and returns an array of documents.
7
+
8
+ require "roseflow/action"
9
+ require "ulid"
10
+
11
+ class Actions::SplitFilesToDocuments
12
+ extend Roseflow::Action
13
+
14
+ # Define the inputs and outputs of the action
15
+ expects :repository # Input: a repository object containing file data
16
+ promises :documents # Output: Array of RepositoryFile objects representing documents
17
+
18
+ executed do |ctx|
19
+ # Initialize splitter and tokenizer instances
20
+ splitter = initialize_splitter
21
+ tokenizer = initialize_tokenizer(ctx)
22
+
23
+ # Iterate over each file in the repository, split and tokenize its content
24
+ ctx[:documents] = ctx.repository.files.each do |file_path, content|
25
+ chunks = splitter.split(content) # Split the content into chunks
26
+ tokenized = chunks.map { |chunk| tokenizer.encode(chunk) } # Tokenize each chunks
27
+
28
+ # Create a RepositoryFile object for each chunk-token pair
29
+ chunks.zip(tokenized).map do |chunk, tkn|
30
+ RepositoryFile.new(
31
+ name: file_path,
32
+ content: chunk,
33
+ tokens: tkn,
34
+ token_count: tkn.length
35
+ )
36
+ end
37
+ end
38
+ end
39
+
40
+ # Initialize a RecursiveCharacterSplitter instance with a chunk_size of 1000
41
+ # and no overlap between chunks.
42
+ #
43
+ # @return [Roseflow::Text::RecursiveCharacterSplitter]
44
+ def self.initialize_splitter
45
+ Roseflow::Text::RecursiveCharacterSplitter.new(chunk_size: 1000, chunk_overlap: 0)
46
+ end
47
+
48
+ # Initialize a Tokenizer instance with the provided model from the context.
49
+ #
50
+ # @param ctx [Roseflow::Context] The context of the action execution
51
+ # @return [Roseflow::Tiktoken::Tokenizer]
52
+ def self.initialize_tokenizer(ctx)
53
+ Roseflow::Tiktoken::Tokenizer.new(model: ctx.model.name)
54
+ end
55
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "roseflow/prompt"
4
+
5
+ class GithubChatPrompt < Roseflow::Prompt
6
+ def initialize(input)
7
+ @input = input
8
+ end
9
+
10
+ attr_reader :input
11
+
12
+ def template
13
+ plain_raw condensed(prompt_string)
14
+ end
15
+
16
+ private
17
+
18
+ def prompt_string
19
+ <<-PROMPT
20
+
21
+ Command: [#{input}]
22
+ PROMPT
23
+ end
24
+ end
@@ -0,0 +1,12 @@
1
+ require_relative "actions/clone_and_load_repository"
2
+ require_relative "actions/create_prompt"
3
+ require_relative "actions/embed_repository"
4
+ require_relative "actions/initialize_vector_store"
5
+ require_relative "actions/interact_with_model"
6
+
7
+ require_relative "interactions/ask_llm"
8
+ require_relative "interactions/github_repository_chat"
9
+ require_relative "interactions/load_repository"
10
+ require_relative "interactions/prepare_vector_store"
11
+
12
+ require_relative "github_chat_prompt"
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This class represents an interaction that asks the LLM (Large Language Model)
4
+ # a question based on a given context. It orchestrates the required actions to
5
+ # initialize the LLM, create a prompt, and interact with the model.
6
+ #
7
+ # Example usage:
8
+ # result = Interactions::AskLLM.call(context)
9
+
10
+ require "roseflow"
11
+ require "roseflow/interactions/ai/initialize_llm"
12
+
13
+ require_relative "../actions/create_prompt"
14
+
15
+ class Interactions::AskLLM
16
+ extend Roseflow::Interaction
17
+
18
+ def self.call(context = {})
19
+ with(context).reduce(actions)
20
+ end
21
+
22
+ # Define the sequence of actions (or interactions) to be performed
23
+ # by the interaction.
24
+ def self.actions
25
+ [
26
+ Roseflow::Interactions::AI::InitializeLlm, # Initialize the LLM
27
+ CreatePrompt, # Create a prompt for the LLM
28
+ InteractWithModel # Interact with the LLM
29
+ ]
30
+ end
31
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This class represents an interaction that allows users to chat about
4
+ # a Github repository. It orchestrates the required actions to load
5
+ # the repository, prepare the vector store, and ask the LLM about the repository.
6
+ #
7
+ # Example usage:
8
+ # question = "What is the repository about?"
9
+ # response = Interactions::GithubRepositoryChat.call(
10
+ # question: question,
11
+ # repository_url: "https://github.com/ljuti/roseflow"
12
+ # )
13
+
14
+ require "roseflow/interaction"
15
+
16
+ require_relative "./ask_llm"
17
+ require_relative "./load_repository"
18
+ require_relative "./prepare_vector_store"
19
+
20
+ class Interactions::GithubRepositoryChat
21
+ extend Roseflow::Interaction
22
+
23
+ def self.call(context = {})
24
+ with(context).reduce(actions)
25
+ end
26
+
27
+ # Define the sequence of actions (or interactions) to be performed
28
+ # by the interaction.
29
+ def self.actions
30
+ [
31
+ LoadRepository, # Load repository from Github and prepare it
32
+ PrepareVectorStore, # Prepare vector store for querying
33
+ AskLLM # Ask the LLM about the repository
34
+ ]
35
+ end
36
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "roseflow/interaction"
4
+
5
+ class Interactions::LoadFilesToDocumentDatabase
6
+ extend Roseflow::Interaction
7
+
8
+ def self.call(ctx)
9
+ with(ctx).reduce(actions)
10
+ end
11
+
12
+ def self.actions
13
+ [
14
+ SplitFilesToDocuments,
15
+ LoadDocumentsToDatabase
16
+ ]
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "roseflow/interaction"
4
+
5
+ require_relative "../actions/clone_and_load_repository"
6
+
7
+ class Interactions::LoadRepository
8
+ extend Roseflow::Interaction
9
+
10
+ def self.call(context = {})
11
+ with(context).reduce(actions)
12
+ end
13
+
14
+ def self.actions
15
+ [
16
+ CloneAndLoadRepository,
17
+ LoadFilesToDocumentDatabase
18
+ ]
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "roseflow/interaction"
4
+
5
+ require_relative "../actions/initialize_vector_store"
6
+ require_relative "../actions/embed_repository"
7
+
8
+ class Interactions::PrepareVectorStore
9
+ extend Roseflow::Interaction
10
+
11
+ def self.call(context = {})
12
+ with(context).reduce(actions)
13
+ end
14
+
15
+ def self.actions
16
+ [
17
+ InitializeVectorStore,
18
+ reduce_if(->(ctx) { ctx.vector_store.has_embeddings? }, EmbedRepository)
19
+ ]
20
+ end
21
+ end
@@ -0,0 +1,9 @@
1
+ class Repository
2
+ def initialize(name, url, files)
3
+ @name = name
4
+ @url = url
5
+ @files = files
6
+ end
7
+
8
+ attr_reader :name, :url, :files
9
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ulid"
4
+
5
+ class RepositoryFile < Roseflow::Embeddings::Base
6
+ def initialize(name:, content:, **kwargs)
7
+ @name = name
8
+ @content = content
9
+ @id = ULID.generate
10
+ @token_count = kwargs[:token_count]
11
+ @tokens = kwargs[:tokens]
12
+ end
13
+
14
+ def embedding
15
+ @embedding ||= create_embedding
16
+ end
17
+
18
+ private
19
+
20
+ def create_embedding
21
+ provider.embedding(model: embedding_model, input: @content)
22
+ end
23
+
24
+ def provider
25
+ @provider ||= Roseflow::OpenAI::Provider.new
26
+ end
27
+
28
+ def embedding_model
29
+ provider.models.embeddable.find { |model| model.name == "text-embedding-ada-002" } || openai.models.embeddable.first
30
+ end
31
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../spec_helper"
4
+
5
+ RSpec.describe Actions::CloneAndLoadRepository do
6
+ let(:repository_url) { "https://github.com/abachman/ulid-ruby.git" }
7
+ let(:ctx) do
8
+ Roseflow::InteractionContext.make(
9
+ repository_url: repository_url
10
+ )
11
+ end
12
+
13
+ describe "cloning and loading the repository" do
14
+ let(:action) { described_class.execute(ctx) }
15
+
16
+ it "returns a repository" do
17
+ expect(action).to be_a_success
18
+ expect(action.repository).to be_a(Repository)
19
+ end
20
+
21
+ it "sets repository attributes correctly" do
22
+ expect(action.repository).to be_a(Repository)
23
+ expect(action.repository.name).to eq "ulid-ruby"
24
+ expect(action.repository.url).to eq repository_url
25
+ expect(action.repository.files).not_to be_empty
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../spec_helper"
4
+ require "roseflow/pinecone"
5
+ require "roseflow/pinecone/vector_store"
6
+
7
+ RSpec.describe Actions::EmbedRepository do
8
+ let(:repository) { Repository.new("ulid-ruby", "https://github.com/abachman/ulid-ruby.git", {"ulid-ruby.gemspec": "This is a gemspec for the gem"}) }
9
+ let(:ctx) do
10
+ Roseflow::InteractionContext.make(
11
+ repository: repository,
12
+ vector_store: Roseflow::Pinecone::VectorStore.new
13
+ )
14
+ end
15
+
16
+ describe "embedding a repository" do
17
+ let(:action) { described_class.execute(ctx) }
18
+
19
+ it "embeds the files of the repository to the vector store" do
20
+ expect(action).to be_a_success
21
+ expect(action.vector_store).to be_a(Roseflow::VectorStores::Base)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../spec_helper"
4
+
5
+ RSpec.describe Actions::InitializeVectorStore do
6
+ let(:ctx) do
7
+ Roseflow::InteractionContext.make(
8
+ provider: :pinecone
9
+ )
10
+ end
11
+
12
+ describe "initializing the vector store" do
13
+ let(:action) { described_class.execute(ctx) }
14
+
15
+ it "returns a vector store" do
16
+ expect(action).to be_a_success
17
+ expect(action.vector_store).to be_a Roseflow::Pinecone::VectorStore
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../spec_helper"
4
+
5
+ RSpec.describe Actions::LoadFilesToDocumentDatabase do
6
+ let(:repository_url) { "https://github.com/abachman/ulid-ruby.git" }
7
+ let(:ctx) do
8
+ Roseflow::InteractionContext.make(
9
+ repository_url: repository_url
10
+ )
11
+ end
12
+
13
+ before do
14
+ @context = Actions::CloneAndLoadRepository.execute(ctx)
15
+ end
16
+
17
+ describe "loading files to document database" do
18
+ it "loads the files" do
19
+ expect(action).to be_a_success
20
+ expect(action.database.files.count).to be > 5
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Interactions::GithubRepositoryChat do
4
+ let(:prompt) { GithubChatPrompt.new("Describe me how to use OpenAI models with Roseflow.") }
5
+ let(:ctx) do
6
+ Roseflow::InteractionContext.make(
7
+ provider: :openai,
8
+ model: "gpt-3.5-turbo",
9
+ repository_url: "https://github.com/roseflow-ai/roseflow-openai",
10
+ prompt: prompt
11
+ )
12
+ end
13
+
14
+ describe "" do
15
+ end
16
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Interactions::PrepareVectorStore do
4
+ end
@@ -0,0 +1,12 @@
1
+ require "spec_helper"
2
+ require "roseflow"
3
+
4
+ Anyway::Settings.use_local_files = true
5
+
6
+ module Interactions
7
+ end
8
+
9
+ module Actions
10
+ end
11
+
12
+ require_relative "../lib/github_repository_chat"
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "light-service"
4
+
5
+ module Roseflow
6
+ module Action
7
+ extend LightService::Action
8
+
9
+ def self.extended(base_class)
10
+ base_class.extend LightService::Action::Macros
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "roseflow/action"
4
+ require "roseflow/ai/model"
5
+
6
+ module Roseflow
7
+ module Actions
8
+ module AI
9
+ class ResolveModel
10
+ extend Roseflow::Action
11
+
12
+ expects :model
13
+ promises :llm
14
+
15
+ executed do |context|
16
+ model = context.provider.models.find(context[:model])
17
+
18
+ unless model
19
+ context.fail_and_return!("Model #{context[:model]} not found")
20
+ end
21
+
22
+ context[:llm] = Roseflow::AI::Model.new(name: model.name, provider: context.provider)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end