intelli_agent 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3fca7e6fcb2e2360ccd76c9d09506f73db72dd525dfd771322a19a6982eedd52
4
+ data.tar.gz: 2bcb9b1cc62b6dfb9a6c4ecc634dab04e9c1c27a2941dd2feb6a0f8aad858934
5
+ SHA512:
6
+ metadata.gz: 3de9eaddade5b5d5f16e385ef4cbff9bd7e7eade087b4bbc04c5c8ae2c3d0cc15ef79b518536d023f3153b62a4b748e53f735b7f33a338450db403d824c86f06
7
+ data.tar.gz: aa27675fcfc8c0bcab9701b1f0e8ca6ec09eb03f8c4fd141b9c0b63465c196f9bfcf85ad8c401eeb2c32e82930f310c3ae0fbac445f43f1e5d4dd6aa6c1622e7
data/README.md ADDED
@@ -0,0 +1 @@
1
+ # AI Agent
data/lib/ai/agent.rb ADDED
@@ -0,0 +1,71 @@
1
+ class AI::Agent
2
+ attr_reader :assistant, :thread, :instructions, :vector_store_id
3
+
4
+ def initialize(assistant_id: nil, thread_id: nil, thread_instructions: nil, vector_store_id: nil)
5
+ @openai_client = OpenAI::Client.new
6
+
7
+ assistant_id ||= ENV.fetch('OPENAI_AKAPU_CORE_ASSISTANT_ID')
8
+ @assistant = @openai_client.assistants.retrieve(id: assistant_id)
9
+
10
+ thread_params = {}
11
+
12
+ # Only one vector store can be attached, according to the OpenAI API documentation
13
+ @vector_store_id = vector_store_id
14
+ thread_params = { tool_resources: { file_search: { vector_store_ids: [vector_store_id] } } } if @vector_store_id
15
+
16
+ thread_id ||= @openai_client.threads.create(parameters: thread_params)['id']
17
+ @thread = @openai_client.threads.retrieve(id: thread_id)
18
+
19
+ @instructions = thread_instructions || @assistant['instructions']
20
+ end
21
+
22
+ def add_message(text, role: 'user')
23
+ @openai_client.messages.create(thread_id: @thread['id'], parameters: { role: role, content: text })
24
+ end
25
+
26
+ def messages
27
+ @openai_client.messages.list(thread_id: @thread['id'])
28
+ end
29
+
30
+ def last_message
31
+ messages['data'].first['content'].first['text']['value']
32
+ end
33
+
34
+ def run(instructions: nil, additional_instructions: nil, additional_message: nil, model: nil, tool_choice: nil)
35
+ params = { assistant_id: @assistant['id'] }
36
+
37
+ params[:instructions] = instructions || @instructions
38
+ params[:additional_instructions] = additional_instructions unless additional_instructions.nil?
39
+ params[:tool_choice] = tool_choice unless tool_choice.nil?
40
+
41
+ params[:additional_messages] = [{ role: :user, content: additional_message }] unless additional_message.nil?
42
+
43
+ params[:model] = model || @assistant['model']
44
+
45
+ run_id = @openai_client.runs.create(thread_id: @thread['id'], parameters: params)['id']
46
+
47
+ loop do
48
+ response = @openai_client.runs.retrieve(id: run_id, thread_id: @thread['id'])
49
+
50
+ case response['status']
51
+ when 'queued', 'in_progress', 'cancelling'
52
+ puts 'Status: Waiting AI Processing finish'
53
+ sleep 1
54
+ when 'completed'
55
+ puts last_message
56
+ break
57
+ when 'requires_action'
58
+ # Handle tool calls (see below)
59
+ when 'cancelled', 'failed', 'expired'
60
+ puts response['last_error'].inspect
61
+ break # or `exit`
62
+ else
63
+ puts "Unknown status response: #{status}"
64
+ end
65
+ end
66
+ end
67
+
68
+ def runs
69
+ @openai_client.runs.list(thread_id: @thread['id'])
70
+ end
71
+ end
File without changes
@@ -0,0 +1,77 @@
1
+ require 'test_helper'
2
+ require 'openai'
3
+
4
+ class AI::AgentTest < ActiveSupport::TestCase
5
+ def setup
6
+ @assistant_id = 'your_assistant_id'
7
+ @thread_id = 'your_thread_id'
8
+ @thread_instructions = 'your_thread_instructions'
9
+ @agent = AI::Agent.new(assistant_id: @assistant_id, thread_id: @thread_id, thread_instructions: @thread_instructions)
10
+ end
11
+
12
+ test 'add_message should create a new message in the thread' do
13
+ text = 'Hello, world!'
14
+ role = 'user'
15
+ message_params = { thread_id: @thread_id, parameters: { role: role, content: text } }
16
+
17
+ OpenAI::Client.any_instance.expects(:messages).returns(stub(create: true))
18
+ @agent.add_message(text, role: role)
19
+
20
+ assert_received(OpenAI::Client) { |expect| expect.messages.create(message_params) }
21
+ end
22
+
23
+ test 'messages should return a list of messages in the thread' do
24
+ messages_params = { thread_id: @thread_id }
25
+
26
+ OpenAI::Client.any_instance.expects(:messages).returns(stub(list: true))
27
+ @agent.messages
28
+
29
+ assert_received(OpenAI::Client) { |expect| expect.messages.list(messages_params) }
30
+ end
31
+
32
+ test 'last_message should return the content of the last message in the thread' do
33
+ message_content = 'Hello, world!'
34
+ messages_response = { 'data' => [{ 'content' => [{ 'text' => { 'value' => message_content } }] }] }
35
+
36
+ OpenAI::Client.any_instance.expects(:messages).returns(stub(list: messages_response))
37
+ assert_equal message_content, @agent.last_message
38
+ end
39
+
40
+ test 'run should create a new run in the thread' do
41
+ instructions = 'your_instructions'
42
+ additional_instructions = 'your_additional_instructions'
43
+ model = 'your_model'
44
+ run_params = { assistant_id: @assistant_id, instructions: instructions, additional_instructions: additional_instructions, model: model }
45
+
46
+ OpenAI::Client.any_instance.expects(:runs).returns(stub(create: true))
47
+ @agent.run(instructions: instructions, additional_instructions: additional_instructions, model: model)
48
+
49
+ assert_received(OpenAI::Client) { |expect| expect.runs.create(run_params) }
50
+ end
51
+
52
+ test 'runs should return a list of runs in the thread' do
53
+ runs_params = { thread_id: @thread_id }
54
+
55
+ OpenAI::Client.any_instance.expects(:runs).returns(stub(list: true))
56
+ @agent.runs
57
+
58
+ assert_received(OpenAI::Client) { |expect| expect.runs.list(runs_params) }
59
+ end
60
+ endrequire 'test_helper'
61
+ require 'artificial_intelligence/ai/agent'
62
+
63
+ class AI::AgentTest < ActiveSupport::TestCase
64
+ def setup
65
+ @agent = AI::Agent.new
66
+ end
67
+
68
+ test "agent can perform action" do
69
+ # Add your test logic here
70
+ end
71
+
72
+ test "agent can learn from experience" do
73
+ # Add your test logic here
74
+ end
75
+
76
+ # Add more tests as needed
77
+ end
File without changes
data/lib/ai.rb ADDED
@@ -0,0 +1,56 @@
1
+ # In the future, this became a bus to more than one AI provider
2
+ module AI
3
+ BASIC_MODEL = ENV.fetch('OPENAI_BASIC_MODEL')
4
+ ADVANCED_MODEL = ENV.fetch('OPENAI_ADVANCED_MODEL')
5
+
6
+ def self.embed(input, model: 'text-embedding-3-large')
7
+ response = OpenAI::Client.new.embeddings(parameters: { input:, model: })
8
+ response.dig('data', 0, 'embedding')
9
+ end
10
+
11
+ def self.single_prompt(prompt:, model: AI::BASIC_MODEL, response_format: nil)
12
+ parameters = { model:, messages: [{ role: 'user', content: prompt }] }
13
+
14
+ parameters[:response_format] = { type: 'json_object' } if response_format.eql?(:json)
15
+
16
+ response = OpenAI::Client.new.chat(parameters:)
17
+ response.dig('choices', 0, 'message', 'content').strip
18
+ end
19
+
20
+ def self.vision(prompt:, image_url:, response_format: nil)
21
+ messages = [{ type: :text, text: prompt },
22
+ { type: :image_url, image_url: { url: image_url } }]
23
+
24
+ parameters = { model: AI::ADVANCED_MODEL, messages: [{ role: :user, content: messages }] }
25
+ parameters[:response_format] = { type: 'json_object' } if response_format.eql?(:json)
26
+
27
+ response = OpenAI::Client.new.chat(parameters:)
28
+
29
+ response.dig('choices', 0, 'message', 'content').strip
30
+ end
31
+
32
+ def self.single_chat(system:, user:, model: AI::BASIC_MODEL, response_format: nil)
33
+ parameters = { model:,
34
+ messages: [
35
+ { role: 'system', content: system },
36
+ { role: 'user', content: user }
37
+ ] }
38
+
39
+ parameters[:response_format] = { type: 'json_object' } if response_format.eql?(:json)
40
+
41
+ response = OpenAI::Client.new.chat(parameters:)
42
+ response.dig('choices', 0, 'message', 'content').strip
43
+ end
44
+
45
+ def self.chat(messages, model: AI::BASIC_MODEL, response_format: nil)
46
+ parameters = { model:, messages: }
47
+ parameters[:response_format] = { type: 'json_object' } if response_format.eql?(:json)
48
+
49
+ response = OpenAI::Client.new.chat(parameters:)
50
+ response.dig('choices', 0, 'message', 'content').strip
51
+ end
52
+
53
+ def self.models
54
+ OpenAI::Client.new.models.list
55
+ end
56
+ end
File without changes
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: intelli_agent
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Gedean Dias
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-07-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ruby-openai
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '7.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '7.1'
27
+ description: AI Agent.
28
+ email: gedean.dias@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - README.md
34
+ - lib/ai.rb
35
+ - lib/ai.rb:Zone.Identifier
36
+ - lib/ai/agent.rb
37
+ - lib/ai/agent.rb:Zone.Identifier
38
+ - lib/ai/agent_test.rb_
39
+ - lib/ai/agent_test.rb_:Zone.Identifier
40
+ homepage: https://github.com/gedean/intelli_agent
41
+ licenses:
42
+ - MIT
43
+ metadata: {}
44
+ post_install_message: Please check readme file for use instructions.
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '3'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubygems_version: 3.5.16
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: AI Agent
63
+ test_files: []