askcii 0.2.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2fdbbba27b8846c738014ebaab5466f00b2a73b74c2b5c898bee87bd60752f6d
4
- data.tar.gz: 737756f8559f8f518829b440d5a8d273a70d331731da02ed5be06230b0cad467
3
+ metadata.gz: fdbabf6bbd313aa11a7868b5df4630a85798e6a59311872bc04cebeaa2ac49e3
4
+ data.tar.gz: cff4449b247c8dcfe5273e122b054d72e54f57866f905854fd94aa39ee8e8547
5
5
  SHA512:
6
- metadata.gz: c2a8b74fd5e2ef08a7c1f386964f3a9ccae35e9e0d1ec9f37b28253a420f1849f909fbac88452b9615f5bb928db6814871633b68bd48ec376f2c1afb4951a089
7
- data.tar.gz: 7bbd8c8a9157c5d7439be1d49dd20db68bb99ca9ef7fc47a9b4cd9a9c8372ebf89521a0edfdb4745587367852d72e017ef1f5fabd2e4cf153f92bfa2c259f31f
6
+ metadata.gz: 5ca4009158417d0eee5a4452c4ec5c49fefedabdeb22495a2f6b6d08136391f19535e9468113c164f714e0a382eb8b57244e56027d6b824f23132fea679a4d29
7
+ data.tar.gz: ee32e1ab823d7a2dc53445e3fa7cf064993272571512f6c4b18966bbb08c87163158262387521d073d5bfa0c158f80b8ab808f05c98f8e330aaaa555122814f2
data/Gemfile.lock CHANGED
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- askcii (0.1.0)
4
+ askcii (0.3.0)
5
5
  amalgalite (~> 1.9)
6
- ruby_llm (= 1.3.0)
6
+ ruby_llm (= 1.5.1)
7
7
  sequel (~> 5.92)
8
8
 
9
9
  GEM
@@ -14,6 +14,7 @@ GEM
14
14
  arrayfields (4.9.2)
15
15
  base64 (0.2.0)
16
16
  bigdecimal (3.1.9)
17
+ csv (3.3.5)
17
18
  event_stream_parser (1.0.0)
18
19
  faraday (2.13.1)
19
20
  faraday-net_http (>= 2.0, < 3.5)
@@ -32,8 +33,9 @@ GEM
32
33
  multipart-post (2.4.1)
33
34
  net-http (0.6.0)
34
35
  uri
36
+ ostruct (0.6.3)
35
37
  rake (13.2.1)
36
- ruby_llm (1.3.0)
38
+ ruby_llm (1.5.1)
37
39
  base64
38
40
  event_stream_parser (~> 1)
39
41
  faraday (>= 1.10.0)
@@ -61,7 +63,9 @@ PLATFORMS
61
63
 
62
64
  DEPENDENCIES
63
65
  askcii!
66
+ csv (~> 3.0)
64
67
  minitest (~> 5.25)
68
+ ostruct (~> 0.6)
65
69
  rake (~> 13.0)
66
70
 
67
71
  BUNDLED WITH
data/Rakefile CHANGED
@@ -1,8 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
4
+ require 'rake/testtask'
5
5
 
6
- RSpec::Core::RakeTask.new(:spec)
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << 'test'
8
+ t.libs << 'lib'
9
+ t.test_files = FileList['test/**/*_test.rb']
10
+ end
7
11
 
8
- task default: :spec
12
+ Rake::TestTask.new(:comprehensive) do |t|
13
+ t.libs << 'test'
14
+ t.libs << 'lib'
15
+ t.test_files = FileList['test/comprehensive_test.rb']
16
+ end
17
+
18
+ Rake::TestTask.new(:simple) do |t|
19
+ t.libs << 'test'
20
+ t.libs << 'lib'
21
+ t.test_files = FileList['test/simple_test.rb']
22
+ end
23
+
24
+ task default: :comprehensive
data/askcii.gemspec CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |spec|
6
6
  spec.name = 'askcii'
7
7
  spec.version = Askcii::VERSION
8
8
  spec.authors = ['Roel Bondoc']
9
- spec.email = ['roelbondoc@example.com']
9
+ spec.email = ['rsbondoc@gmail.com']
10
10
 
11
11
  spec.summary = 'Command line application for LLM interactions'
12
12
  spec.description = 'A terminal-friendly interface for interacting with LLM models'
@@ -27,9 +27,11 @@ Gem::Specification.new do |spec|
27
27
  spec.require_paths = ['lib']
28
28
 
29
29
  spec.add_dependency 'amalgalite', '~> 1.9'
30
- spec.add_dependency 'ruby_llm', '1.3.0'
30
+ spec.add_dependency 'ruby_llm', '1.5.1'
31
31
  spec.add_dependency 'sequel', '~> 5.92'
32
32
 
33
+ spec.add_development_dependency 'csv', '~> 3.0'
33
34
  spec.add_development_dependency 'minitest', '~> 5.25'
35
+ spec.add_development_dependency 'ostruct', '~> 0.6'
34
36
  spec.add_development_dependency 'rake', '~> 13.0'
35
37
  end
@@ -23,19 +23,20 @@ module Askcii
23
23
  exit 0
24
24
  end
25
25
 
26
- if @cli.show_usage?
27
- puts @cli.usage_message
28
- exit 1
29
- end
30
-
31
26
  selected_config = determine_configuration
32
27
  configure_llm(selected_config)
33
28
 
34
29
  chat_session = ChatSession.new(@cli.options, selected_config)
35
30
  chat_session.handle_last_response if @cli.last_response?
36
31
 
37
- input = read_stdin_input
38
- chat_session.execute_chat(@cli.prompt, input)
32
+ prompt, input = determine_prompt_and_input
33
+
34
+ if prompt.empty? && input.nil?
35
+ puts @cli.usage_message
36
+ exit 1
37
+ end
38
+
39
+ chat_session.execute_chat(prompt, input)
39
40
  end
40
41
 
41
42
  private
@@ -61,6 +62,21 @@ module Askcii
61
62
  Askcii.configure_llm(selected_config)
62
63
  end
63
64
 
65
+ def determine_prompt_and_input
66
+ stdin_content = read_stdin_input
67
+
68
+ if @cli.prompt.empty? && stdin_content
69
+ # No prompt provided via args, use stdin as prompt
70
+ [stdin_content.strip, nil]
71
+ elsif !@cli.prompt.empty? && stdin_content
72
+ # Both prompt and stdin provided, use stdin as input context
73
+ [@cli.prompt, stdin_content]
74
+ else
75
+ # Only prompt provided (or neither)
76
+ [@cli.prompt, nil]
77
+ end
78
+ end
79
+
64
80
  def read_stdin_input
65
81
  return nil if $stdin.tty?
66
82
 
@@ -16,7 +16,7 @@ module Askcii
16
16
  model_id = @selected_config['model_id']
17
17
  chat_record = Askcii::Chat.find_or_create(context: context, model_id: model_id)
18
18
 
19
- last_message = chat_record.messages.where(role: 'assistant').last
19
+ last_message = chat_record.messages.select { |msg| msg.role == 'assistant' }.last
20
20
  if last_message
21
21
  puts last_message.content
22
22
  exit 0
data/lib/askcii/cli.rb CHANGED
@@ -23,7 +23,7 @@ module Askcii
23
23
  end
24
24
 
25
25
  def show_usage?
26
- @prompt.empty? && !configure? && !last_response?
26
+ false # Usage logic is now handled in Application class
27
27
  end
28
28
 
29
29
  def configure?
@@ -50,8 +50,10 @@ module Askcii
50
50
  <<~USAGE
51
51
  Usage:
52
52
  askcii [options] 'Your prompt here'
53
- echo 'Your prompt here' | askcii 'Your prompt here'
54
- askcii 'Your prompt here' < prompt.txt
53
+ echo 'Your prompt here' | askcii # Use piped text as prompt
54
+ echo 'Context text' | askcii 'Your prompt here' # Use piped text as context
55
+ askcii 'Your prompt here' < prompt.txt # Use file content as context
56
+ cat prompt.txt | askcii # Use file content as prompt
55
57
  askcii -p (start a private session)
56
58
  askcii -r (to get the last response)
57
59
  askcii -c (manage configurations)
@@ -20,6 +20,67 @@ module Askcii
20
20
  'ollama' => 'http://localhost:11434/v1'
21
21
  }.freeze
22
22
 
23
+ PROVIDER_MODELS = {
24
+ 'openai' => {
25
+ default: 'gpt-4o',
26
+ models: [
27
+ 'gpt-4o',
28
+ 'gpt-4o-mini',
29
+ 'gpt-4-turbo',
30
+ 'gpt-4',
31
+ 'gpt-3.5-turbo'
32
+ ]
33
+ },
34
+ 'anthropic' => {
35
+ default: 'claude-3-5-sonnet-20241022',
36
+ models: [
37
+ 'claude-3-5-sonnet-20241022',
38
+ 'claude-3-5-haiku-20241022',
39
+ 'claude-3-opus-20240229',
40
+ 'claude-3-sonnet-20240229',
41
+ 'claude-3-haiku-20240307'
42
+ ]
43
+ },
44
+ 'gemini' => {
45
+ default: 'gemini-pro',
46
+ models: [
47
+ 'gemini-pro',
48
+ 'gemini-pro-vision',
49
+ 'gemini-1.5-pro',
50
+ 'gemini-1.5-flash'
51
+ ]
52
+ },
53
+ 'deepseek' => {
54
+ default: 'deepseek-chat',
55
+ models: %w[
56
+ deepseek-chat
57
+ deepseek-coder
58
+ ]
59
+ },
60
+ 'openrouter' => {
61
+ default: 'anthropic/claude-3.5-sonnet',
62
+ models: [
63
+ 'anthropic/claude-3.5-sonnet',
64
+ 'openai/gpt-4o',
65
+ 'google/gemini-pro',
66
+ 'meta-llama/llama-3.1-405b-instruct',
67
+ 'anthropic/claude-3-opus',
68
+ 'openai/gpt-4-turbo'
69
+ ]
70
+ },
71
+ 'ollama' => {
72
+ default: 'llama3.2',
73
+ models: [
74
+ 'llama3.2',
75
+ 'llama3.1',
76
+ 'mistral',
77
+ 'codellama',
78
+ 'phi3',
79
+ 'gemma2'
80
+ ]
81
+ }
82
+ }.freeze
83
+
23
84
  def run
24
85
  show_current_configurations
25
86
  show_menu
@@ -85,7 +146,7 @@ module Askcii
85
146
  return unless api_key || provider == 'ollama'
86
147
 
87
148
  endpoint = get_api_endpoint(provider)
88
- model_id = get_model_id
149
+ model_id = get_model_id(provider)
89
150
 
90
151
  return unless model_id
91
152
 
@@ -136,16 +197,48 @@ module Askcii
136
197
  api_endpoint.empty? ? default_endpoint : api_endpoint
137
198
  end
138
199
 
139
- def get_model_id
140
- print 'Enter model ID: '
141
- model_id = $stdin.gets.chomp
200
+ def get_model_id(provider)
201
+ provider_config = PROVIDER_MODELS[provider]
142
202
 
143
- if model_id.empty?
144
- puts 'Model ID is required.'
145
- return nil
146
- end
203
+ if provider_config
204
+ default_model = provider_config[:default]
205
+ available_models = provider_config[:models]
206
+
207
+ puts "\nAvailable models for #{provider.capitalize}:"
208
+ available_models.each_with_index do |model, index|
209
+ marker = model == default_model ? ' (recommended)' : ''
210
+ puts " #{index + 1}. #{model}#{marker}"
211
+ end
212
+
213
+ puts " #{available_models.length + 1}. Enter custom model ID"
214
+ print "\nSelect model (1-#{available_models.length + 1}) or press Enter for default [#{default_model}]: "
215
+
216
+ choice = $stdin.gets.chomp
147
217
 
148
- model_id
218
+ if choice.empty?
219
+ default_model
220
+ elsif choice.to_i.between?(1, available_models.length)
221
+ available_models[choice.to_i - 1]
222
+ elsif choice.to_i == available_models.length + 1
223
+ print 'Enter custom model ID: '
224
+ custom_model = $stdin.gets.chomp
225
+ custom_model.empty? ? nil : custom_model
226
+ else
227
+ puts 'Invalid selection.'
228
+ nil
229
+ end
230
+ else
231
+ # Fallback for unknown providers
232
+ print 'Enter model ID: '
233
+ model_id = $stdin.gets.chomp
234
+
235
+ if model_id.empty?
236
+ puts 'Model ID is required.'
237
+ return nil
238
+ end
239
+
240
+ model_id
241
+ end
149
242
  end
150
243
 
151
244
  def set_default_configuration
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Askcii
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: askcii
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roel Bondoc
@@ -29,14 +29,14 @@ dependencies:
29
29
  requirements:
30
30
  - - '='
31
31
  - !ruby/object:Gem::Version
32
- version: 1.3.0
32
+ version: 1.5.1
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - '='
38
38
  - !ruby/object:Gem::Version
39
- version: 1.3.0
39
+ version: 1.5.1
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: sequel
42
42
  requirement: !ruby/object:Gem::Requirement
@@ -51,6 +51,20 @@ dependencies:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
53
  version: '5.92'
54
+ - !ruby/object:Gem::Dependency
55
+ name: csv
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '3.0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '3.0'
54
68
  - !ruby/object:Gem::Dependency
55
69
  name: minitest
56
70
  requirement: !ruby/object:Gem::Requirement
@@ -65,6 +79,20 @@ dependencies:
65
79
  - - "~>"
66
80
  - !ruby/object:Gem::Version
67
81
  version: '5.25'
82
+ - !ruby/object:Gem::Dependency
83
+ name: ostruct
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '0.6'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '0.6'
68
96
  - !ruby/object:Gem::Dependency
69
97
  name: rake
70
98
  requirement: !ruby/object:Gem::Requirement
@@ -81,7 +109,7 @@ dependencies:
81
109
  version: '13.0'
82
110
  description: A terminal-friendly interface for interacting with LLM models
83
111
  email:
84
- - roelbondoc@example.com
112
+ - rsbondoc@gmail.com
85
113
  executables:
86
114
  - askcii
87
115
  extensions: []