roseflow 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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