gchatsh 0.1.0 → 0.1.3

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: 9788d98155c783b0e7b9abd2294319e6c2573251f15a44d3da489d60f8b8d3e4
4
- data.tar.gz: bd41b359d6442ee99911a3acc7bf54eb2eeec17649d72bd4c1ff6a0b49e3caf9
3
+ metadata.gz: 15e8554d23c59775496e8459936f7fba1caecb5bab66d7037ac65e84c8592068
4
+ data.tar.gz: dd6d7d0b047f450923fc984771aa610afdd6d4ef5d0379e656666957e4407525
5
5
  SHA512:
6
- metadata.gz: 5351abe9692787e524912aa96fff6c730ed398fe6760db35d2af9e6f8289c284a8c7cdf614d952b01d039137f25de63191e74ad5ef92c49467f176c71c9e1d25
7
- data.tar.gz: ed4fd7ca9868a4e75247a9ce056e5778815523d68c3a9a6324a93bbc12c0683d6960c835e06c64d8493f332d8f749e5bc83f2378b81aa94cde87018119d5f4b5
6
+ metadata.gz: 1ed0cb1b67355dd020c42f3ef3360b346f814d1ef016918796dc5ab3f166df109e42a41fd0addb56572ffbfa5eb2d3c679714ba04878555769fa97d78eaf4ae6
7
+ data.tar.gz: d95fa6665e69e4eaf21fe9e044f7ae246d9c5da5a969fd4b8cf3fa831028f1ce7ec7bf00a24af9f6a9a5518b534f608057bd5db6f6199c3451f66fe8cdeba732
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.1.3
data/Makefile ADDED
@@ -0,0 +1,7 @@
1
+
2
+ start:
3
+ bin/gchatsh
4
+
5
+ deploy:
6
+ @echo "Deploying to Heroku..."
7
+ git push heroku master
data/bin/gchatsh ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/gchatsh'
4
+
5
+ GChatSH::Application.new.call
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Credentials class
4
+ class Credentials
5
+ attr_accessor :url, :key, :model
6
+
7
+ def initialize
8
+ credentials_file = File.expand_path('~/.gchatsh')
9
+ unless File.exist?(credentials_file)
10
+ raise "Credentials file not found at #{credentials_file} " \
11
+ "add a file here with the following credentials format:\n" \
12
+ "GROQ_API_URL=<API_URL>\nAPI_KEY=<API_KEY>"
13
+ end
14
+
15
+ File.readlines(credentials_file).each do |line|
16
+ key, value = line.strip.split('=')
17
+ case key
18
+ when 'KEY'
19
+ @key = value
20
+ when 'URL'
21
+ @url = value
22
+ when 'MODEL'
23
+ @model = value
24
+ else
25
+ raise 'Invalid credentials file format'
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Gchatsh
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.3"
5
5
  end
data/lib/gchatsh.rb CHANGED
@@ -1,222 +1,25 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'net/http'
5
- require 'json'
6
-
7
- def read_credentials
8
- credentials_file = File.expand_path('~/.gchatsh')
9
- credentials = {}
10
-
11
- if File.exist?(credentials_file)
12
- File.readlines(credentials_file).each do |line|
13
- key, value = line.strip.split('=')
14
- credentials[key] = value
4
+ require_relative 'credentials'
5
+ require_relative 'options'
6
+ require_relative 'groq_api'
7
+ require_relative 'user_input'
8
+
9
+ module GChatSH
10
+ class Application
11
+ attr_accessor :options
12
+ def initialize
13
+ @options = Options.new
14
+ @options.credentials = Credentials.new
15
15
  end
16
- else
17
- raise "Credentials file not found at #{credentials_file} add a file here with the following credentials format:\nGROQ_API_URL=<API_URL>\nAPI_KEY=<API_KEY>"
18
- end
19
-
20
- credentials
21
- end
22
-
23
- credentials = read_credentials
24
- GROQ_API_URL = credentials['GROQ_API_URL']
25
- API_KEY = credentials['API_KEY']
26
-
27
- SYSTEM_PROMPT = <<~SYSTEM_PROMPT
28
- You are ChatSH, an AI language model that specializes in assisting users with tasks on their system using shell commands, AND chatting or answering open-ended questions via the terminal.
29
-
30
- # CHATSH GUIDE:
31
-
32
- - If the USER asks you to perform a SYSTEM TASK, ChatSH must answer with a SHELL SCRIPT to perform the task.
33
-
34
- - If the USER asks an open-ended question, ChatSH must answer with a friendly, concise, factual response.
35
-
36
- # EXAMPLE 1: CHATTING AND PERFORMING SYSTEM COMMANDS
37
-
38
- <USER>
39
- Show me local files.
40
- </USER>
41
-
42
- <ChatSH>
43
- \`\`\`sh
44
- ls
45
- \`\`\`
46
- </ChatSH>
47
-
48
- <SYSTEM>
49
- example.gif example.tst example_dir/
50
- </SYSTEM>
51
-
52
- <USER>
53
- Is there any text file?
54
- </USER>
55
-
56
- <ChatSH>
57
- Yes, there is a file named example.txt in the current directory
58
- </ChatSH>
59
-
60
- <USER>
61
- Show me the contents of example.txt.
62
- </USER>
63
-
64
- <ChatSH>
65
- \`\`\`sh
66
- cat example.txt
67
- \`\`\`
68
- </ChatSH>
69
-
70
- # EXAMPLE 2: ASSISTING WITH CODING TASKS
71
-
72
- <USER>
73
- Fix main.ts
74
- </USER>
75
-
76
- <ChatSH>
77
- \`\`\`sh
78
- cat main.ts
79
- tsc --noEmit main.ts
80
- \`\`\`
81
- </ChatSH>
82
-
83
- <SYSTEM>
84
- import List from './list';
85
- import map from './map';
86
-
87
- const n_1_2: List<number> = { $: "cons", head: 1, tail: { $: "cons", head: 2, tail: { $: "nil" }}};
88
- const n_2_4: List<number> = map(n_1_2, x => x * 2);
89
-
90
- console.log(JSON.stringify(n_2_4));
91
-
92
- map.ts:7:22 - error TS2345: Argument of type '(val: T) => U' is not assignable to parameter of type 'List<unknown>'.
93
-
94
- 7 let tail = map(fun, list.tail);
95
- ~~~
96
- </SYSTEM>
97
16
 
98
- <ChatSH>
99
- \`\`\`sh
100
- ls
101
- \`\`\`
102
- </ChatSH>
103
-
104
- <SYSTEM>
105
- list.ts main.ts map.ts
106
- </SYSTEM>
107
-
108
- <ChatSH>
109
- \`\`\`sh
110
- cat map.ts
111
- \`\`\`
112
- </ChatSH>
113
-
114
- <SYSTEM>
115
- import List from './list';
116
-
117
- function map<T, U>(list: List<T>, fun: (val: T) => U): List<U> {
118
- switch (list.$) {
119
- case "cons":
120
- let head = fun(list.head);
121
- let tail = map(fun, list.tail);
122
- return { $: "cons", head, tail };
123
- case "nil":
124
- return { $: "nil" };
125
- }
126
- }
127
-
128
- export default map;
129
- </SYSTEM>
130
-
131
- <ChatSH>
132
- \`\`\`sh
133
- cat > map.ts << EOL
134
- import List from './list';
135
-
136
- function map<T, U>(list: List<T>, fun: (val: T) => U): List<U> {
137
- switch (list.$) {
138
- case "cons":
139
- let head = fun(list.head);
140
- let tail = map(list.tail, fun);
141
- return { $: "cons", head, tail };
142
- case "nil":
143
- return { $: "nil" };
144
- }
145
- }
146
-
147
- export default map;
148
- EOL
149
- tsc --noEmit map.ts
150
- \`\`\`
151
- </ChatSH>
152
-
153
- <SYSTEM>
154
-
155
- </SYSTEM>
156
-
157
- <ChatSH>
158
- Done.
159
- </ChatSH>
160
-
161
- ## NOTES:
162
-
163
- - In COMMAND MODE, answer with SH BLOCKS.
164
-
165
- - In TEXT MODE, answer with normal text.
166
-
167
- - Be concise, objective, correct and factual.
168
-
169
- - Do not attempt to install new tools; assume they're available.
170
-
171
- - Do not include the <ChatSH> tags in your answer.
172
-
173
- - REMEMBER: you are NOT limited to system tasks or shell commands. You must answer ANY question or request by the user.
174
-
175
- - The system shell in use is: bash.;
176
- SYSTEM_PROMPT
177
-
178
- # Function to send a code generation request to Groq API
179
- def generate_code(prompt)
180
- uri = URI(GROQ_API_URL)
181
- request = Net::HTTP::Post.new(uri)
182
- request['Content-Type'] = 'application/json'
183
- request['Authorization'] = "Bearer #{API_KEY}"
184
-
185
- request.body = {
186
- "model": 'llama3-8b-8192',
187
- "messages": [
188
- {
189
- "role": 'system',
190
- "content": SYSTEM_PROMPT
191
- },
192
- {
193
- "role": 'user',
194
- "content": prompt
195
- }
196
- ]
197
- }.to_json
198
-
199
- # Perform the request
200
- response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
201
- http.request(request)
202
- end
203
-
204
- # Process and display the result
205
- if response.code.to_i == 200
206
- result = JSON.parse(response.body)
207
- message_content = result.dig('choices', 0, 'message', 'content')
208
- puts message_content
209
- command = message_content.match(/sh\n(.+?)\n/m)[1]
210
- puts "\033[32m Execute the following command? (y/n) \033[0m"
211
- prompt = gets.chomp
212
- system(command) if prompt == 'y'
213
- else
214
- puts "Error: #{response.code} - #{response.message}"
215
- puts response.body
17
+ def call
18
+ system_prompt = File.read(File.join(__dir__, 'system_prompt.txt'))
19
+ user_prompt = UserInput.new.call
20
+ options.user_prompt = user_prompt
21
+ options.system_prompt = system_prompt
22
+ GroqApi.new(options).call
23
+ end
216
24
  end
217
25
  end
218
-
219
- # Example usage
220
- puts 'Enter your prompt for code generation:'
221
- prompt = gets.chomp
222
- generate_code(prompt)
data/lib/groq_api.rb ADDED
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'request'
4
+ require_relative 'parser'
5
+ require_relative 'syntax_highlighter'
6
+ require 'net/http'
7
+ require 'json'
8
+
9
+ # GroqApi
10
+ class GroqApi
11
+ attr_accessor :request, :syntax_highlighter
12
+
13
+ def initialize(options)
14
+ @request = Request.new(options)
15
+ @syntax_highlighter = SyntaxHighlighter.new
16
+ end
17
+
18
+ def xclip_installed?
19
+ system('which xclip > /dev/null 2>&1')
20
+ end
21
+
22
+ def call
23
+ message_content = request.call
24
+ File.open(File.expand_path('~/.gchat.log'), 'a') do |file|
25
+ file.puts("#{message_content}\n")
26
+ end
27
+ # puts ''
28
+ # puts message_content
29
+ matches = Parser.new(message_content).parse
30
+ if matches
31
+ command = matches[0]
32
+ else
33
+ puts "\033[31m No command found in the message content. \033[0m"
34
+ return
35
+ end
36
+
37
+ puts ''
38
+ puts ''
39
+ puts "\033[32m====================================== \033[0m"
40
+ puts ''
41
+ puts syntax_highlighter.highlight(command)
42
+ puts ''
43
+ puts "\033[32mrun(r) copy(o) cancel(c) \033[0m"
44
+ prompt = gets.chomp
45
+ exit if prompt == 'c'
46
+ system(command) if prompt == 'r'
47
+ if prompt == 'o'
48
+ if xclip_installed?
49
+ IO.popen('xclip -selection clipboard', 'w') { |f| f << command }
50
+ else
51
+ puts "\033[31m xclip is not installed. Please install xclip to use the copy feature. \033[0m"
52
+ end
53
+ end
54
+ end
55
+ end
data/lib/options.rb ADDED
@@ -0,0 +1,9 @@
1
+ class Options
2
+ attr_accessor :user_prompt, :system_prompt, :credentials
3
+
4
+ def initialize
5
+ @user_prompt = nil
6
+ @system_prompt = nil
7
+ @credentials = nil
8
+ end
9
+ end
data/lib/parser.rb ADDED
@@ -0,0 +1,41 @@
1
+ class Parser
2
+ attr_accessor :text
3
+
4
+ def initialize(text)
5
+ @text = text
6
+ end
7
+
8
+ def match_triple_backticks_sh
9
+ triple_sh = text.scan(/```sh\s*(.*?)\s*```/m).flatten
10
+ text.gsub!(/```sh\s*.*?\s*```/m, '')
11
+ triple_sh
12
+ end
13
+
14
+ def match_backticks
15
+ match_backticks = text.scan(/`(.*?)`/).flatten
16
+ text.gsub!(/`.*?`/, '')
17
+ match_backticks
18
+ end
19
+
20
+ def match_triple_backticks
21
+ triple_backtick_content = text.scan(/```\s*(.*?)\s*```/m).flatten
22
+ text.gsub!(/```\s*.*?\s```/m, '')
23
+ triple_backtick_content
24
+ end
25
+
26
+ def parse
27
+ matches = match_triple_backticks_sh + match_triple_backticks + match_backticks
28
+ matches.reject!(&:empty?)
29
+ matches
30
+ end
31
+ end
32
+
33
+ # text = <<~TEXT
34
+ # this is a text
35
+ # ```
36
+ # echo "hello"
37
+ # ```
38
+ # and that
39
+ # TEXT
40
+
41
+ # Parser.new(text).parse
data/lib/request.rb ADDED
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'json'
5
+
6
+ # request
7
+ class Request
8
+ attr_accessor :uri, :request
9
+
10
+ def initialize(options)
11
+ @uri = URI(options.credentials.url)
12
+ @request = Net::HTTP::Post.new(@uri)
13
+ @request['Content-Type'] = 'application/json'
14
+ @request['Authorization'] = "Bearer #{options.credentials.key}"
15
+ request_body(options)
16
+ end
17
+
18
+ def request_body(options)
19
+ request.body = {
20
+ "model": options.credentials.model,
21
+ "messages": [
22
+ {
23
+ "role": 'system',
24
+ "content": options.system_prompt
25
+ },
26
+ {
27
+ "role": 'user',
28
+ "content": options.user_prompt
29
+ }
30
+ ]
31
+ }.to_json
32
+ end
33
+
34
+ def call
35
+ response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
36
+ http.request(request)
37
+ end
38
+
39
+ if response.code.to_i != 200
40
+ puts "Error: #{response.code} - #{response.message}"
41
+ puts response.body
42
+ return
43
+ end
44
+
45
+ result = JSON.parse(response.body)
46
+ result.dig('choices', 0, 'message', 'content')
47
+ end
48
+ end
@@ -0,0 +1,15 @@
1
+ require 'rouge'
2
+
3
+ # syntax highlighting class
4
+ class SyntaxHighlighter
5
+ attr_reader :formatter, :lexer
6
+
7
+ def initialize
8
+ @formatter = Rouge::Formatters::Terminal256.new
9
+ @lexer = Rouge::Lexers::Shell.new
10
+ end
11
+
12
+ def highlight(code)
13
+ formatter.format(lexer.lex(code))
14
+ end
15
+ end
@@ -0,0 +1,184 @@
1
+ You are ChatSH, an AI language model that specializes in assisting users with tasks on their system using shell commands.
2
+
3
+ # CHATSH GUIDE:
4
+
5
+ - If the USER asks you to perform a SYSTEM TASK, ChatSH must answer with a SHELL SCRIPT to perform the task.
6
+
7
+ # EXAMPLE 1: CHATTING AND PERFORMING SYSTEM COMMANDS
8
+
9
+ <USER>
10
+ Show me local files.
11
+ </USER>
12
+
13
+ <ChatSH>
14
+ ```sh
15
+ ls
16
+ ```
17
+ </ChatSH>
18
+
19
+ <SYSTEM>
20
+ example.gif example.tst example_dir/
21
+ </SYSTEM>
22
+
23
+ <USER>
24
+ Is there any text file?
25
+ </USER>
26
+
27
+ <ChatSH>
28
+ Yes, there is a file named example.txt in the current directory
29
+ </ChatSH>
30
+
31
+ <USER>
32
+ Show me the contents of example.txt.
33
+ </USER>
34
+
35
+ <ChatSH>
36
+ \\\sh
37
+ cat example.txt
38
+ \\\
39
+ </ChatSH>
40
+
41
+ <SYSTEM>
42
+ Na matemática, um grupo é um conjunto de elementos associados a uma operação que combina dois elementos quaisquer para formar um terceiro. Para se qualificar como grupo o conjunto e a operação devem satisfazer algumas condições chamadas axiomas de grupo: associatividade, elemento neutro e elementos inversos.
43
+ </SYSTEM>
44
+
45
+ <USER>
46
+ Can you translate the first sentence to English?
47
+ </USER>
48
+
49
+ <ChatSH>
50
+ In mathematics, a group is a set of elements associated with an operation that combines any two elements to form a third element.
51
+ </ChatSH>
52
+
53
+ <USER>
54
+ What is the monster group?
55
+ </USER>
56
+
57
+ <ChatSH>
58
+ The monster group is the largest sporadic simple group, with order approximately 8×10^53.
59
+ </ChatSH>
60
+
61
+ <USER>
62
+ What is a simple group?
63
+ </USER>
64
+
65
+ <ChatSH>
66
+ A simple group is a nontrivial group that contains no proper nontrivial normal subgroups.
67
+ </ChatSH>
68
+
69
+ <USER>
70
+ Move the text file to that dir.
71
+ </USER>
72
+
73
+ <ChatSH>
74
+ ```sh
75
+ mv example.txt example_dir/
76
+ ```
77
+ </ChatSH>
78
+
79
+ # EXAMPLE 2: ASSISTING WITH CODING TASKS
80
+
81
+ <USER>
82
+ Fix main.ts
83
+ </USER>
84
+
85
+ <ChatSH>
86
+ ```sh
87
+ cat main.ts
88
+ tsc --noEmit main.ts
89
+ ```
90
+ </ChatSH>
91
+
92
+ <SYSTEM>
93
+ import List from './list';
94
+ import map from './map';
95
+
96
+ const n_1_2: List<number> = { $: "cons", head: 1, tail: { $: "cons", head: 2, tail: { $: "nil" }}};
97
+ const n_2_4: List<number> = map(n_1_2, x => x * 2);
98
+
99
+ console.log(JSON.stringify(n_2_4));
100
+
101
+ map.ts:7:22 - error TS2345: Argument of type '(val: T) => U' is not assignable to parameter of type 'List<unknown>'.
102
+
103
+ 7 let tail = map(fun, list.tail);
104
+ ~~~
105
+ </SYSTEM>
106
+
107
+ <ChatSH>
108
+ ```sh
109
+ ls
110
+ ```
111
+ </ChatSH>
112
+
113
+ <SYSTEM>
114
+ list.ts main.ts map.ts
115
+ </SYSTEM>
116
+
117
+ <ChatSH>
118
+ import List from './list';
119
+ ```sh
120
+ cat map.ts
121
+ ```
122
+ </ChatSH>
123
+
124
+ <SYSTEM>
125
+
126
+ function map<T, U>(list: List<T>, fun: (val: T) => U): List<U> {
127
+ switch (list.$) {
128
+ case "cons":
129
+ let head = fun(list.head);
130
+ let tail = map(fun, list.tail);
131
+ return { $: "cons", head, tail };
132
+ case "nil":
133
+ return { $: "nil" };
134
+ }
135
+ }
136
+
137
+ export default map;
138
+ </SYSTEM>
139
+
140
+ <ChatSH>
141
+ ```sh
142
+ cat > map.ts << EOL
143
+ import List from './list';
144
+
145
+ function map<T, U>(list: List<T>, fun: (val: T) => U): List<U> {
146
+ switch (list.$) {
147
+ case "cons":
148
+ let head = fun(list.head);
149
+ let tail = map(list.tail, fun);
150
+ return { $: "cons", head, tail };
151
+ case "nil":
152
+ return { $: "nil" };
153
+ }
154
+ }
155
+
156
+ export default map;
157
+ EOL
158
+ tsc --noEmit map.ts
159
+ ```
160
+ </ChatSH>
161
+
162
+ <SYSTEM>
163
+
164
+ </SYSTEM>
165
+
166
+ <ChatSH>
167
+ Done.
168
+ </ChatSH>
169
+
170
+ ## NOTES:
171
+
172
+ - In COMMAND MODE, answer with SH BLOCKS.
173
+
174
+ - In TEXT MODE, answer with normal text.
175
+
176
+ - Be concise, objective, correct and factual.
177
+
178
+ - Do not attempt to install new tools; assume they're available.
179
+
180
+ - Do not include the <ChatSH> tags in your answer.
181
+
182
+ - REMEMBER: you are NOT limited to system tasks or shell commands. You must answer ANY question or request by the user.
183
+
184
+ - The system shell in use is: bash.
data/lib/user_input.rb ADDED
@@ -0,0 +1,26 @@
1
+ require 'io/console'
2
+
3
+ class UserInput
4
+ def clean_input
5
+ input = ""
6
+ while (char = STDIN.getch) != "\r"
7
+ if char == "\u0003" # Handle Ctrl+C
8
+ puts "\nOperation cancelled."
9
+ exit
10
+ elsif char == "\u0008" || char == "\u007F" # Handle Backspace (ASCII 8 or 127)
11
+ input.chop! unless input.empty?
12
+ print "\b \b"
13
+ else
14
+ input << char
15
+ print char
16
+ end
17
+ end
18
+ input
19
+ end
20
+
21
+ def call
22
+ puts "\033[32mEnter your input: \033[0m"
23
+ input = clean_input
24
+ input
25
+ end
26
+ end
metadata CHANGED
@@ -1,37 +1,44 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gchatsh
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - ____marcell
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2024-12-04 00:00:00.000000000 Z
11
+ date: 2024-12-14 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Use bash to interact with groq in your terminal and execute sh scripts
13
+ description:
14
14
  email:
15
15
  - 0000marcell@gmail.com
16
- executables: []
16
+ executables:
17
+ - gchatsh
17
18
  extensions: []
18
19
  extra_rdoc_files: []
19
20
  files:
20
- - LICENSE.txt
21
+ - ".ruby-version"
22
+ - Makefile
21
23
  - README.md
22
24
  - Rakefile
23
- - gchatsh.rb
24
- - install-locally.sh
25
+ - bin/gchatsh
26
+ - lib/credentials.rb
25
27
  - lib/gchatsh.rb
26
28
  - lib/gchatsh/version.rb
29
+ - lib/groq_api.rb
30
+ - lib/options.rb
31
+ - lib/parser.rb
32
+ - lib/request.rb
33
+ - lib/syntax_highlighter.rb
34
+ - lib/system_prompt.txt
35
+ - lib/user_input.rb
27
36
  - sig/gchatsh.rbs
28
- homepage: ''
37
+ homepage: https://github.com/0000marcell/gchatsh
29
38
  licenses:
30
39
  - MIT
31
40
  metadata:
32
- homepage_uri: https://github.com/0000marcell/gchatsh
33
41
  source_code_uri: https://github.com/0000marcell/gchatsh
34
- changelog_uri: https://github.com/0000marcell/gchatsh
35
42
  post_install_message:
36
43
  rdoc_options: []
37
44
  require_paths:
@@ -47,7 +54,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
47
54
  - !ruby/object:Gem::Version
48
55
  version: '0'
49
56
  requirements: []
50
- rubygems_version: 3.5.22
57
+ rubygems_version: 3.3.26
51
58
  signing_key:
52
59
  specification_version: 4
53
60
  summary: Use bash to interact with groq in your terminal and execute sh scripts
data/LICENSE.txt DELETED
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2024 ____marcell
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
data/gchatsh.rb DELETED
@@ -1,222 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require 'net/http'
5
- require 'json'
6
-
7
- def read_credentials
8
- credentials_file = File.expand_path('~/.gchatsh')
9
- credentials = {}
10
-
11
- if File.exist?(credentials_file)
12
- File.readlines(credentials_file).each do |line|
13
- key, value = line.strip.split('=')
14
- credentials[key] = value
15
- end
16
- else
17
- raise "Credentials file not found at #{credentials_file} add a file here with the following credentials format:\nGROQ_API_URL=<API_URL>\nAPI_KEY=<API_KEY>"
18
- end
19
-
20
- credentials
21
- end
22
-
23
- credentials = read_credentials
24
- GROQ_API_URL = credentials['GROQ_API_URL']
25
- API_KEY = credentials['API_KEY']
26
-
27
- SYSTEM_PROMPT = <<~SYSTEM_PROMPT
28
- You are ChatSH, an AI language model that specializes in assisting users with tasks on their system using shell commands, AND chatting or answering open-ended questions via the terminal.
29
-
30
- # CHATSH GUIDE:
31
-
32
- - If the USER asks you to perform a SYSTEM TASK, ChatSH must answer with a SHELL SCRIPT to perform the task.
33
-
34
- - If the USER asks an open-ended question, ChatSH must answer with a friendly, concise, factual response.
35
-
36
- # EXAMPLE 1: CHATTING AND PERFORMING SYSTEM COMMANDS
37
-
38
- <USER>
39
- Show me local files.
40
- </USER>
41
-
42
- <ChatSH>
43
- \`\`\`sh
44
- ls
45
- \`\`\`
46
- </ChatSH>
47
-
48
- <SYSTEM>
49
- example.gif example.tst example_dir/
50
- </SYSTEM>
51
-
52
- <USER>
53
- Is there any text file?
54
- </USER>
55
-
56
- <ChatSH>
57
- Yes, there is a file named example.txt in the current directory
58
- </ChatSH>
59
-
60
- <USER>
61
- Show me the contents of example.txt.
62
- </USER>
63
-
64
- <ChatSH>
65
- \`\`\`sh
66
- cat example.txt
67
- \`\`\`
68
- </ChatSH>
69
-
70
- # EXAMPLE 2: ASSISTING WITH CODING TASKS
71
-
72
- <USER>
73
- Fix main.ts
74
- </USER>
75
-
76
- <ChatSH>
77
- \`\`\`sh
78
- cat main.ts
79
- tsc --noEmit main.ts
80
- \`\`\`
81
- </ChatSH>
82
-
83
- <SYSTEM>
84
- import List from './list';
85
- import map from './map';
86
-
87
- const n_1_2: List<number> = { $: "cons", head: 1, tail: { $: "cons", head: 2, tail: { $: "nil" }}};
88
- const n_2_4: List<number> = map(n_1_2, x => x * 2);
89
-
90
- console.log(JSON.stringify(n_2_4));
91
-
92
- map.ts:7:22 - error TS2345: Argument of type '(val: T) => U' is not assignable to parameter of type 'List<unknown>'.
93
-
94
- 7 let tail = map(fun, list.tail);
95
- ~~~
96
- </SYSTEM>
97
-
98
- <ChatSH>
99
- \`\`\`sh
100
- ls
101
- \`\`\`
102
- </ChatSH>
103
-
104
- <SYSTEM>
105
- list.ts main.ts map.ts
106
- </SYSTEM>
107
-
108
- <ChatSH>
109
- \`\`\`sh
110
- cat map.ts
111
- \`\`\`
112
- </ChatSH>
113
-
114
- <SYSTEM>
115
- import List from './list';
116
-
117
- function map<T, U>(list: List<T>, fun: (val: T) => U): List<U> {
118
- switch (list.$) {
119
- case "cons":
120
- let head = fun(list.head);
121
- let tail = map(fun, list.tail);
122
- return { $: "cons", head, tail };
123
- case "nil":
124
- return { $: "nil" };
125
- }
126
- }
127
-
128
- export default map;
129
- </SYSTEM>
130
-
131
- <ChatSH>
132
- \`\`\`sh
133
- cat > map.ts << EOL
134
- import List from './list';
135
-
136
- function map<T, U>(list: List<T>, fun: (val: T) => U): List<U> {
137
- switch (list.$) {
138
- case "cons":
139
- let head = fun(list.head);
140
- let tail = map(list.tail, fun);
141
- return { $: "cons", head, tail };
142
- case "nil":
143
- return { $: "nil" };
144
- }
145
- }
146
-
147
- export default map;
148
- EOL
149
- tsc --noEmit map.ts
150
- \`\`\`
151
- </ChatSH>
152
-
153
- <SYSTEM>
154
-
155
- </SYSTEM>
156
-
157
- <ChatSH>
158
- Done.
159
- </ChatSH>
160
-
161
- ## NOTES:
162
-
163
- - In COMMAND MODE, answer with SH BLOCKS.
164
-
165
- - In TEXT MODE, answer with normal text.
166
-
167
- - Be concise, objective, correct and factual.
168
-
169
- - Do not attempt to install new tools; assume they're available.
170
-
171
- - Do not include the <ChatSH> tags in your answer.
172
-
173
- - REMEMBER: you are NOT limited to system tasks or shell commands. You must answer ANY question or request by the user.
174
-
175
- - The system shell in use is: bash.;
176
- SYSTEM_PROMPT
177
-
178
- # Function to send a code generation request to Groq API
179
- def generate_code(prompt)
180
- uri = URI(GROQ_API_URL)
181
- request = Net::HTTP::Post.new(uri)
182
- request['Content-Type'] = 'application/json'
183
- request['Authorization'] = "Bearer #{API_KEY}"
184
-
185
- request.body = {
186
- "model": 'llama3-8b-8192',
187
- "messages": [
188
- {
189
- "role": 'system',
190
- "content": SYSTEM_PROMPT
191
- },
192
- {
193
- "role": 'user',
194
- "content": prompt
195
- }
196
- ]
197
- }.to_json
198
-
199
- # Perform the request
200
- response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
201
- http.request(request)
202
- end
203
-
204
- # Process and display the result
205
- if response.code.to_i == 200
206
- result = JSON.parse(response.body)
207
- message_content = result.dig('choices', 0, 'message', 'content')
208
- puts message_content
209
- command = message_content.match(/sh\n(.+?)\n/m)[1]
210
- puts "\033[32m Execute the following command? (y/n) \033[0m"
211
- prompt = gets.chomp
212
- system(command) if prompt == 'y'
213
- else
214
- puts "Error: #{response.code} - #{response.message}"
215
- puts response.body
216
- end
217
- end
218
-
219
- # Example usage
220
- puts 'Enter your prompt for code generation:'
221
- prompt = gets.chomp
222
- generate_code(prompt)
data/install-locally.sh DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/bash
2
-
3
- cp ./gchatsh.rb $s/gchatsh
4
- chmod +x $s/gchatsh