richat 0.2.4 → 0.2.5

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: 90dc1c0cb9c1069b11e432d7164fe8b17d0095e19a82ea5830ba1f57fd98511c
4
- data.tar.gz: 11b9948cc323b52f14f3d89e0d2ca392988130c284c95e5b2e44df3c0e2ce356
3
+ metadata.gz: a6a6598af5c6e17f582012237108fdb8476d3c8c2b015114a8f2e5b72fcd8e02
4
+ data.tar.gz: 2103424385ccbc8342beca1be859faeb2c42a5f15ae4188b8253651d18a438d1
5
5
  SHA512:
6
- metadata.gz: 3c4171cad77ca01fa510cda74a1a8ff08c7a9db288d7172c16bf6d31219f4436f8e228b10bd735369bdf2f3f7b0b7782ebfcf003df86572941b7bc0add8e1abc
7
- data.tar.gz: e37cd9b94f2e2346d8412627be3538453922c1ce0b0bd1b165451861f6060b13781a7cde6f4cc399f1096d128238549508e0449326a739d5e14b8d2fb4c3b69a
6
+ metadata.gz: e6a3aad954fb88a24cf79e9f334d5912fd0fac875b74c4e585d4fa10626179ce22c0912686b8b7e2ac4642ed77fdab7962b2a63a5fbca8c0df4ebf821e4ecad4
7
+ data.tar.gz: c4012e6a086e7bddfdcc1e65a488f4248254e4ab3d814319806cd53725f12e8b4f5ac6eff78b1df5203398e34d82825f3082ccc0a96823b891e295a779e70510
data/exe/richat CHANGED
@@ -1,36 +1,76 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'bundler/setup'
3
+ require 'optparse'
4
4
  require 'richat'
5
5
 
6
- log_dir = File.expand_path(Richat::Config.get("log", "log_dir"))
7
- FileUtils.mkdir_p(log_dir) unless File.directory?(log_dir)
6
+ cli_opts = {}
8
7
 
9
- prompt_dir = File.expand_path(Richat::Config.get("prompt", "prompt_dir"))
10
- FileUtils.mkdir_p(prompt_dir) unless File.directory?(prompt_dir)
8
+ OptionParser.new do |opts|
9
+ opts.banner = %q{Usage: richat [options] [chat content]
10
+ richat will enter shell mode if chat content is empty}
11
+ opts.version = Richat::VERSION
12
+ opts.program_name = "richat"
11
13
 
12
- chat_config = {
13
- api_key: Richat::Config.get("chatgpt", "api_key"),
14
- model: Richat::Config.get("chatgpt", "model"),
15
- temperature: Richat::Config.get("chatgpt", "temperature"),
16
- stream: true
17
- }
14
+ opts.separator "\nOptions:"
15
+
16
+ opts.on("-l", "--logfile=LOG FILE", "Set log file path") do |l|
17
+ cli_opts["log"] = { "log_file" => l }
18
+ end
19
+
20
+ opts.on_tail("-h", "--help", "Print help") do
21
+ puts opts
22
+ puts "\nFurther help: https://github.com/fzdp/richat"
23
+ exit
24
+ end
18
25
 
19
- if chat_config[:api_key].nil? || chat_config[:api_key].empty?
26
+ opts.on_tail("-v", "--version", "Version") do
27
+ puts "richat " + Richat::VERSION
28
+ exit
29
+ end
30
+ end.parse!
31
+
32
+ Richat::Config.override_with(cli_opts) unless cli_opts.empty?
33
+
34
+ api_key = Richat::Config.get("chatgpt", "api_key")
35
+ if api_key.nil? || api_key.empty?
20
36
  puts "OpenAI API key not set, refer https://github.com/fzdp/richat#usage for more info."
21
37
  exit
22
38
  end
23
39
 
24
40
  if Richat::Config.get("log", "enable")
25
- logger = Richat::Logger.new(log_file: "#{log_dir}/#{Time.now.strftime('%Y%m%d')}.md")
41
+ log_dir = File.expand_path(Richat::Config.get("log", "log_dir"))
42
+ log_file = Richat::Config.get("log", "log_file")
43
+
44
+ if log_file.nil? || log_file.empty?
45
+ log_file = File.join(log_dir, "#{Time.now.strftime('%Y%m%d')}.md")
46
+ elsif log_file.start_with? "~/"
47
+ log_file = File.expand_path(log_file)
48
+ elsif !Richat::Utils.absolute_path?(log_file)
49
+ log_file = File.join(log_dir, log_file)
50
+ end
51
+
52
+ Richat::Utils.ensure_dir_exist(File.dirname(log_file))
53
+ logger = Richat::Logger.new(log_file: log_file)
26
54
  else
27
55
  logger = Richat::Logger.empty_logger
28
56
  end
29
57
 
30
- if ARGV.size.zero?
58
+ prompt_dir = File.expand_path(Richat::Config.get("prompt", "prompt_dir"))
59
+ Richat::Utils.ensure_dir_exist(prompt_dir)
60
+
61
+ user_content = ARGV.join(" ")
62
+
63
+ chat_config = {
64
+ api_key: Richat::Config.get("chatgpt", "api_key"),
65
+ model: Richat::Config.get("chatgpt", "model"),
66
+ temperature: Richat::Config.get("chatgpt", "temperature"),
67
+ stream: true
68
+ }
69
+
70
+ if user_content.empty?
31
71
  client = Openai::Chat.new(chat_config)
32
72
  Richat::Shell.new(chat_client: client, logger: logger).call
33
73
  else
34
74
  client = Openai::Chat.new(chat_config.merge(stream: false))
35
- Richat::Cli.new(chat_client: client, logger: logger, user_content: ARGV.join(" ")).call
75
+ Richat::Cli.new(chat_client: client, logger: logger, user_content: user_content).call
36
76
  end
@@ -32,7 +32,7 @@ module Richat
32
32
 
33
33
  def handle_config
34
34
  puts "\e[32mConfiguration file path is #{File.expand_path("~/.richat/config.json")}\e[0m"
35
- puts JSON.pretty_generate(Config.config)
35
+ puts JSON.pretty_generate(Config.get_config)
36
36
  NEXT_CODE
37
37
  end
38
38
 
data/lib/richat/config.rb CHANGED
@@ -9,6 +9,7 @@ module Richat
9
9
  "log" => {
10
10
  "enable" => true,
11
11
  "log_dir" => "~/.richat/logs",
12
+ "log_file" => nil,
12
13
  "user_role" => "USR",
13
14
  "ai_role" => "GPT",
14
15
  "system_role" => "SYS"
@@ -28,8 +29,16 @@ module Richat
28
29
  class << self
29
30
  attr_reader :config
30
31
 
32
+ def get_config
33
+ (@config ||= merge_config)
34
+ end
35
+
31
36
  def get(*keys)
32
- (@config ||= merge_config).dig(*keys)
37
+ get_config.dig(*keys)
38
+ end
39
+
40
+ def override_with(other_config)
41
+ @config = Utils.deep_merge_hash(get_config, other_config)
33
42
  end
34
43
  end
35
44
 
@@ -41,7 +50,7 @@ module Richat
41
50
  else
42
51
  {}
43
52
  end
44
- DEFAULT_CONFIG.deep_merge(user_config)
53
+ Utils.deep_merge_hash(DEFAULT_CONFIG, user_config)
45
54
  end
46
55
  end
47
56
  end
@@ -0,0 +1,33 @@
1
+ module Richat
2
+ class Utils
3
+ class << self
4
+ def deep_merge_hash(hs1, hs2)
5
+ result = hs1.dup
6
+
7
+ hs2.each do |key, value|
8
+ if value.is_a?(Hash) && hs1[key].is_a?(Hash)
9
+ result[key] = deep_merge_hash(result[key], value)
10
+ else
11
+ result[key] = value
12
+ end
13
+ end
14
+
15
+ result
16
+ end
17
+
18
+ def absolute_path?(fp)
19
+ File.expand_path(fp) == fp
20
+ end
21
+
22
+ def ensure_dir_exist(*dirs)
23
+ dirs.each do |dir_name|
24
+ if dir_name.nil? || dir_name.empty?
25
+ puts "invalid directory"
26
+ exit
27
+ end
28
+ FileUtils.mkdir_p(dir_name) unless File.directory?(dir_name)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,3 +1,3 @@
1
1
  module Richat
2
- VERSION = "0.2.4"
2
+ VERSION = "0.2.5"
3
3
  end
data/lib/richat.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require "richat/version"
2
2
 
3
- require_relative 'extension/hash'
3
+ require_relative 'richat/utils'
4
4
  require_relative 'richat/config'
5
5
  require_relative 'richat/command'
6
6
  require_relative 'openai/chat'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: richat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - fzdp
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-04-04 00:00:00.000000000 Z
11
+ date: 2023-04-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -77,7 +77,6 @@ extensions: []
77
77
  extra_rdoc_files: []
78
78
  files:
79
79
  - exe/richat
80
- - lib/extension/hash.rb
81
80
  - lib/openai/chat.rb
82
81
  - lib/richat.rb
83
82
  - lib/richat/cli.rb
@@ -85,6 +84,7 @@ files:
85
84
  - lib/richat/config.rb
86
85
  - lib/richat/logger.rb
87
86
  - lib/richat/shell.rb
87
+ - lib/richat/utils.rb
88
88
  - lib/richat/version.rb
89
89
  homepage: https://github.com/fzdp/richat
90
90
  licenses:
@@ -107,7 +107,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
107
  - !ruby/object:Gem::Version
108
108
  version: '0'
109
109
  requirements: []
110
- rubygems_version: 3.0.9
110
+ rubygems_version: 3.4.10
111
111
  signing_key:
112
112
  specification_version: 4
113
113
  summary: Richat is a command-line ChatGPT tool
@@ -1,15 +0,0 @@
1
- class Hash
2
- def deep_merge(other_hash)
3
- result = self.dup
4
-
5
- other_hash.each do |key, value|
6
- if value.is_a?(Hash) && self[key].is_a?(Hash)
7
- result[key] = result[key].deep_merge(value)
8
- else
9
- result[key] = value
10
- end
11
- end
12
-
13
- result
14
- end
15
- end