aia 0.9.5 → 0.9.7
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 +4 -4
- data/.version +1 -1
- data/CHANGELOG.md +24 -1
- data/README.md +569 -529
- data/examples/headlines +24 -15
- data/examples/tools/run_shell_command.rb +16 -4
- data/images/aia.png +0 -0
- data/lib/aia/chat_processor_service.rb +10 -9
- data/lib/aia/config.rb +96 -4
- data/lib/aia/directive_processor.rb +50 -10
- data/lib/aia/ruby_llm_adapter.rb +7 -5
- data/lib/aia/session.rb +12 -3
- data/lib/aia/ui_presenter.rb +1 -1
- data/lib/aia/utility.rb +1 -1
- data/lib/aia.rb +7 -1
- data/lib/extensions/ruby_llm/modalities.rb +30 -22
- metadata +32 -3
data/examples/headlines
CHANGED
@@ -1,21 +1,30 @@
|
|
1
|
-
#!/usr/bin/env aia run --no-out_file
|
2
|
-
#
|
1
|
+
#!/usr/bin/env aia run --no-out_file --exec
|
2
|
+
# NOTE: the --exec option is REQUIRED to run this executable prompt file
|
3
|
+
# This option signals that the contents of this file are to be appended
|
4
|
+
# to the contents of the given prompt ID file. In this case it is the
|
5
|
+
# "run" prompt ID's text file.
|
6
|
+
#
|
7
|
+
# All other AIA options are, well, optional. The --no-out_file is
|
8
|
+
# used here to cause the response to this executable prompt to be
|
9
|
+
# sent to STDOUT like a good little *nix CLI tool. Its not necessary.
|
10
|
+
# if you do not use it, the output will go to the default out_file.
|
11
|
+
# You could also specify a specific file to write the output to built
|
12
|
+
# but it is more convential to use the *nix STDOUT redirect "> output.md"
|
13
|
+
#
|
3
14
|
# Desc: retrieves the news.google.com website
|
4
15
|
# extracts and formats the headlines
|
5
|
-
# and prints them to
|
16
|
+
# and prints them to STDOUT
|
17
|
+
#
|
18
|
+
# Method:
|
19
|
+
# There are several ways you can accomplish this task using
|
20
|
+
# the shell or ERB integration. For this example lets use
|
21
|
+
# a built-in directive.
|
6
22
|
|
7
|
-
|
8
|
-
# //config
|
23
|
+
Extract and summarize the headlines from the following markdown:
|
9
24
|
|
10
|
-
|
11
|
-
# //shell wget2 https://news.google.com
|
25
|
+
//webpage https://news.google.com
|
12
26
|
|
13
|
-
|
27
|
+
__END__
|
14
28
|
|
15
|
-
|
16
|
-
|
17
|
-
//config speak = true
|
18
|
-
|
19
|
-
Extract and summarize the headlines from the following text:
|
20
|
-
|
21
|
-
$(html2text index.html)
|
29
|
+
The //webpage directive makes use of the website https://pure.md
|
30
|
+
to convert any given URL to a markdown file.
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# experiments/ai_misc/coding_agent_with_ruby_llm/tools/run_shell_command.rb
|
2
2
|
|
3
|
+
require "io/console"
|
3
4
|
require "ruby_llm/tool"
|
4
5
|
|
5
6
|
module Tools
|
@@ -8,10 +9,21 @@ module Tools
|
|
8
9
|
param :command, desc: "The command to execute"
|
9
10
|
|
10
11
|
def execute(command:)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
print "\n\n"
|
13
|
+
puts "AI wants to execute the following shell command:"
|
14
|
+
puts "="*command.size
|
15
|
+
puts command
|
16
|
+
puts "="*command.size
|
17
|
+
print "\n\n"
|
18
|
+
|
19
|
+
sleep 0.5
|
20
|
+
print "Execute the command? (y/N):"
|
21
|
+
allowed = STDIN.getch == "y"
|
22
|
+
|
23
|
+
unless allowed
|
24
|
+
print "Command aborted" + " "*30 if defined?(AIA)
|
25
|
+
return { error: "User declined to execute the command" }
|
26
|
+
end
|
15
27
|
|
16
28
|
`#{command}`
|
17
29
|
rescue => e
|
data/images/aia.png
ADDED
Binary file
|
@@ -62,7 +62,7 @@ module AIA
|
|
62
62
|
|
63
63
|
# Only output to STDOUT if we're in chat mode
|
64
64
|
|
65
|
-
if AIA.chat? || 'STDOUT' == AIA.config.out_file.upcase
|
65
|
+
if AIA.chat? || AIA.config.out_file.nil? || 'STDOUT' == AIA.config.out_file.upcase
|
66
66
|
print "\nAI:\n "
|
67
67
|
puts response
|
68
68
|
else
|
@@ -94,21 +94,22 @@ module AIA
|
|
94
94
|
|
95
95
|
def determine_operation_type
|
96
96
|
mode = AIA.config.client.model.modalities
|
97
|
-
|
97
|
+
|
98
|
+
if mode.text_to_image?
|
98
99
|
:text_to_image
|
99
|
-
elsif mode.
|
100
|
+
elsif mode.image_to_text?
|
100
101
|
:image_to_text
|
101
|
-
elsif mode.
|
102
|
+
elsif mode.audio_to_text?
|
102
103
|
:audio_to_text
|
103
|
-
elsif mode.
|
104
|
+
elsif mode.text_to_audio?
|
104
105
|
:text_to_audio
|
105
|
-
elsif mode.
|
106
|
+
elsif mode.audio_to_audio?
|
106
107
|
:audio_to_audio
|
107
|
-
elsif mode.
|
108
|
+
elsif mode.image_to_image?
|
108
109
|
:image_to_image
|
109
|
-
elsif mode.
|
110
|
+
elsif mode.audio_to_image?
|
110
111
|
:audio_to_image
|
111
|
-
elsif mode.
|
112
|
+
elsif mode.image_to_audio?
|
112
113
|
:image_to_audio
|
113
114
|
else
|
114
115
|
:text_to_text
|
data/lib/aia/config.rb
CHANGED
@@ -124,6 +124,17 @@ module AIA
|
|
124
124
|
remaining_args = config.remaining_args.dup
|
125
125
|
config.remaining_args = nil
|
126
126
|
|
127
|
+
# Check for STDIN content
|
128
|
+
stdin_content = nil
|
129
|
+
if !STDIN.tty? && !STDIN.closed?
|
130
|
+
begin
|
131
|
+
stdin_content = STDIN.read
|
132
|
+
STDIN.reopen('/dev/tty') # Reopen STDIN for interactive use
|
133
|
+
rescue => _
|
134
|
+
# If we can't reopen, continue without error
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
127
138
|
# Is first remaining argument a prompt ID?
|
128
139
|
unless remaining_args.empty?
|
129
140
|
maybe_id = remaining_args.first
|
@@ -134,6 +145,11 @@ module AIA
|
|
134
145
|
end
|
135
146
|
end
|
136
147
|
|
148
|
+
# Store STDIN content for later processing in session.rb
|
149
|
+
if stdin_content && !stdin_content.strip.empty?
|
150
|
+
config.stdin_content = stdin_content
|
151
|
+
end
|
152
|
+
|
137
153
|
unless remaining_args.empty?
|
138
154
|
bad_files = remaining_args.reject { |filename| AIA.good_file?(filename) }
|
139
155
|
if bad_files.any?
|
@@ -141,9 +157,21 @@ module AIA
|
|
141
157
|
exit 1
|
142
158
|
end
|
143
159
|
|
144
|
-
config.context_files
|
160
|
+
config.context_files ||= []
|
161
|
+
config.context_files += remaining_args
|
162
|
+
end
|
163
|
+
|
164
|
+
# Check if the last context file is an executable prompt
|
165
|
+
if config.executable_prompt &&
|
166
|
+
config.context_files &&
|
167
|
+
!config.context_files.empty?
|
168
|
+
config.executable_prompt_file = config.context_files.pop
|
145
169
|
end
|
146
170
|
|
171
|
+
# TODO: Consider that if there is no prompt ID but there is an executable prompt
|
172
|
+
# then maybe that is all that is needed.
|
173
|
+
|
174
|
+
|
147
175
|
if config.prompt_id.nil? && !config.chat && !config.fuzzy
|
148
176
|
STDERR.puts "Error: A prompt ID is required unless using --chat, --fuzzy, or providing context files. Use -h or --help for help."
|
149
177
|
exit 1
|
@@ -325,10 +353,68 @@ module AIA
|
|
325
353
|
end
|
326
354
|
end
|
327
355
|
|
356
|
+
opts.on('--available_models [QUERY]', 'List (then exit) available models that match the optional query - a comma separated list of AND components like: openai,mini') do |query|
|
357
|
+
|
358
|
+
# SMELL: mostly duplications the code in the vailable_models directive
|
359
|
+
# assumes that the adapter is for the ruby_llm gem
|
360
|
+
# should this be moved to the Utilities class as a common method?
|
361
|
+
|
362
|
+
if query.nil?
|
363
|
+
query = []
|
364
|
+
else
|
365
|
+
query = query.split(',')
|
366
|
+
end
|
367
|
+
|
368
|
+
header = "\nAvailable LLMs"
|
369
|
+
header += " for #{query.join(' and ')}" if query
|
370
|
+
|
371
|
+
puts header + ':'
|
372
|
+
puts
|
373
|
+
|
374
|
+
q1 = query.select{|q| q.include?('_to_')}.map{|q| ':'==q[0] ? q[1...] : q}
|
375
|
+
q2 = query.reject{|q| q.include?('_to_')}
|
376
|
+
|
377
|
+
|
378
|
+
# query = nil
|
379
|
+
counter = 0
|
380
|
+
|
381
|
+
RubyLLM.models.all.each do |llm|
|
382
|
+
inputs = llm.modalities.input.join(',')
|
383
|
+
outputs = llm.modalities.output.join(',')
|
384
|
+
entry = "- #{llm.id} (#{llm.provider}) #{inputs} to #{outputs}"
|
385
|
+
|
386
|
+
if query.nil? || query.empty?
|
387
|
+
counter += 1
|
388
|
+
puts entry
|
389
|
+
next
|
390
|
+
end
|
391
|
+
|
392
|
+
show_it = true
|
393
|
+
q1.each{|q| show_it &&= llm.modalities.send("#{q}?")}
|
394
|
+
q2.each{|q| show_it &&= entry.include?(q)}
|
395
|
+
|
396
|
+
if show_it
|
397
|
+
counter += 1
|
398
|
+
puts entry
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
puts if counter > 0
|
403
|
+
puts "#{counter} LLMs matching your query"
|
404
|
+
puts
|
405
|
+
|
406
|
+
exit
|
407
|
+
end
|
408
|
+
|
328
409
|
opts.on("-m MODEL", "--model MODEL", "Name of the LLM model to use") do |model|
|
329
410
|
config.model = model
|
330
411
|
end
|
331
412
|
|
413
|
+
opts.on("-x", "--[no-]exec", "Used to designate an executable prompt file") do |value|
|
414
|
+
config.executable_prompt = value
|
415
|
+
end
|
416
|
+
|
417
|
+
|
332
418
|
opts.on("--terse", "Adds a special instruction to the prompt asking the AI to keep responses short and to the point") do
|
333
419
|
config.terse = true
|
334
420
|
end
|
@@ -383,7 +469,13 @@ module AIA
|
|
383
469
|
end
|
384
470
|
|
385
471
|
opts.on("-o", "--[no-]out_file [FILE]", "Output file (default: temp.md)") do |file|
|
386
|
-
|
472
|
+
if file == false # --no-out_file was used
|
473
|
+
config.out_file = nil
|
474
|
+
elsif file.nil? # No argument provided
|
475
|
+
config.out_file = 'temp.md'
|
476
|
+
else # File name provided
|
477
|
+
config.out_file = File.expand_path(file, Dir.pwd)
|
478
|
+
end
|
387
479
|
end
|
388
480
|
|
389
481
|
opts.on("-a", "--[no-]append", "Append to output file instead of overwriting") do |append|
|
@@ -422,8 +514,8 @@ module AIA
|
|
422
514
|
config.debug = $DEBUG_ME = false
|
423
515
|
end
|
424
516
|
|
425
|
-
opts.on("-v", "--verbose", "Be verbose") do
|
426
|
-
config.verbose =
|
517
|
+
opts.on("-v", "--[no-]verbose", "Be verbose") do |value|
|
518
|
+
config.verbose = value
|
427
519
|
end
|
428
520
|
|
429
521
|
opts.on("--speak", "Simple implementation. Uses the speech model to convert text to audio, then plays the audio. Fun with --chat. Supports configuration of speech model and voice.") do
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# lib/aia/directive_processor.rb
|
2
2
|
|
3
|
+
require 'active_support/all'
|
3
4
|
require 'faraday'
|
5
|
+
require 'word_wrapper' # Pure ruby word wrapping
|
4
6
|
|
5
7
|
module AIA
|
6
8
|
class DirectiveProcessor
|
@@ -145,7 +147,7 @@ module AIA
|
|
145
147
|
end
|
146
148
|
|
147
149
|
desc "Specify the next prompt ID to process after this one"
|
148
|
-
def next(args = [])
|
150
|
+
def next(args = [], context_manager=nil)
|
149
151
|
if args.empty?
|
150
152
|
ap AIA.config.next
|
151
153
|
else
|
@@ -154,8 +156,33 @@ module AIA
|
|
154
156
|
''
|
155
157
|
end
|
156
158
|
|
159
|
+
desc "Show a list of tools and their description"
|
160
|
+
def tools(args = [], context_manager=nil)
|
161
|
+
indent = 4
|
162
|
+
spaces = " "*indent
|
163
|
+
width = TTY::Screen.width - indent - 2
|
164
|
+
|
165
|
+
if !AIA.config.tools.empty?
|
166
|
+
puts
|
167
|
+
puts "Available Tools"
|
168
|
+
puts "==============="
|
169
|
+
|
170
|
+
AIA.config.tools.split(',').map(&:strip).each do |tool|
|
171
|
+
klass = tool.constantize
|
172
|
+
puts "\n#{klass.name}"
|
173
|
+
puts "-"*klass.name.size
|
174
|
+
puts WordWrapper::MinimumRaggedness.new(width, klass.description).wrap.split("\n").map{|s| spaces+s+"\n"}.join
|
175
|
+
end
|
176
|
+
else
|
177
|
+
puts "No tools configured"
|
178
|
+
end
|
179
|
+
puts
|
180
|
+
|
181
|
+
''
|
182
|
+
end
|
183
|
+
|
157
184
|
desc "Specify a sequence pf prompt IDs to process after this one"
|
158
|
-
def pipeline(args = [])
|
185
|
+
def pipeline(args = [], context_manager=nil)
|
159
186
|
if args.empty?
|
160
187
|
ap AIA.config.pipeline
|
161
188
|
else
|
@@ -299,16 +326,21 @@ module AIA
|
|
299
326
|
desc "All Available models or query on [partial LLM or provider name] Examples: //llms ; //llms openai ; //llms claude"
|
300
327
|
def available_models( args=nil, context_manager=nil)
|
301
328
|
query = args
|
302
|
-
header = "Available LLMs"
|
303
329
|
|
304
|
-
if query
|
305
|
-
|
330
|
+
if 1 == query.size
|
331
|
+
query = query.first.split(',')
|
306
332
|
end
|
307
333
|
|
334
|
+
header = "\nAvailable LLMs"
|
335
|
+
header += " for #{query.join(' and ')}" if query
|
336
|
+
|
308
337
|
puts header + ':'
|
338
|
+
puts
|
309
339
|
|
310
|
-
q1 = query.select{|q|
|
311
|
-
q2 = query.
|
340
|
+
q1 = query.select{|q| q.include?('_to_')}.map{|q| ':'==q[0] ? q[1...] : q}
|
341
|
+
q2 = query.reject{|q| q.include?('_to_')}
|
342
|
+
|
343
|
+
counter = 0
|
312
344
|
|
313
345
|
RubyLLM.models.all.each do |llm|
|
314
346
|
inputs = llm.modalities.input.join(',')
|
@@ -316,17 +348,25 @@ module AIA
|
|
316
348
|
entry = "- #{llm.id} (#{llm.provider}) #{inputs} to #{outputs}"
|
317
349
|
|
318
350
|
if query.nil? || query.empty?
|
351
|
+
counter += 1
|
319
352
|
puts entry
|
320
353
|
next
|
321
354
|
end
|
322
355
|
|
323
356
|
show_it = true
|
324
|
-
q1.each{|q| show_it &&=
|
325
|
-
q2.each{|q| show_it &&=
|
357
|
+
q1.each{|q| show_it &&= llm.modalities.send("#{q}?")}
|
358
|
+
q2.each{|q| show_it &&= entry.include?(q)}
|
326
359
|
|
327
|
-
|
360
|
+
if show_it
|
361
|
+
counter += 1
|
362
|
+
puts entry
|
363
|
+
end
|
328
364
|
end
|
329
365
|
|
366
|
+
puts if counter > 0
|
367
|
+
puts "#{counter} LLMs matching your query"
|
368
|
+
puts
|
369
|
+
|
330
370
|
""
|
331
371
|
end
|
332
372
|
alias_method :am, :available_models
|
data/lib/aia/ruby_llm_adapter.rb
CHANGED
@@ -74,6 +74,8 @@ module AIA
|
|
74
74
|
exit 1
|
75
75
|
end
|
76
76
|
|
77
|
+
return unless @chat.model.supports_functions?
|
78
|
+
|
77
79
|
if !AIA.config.tool_paths.empty? && !@chat.model.supports?(:function_calling)
|
78
80
|
STDERR.puts "ERROR: The model #{@model} does not support tools"
|
79
81
|
exit 1
|
@@ -96,17 +98,17 @@ module AIA
|
|
96
98
|
modes = @chat.model.modalities
|
97
99
|
|
98
100
|
# TODO: Need to consider how to handle multi-mode models
|
99
|
-
if modes.
|
101
|
+
if modes.text_to_text?
|
100
102
|
text_to_text(prompt)
|
101
103
|
|
102
|
-
elsif modes.
|
104
|
+
elsif modes.image_to_text?
|
103
105
|
image_to_text(prompt)
|
104
|
-
elsif modes.
|
106
|
+
elsif modes.text_to_image?
|
105
107
|
text_to_image(prompt)
|
106
108
|
|
107
|
-
elsif modes.
|
109
|
+
elsif modes.text_to_audio?
|
108
110
|
text_to_audio(prompt)
|
109
|
-
elsif modes.
|
111
|
+
elsif modes.audio_to_text?
|
110
112
|
audio_to_text(prompt)
|
111
113
|
|
112
114
|
else
|
data/lib/aia/session.rb
CHANGED
@@ -41,7 +41,7 @@ module AIA
|
|
41
41
|
@directive_processor = DirectiveProcessor.new
|
42
42
|
@chat_processor = ChatProcessorService.new(@ui_presenter, @directive_processor)
|
43
43
|
|
44
|
-
if AIA.config.out_file && !AIA.append? && File.exist?(AIA.config.out_file)
|
44
|
+
if AIA.config.out_file && !AIA.config.out_file.nil? && !AIA.append? && File.exist?(AIA.config.out_file)
|
45
45
|
File.open(AIA.config.out_file, 'w') {} # Truncate the file
|
46
46
|
end
|
47
47
|
end
|
@@ -111,8 +111,17 @@ module AIA
|
|
111
111
|
prompt.text << TERSE_PROMPT
|
112
112
|
end
|
113
113
|
|
114
|
-
|
115
|
-
|
114
|
+
if AIA.config.stdin_content && !AIA.config.stdin_content.strip.empty?
|
115
|
+
prompt.text << "\n\n" << AIA.config.stdin_content
|
116
|
+
end
|
117
|
+
|
118
|
+
if AIA.config.executable_prompt_file
|
119
|
+
prompt.text << "\n\n" << File.read(AIA.config.executable_prompt_file)
|
120
|
+
.lines[1..]
|
121
|
+
.join
|
122
|
+
end
|
123
|
+
|
124
|
+
# Substitute variables, execute dynamic content and get final prompt text
|
116
125
|
prompt_text = prompt.to_s
|
117
126
|
|
118
127
|
# Add context files if any
|
data/lib/aia/ui_presenter.rb
CHANGED
data/lib/aia/utility.rb
CHANGED
@@ -21,7 +21,7 @@ module AIA
|
|
21
21
|
(O) using #{AIA.config.adapter} (v#{RubyLLM::VERSION})
|
22
22
|
__||__ \\) model db was last refreshed on
|
23
23
|
[/______\\] / #{AIA.config.last_refresh}
|
24
|
-
/ \\__AI__/ \\/ #{AIA.config.tool_paths.empty? ? '
|
24
|
+
/ \\__AI__/ \\/ #{AIA.config.tool_paths.empty? ? 'You can share my tools' : 'I will also use your tools'}
|
25
25
|
/ /__\\
|
26
26
|
(\\ /____\\ #{AIA.config.tool_paths.empty? ? '' : 'My Toolbox contains:'}
|
27
27
|
ROBOT
|
data/lib/aia.rb
CHANGED
@@ -5,15 +5,17 @@
|
|
5
5
|
# provides an interface for interacting with AI models and managing prompts.
|
6
6
|
|
7
7
|
require 'ruby_llm'
|
8
|
+
require 'ruby_llm/mcp'
|
8
9
|
require 'prompt_manager'
|
9
10
|
|
11
|
+
|
10
12
|
require 'debug_me'
|
11
13
|
include DebugMe
|
12
14
|
$DEBUG_ME = false
|
13
15
|
DebugMeDefaultOptions[:skip1] = true
|
14
16
|
|
15
17
|
require_relative 'extensions/openstruct_merge' # adds self.merge self.get_value
|
16
|
-
require_relative 'extensions/ruby_llm/modalities' # adds model.modalities.
|
18
|
+
require_relative 'extensions/ruby_llm/modalities' # adds model.modalities.text_to_text? etc.
|
17
19
|
|
18
20
|
require_relative 'refinements/string.rb' # adds #include_any? #include_all?
|
19
21
|
|
@@ -37,6 +39,10 @@ require_relative 'aia/session'
|
|
37
39
|
module AIA
|
38
40
|
at_exit do
|
39
41
|
STDERR.puts "Exiting AIA application..."
|
42
|
+
# Clean up temporary STDIN file if it exists
|
43
|
+
if @config&.stdin_temp_file && File.exist?(@config.stdin_temp_file)
|
44
|
+
File.unlink(@config.stdin_temp_file)
|
45
|
+
end
|
40
46
|
end
|
41
47
|
|
42
48
|
@config = nil
|
@@ -1,26 +1,34 @@
|
|
1
1
|
# lib/extensions/ruby_llm/modalities.rb
|
2
|
-
# A models "modes" are often expressed in terms like:
|
3
|
-
# text-to-text
|
4
|
-
# text_to_audio
|
5
|
-
# audio to image
|
6
|
-
# image2image
|
7
|
-
# This new supports? method tests the models modalities against
|
8
|
-
# these common expressions
|
9
2
|
|
10
3
|
class RubyLLM::Model::Modalities
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
4
|
+
#
|
5
|
+
def text_to_text? = input.include?('text') && output.include?('text')
|
6
|
+
def text_to_embeddings? = input.include?('text') && output.include?('embeddings')
|
7
|
+
def text_to_audio? = input.include?('text') && output.include?('audio')
|
8
|
+
def text_to_image? = input.include?('text') && output.include?('image')
|
9
|
+
def text_to_moderation? = input.include?('text') && output.include?('moderation')
|
10
|
+
#
|
11
|
+
def image_to_text? = input.include?('image') && output.include?('text')
|
12
|
+
def image_to_embeddings? = input.include?('image') && output.include?('embeddings')
|
13
|
+
def image_to_audio? = input.include?('image') && output.include?('audio')
|
14
|
+
def image_to_image? = input.include?('image') && output.include?('image')
|
15
|
+
def image_to_moderation? = input.include?('image') && output.include?('moderation')
|
16
|
+
#
|
17
|
+
def pdf_to_text? = input.include?('pdf') && output.include?('text')
|
18
|
+
def pdf_to_embeddings? = input.include?('pdf') && output.include?('embeddings')
|
19
|
+
def pdf_to_audio? = input.include?('pdf') && output.include?('audio')
|
20
|
+
def pdf_to_image? = input.include?('pdf') && output.include?('image')
|
21
|
+
def pdf_to_moderation? = input.include?('pdf') && output.include?('moderation')
|
22
|
+
#
|
23
|
+
def audio_to_text? = input.include?('audio') && output.include?('text')
|
24
|
+
def audio_to_embeddings? = input.include?('audio') && output.include?('embeddings')
|
25
|
+
def audio_to_audio? = input.include?('audio') && output.include?('audio')
|
26
|
+
def audio_to_image? = input.include?('audio') && output.include?('image')
|
27
|
+
def audio_to_moderation? = input.include?('audio') && output.include?('moderation')
|
28
|
+
#
|
29
|
+
def file_to_text? = input.include?('file') && output.include?('text')
|
30
|
+
def file_to_embeddings? = input.include?('file') && output.include?('embeddings')
|
31
|
+
def file_to_audio? = input.include?('file') && output.include?('audio')
|
32
|
+
def file_to_image? = input.include?('file') && output.include?('image')
|
33
|
+
def file_to_moderation? = input.include?('file') && output.include?('moderation')
|
26
34
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dewayne VanHoozer
|
@@ -9,6 +9,20 @@ bindir: bin
|
|
9
9
|
cert_chain: []
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: activesupport
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '0'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '0'
|
12
26
|
- !ruby/object:Gem::Dependency
|
13
27
|
name: amazing_print
|
14
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -57,14 +71,28 @@ dependencies:
|
|
57
71
|
requirements:
|
58
72
|
- - ">="
|
59
73
|
- !ruby/object:Gem::Version
|
60
|
-
version: 1.3.
|
74
|
+
version: 1.3.1
|
61
75
|
type: :runtime
|
62
76
|
prerelease: false
|
63
77
|
version_requirements: !ruby/object:Gem::Requirement
|
64
78
|
requirements:
|
65
79
|
- - ">="
|
66
80
|
- !ruby/object:Gem::Version
|
67
|
-
version: 1.3.
|
81
|
+
version: 1.3.1
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: ruby_llm-mcp
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
type: :runtime
|
90
|
+
prerelease: false
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
68
96
|
- !ruby/object:Gem::Dependency
|
69
97
|
name: reline
|
70
98
|
requirement: !ruby/object:Gem::Requirement
|
@@ -292,6 +320,7 @@ files:
|
|
292
320
|
- examples/tools/list_files.rb
|
293
321
|
- examples/tools/read_file.rb
|
294
322
|
- examples/tools/run_shell_command.rb
|
323
|
+
- images/aia.png
|
295
324
|
- justfile
|
296
325
|
- lib/aia.rb
|
297
326
|
- lib/aia/aia_completion.bash
|