aia 0.5.2 → 0.5.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.semver +1 -1
- data/CHANGELOG.md +7 -0
- data/README.md +77 -11
- data/lib/aia/cli.rb +8 -7
- data/lib/aia/directives.rb +7 -5
- data/lib/aia/dynamic_content.rb +26 -0
- data/lib/aia/main.rb +85 -40
- data/lib/aia/prompt.rb +8 -21
- data/lib/aia/tools/backend_common.rb +6 -24
- data/lib/aia/tools/glow.rb +90 -0
- data/man/aia.1 +19 -1
- data/man/aia.1.md +11 -1
- metadata +44 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '021416691c11252ce3462ee7ec394691e0a7d0fd81eb6df473df3447dd02da3b'
|
4
|
+
data.tar.gz: 2bd5eb6bd2098c7e9bd04234a11c1192004bb217ec054aa9222334d9b96309d2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e2d78c3b6b1b8848645ef586c3b2f7a4557339504efc1a7434b12e313637e47b6803da8e5fa21908f88ee59046a372ef22553a5fdffe97d5777b65845f5ce41
|
7
|
+
data.tar.gz: 142dd7b40622124089363670fcb6ffde02368ad07de7016e6c12e0511a47d89d8b0be9b153d31076758c321e6762e1d361fd4ac086b6f8ffca8d2a2abebeff7b
|
data/.semver
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.5.6] 2024-01-15
|
4
|
+
- Adding processing for directives, shell integration and erb to the follow up prompt in a chat session
|
5
|
+
- some code refactoring.
|
6
|
+
|
7
|
+
## [0.5.3] 2024-01-14
|
8
|
+
- adding ability to render markdown to the terminal using the "glow" CLI utility
|
9
|
+
|
3
10
|
## [0.5.2] 2024-01-13
|
4
11
|
- wrap response when its going to the terminal
|
5
12
|
|
data/README.md
CHANGED
@@ -5,6 +5,15 @@
|
|
5
5
|
It leverages the `prompt_manager` gem to manage prompts for the `mods` and `sgpt` CLI utilities. It utilizes "ripgrep" for searching for prompt files. It uses `fzf` for prompt selection based on a search term and fuzzy matching.
|
6
6
|
|
7
7
|
**Most Recent Change**: Refer to the [Changelog](CHANGELOG.md)
|
8
|
+
v0.5.6
|
9
|
+
- Directives within a chat session follow up are now available
|
10
|
+
- when the `--shell` option is set access to envars and shell scripts are availabe in a chat session follow up prompt
|
11
|
+
- when the `--erb` option is set, access to ERB-based dynamic content is available in a chat session follow up prompt.
|
12
|
+
|
13
|
+
v0.5.3
|
14
|
+
- `--render` will render markdown formatted content to the terminal using the `glow` CLI utility.
|
15
|
+
- fixes to some terminal UI stuff like AI response is not being wrapped to the terminal width to make for easier reading.
|
16
|
+
- fixed the completion functions to use the correct $AIA_PROMPTS_DIR envar
|
8
17
|
|
9
18
|
v0.5.0 - Breaking changes:
|
10
19
|
- `--config` is now `--config_file`
|
@@ -21,11 +30,14 @@ v0.5.0 - Breaking changes:
|
|
21
30
|
- [Shell Integration inside of a Prompt](#shell-integration-inside-of-a-prompt)
|
22
31
|
- [Access to System Environment Variables](#access-to-system-environment-variables)
|
23
32
|
- [Dynamic Shell Commands](#dynamic-shell-commands)
|
33
|
+
- [Chat Session Use](#chat-session-use)
|
24
34
|
- [*E*mbedded *R*u*B*y (ERB)](#embedded-ruby-erb)
|
35
|
+
- [Chat Session Behavior](#chat-session-behavior)
|
25
36
|
- [Prompt Directives](#prompt-directives)
|
26
37
|
- [`aia` Specific Directive Commands](#aia-specific-directive-commands)
|
27
38
|
- [//config](#config)
|
28
39
|
- [Backend Directive Commands](#backend-directive-commands)
|
40
|
+
- [Using Directives in Chat Sessions](#using-directives-in-chat-sessions)
|
29
41
|
- [All About ROLES](#all-about-roles)
|
30
42
|
- [Other Ways to Insert Roles into Prompts](#other-ways-to-insert-roles-into-prompts)
|
31
43
|
- [External CLI Tools Used](#external-cli-tools-used)
|
@@ -97,7 +109,15 @@ ARGUMENTS
|
|
97
109
|
|
98
110
|
OPTIONS
|
99
111
|
--chat begin a chat session with the backend after the initial prompt response; will
|
100
|
-
set --no-out_file so that the backend response comes to STDOUT.
|
112
|
+
set --no-out_file so that the backend response comes to STDOUT. After the
|
113
|
+
initial prompt is processed, you will be asked to provide a follow up. Just
|
114
|
+
enter whatever is appropriate terminating your input with a RETURN. The
|
115
|
+
backend will provide a response to you follow up and ask you again if you have
|
116
|
+
another follow up. This back and forth chatting will continue until you enter a
|
117
|
+
RETURN without any other content - an empty follow up prompt. You may also
|
118
|
+
enter a directive to be processed after which another follow up is requested.
|
119
|
+
If you have the --shell and/or the --erb options set you may use those tools
|
120
|
+
within your follow up to provide dynamic content.
|
101
121
|
|
102
122
|
--completion SHELL_NAME
|
103
123
|
|
@@ -125,6 +145,9 @@ OPTIONS
|
|
125
145
|
--model NAME
|
126
146
|
Name of the LLM model to use - default is gpt-4-1106-preview
|
127
147
|
|
148
|
+
--render
|
149
|
+
Render markdown to the terminal using the external tool “glow” - default: false
|
150
|
+
|
128
151
|
--speak
|
129
152
|
Simple implementation. Uses the “say” command to speak the response. Fun with
|
130
153
|
--chat
|
@@ -251,12 +274,29 @@ SEE ALSO
|
|
251
274
|
text, and more, using simple commands. Streamline your workflow and enhance
|
252
275
|
productivity with this powerful and user-friendly CLI tool.
|
253
276
|
|
277
|
+
• fzf <https://github.com/junegunn/fzf>
|
278
|
+
fzf is a general-purpose command-line fuzzy finder. It’s an interactive
|
279
|
+
Unix filter for command-line that can be used with any list; files, command
|
280
|
+
history, processes, hostnames, bookmarks, git commits, etc.
|
281
|
+
|
282
|
+
• ripgrep <https://github.com/BurntSushi/ripgrep>
|
283
|
+
Search tool like grep and The Silver Searcher. It is a line-oriented search
|
284
|
+
tool that recursively searches a directory tree for a regex pattern. By
|
285
|
+
default, ripgrep will respect gitignore rules and automatically skip hidden
|
286
|
+
files/directories and binary files. (To disable all automatic filtering by
|
287
|
+
default, use rg -uuu.) ripgrep has first class support on Windows, macOS and
|
288
|
+
Linux, with binary downloads available for every release.
|
289
|
+
|
290
|
+
• glow <https://github.com/charmbracelet/glow>
|
291
|
+
Render markdown on the CLI
|
292
|
+
|
254
293
|
AUTHOR
|
255
294
|
Dewayne VanHoozer <dvanhoozer@gmail.com>
|
256
295
|
|
257
296
|
AIA 2024-01-01 aia(1)
|
258
297
|
```
|
259
298
|
|
299
|
+
|
260
300
|
## Configuration Using Envars
|
261
301
|
|
262
302
|
The `aia` configuration defaults can be over-ridden by system environment variables *(envars)* with the prefix "AIA_" followed by the config item name also in uppercase. All configuration items can be over-ridden in this way by an envar. The following table show a few examples.
|
@@ -305,6 +345,15 @@ or insert content from a file in your home directory:
|
|
305
345
|
Given the following constraints $(cat ~/3_laws_of_robotics.txt) determine the best way to instruct my roomba to clean my kids room.
|
306
346
|
```
|
307
347
|
|
348
|
+
#### Chat Session Use
|
349
|
+
|
350
|
+
When you use the `--shell` option to start a chat session, shell integration is available in your follow up prompts. Suppose you started up a chat session using a roll of "Ruby Expert" expecting to chat about changes that could be made to a specific class BUT you forgot to include the class source file as part of the context when you got started. You could enter this as your follow up prompt to this to keep going:
|
351
|
+
|
352
|
+
```
|
353
|
+
The class I want to chat about refactoring is this one: $(cat my_class.rb)
|
354
|
+
```
|
355
|
+
|
356
|
+
That inserts the entire class source file into your follow up prompt. You can continue chatting with you AI Assistant avout changes to the class.
|
308
357
|
|
309
358
|
## *E*mbedded *R*u*B*y (ERB)
|
310
359
|
|
@@ -314,6 +363,11 @@ The `--erb` option turns the prompt text file into a fully functioning ERB templ
|
|
314
363
|
|
315
364
|
Most websites that have information about ERB will give examples of how to use ERB to generate dynamice HTML content for web-based applications. That is a common use case for ERB. `aia` on the other hand uses ERB to generate dynamic prompt text.
|
316
365
|
|
366
|
+
### Chat Session Behavior
|
367
|
+
|
368
|
+
In a chat session whether started by the `--chat` option or its equivalent with a directive within a prompt text file behaves a little differently w/r/t its binding and local variable assignments. Since a chat session by definition has multiple prompts, setting a local variable in one prompt and expecting it to be available in a subsequent prompt does not work. You need to use instance variables to accomplish this prompt to prompt carry over of information.
|
369
|
+
|
370
|
+
Also since follow up prompts are expected to be a single thing - sentence or paragraph - terminated by a single return, its likely that ERB enhance will be of benefit; but, you may find a use for it.
|
317
371
|
|
318
372
|
## Prompt Directives
|
319
373
|
|
@@ -367,6 +421,17 @@ FOr example `mods` has a configuration item `topp` which can be set by a directi
|
|
367
421
|
|
368
422
|
If `mods` is not the backend the `//topp` direcive is ignored.
|
369
423
|
|
424
|
+
### Using Directives in Chat Sessions
|
425
|
+
|
426
|
+
Whe you are in a chat session, you may use a directive as a follow up prompt. For example if you started the chat session with the option `--terse` expecting to get short answers from the backend; but, then you decide that you want more comprehensive answers you may do this:
|
427
|
+
|
428
|
+
```
|
429
|
+
//config terse? false
|
430
|
+
```
|
431
|
+
|
432
|
+
The directive is executed and a new follow up prompt can be entered with a more lengthy response generated from the backend.
|
433
|
+
|
434
|
+
|
370
435
|
## All About ROLES
|
371
436
|
|
372
437
|
`aia` provides the `--role` CLI option to identify a prompt ID within your prompts directory which defines the context within which the LLM is to provide its response. The text of the role ID is pre-pended to the text of the primary prompt to form a complete prompt to be processed by the backend.
|
@@ -402,31 +467,32 @@ When this prompt is processed, `aia` will ask you for a value for the keyword "R
|
|
402
467
|
|
403
468
|
## External CLI Tools Used
|
404
469
|
|
405
|
-
```text
|
406
|
-
External Tools Used
|
407
|
-
-------------------
|
408
|
-
|
409
470
|
To install the external CLI programs used by aia:
|
410
|
-
|
471
|
+
|
472
|
+
brew install fzf mods rg glow
|
411
473
|
|
412
474
|
fzf
|
413
475
|
Command-line fuzzy finder written in Go
|
414
|
-
https://github.com/junegunn/fzf
|
476
|
+
[https://github.com/junegunn/fzf](https://github.com/junegunn/fzf)
|
415
477
|
|
416
478
|
mods
|
417
479
|
AI on the command-line
|
418
|
-
https://github.com/charmbracelet/mods
|
480
|
+
[https://github.com/charmbracelet/mods](https://github.com/charmbracelet/mods)
|
419
481
|
|
420
482
|
rg
|
421
483
|
Search tool like grep and The Silver Searcher
|
422
|
-
https://github.com/BurntSushi/ripgrep
|
484
|
+
[https://github.com/BurntSushi/ripgrep](https://github.com/BurntSushi/ripgrep)
|
485
|
+
|
486
|
+
glow
|
487
|
+
Render markdown on the CLI
|
488
|
+
[https://github.com/charmbracelet/glow](https://github.com/charmbracelet/glow)
|
423
489
|
|
424
490
|
A text editor whose executable is setup in the
|
425
491
|
system environment variable 'EDITOR' like this:
|
426
492
|
|
427
|
-
export EDITOR="subl -w"
|
493
|
+
export EDITOR="subl -w"
|
494
|
+
|
428
495
|
|
429
|
-
```
|
430
496
|
|
431
497
|
## Shell Completion
|
432
498
|
|
data/lib/aia/cli.rb
CHANGED
@@ -125,18 +125,19 @@ class AIA::Cli
|
|
125
125
|
dump: [nil, "--dump"],
|
126
126
|
completion: [nil, "--completion"],
|
127
127
|
#
|
128
|
+
chat?: [false, "--chat"],
|
129
|
+
debug?: [false, "-d --debug"],
|
128
130
|
edit?: [false, "-e --edit"],
|
129
|
-
shell?: [false, "--shell"],
|
130
131
|
erb?: [false, "--erb"],
|
131
|
-
debug?: [false, "-d --debug"],
|
132
|
-
verbose?: [false, "-v --verbose"],
|
133
|
-
version?: [false, "--version"],
|
134
|
-
help?: [false, "-h --help"],
|
135
132
|
fuzzy?: [false, "-f --fuzzy"],
|
133
|
+
help?: [false, "-h --help"],
|
136
134
|
markdown?: [true, "-m --markdown --no-markdown --md --no-md"],
|
137
|
-
|
138
|
-
|
135
|
+
render?: [false, "--render"],
|
136
|
+
shell?: [false, "--shell"],
|
139
137
|
speak?: [false, "--speak"],
|
138
|
+
terse?: [false, "--terse"],
|
139
|
+
verbose?: [false, "-v --verbose"],
|
140
|
+
version?: [false, "--version"],
|
140
141
|
#
|
141
142
|
role: ['', "-r --role"],
|
142
143
|
#
|
data/lib/aia/directives.rb
CHANGED
@@ -2,13 +2,15 @@
|
|
2
2
|
|
3
3
|
require 'hashie'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
=begin
|
6
|
+
AIA.config.directives is an Array of Arrays. An
|
7
|
+
entry looks like this:
|
8
|
+
[directive, parameters]
|
9
|
+
where both are String objects
|
10
|
+
=end
|
10
11
|
|
11
12
|
|
13
|
+
class AIA::Directives
|
12
14
|
def execute_my_directives
|
13
15
|
return if AIA.config.directives.nil? || AIA.config.directives.empty?
|
14
16
|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# aia/lib/aia/dynamic_content.rb
|
2
|
+
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
module AIA::DynamicContent
|
6
|
+
|
7
|
+
# inserts environment variables (envars) and dynamic content into a prompt
|
8
|
+
# replaces patterns like $HOME and ${HOME} with the value of ENV['HOME']
|
9
|
+
# replaces patterns like $(shell command) with the output of the shell command
|
10
|
+
#
|
11
|
+
def render_env(a_string)
|
12
|
+
a_string.gsub(/\$(\w+|\{\w+\})/) do |match|
|
13
|
+
ENV[match.tr('$', '').tr('{}', '')]
|
14
|
+
end.gsub(/\$\((.*?)\)/) do |match|
|
15
|
+
`#{match[2..-2]}`.chomp
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
# Need to use instance variables in assignments
|
21
|
+
# to maintain binding from one follow up prompt
|
22
|
+
# to another.
|
23
|
+
def render_erb(the_prompt_text)
|
24
|
+
ERB.new(the_prompt_text).result(binding)
|
25
|
+
end
|
26
|
+
end
|
data/lib/aia/main.rb
CHANGED
@@ -5,6 +5,7 @@ module AIA ; end
|
|
5
5
|
require_relative 'config'
|
6
6
|
require_relative 'cli'
|
7
7
|
require_relative 'directives'
|
8
|
+
require_relative 'dynamic_content'
|
8
9
|
require_relative 'prompt'
|
9
10
|
require_relative 'logging'
|
10
11
|
require_relative 'tools'
|
@@ -13,6 +14,7 @@ require_relative 'tools'
|
|
13
14
|
# of a single class.
|
14
15
|
|
15
16
|
class AIA::Main
|
17
|
+
include AIA::DynamicContent
|
16
18
|
|
17
19
|
attr_accessor :logger, :tools, :backend
|
18
20
|
|
@@ -33,7 +35,8 @@ class AIA::Main
|
|
33
35
|
|
34
36
|
@prompt = AIA::Prompt.new.prompt
|
35
37
|
|
36
|
-
|
38
|
+
|
39
|
+
@directives_processor = AIA::Directives.new
|
37
40
|
|
38
41
|
# TODO: still should verify that the tools are ion the $PATH
|
39
42
|
# tools.class.verify_tools
|
@@ -57,6 +60,7 @@ class AIA::Main
|
|
57
60
|
# Function to prompt the user with a question using reline
|
58
61
|
def ask_question_with_reline(prompt)
|
59
62
|
if prompt.start_with?("\n")
|
63
|
+
puts
|
60
64
|
puts
|
61
65
|
prompt = prompt[1..]
|
62
66
|
end
|
@@ -70,7 +74,7 @@ class AIA::Main
|
|
70
74
|
|
71
75
|
|
72
76
|
def call
|
73
|
-
@
|
77
|
+
@directives_processor.execute_my_directives
|
74
78
|
|
75
79
|
if AIA.config.chat?
|
76
80
|
AIA.config.out_file = STDOUT
|
@@ -111,20 +115,10 @@ class AIA::Main
|
|
111
115
|
files: AIA.config.arguments # FIXME: want validated context files
|
112
116
|
)
|
113
117
|
|
114
|
-
|
115
|
-
result = backend.run
|
116
|
-
|
117
|
-
if STDOUT == AIA.config.out_file
|
118
|
-
result = result.wrap(indent: 2)
|
119
|
-
end
|
120
|
-
|
121
|
-
# TODO: consider using glow to render markdown to
|
122
|
-
# terminal `brew install glow`
|
123
|
-
AIA.config.out_file.write result
|
118
|
+
result = get_and_display_result(the_prompt)
|
124
119
|
|
125
120
|
logger.prompt_result(@prompt, result)
|
126
121
|
|
127
|
-
|
128
122
|
if AIA.config.chat?
|
129
123
|
setup_reline_history
|
130
124
|
speak result
|
@@ -133,36 +127,87 @@ class AIA::Main
|
|
133
127
|
end
|
134
128
|
|
135
129
|
|
136
|
-
def
|
130
|
+
def get_and_display_result(the_prompt_text)
|
131
|
+
backend.text = the_prompt_text
|
132
|
+
result = backend.run
|
133
|
+
|
134
|
+
AIA.config.out_file.write "\nResponse:\n"
|
135
|
+
|
136
|
+
if STDOUT == AIA.config.out_file
|
137
|
+
if AIA.config.render?
|
138
|
+
AIA::Glow.new(content: result).run
|
139
|
+
else
|
140
|
+
result = result.wrap(indent: 2)
|
141
|
+
AIA.config.out_file.write result
|
142
|
+
end
|
143
|
+
else
|
144
|
+
AIA.config.out_file.write result
|
145
|
+
if AIA.config.render?
|
146
|
+
AIA::Glow.new(file_path: AIA.config.out_file).run
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
result
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
def log_the_follow_up(the_prompt_text, result)
|
155
|
+
logger.info "Follow Up:\n#{the_prompt_text}"
|
156
|
+
logger.info "Response:\n#{result}"
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
def add_continue_option
|
137
161
|
if 'mods' == AIA.config.backend
|
138
|
-
|
162
|
+
continue_option = " -C"
|
163
|
+
AIA.config.extra += continue_option unless AIA.config.extra.include?(continue_option)
|
139
164
|
end
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
speak response
|
152
|
-
|
153
|
-
puts "\nResponse:\n#{response.wrap(indent: 2)}"
|
154
|
-
logger.info "Response: #{backend.run}"
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
def insert_terse_phrase(a_string)
|
169
|
+
if AIA.config.terse?
|
170
|
+
a_string.prepend "Be terse in your response. "
|
171
|
+
end
|
172
|
+
|
173
|
+
a_string
|
174
|
+
end
|
175
|
+
|
155
176
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
177
|
+
def handle_directives(the_prompt_text)
|
178
|
+
signal = PromptManager::Prompt::DIRECTIVE_SIGNAL
|
179
|
+
result = the_prompt_text.start_with?(signal)
|
180
|
+
|
181
|
+
if result
|
182
|
+
parts = the_prompt_text[signal.size..].split(' ')
|
183
|
+
directive = parts.shift
|
184
|
+
parameters = parts.join(' ')
|
185
|
+
AIA.config.directives << [directive, parameters]
|
186
|
+
@directives_processor.execute_my_directives
|
187
|
+
end
|
188
|
+
|
189
|
+
result
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
def lets_chat
|
194
|
+
add_continue_option
|
195
|
+
|
196
|
+
the_prompt_text = ask_question_with_reline("\nFollow Up: ")
|
197
|
+
|
198
|
+
until the_prompt_text.empty?
|
199
|
+
the_prompt_text = render_erb(the_prompt_text) if AIA.config.erb?
|
200
|
+
the_prompt_text = render_env(the_prompt_text) if AIA.config.shell?
|
201
|
+
|
202
|
+
unless handle_directives(the_prompt_text)
|
203
|
+
the_prompt_text = insert_terse_phrase(the_prompt_text)
|
204
|
+
result = get_and_display_result(the_prompt_text)
|
205
|
+
|
206
|
+
log_the_follow_up(the_prompt_text, result)
|
207
|
+
speak result
|
208
|
+
end
|
209
|
+
|
210
|
+
the_prompt_text = ask_question_with_reline("\nFollow Up: ")
|
166
211
|
end
|
167
212
|
end
|
168
213
|
end
|
data/lib/aia/prompt.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
# lib/aia/prompt.rb
|
2
2
|
|
3
3
|
require 'reline'
|
4
|
-
|
4
|
+
|
5
|
+
require_relative 'dynamic_content'
|
5
6
|
|
6
7
|
class AIA::Prompt
|
8
|
+
include AIA::DynamicContent
|
9
|
+
|
7
10
|
#
|
8
11
|
# used when no prompt_id is provided but there
|
9
12
|
# are extra parameters that need to be passed
|
@@ -42,9 +45,11 @@ class AIA::Prompt
|
|
42
45
|
|
43
46
|
if build
|
44
47
|
@prompt.text = render_erb(@prompt.text) if AIA.config.erb?
|
45
|
-
@prompt.text =
|
48
|
+
@prompt.text = render_env(@prompt.text) if AIA.config.shell?
|
46
49
|
process_prompt
|
47
50
|
end
|
51
|
+
|
52
|
+
AIA.config.directives = @prompt.directives
|
48
53
|
end
|
49
54
|
|
50
55
|
|
@@ -93,25 +98,6 @@ class AIA::Prompt
|
|
93
98
|
end
|
94
99
|
|
95
100
|
|
96
|
-
# inserts environmant variables and dynamic content into a prompt
|
97
|
-
# replaces patterns like $HOME and ${HOME} with the value of ENV['HOME']
|
98
|
-
# replaces patterns like $(shell command) with the output of the shell command
|
99
|
-
#
|
100
|
-
def replace_env(a_string)
|
101
|
-
a_string.gsub(/\$(\w+|\{\w+\})/) do |match|
|
102
|
-
ENV[match.tr('$', '').tr('{}', '')]
|
103
|
-
end.gsub(/\$\((.*?)\)/) do |match|
|
104
|
-
`#{match[2..-2]}`.chomp
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
|
109
|
-
# You are just asking for trouble!
|
110
|
-
def render_erb(a_string)
|
111
|
-
ERB.new(a_string).result(binding)
|
112
|
-
end
|
113
|
-
|
114
|
-
|
115
101
|
def replace_keywords
|
116
102
|
puts
|
117
103
|
puts "ID: #{@prompt.id}"
|
@@ -151,6 +137,7 @@ class AIA::Prompt
|
|
151
137
|
# Function to prompt the user with a question using reline
|
152
138
|
def ask_question_with_reline(prompt)
|
153
139
|
if prompt.start_with?("\n")
|
140
|
+
puts
|
154
141
|
puts
|
155
142
|
prompt = prompt[1..]
|
156
143
|
end
|
@@ -12,9 +12,12 @@ module AIA::BackendCommon
|
|
12
12
|
build_command
|
13
13
|
end
|
14
14
|
|
15
|
+
|
15
16
|
def sanitize(input)
|
16
17
|
Shellwords.escape(input)
|
17
18
|
end
|
19
|
+
|
20
|
+
|
18
21
|
def build_command
|
19
22
|
@parameters += " --model #{AIA.config.model} " if AIA.config.model
|
20
23
|
@parameters += AIA.config.extra
|
@@ -29,6 +32,7 @@ module AIA::BackendCommon
|
|
29
32
|
@command
|
30
33
|
end
|
31
34
|
|
35
|
+
|
32
36
|
def set_parameter_from_directives
|
33
37
|
AIA.config.directives.each do |entry|
|
34
38
|
directive, value = entry
|
@@ -38,6 +42,7 @@ module AIA::BackendCommon
|
|
38
42
|
end
|
39
43
|
end
|
40
44
|
|
45
|
+
|
41
46
|
def run
|
42
47
|
case @files.size
|
43
48
|
when 0
|
@@ -45,32 +50,9 @@ module AIA::BackendCommon
|
|
45
50
|
when 1
|
46
51
|
@result = `#{build_command} < #{@files.first}`
|
47
52
|
else
|
48
|
-
|
49
|
-
run_with_temp_file
|
50
|
-
clean_up_temp_file
|
53
|
+
@result = %x[cat #{@files.join(' ')} | #{build_command}]
|
51
54
|
end
|
52
55
|
|
53
56
|
@result
|
54
57
|
end
|
55
|
-
|
56
|
-
def create_temp_file_with_contexts
|
57
|
-
@temp_file = Tempfile.new("#{self.class::COMMAND_NAME}-context")
|
58
|
-
|
59
|
-
@files.each do |file|
|
60
|
-
content = File.read(file)
|
61
|
-
@temp_file.write(content)
|
62
|
-
@temp_file.write("\n")
|
63
|
-
end
|
64
|
-
|
65
|
-
@temp_file.close
|
66
|
-
end
|
67
|
-
|
68
|
-
def run_with_temp_file
|
69
|
-
command = "#{build_command} < #{@temp_file.path}"
|
70
|
-
@result = `#{command}`
|
71
|
-
end
|
72
|
-
|
73
|
-
def clean_up_temp_file
|
74
|
-
@temp_file.unlink if @temp_file
|
75
|
-
end
|
76
58
|
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# aia/lib/aia/tools/glow.rb
|
2
|
+
|
3
|
+
require 'tempfile'
|
4
|
+
require 'tty-screen'
|
5
|
+
require 'shellwords'
|
6
|
+
|
7
|
+
|
8
|
+
=begin
|
9
|
+
|
10
|
+
This class supports two use cases:
|
11
|
+
1) rendering markdown from an existing file
|
12
|
+
2) rendering markdown from a String object via a temporary file
|
13
|
+
|
14
|
+
In both cases a String object is created and returned that contains the
|
15
|
+
rendered version of the content so that it can be written to STDOUT
|
16
|
+
by the caller.
|
17
|
+
|
18
|
+
=end
|
19
|
+
|
20
|
+
class AIA::Glow < AIA::Tools
|
21
|
+
|
22
|
+
meta(
|
23
|
+
name: 'glow',
|
24
|
+
role: :markdown_renderer,
|
25
|
+
desc: "A markdown renderer utility",
|
26
|
+
url: "https://github.com/charmbracelet/glow",
|
27
|
+
install: "brew install glow",
|
28
|
+
)
|
29
|
+
|
30
|
+
DEFAULT_PARAMETERS = "--width #{TTY::Screen.width-2}" # Magic: -2 just because I want it
|
31
|
+
|
32
|
+
attr_accessor :content, :file_path
|
33
|
+
|
34
|
+
|
35
|
+
def initialize(content: nil, file_path: nil)
|
36
|
+
@content = content
|
37
|
+
@file_path = file_path
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
def build_command(file_path)
|
42
|
+
"#{self.class.meta[:name]} #{DEFAULT_PARAMETERS} #{Shellwords.escape(file_path)}"
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def run
|
47
|
+
return unless content || file_path
|
48
|
+
|
49
|
+
if @file_path && File.exist?(@file_path)
|
50
|
+
command = build_command(@file_path)
|
51
|
+
system(command)
|
52
|
+
else
|
53
|
+
Tempfile.create(['glow', '.md']) do |file|
|
54
|
+
file.write(@content)
|
55
|
+
file.close
|
56
|
+
command = build_command(file.path)
|
57
|
+
system(command)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
__END__
|
64
|
+
|
65
|
+
$ glow --help
|
66
|
+
|
67
|
+
Render markdown on the CLI, with pizzazz!
|
68
|
+
|
69
|
+
Usage:
|
70
|
+
glow [SOURCE|DIR] [flags]
|
71
|
+
glow [command]
|
72
|
+
|
73
|
+
Available Commands:
|
74
|
+
completion Generate the autocompletion script for the specified shell
|
75
|
+
config Edit the glow config file
|
76
|
+
help Help about any command
|
77
|
+
stash Stash a markdown
|
78
|
+
|
79
|
+
Flags:
|
80
|
+
-a, --all show system files and directories (TUI-mode only)
|
81
|
+
--config string config file (default /Users/dewayne/Library/Preferences/glow/glow.yml)
|
82
|
+
-h, --help help for glow
|
83
|
+
-l, --local show local files only; no network (TUI-mode only)
|
84
|
+
-p, --pager display with pager
|
85
|
+
-s, --style string style name or JSON path (default "auto")
|
86
|
+
-v, --version version for glow
|
87
|
+
-w, --width uint word-wrap at width
|
88
|
+
|
89
|
+
Use "glow [command] --help" for more information about a command.
|
90
|
+
|
data/man/aia.1
CHANGED
@@ -23,7 +23,7 @@ External options are optional\. Anything that follow \[lq] \-\- \[lq] will be s
|
|
23
23
|
.SH OPTIONS
|
24
24
|
.TP
|
25
25
|
\fB\-\-chat\fR
|
26
|
-
begin a chat session with the backend after the initial prompt response; will set \-\-no\-out\[ru]file so that the backend response comes to STDOUT\.
|
26
|
+
begin a chat session with the backend after the initial prompt response; will set \-\-no\-out\[ru]file so that the backend response comes to STDOUT\. After the initial prompt is processed, you will be asked to provide a follow up\. Just enter whatever is appropriate terminating your input with a RETURN\. The backend will provide a response to you follow up and ask you again if you have another follow up\. This back and forth chatting will continue until you enter a RETURN without any other content \- an empty follow up prompt\. You may also enter a directive to be processed after which another follow up is requested\. If you have the \fB\-\-shell\fR and\[sl]or the \fB\-\-erb\fR options set you may use those tools within your follow up to provide dynamic content\.
|
27
27
|
.TP
|
28
28
|
\fB\-\-completion\fR \fISHELL\[ru]NAME\fP
|
29
29
|
.TP
|
@@ -41,6 +41,9 @@ If dynamic prompt content using \[Do](\.\.\.) wasn\[cq]t enough here is ERB\. E
|
|
41
41
|
\fB\-\-model\fR \fINAME\fP
|
42
42
|
Name of the LLM model to use \- default is gpt\-4\-1106\-preview
|
43
43
|
.TP
|
44
|
+
\fB\-\-render\fR
|
45
|
+
Render markdown to the terminal using the external tool \[lq]glow\[rq] \- default: false
|
46
|
+
.TP
|
44
47
|
\fB\-\-speak\fR
|
45
48
|
Simple implementation\. Uses the \[lq]say\[rq] command to speak the response\. Fun with \-\-chat
|
46
49
|
.TP
|
@@ -147,6 +150,21 @@ sgpt
|
|
147
150
|
.UR https:\[sl]\[sl]github\.com\[sl]tbckr\[sl]sgpt
|
148
151
|
.UE
|
149
152
|
(aka shell\-gpt) is a powerful command\-line interface (CLI) tool designed for seamless interaction with OpenAI models directly from your terminal\. Effortlessly run queries, generate shell commands or code, create images from text, and more, using simple commands\. Streamline your workflow and enhance productivity with this powerful and user\-friendly CLI tool\.
|
153
|
+
.IP \(bu 2
|
154
|
+
fzf
|
155
|
+
.UR https:\[sl]\[sl]github\.com\[sl]junegunn\[sl]fzf
|
156
|
+
.UE
|
157
|
+
fzf is a general\-purpose command\-line fuzzy finder\. It\[cq]s an interactive Unix filter for command\-line that can be used with any list; files, command history, processes, hostnames, bookmarks, git commits, etc\.
|
158
|
+
.IP \(bu 2
|
159
|
+
ripgrep
|
160
|
+
.UR https:\[sl]\[sl]github\.com\[sl]BurntSushi\[sl]ripgrep
|
161
|
+
.UE
|
162
|
+
Search tool like grep and The Silver Searcher\. It is a line\-oriented search tool that recursively searches a directory tree for a regex pattern\. By default, ripgrep will respect gitignore rules and automatically skip hidden files\[sl]directories and binary files\. (To disable all automatic filtering by default, use rg \-uuu\.) ripgrep has first class support on Windows, macOS and Linux, with binary downloads available for every release\.
|
163
|
+
.IP \(bu 2
|
164
|
+
glow
|
165
|
+
.UR https:\[sl]\[sl]github\.com\[sl]charmbracelet\[sl]glow
|
166
|
+
.UE
|
167
|
+
Render markdown on the CLI
|
150
168
|
.RE
|
151
169
|
.SH AUTHOR
|
152
170
|
.PP
|
data/man/aia.1.md
CHANGED
@@ -26,7 +26,7 @@ The aia command-line tool is an interface for interacting with an AI model backe
|
|
26
26
|
## OPTIONS
|
27
27
|
|
28
28
|
`--chat`
|
29
|
-
: begin a chat session with the backend after the initial prompt response; will set --no-out_file so that the backend response comes to STDOUT.
|
29
|
+
: begin a chat session with the backend after the initial prompt response; will set --no-out_file so that the backend response comes to STDOUT. After the initial prompt is processed, you will be asked to provide a follow up. Just enter whatever is appropriate terminating your input with a RETURN. The backend will provide a response to you follow up and ask you again if you have another follow up. This back and forth chatting will continue until you enter a RETURN without any other content - an empty follow up prompt. You may also enter a directive to be processed after which another follow up is requested. If you have the `--shell` and/or the `--erb` options set you may use those tools within your follow up to provide dynamic content.
|
30
30
|
|
31
31
|
`--completion` *SHELL_NAME*
|
32
32
|
: Show completion script for bash|zsh|fish - default is nil
|
@@ -46,6 +46,9 @@ The aia command-line tool is an interface for interacting with an AI model backe
|
|
46
46
|
`--model` *NAME*
|
47
47
|
: Name of the LLM model to use - default is gpt-4-1106-preview
|
48
48
|
|
49
|
+
`--render`
|
50
|
+
: Render markdown to the terminal using the external tool "glow" - default: false
|
51
|
+
|
49
52
|
`--speak`
|
50
53
|
: Simple implementation. Uses the "say" command to speak the response. Fun with --chat
|
51
54
|
|
@@ -135,6 +138,13 @@ Detail discussion on individual prompt directives is TBD. Most likely it will b
|
|
135
138
|
|
136
139
|
- [sgpt](https://github.com/tbckr/sgpt) (aka shell-gpt) is a powerful command-line interface (CLI) tool designed for seamless interaction with OpenAI models directly from your terminal. Effortlessly run queries, generate shell commands or code, create images from text, and more, using simple commands. Streamline your workflow and enhance productivity with this powerful and user-friendly CLI tool.
|
137
140
|
|
141
|
+
- [fzf](https://github.com/junegunn/fzf) fzf is a general-purpose command-line fuzzy finder. It's an interactive Unix filter for command-line that can be used with any list; files, command history, processes, hostnames, bookmarks, git commits, etc.
|
142
|
+
|
143
|
+
- [ripgrep](https://github.com/BurntSushi/ripgrep) Search tool like grep and The Silver Searcher. It is a line-oriented search tool that recursively searches a directory tree for a regex pattern. By default, ripgrep will respect gitignore rules and automatically skip hidden files/directories and binary files. (To disable all automatic filtering by default, use rg -uuu.) ripgrep has first class support on Windows, macOS and Linux, with binary downloads available for every release.
|
144
|
+
|
145
|
+
- [glow](https://github.com/charmbracelet/glow) Render markdown on the CLI
|
146
|
+
|
147
|
+
|
138
148
|
## AUTHOR
|
139
149
|
|
140
150
|
Dewayne VanHoozer <dvanhoozer@gmail.com>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dewayne VanHoozer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-01-
|
11
|
+
date: 2024-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|
@@ -94,6 +94,34 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: tty-screen
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: tty-spinner
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
97
125
|
- !ruby/object:Gem::Dependency
|
98
126
|
name: minitest
|
99
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -164,12 +192,18 @@ dependencies:
|
|
164
192
|
- - ">="
|
165
193
|
- !ruby/object:Gem::Version
|
166
194
|
version: '0'
|
167
|
-
description:
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
195
|
+
description: |
|
196
|
+
`aia` - the AI Assistant - is a command-line (CLI) tool for
|
197
|
+
interfacing with generative AI (gen-AI/GPT) backends. Its designed
|
198
|
+
to provide developers with the ability to issue prompts, receive
|
199
|
+
AI-generated responses, and incorporate additional context from files
|
200
|
+
such as Ruby source code. It supports configuration and customization
|
201
|
+
for different environments, includes options for output formats like
|
202
|
+
markdown rendering or spoken responses, and allows dynamic content
|
203
|
+
generation within prompts such as shell integration and embedded
|
204
|
+
Ruby. With `aia`, users benefit from a simplified setup process and
|
205
|
+
an extendable interaction model with AI, suitable for a range of
|
206
|
+
command-line tasks.
|
173
207
|
email:
|
174
208
|
- dvanhoozer@gmail.com
|
175
209
|
executables:
|
@@ -195,12 +229,14 @@ files:
|
|
195
229
|
- lib/aia/cli.rb
|
196
230
|
- lib/aia/config.rb
|
197
231
|
- lib/aia/directives.rb
|
232
|
+
- lib/aia/dynamic_content.rb
|
198
233
|
- lib/aia/logging.rb
|
199
234
|
- lib/aia/main.rb
|
200
235
|
- lib/aia/prompt.rb
|
201
236
|
- lib/aia/tools.rb
|
202
237
|
- lib/aia/tools/backend_common.rb
|
203
238
|
- lib/aia/tools/editor.rb
|
239
|
+
- lib/aia/tools/glow.rb
|
204
240
|
- lib/aia/tools/mods.rb
|
205
241
|
- lib/aia/tools/sgpt.rb
|
206
242
|
- lib/aia/tools/subl.rb
|