aia 0.5.9 → 0.5.11
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 +14 -0
- data/README.md +151 -249
- data/lib/aia/clause.rb +7 -0
- data/lib/aia/cli.rb +57 -2
- data/lib/aia/directives.rb +41 -2
- data/lib/aia/main.rb +19 -5
- data/lib/aia/prompt.rb +19 -36
- data/lib/aia/tools/fzf.rb +105 -0
- data/lib/aia/tools.rb +36 -0
- data/lib/aia.rb +8 -0
- data/man/aia.1 +17 -2
- data/man/aia.1.md +13 -2
- metadata +30 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 740cb6d71c83fae27f2918e76a10802d805e4172aef40154b8cea3ae6800ad65
|
4
|
+
data.tar.gz: 0e9aac0e6a0917b6adb04550cac137be65d7e0fa3507af89058f0a1d96aa3b58
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 24f4eb6ace28c79ccf7c5465e3027dd03e25457df5c522b828775c681e51cfeab207d1c6eb9f237b3b84fa768b20f2c49b27779a8987fb1c7160f68152fe5e8f
|
7
|
+
data.tar.gz: 260685bca6ab7c0cc53b2fc566b997026d857d96c71b6889bcff3b85bd57bbfa526d4a8df6d0044b7c400a2b3be26669a81be77900669deffc4f318f1a7674c2
|
data/.semver
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.5.11] 2024-02-18
|
4
|
+
- allow directives to return information that is inserted into the prompt text
|
5
|
+
- added //shell command directive
|
6
|
+
- added //ruby ruby_code directive
|
7
|
+
- added //include path_to_file directive
|
8
|
+
|
9
|
+
## [0.5.10] 2024-02-03
|
10
|
+
- Added --roles_dir to isolate roles from other prompts if desired
|
11
|
+
- Changed --prompts to --prompts_dir to be consistent
|
12
|
+
- Refactored common fzf usage into its own tool class
|
13
|
+
|
14
|
+
## [0.5.9] 2024-02-01
|
15
|
+
- Added a "I'm working" spinner thing when "--verbose" is used as an indication that the backend is in the process of composing its response to the prompt.
|
16
|
+
|
3
17
|
## [0.5.8] 2024-01-17
|
4
18
|
- Changed the behavior of the --dump option. It must now be followed by path/to/file.ext where ext is a supported config file format: yml, yaml, toml
|
5
19
|
|
data/README.md
CHANGED
@@ -5,23 +5,19 @@
|
|
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.7
|
9
|
-
- Added ERB processing to config files that have the pattern any_file.ext.erb where ext is the real extension of the file.
|
10
8
|
|
11
|
-
v0.5.
|
12
|
-
-
|
13
|
-
-
|
14
|
-
|
9
|
+
> v0.5.11
|
10
|
+
> - Allow directives to prepend content into the prompt text
|
11
|
+
> - Added //include path_to_file
|
12
|
+
> - Added //shell shell_command
|
13
|
+
> - Added //ruby ruby code
|
14
|
+
>
|
15
|
+
> v0.5.10
|
16
|
+
> - Added --roles_dir
|
17
|
+
> - Changed --prompts to --prompts_dir
|
18
|
+
> - Fixed Issue 33
|
19
|
+
>
|
15
20
|
|
16
|
-
v0.5.3
|
17
|
-
- `--render` will render markdown formatted content to the terminal using the `glow` CLI utility.
|
18
|
-
- fixes to some terminal UI stuff like AI response is not being wrapped to the terminal width to make for easier reading.
|
19
|
-
- fixed the completion functions to use the correct $AIA_PROMPTS_DIR envar
|
20
|
-
|
21
|
-
v0.5.0 - Breaking changes:
|
22
|
-
- `--config` is now `--config_file`
|
23
|
-
- `--env` is now `--shell`
|
24
|
-
- `--output` is now `--out_file`
|
25
21
|
|
26
22
|
<!-- Tocer[start]: Auto-generated, don't remove. -->
|
27
23
|
|
@@ -37,15 +33,22 @@ v0.5.0 - Breaking changes:
|
|
37
33
|
- [*E*mbedded *R*u*B*y (ERB)](#embedded-ruby-erb)
|
38
34
|
- [Chat Session Behavior](#chat-session-behavior)
|
39
35
|
- [Prompt Directives](#prompt-directives)
|
36
|
+
- [Parameter and Shell Substitution in Directives](#parameter-and-shell-substitution-in-directives)
|
40
37
|
- [`aia` Specific Directive Commands](#aia-specific-directive-commands)
|
41
38
|
- [//config](#config)
|
39
|
+
- [//include](#include)
|
40
|
+
- [//ruby](#ruby)
|
41
|
+
- [//shell](#shell)
|
42
42
|
- [Backend Directive Commands](#backend-directive-commands)
|
43
43
|
- [Using Directives in Chat Sessions](#using-directives-in-chat-sessions)
|
44
44
|
- [All About ROLES](#all-about-roles)
|
45
|
+
- [The --roles_dir (AIA_ROLES_DIR)](#the---roles_dir-aia_roles_dir)
|
46
|
+
- [The --role Option](#the---role-option)
|
45
47
|
- [Other Ways to Insert Roles into Prompts](#other-ways-to-insert-roles-into-prompts)
|
46
48
|
- [External CLI Tools Used](#external-cli-tools-used)
|
47
49
|
- [Shell Completion](#shell-completion)
|
48
50
|
- [My Most Powerful Prompt](#my-most-powerful-prompt)
|
51
|
+
- [My Configuration](#my-configuration)
|
49
52
|
- [Development](#development)
|
50
53
|
- [Contributing](#contributing)
|
51
54
|
- [License](#license)
|
@@ -66,7 +69,7 @@ Install the command-line utilities by executing:
|
|
66
69
|
|
67
70
|
You will also need to establish a directory in your file system where your prompt text files, last used parameters and usage log files are kept.
|
68
71
|
|
69
|
-
Setup a system environment variable named "AIA_PROMPTS_DIR" that points to your prompts directory. The default is in your HOME directory named ".
|
72
|
+
Setup a system environment variable (envar) named "AIA_PROMPTS_DIR" that points to your prompts directory. The default is in your HOME directory named ".prompts". The envar "AIA_ROLES_DIR" points to your role directory where you have prompts that define the different roles you want the LLM to assume when it is doing its work. The default roles directory is inside the prompts directory. Its name is "roles".
|
70
73
|
|
71
74
|
You may also want to install the completion script for your shell. To get a copy of the completion script do:
|
72
75
|
|
@@ -79,234 +82,10 @@ You may also want to install the completion script for your shell. To get a cop
|
|
79
82
|
|
80
83
|
The usage report obtained using either `-h` or `--help` is implemented as a standard `man` page. You can use both `--help --verbose` of `-h -v` together to get not only the `aia` man page but also the usage report from the `backend` LLM processing tool.
|
81
84
|
|
82
|
-
```
|
85
|
+
```shell
|
83
86
|
$ aia --help
|
84
|
-
|
85
|
-
aia(1) User Manuals aia(1)
|
86
|
-
|
87
|
-
NAME
|
88
|
-
aia - command-line interface for an AI assistant
|
89
|
-
|
90
|
-
SYNOPSIS
|
91
|
-
aia [options]* PROMPT_ID [CONTEXT_FILE]* [-- EXTERNAL_OPTIONS+]
|
92
|
-
|
93
|
-
DESCRIPTION
|
94
|
-
The aia command-line tool is an interface for interacting with an AI model backend,
|
95
|
-
providing a simple way to send prompts and receive responses. The CLI supports various
|
96
|
-
options to customize the interaction, load a configuration file, edit prompts, set
|
97
|
-
debugging levels, and more.
|
98
|
-
|
99
|
-
ARGUMENTS
|
100
|
-
PROMPT_ID
|
101
|
-
This is a required argument.
|
102
|
-
|
103
|
-
CONTEXT_FILES
|
104
|
-
This is an optional argument. One or more files can be added to the prompt as
|
105
|
-
context for the backend gen-AI tool to process.
|
106
|
-
|
107
|
-
EXTERNAL_OPTIONS
|
108
|
-
External options are optional. Anything that follow “ -- “ will be sent to the
|
109
|
-
backend gen-AI tool. For example “-- -C -m gpt4-128k” will send the options
|
110
|
-
“-C -m gpt4-128k” to the backend gen-AI tool. aia will not validate these
|
111
|
-
external options before sending them to the backend gen-AI tool.
|
112
|
-
|
113
|
-
OPTIONS
|
114
|
-
--chat begin a chat session with the backend after the initial prompt response; will
|
115
|
-
set --no-out_file so that the backend response comes to STDOUT. After the
|
116
|
-
initial prompt is processed, you will be asked to provide a follow up. Just
|
117
|
-
enter whatever is appropriate terminating your input with a RETURN. The
|
118
|
-
backend will provide a response to you follow up and ask you again if you have
|
119
|
-
another follow up. This back and forth chatting will continue until you enter a
|
120
|
-
RETURN without any other content - an empty follow up prompt. You may also
|
121
|
-
enter a directive to be processed after which another follow up is requested.
|
122
|
-
If you have the --shell and/or the --erb options set you may use those tools
|
123
|
-
within your follow up to provide dynamic content.
|
124
|
-
|
125
|
-
--completion SHELL_NAME
|
126
|
-
|
127
|
-
--dump PATH/TO/FILE.ext
|
128
|
-
Dump the current configuration to a file in the format denoted by the file’s
|
129
|
-
extension. Currently only .yml, .yaml and .toml are acceptable file
|
130
|
-
extensions. If the file exists, it will be over-written without warning.
|
131
|
-
|
132
|
-
-e, --edit
|
133
|
-
Invokes an editor on the prompt file. You can make changes to the prompt file,
|
134
|
-
save it and the newly saved prompt will be processed by the backend.
|
135
|
-
|
136
|
-
--shell
|
137
|
-
This option tells aia to replace references to system environment variables in
|
138
|
-
the prompt with the value of the envar. envars are like $HOME and ${HOME} in
|
139
|
-
this example their occurance will be replaced by the value of ENV[‘HOME’].
|
140
|
-
Also the dynamic shell command in the pattern $(shell command) will be executed
|
141
|
-
and its output replaces its pattern. It does not matter if your shell uses
|
142
|
-
different patters than BASH since the replacement is being done within a Ruby
|
143
|
-
context.
|
144
|
-
|
145
|
-
--erb If dynamic prompt content using $(...) wasn’t enough here is ERB. Embedded
|
146
|
-
RUby. <%= ruby code %> within a prompt will have its ruby code executed and
|
147
|
-
the results of that execution will be inserted into the prompt. I’m sure we
|
148
|
-
will find a way to truly misuse this capability. Remember, some say that the
|
149
|
-
simple prompt is the best prompt.
|
150
|
-
|
151
|
-
--model NAME
|
152
|
-
Name of the LLM model to use - default is gpt-4-1106-preview
|
153
|
-
|
154
|
-
--render
|
155
|
-
Render markdown to the terminal using the external tool “glow” - default: false
|
156
|
-
|
157
|
-
--speak
|
158
|
-
Simple implementation. Uses the “say” command to speak the response. Fun with
|
159
|
-
--chat
|
160
|
-
|
161
|
-
--terse
|
162
|
-
Add a clause to the prompt text that instructs the backend to be terse in its
|
163
|
-
response.
|
164
|
-
|
165
|
-
--version
|
166
|
-
Print Version - default is false
|
167
|
-
|
168
|
-
-b, --[no]-backend LLM TOOL
|
169
|
-
Specify the backend prompt resolver - default is mods
|
170
|
-
|
171
|
-
-c, --config_file PATH_TO_CONFIG_FILE
|
172
|
-
Load Config File. both YAML and TOML formats are supported. Also ERB is
|
173
|
-
supported. For example ~/aia_config.yml.erb will be processed through ERB and
|
174
|
-
then through YAML. The result will be written out to ~/aia_config.yml so that
|
175
|
-
you can manually verify that you got what you wanted from the ERB processing.
|
176
|
-
|
177
|
-
-d, --debug
|
178
|
-
Turn On Debugging - default is false
|
179
|
-
|
180
|
-
-e, --edit
|
181
|
-
Edit the Prompt File - default is false
|
182
|
-
|
183
|
-
-f, --fuzzy`
|
184
|
-
Use Fuzzy Matching when searching for a prompt - default is false
|
185
|
-
|
186
|
-
-h, --help
|
187
|
-
Show Usage - default is false
|
188
|
-
|
189
|
-
-l, --[no]-log_file PATH_TO_LOG_FILE
|
190
|
-
Log FILEPATH - default is $HOME/.prompts/prompts.log
|
191
|
-
|
192
|
-
-m, --[no]-markdown
|
193
|
-
Format with Markdown - default is true
|
194
|
-
|
195
|
-
-o, --[no]-out_file PATH_TO_OUTPUT_FILE
|
196
|
-
Out FILENAME - default is ./temp.md
|
197
|
-
|
198
|
-
-p, --prompts PATH_TO_DIRECTORY
|
199
|
-
Directory containing the prompt files - default is ~/.prompts
|
200
|
-
|
201
|
-
-r, --role ROLE_ID
|
202
|
-
A role ID is the same as a prompt ID. A “role” is a specialized prompt that
|
203
|
-
gets pre-pended to another prompt. It’s purpose is to configure the LLM into a
|
204
|
-
certain orientation within which to resolve its primary prompt.
|
205
|
-
|
206
|
-
-v, --verbose
|
207
|
-
Be Verbose - default is false
|
208
|
-
|
209
|
-
CONFIGURATION HIERARCHY
|
210
|
-
System Environment Variables (envars) that are all uppercase and begin with “AIA_” can
|
211
|
-
be used to over-ride the default configuration settings. For example setting “export
|
212
|
-
AIA_PROMPTS_DIR=~/Documents/prompts” will over-ride the default configuration;
|
213
|
-
however, a config value provided by a command line options will over-ride an envar
|
214
|
-
setting.
|
215
|
-
|
216
|
-
Configuration values found in a config file will over-ride all other values set for a
|
217
|
-
config item.
|
218
|
-
|
219
|
-
”//config” directives found inside a prompt file over-rides that config item
|
220
|
-
regardless of where the value was set.
|
221
|
-
|
222
|
-
For example “//config chat? = true” within a prompt will setup the chat back and forth
|
223
|
-
chat session for that specific prompt regardless of the command line options or the
|
224
|
-
envar AIA_CHAT settings
|
225
|
-
|
226
|
-
OpenAI ACCOUNT IS REQUIRED
|
227
|
-
Additionally, the program requires an OpenAI access key, which can be specified using
|
228
|
-
one of the following environment variables:
|
229
|
-
|
230
|
-
• OPENAI_ACCESS_TOKEN
|
231
|
-
|
232
|
-
• OPENAI_API_KEY
|
233
|
-
|
234
|
-
Currently there is not specific standard for name of the OpenAI key. Some programs
|
235
|
-
use one name, while others use a different name. Both of the envars listed above mean
|
236
|
-
the same thing. If you use more than one tool to access OpenAI resources, you may
|
237
|
-
have to set several envars to the same key value.
|
238
|
-
|
239
|
-
To acquire an OpenAI access key, first create an account on the OpenAI platform, where
|
240
|
-
further documentation is available.
|
241
|
-
|
242
|
-
USAGE NOTES
|
243
|
-
aia is designed for flexibility, allowing users to pass prompt ids and context files
|
244
|
-
as arguments. Some options change the behavior of the output, such as --out_file for
|
245
|
-
specifying a file or --no-out_file for disabling file output in favor of standard
|
246
|
-
output (STDPIT).
|
247
|
-
|
248
|
-
The --completion option displays a script that enables prompt ID auto-completion for
|
249
|
-
bash, zsh, or fish shells. It’s crucial to integrate the script into the shell’s
|
250
|
-
runtime to take effect.
|
251
|
-
|
252
|
-
The --dump path/to/file.ext option will write the current configuration to a file in
|
253
|
-
the format requested by the file’s extension. The following extensions are supported:
|
254
|
-
.yml, .yaml and .toml
|
255
|
-
|
256
|
-
PROMPT DIRECTIVES
|
257
|
-
Within a prompt text file any line that begins with “//” is considered a prompt
|
258
|
-
directive. There are numerious prompt directives available. In the discussion above
|
259
|
-
on the configuration you learned about the “//config” directive.
|
260
|
-
|
261
|
-
Detail discussion on individual prompt directives is TBD. Most likely it will be
|
262
|
-
handled in the github wiki <https://github.com/MadBomber/aia>
|
263
|
-
|
264
|
-
SEE ALSO
|
265
|
-
|
266
|
-
• OpenAI Platform Documentation <https://platform.openai.com/docs/overview>
|
267
|
-
for more information on obtaining access tokens
|
268
|
-
<https://platform.openai.com/account/api-keys>
|
269
|
-
and working with OpenAI models.
|
270
|
-
|
271
|
-
• mods <https://github.com/charmbracelet/mods>
|
272
|
-
for more information on mods - AI for the command line, built for pipelines.
|
273
|
-
LLM based AI is really good at interpreting the output of commands and
|
274
|
-
returning the results in CLI friendly text formats like Markdown. Mods is a
|
275
|
-
simple tool that makes it super easy to use AI on the command line and in
|
276
|
-
your pipelines. Mods works with OpenAI
|
277
|
-
<https://platform.openai.com/account/api-keys>
|
278
|
-
and LocalAI <https://github.com/go-skynet/LocalAI>
|
279
|
-
|
280
|
-
• sgpt <https://github.com/tbckr/sgpt>
|
281
|
-
(aka shell-gpt) is a powerful command-line interface (CLI) tool designed for
|
282
|
-
seamless interaction with OpenAI models directly from your terminal.
|
283
|
-
Effortlessly run queries, generate shell commands or code, create images from
|
284
|
-
text, and more, using simple commands. Streamline your workflow and enhance
|
285
|
-
productivity with this powerful and user-friendly CLI tool.
|
286
|
-
|
287
|
-
• fzf <https://github.com/junegunn/fzf>
|
288
|
-
fzf is a general-purpose command-line fuzzy finder. It’s an interactive
|
289
|
-
Unix filter for command-line that can be used with any list; files, command
|
290
|
-
history, processes, hostnames, bookmarks, git commits, etc.
|
291
|
-
|
292
|
-
• ripgrep <https://github.com/BurntSushi/ripgrep>
|
293
|
-
Search tool like grep and The Silver Searcher. It is a line-oriented search
|
294
|
-
tool that recursively searches a directory tree for a regex pattern. By
|
295
|
-
default, ripgrep will respect gitignore rules and automatically skip hidden
|
296
|
-
files/directories and binary files. (To disable all automatic filtering by
|
297
|
-
default, use rg -uuu.) ripgrep has first class support on Windows, macOS and
|
298
|
-
Linux, with binary downloads available for every release.
|
299
|
-
|
300
|
-
• glow <https://github.com/charmbracelet/glow>
|
301
|
-
Render markdown on the CLI
|
302
|
-
|
303
|
-
AUTHOR
|
304
|
-
Dewayne VanHoozer <dvanhoozer@gmail.com>
|
305
|
-
|
306
|
-
AIA 2024-01-01 aia(1)
|
307
87
|
```
|
308
88
|
|
309
|
-
|
310
89
|
## Configuration Using Envars
|
311
90
|
|
312
91
|
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.
|
@@ -389,9 +168,28 @@ Downstream processing directives were added to the `prompt_manager` gem used by
|
|
389
168
|
|
390
169
|
There is no space between the "//" and the command.
|
391
170
|
|
171
|
+
### Parameter and Shell Substitution in Directives
|
172
|
+
|
173
|
+
When you combine prompt directives with prompt parameters and shell envar substitutions you can get some powerful compositional prompts.
|
174
|
+
|
175
|
+
Here is an example of a pure generic directive.
|
176
|
+
|
177
|
+
```
|
178
|
+
//[DIRECTIVE_NAME] [DIRECTIVE_PARAMS]
|
179
|
+
```
|
180
|
+
|
181
|
+
When the prompt runs, you will be asked to provide a value for each of the parameters. You could answer "shell" for the directive name and "calc 22/7" if you wanted a bad approximation of PI.
|
182
|
+
|
183
|
+
Try this prompt file:
|
184
|
+
```
|
185
|
+
//shell calc [FORMULA]
|
186
|
+
|
187
|
+
What does that number mean to you?
|
188
|
+
```
|
189
|
+
|
392
190
|
### `aia` Specific Directive Commands
|
393
191
|
|
394
|
-
At this time `aia` only has
|
192
|
+
At this time `aia` only has a few directives which are detailed below.
|
395
193
|
|
396
194
|
#### //config
|
397
195
|
|
@@ -416,6 +214,64 @@ A configuration item such as `--out_file` or `--model` has an associated value o
|
|
416
214
|
//config backend = mods
|
417
215
|
```
|
418
216
|
|
217
|
+
BTW: the "=" is completely options. Its actuall ignored as is ":=" if you were to choose that as your assignment operator. Also the number of spaces between the item and the value is complete arbitrary. I like to line things up so this syntax is just as valie:
|
218
|
+
|
219
|
+
```
|
220
|
+
//config model gpt-3.5-turbo
|
221
|
+
//config out_file temp.md
|
222
|
+
//config backend mods
|
223
|
+
//config chat? true
|
224
|
+
//config terse? true
|
225
|
+
//config model gpt-4
|
226
|
+
```
|
227
|
+
|
228
|
+
NOTE: if you specify the same config item name more than once within the prompt file, its the last one which will be set when the prompt is finally process through the LLM. For example in the example above `gpt-4` will be the model used. Being first does not count in this case.
|
229
|
+
|
230
|
+
#### //include
|
231
|
+
|
232
|
+
Example:
|
233
|
+
```
|
234
|
+
//include path_to_file
|
235
|
+
```
|
236
|
+
|
237
|
+
The `path_to_file` can be either absolute or relative. If it is relative, it is achored at the PWD. If the `path_to_file` includes envars, the `--shell` CLI option must be used to replace the envar in the directive with its actual value.
|
238
|
+
|
239
|
+
The file that is included will have any comments or directives excluded. It is expected that the file will be a text file so that its content can be pre-pended to the existing prompt; however, if the file is a source code file (ex: file.rb) the source code will be included HOWEVER any comment line or line that starts with "//" will be excluded.
|
240
|
+
|
241
|
+
TODO: Consider adding a command line option `--include_dir` to specify the place from which relative files are to come.
|
242
|
+
|
243
|
+
#### //ruby
|
244
|
+
Example:
|
245
|
+
```
|
246
|
+
//ruby any_code_that_returns_an_instance_of_String
|
247
|
+
```
|
248
|
+
|
249
|
+
This directive is in addition to ERB. At this point the `//ruby` directive is limited by the current binding which is within the `AIA::Directives#ruby` method. As such it is not likely to see much use.
|
250
|
+
|
251
|
+
However, sinces it implemented as a simple `eval(code)` then there is a potential for use like this:
|
252
|
+
```
|
253
|
+
//ruby load(some_ruby_file); execute_some_method
|
254
|
+
```
|
255
|
+
|
256
|
+
Each execution of a `//ruby` directive will be a fresh execution of the `AIA::Directives#ruby` method so you cannot carry local variables from one invocation to another; however, you could do something with instance variables or global variables. You might even add something to the `AIA.config` object to be pasted on to the next invocation of the directive within the context of the same prompt.
|
257
|
+
|
258
|
+
#### //shell
|
259
|
+
Example:
|
260
|
+
```
|
261
|
+
//shell some_shell_command
|
262
|
+
```
|
263
|
+
|
264
|
+
It is expected that the shell command will return some text to STDOUT which will be pre-pending to the existing prompt text within the prompt file.
|
265
|
+
|
266
|
+
There are no limitations on what the shell command can be. For example if you wanted to bypass the stripping of comments and directives from a file you could do something like this:
|
267
|
+
```
|
268
|
+
//shell cat path_to_file
|
269
|
+
```
|
270
|
+
|
271
|
+
Which does basically the same thing as the `//include` directive, except it uses the entire content of the file. For relative file paths the same thing applies. The file's path will be relative to the PWD.
|
272
|
+
|
273
|
+
|
274
|
+
|
419
275
|
### Backend Directive Commands
|
420
276
|
|
421
277
|
See the source code for the directives supported by the backends which at this time are configuration-based as well.
|
@@ -423,7 +279,7 @@ See the source code for the directives supported by the backends which at this t
|
|
423
279
|
- [mods](lib/aia/tools/mods.rb)
|
424
280
|
- [sgpt](lib/aia/tools/sgpt.rb)
|
425
281
|
|
426
|
-
|
282
|
+
For example `mods` has a configuration item `topp` which can be set by a directive in a prompt text file directly.
|
427
283
|
|
428
284
|
```
|
429
285
|
//topp 1.5
|
@@ -444,7 +300,19 @@ The directive is executed and a new follow up prompt can be entered with a more
|
|
444
300
|
|
445
301
|
## All About ROLES
|
446
302
|
|
447
|
-
|
303
|
+
### The --roles_dir (AIA_ROLES_DIR)
|
304
|
+
|
305
|
+
There are two kinds of prompts
|
306
|
+
1. instructional - tells the LLM what to do
|
307
|
+
2. personification - tells the LLM who it should pretend to be when it does its transformational work.
|
308
|
+
|
309
|
+
That second kind of prompt is called a role. Sometimes the role is incorporated into the instruction. For example "As a magician make a rabbit appear out of a hat." To reuse the same role in multiple prompts `aia` encourages you to designate a special `roles_dir` into which you put prompts that are specific to personification - roles.
|
310
|
+
|
311
|
+
The default `roles_dir` is a sub-directory of the `prompts_dir` named roles. You can, however, put your `roles_dir` anywhere that makes sense to you.
|
312
|
+
|
313
|
+
### The --role Option
|
314
|
+
|
315
|
+
The `--role` option is used to identify a personification prompt within your roles 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.
|
448
316
|
|
449
317
|
For example consider:
|
450
318
|
|
@@ -452,17 +320,17 @@ For example consider:
|
|
452
320
|
aia -r ruby refactor my_class.rb
|
453
321
|
```
|
454
322
|
|
455
|
-
Within the
|
323
|
+
Within the roles directory the contents of the text file `ruby.txt` will be pre-pre-pended to the contents of the `refactor.txt` file from the prompts directory to produce a complete prompt. That complete prompt will have any parameters followed by directives processed before sending the combined prompt text to the backend.
|
456
324
|
|
457
325
|
Note that `--role` is just a way of saying add this prompt text file to the front of this other prompt text file. The contents of the "role" prompt could be anything. It does not necessarily have be an actual role.
|
458
326
|
|
459
|
-
|
327
|
+
`aia` fully supports a directory tree within the `prompts_dir` as a way of organization or classification of your different prompt text files.
|
460
328
|
|
461
329
|
```shell
|
462
|
-
aia -r
|
330
|
+
aia -r sw_eng doc_the_methods my_class.rb
|
463
331
|
```
|
464
332
|
|
465
|
-
In this example the prompt text file `$
|
333
|
+
In this example the prompt text file `$AIA_ROLES_DIR/sw_eng.txt` is prepended to the prompt text file `$AIA_PROMPTS_DIR/doc_the_methods.txt`
|
466
334
|
|
467
335
|
|
468
336
|
### Other Ways to Insert Roles into Prompts
|
@@ -473,7 +341,7 @@ Since `aia` supports parameterized prompts you could make a keyword like "[ROLE]
|
|
473
341
|
As a [ROLE] tell me what you think about [SUBJECT]
|
474
342
|
```
|
475
343
|
|
476
|
-
When this prompt is processed, `aia` will ask you for a value for the keyword "ROLE" and the keyword "SUBJECT" to complete the prompt. Since `aia` maintains a history your previous answers, you could just choose something that you used in the past or answer with a completely new value.
|
344
|
+
When this prompt is processed, `aia` will ask you for a value for the keyword "ROLE" and the keyword "SUBJECT" to complete the prompt. Since `aia` maintains a history of your previous answers, you could just choose something that you used in the past or answer with a completely new value.
|
477
345
|
|
478
346
|
## External CLI Tools Used
|
479
347
|
|
@@ -538,6 +406,40 @@ aia ad_hoc financial_statement.txt
|
|
538
406
|
|
539
407
|
Both do the same thing; however, `aia` does not put the text of the prompt into the shell's history file.... of course the keyword/parameter value is saved in the prompt's JSON file and the prompt with the response are logged unless `--no-log` is specified; but, its not messing up the shell history!
|
540
408
|
|
409
|
+
## My Configuration
|
410
|
+
|
411
|
+
I use the `bash` shell. In my `.bashrc` file I source another file named `.bashrc__aia` which looks like this:
|
412
|
+
|
413
|
+
```shell
|
414
|
+
# ~/.bashic_aia
|
415
|
+
# AI Assistant
|
416
|
+
|
417
|
+
# These are the defaults:
|
418
|
+
export AIA_PROMPTS_DIR=~/.prompts
|
419
|
+
export AIA_OUT_FILE=./temp.md
|
420
|
+
export AIA_LOG_FILE=$AIA_PROMPTS_DIR/_prompts.log
|
421
|
+
export AIA_BACKEND=mods
|
422
|
+
export AIA_MODEL=gpt-4-1106-preview
|
423
|
+
|
424
|
+
# Not a default. Invokes spinner.
|
425
|
+
export AIA_VERBOSE=true
|
426
|
+
|
427
|
+
alias chat='aia chat --terse'
|
428
|
+
|
429
|
+
# rest of the file is the completion function
|
430
|
+
```
|
431
|
+
|
432
|
+
Here is what my `chat` prompt file looks like:
|
433
|
+
|
434
|
+
```shell
|
435
|
+
# ~/.prompts/chat.txt
|
436
|
+
# Desc: Start a chat session
|
437
|
+
|
438
|
+
//config chat? = true
|
439
|
+
|
440
|
+
[WHAT]
|
441
|
+
```
|
442
|
+
|
541
443
|
## Development
|
542
444
|
|
543
445
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/aia/clause.rb
ADDED
data/lib/aia/cli.rb
CHANGED
@@ -154,7 +154,8 @@ class AIA::Cli
|
|
154
154
|
role: ['', "-r --role"],
|
155
155
|
#
|
156
156
|
config_file:[nil, "-c --config_file"],
|
157
|
-
prompts_dir:["~/.prompts", "-p --
|
157
|
+
prompts_dir:["~/.prompts", "-p --prompts_dir"],
|
158
|
+
roles_dir: ["~/.prompts/roles", "--roles_dir"],
|
158
159
|
out_file: [STDOUT, "-o --out_file --no-out_file"],
|
159
160
|
log_file: ["~/.prompts/_prompts.log", "-l --log_file --no-log_file"],
|
160
161
|
#
|
@@ -230,10 +231,14 @@ class AIA::Cli
|
|
230
231
|
|
231
232
|
EOS
|
232
233
|
|
233
|
-
|
234
|
+
show_error_usage
|
234
235
|
|
235
236
|
exit
|
236
237
|
end
|
238
|
+
|
239
|
+
# After all other arguments
|
240
|
+
# are processed, check for role parameter.
|
241
|
+
check_for_role_parameter
|
237
242
|
end
|
238
243
|
|
239
244
|
|
@@ -272,6 +277,56 @@ class AIA::Cli
|
|
272
277
|
end
|
273
278
|
end
|
274
279
|
|
280
|
+
|
281
|
+
def check_for_role_parameter
|
282
|
+
role = AIA.config.role
|
283
|
+
return if role.empty?
|
284
|
+
|
285
|
+
role_path = string_to_pathname(AIA.config.roles_dir) + "#{role}.txt"
|
286
|
+
|
287
|
+
unless role_path.exist?
|
288
|
+
puts "Role prompt '#{role}' not found. Invoking fzf to choose a role..."
|
289
|
+
invoke_fzf_to_choose_role
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
|
294
|
+
def invoke_fzf_to_choose_role
|
295
|
+
roles_path = string_to_pathname AIA.config.roles_dir
|
296
|
+
|
297
|
+
available_roles = roles_path
|
298
|
+
.children
|
299
|
+
.select { |f| '.txt' == f.extname}
|
300
|
+
.map{|role| role.basename.to_s.gsub('.txt','')}
|
301
|
+
|
302
|
+
fzf = AIA::Fzf.new(
|
303
|
+
list: available_roles,
|
304
|
+
directory: roles_path,
|
305
|
+
prompt: 'Select Role:',
|
306
|
+
extension: '.txt'
|
307
|
+
)
|
308
|
+
|
309
|
+
chosen_role = fzf.run
|
310
|
+
|
311
|
+
if chosen_role.nil?
|
312
|
+
abort("No role selected. Exiting...")
|
313
|
+
else
|
314
|
+
AIA.config.role = chosen_role
|
315
|
+
puts "Role changed to '#{chosen_role}'."
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
|
320
|
+
def show_error_usage
|
321
|
+
puts <<~ERROR_USAGE
|
322
|
+
|
323
|
+
Usage: aia [options] PROMPT_ID [CONTEXT_FILE(s)] [-- EXTERNAL_OPTIONS]"
|
324
|
+
Try 'aia --help' for more information."
|
325
|
+
|
326
|
+
ERROR_USAGE
|
327
|
+
end
|
328
|
+
|
329
|
+
|
275
330
|
# aia usage is maintained in a man page
|
276
331
|
def show_usage
|
277
332
|
@options[:help?][0] = false
|
data/lib/aia/directives.rb
CHANGED
@@ -14,20 +14,24 @@ class AIA::Directives
|
|
14
14
|
def execute_my_directives
|
15
15
|
return if AIA.config.directives.nil? || AIA.config.directives.empty?
|
16
16
|
|
17
|
-
|
17
|
+
result = ""
|
18
|
+
not_mine = []
|
18
19
|
|
19
20
|
AIA.config.directives.each do |entry|
|
20
21
|
directive = entry[0].to_sym
|
21
22
|
parameters = entry[1]
|
22
23
|
|
23
24
|
if respond_to? directive
|
24
|
-
send(directive, parameters)
|
25
|
+
output = send(directive, parameters)
|
26
|
+
result << "#{output}\n" unless output.nil?
|
25
27
|
else
|
26
28
|
not_mine << entry
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
30
32
|
AIA.config.directives = not_mine
|
33
|
+
|
34
|
+
result.empty? ? nil : result
|
31
35
|
end
|
32
36
|
|
33
37
|
|
@@ -60,5 +64,40 @@ class AIA::Directives
|
|
60
64
|
AIA.config[item] = "STDOUT" == value ? STDOUT : value
|
61
65
|
end
|
62
66
|
end
|
67
|
+
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
# when path_to_file is relative it will be
|
73
|
+
# relative to the PWD.
|
74
|
+
#
|
75
|
+
# TODO: Consider an AIA_INCLUDE_DIR --include_dir
|
76
|
+
# option to be used for all relative include paths
|
77
|
+
#
|
78
|
+
def include(path_to_file)
|
79
|
+
path = Pathname.new path_to_file
|
80
|
+
if path.exist? && path.readable?
|
81
|
+
content = path.readlines.reject do |a_line|
|
82
|
+
a_line.strip.start_with?(AIA::Prompt::COMMENT_SIGNAL) ||
|
83
|
+
a_line.strip.start_with?(AIA::Prompt::DIRECTIVE_SIGNAL)
|
84
|
+
end.join("\n")
|
85
|
+
else
|
86
|
+
abort "ERROR: could not include #{path_to_file}"
|
87
|
+
end
|
88
|
+
|
89
|
+
content
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
def shell(command)
|
94
|
+
`#{command}`
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
def ruby(code)
|
99
|
+
output = eval(code)
|
100
|
+
|
101
|
+
output.is_a?(String) ? output : nil
|
63
102
|
end
|
64
103
|
end
|
data/lib/aia/main.rb
CHANGED
@@ -20,11 +20,12 @@ class AIA::Main
|
|
20
20
|
include AIA::DynamicContent
|
21
21
|
include AIA::UserQuery
|
22
22
|
|
23
|
-
attr_accessor :logger, :tools, :backend
|
23
|
+
attr_accessor :logger, :tools, :backend, :directive_output
|
24
24
|
|
25
25
|
attr_reader :spinner
|
26
26
|
|
27
|
-
def initialize(args= ARGV)
|
27
|
+
def initialize(args= ARGV)
|
28
|
+
@directive_output = ""
|
28
29
|
AIA::Tools.load_tools
|
29
30
|
|
30
31
|
AIA::Cli.new(args)
|
@@ -71,7 +72,7 @@ class AIA::Main
|
|
71
72
|
|
72
73
|
|
73
74
|
def call
|
74
|
-
@directives_processor.execute_my_directives
|
75
|
+
directive_output = @directives_processor.execute_my_directives
|
75
76
|
|
76
77
|
if AIA.config.chat?
|
77
78
|
AIA.config.out_file = STDOUT
|
@@ -103,6 +104,8 @@ class AIA::Main
|
|
103
104
|
|
104
105
|
the_prompt = @prompt.to_s
|
105
106
|
|
107
|
+
the_prompt.prepend(directive_output + "\n") unless directive_output.nil? || directive_output.empty?
|
108
|
+
|
106
109
|
if AIA.config.terse?
|
107
110
|
the_prompt.prepend "Be terse in your response. "
|
108
111
|
end
|
@@ -186,7 +189,9 @@ class AIA::Main
|
|
186
189
|
directive = parts.shift
|
187
190
|
parameters = parts.join(' ')
|
188
191
|
AIA.config.directives << [directive, parameters]
|
189
|
-
@directives_processor.execute_my_directives
|
192
|
+
directive_output = @directives_processor.execute_my_directives
|
193
|
+
else
|
194
|
+
directive_output = ""
|
190
195
|
end
|
191
196
|
|
192
197
|
result
|
@@ -202,7 +207,16 @@ class AIA::Main
|
|
202
207
|
the_prompt_text = render_erb(the_prompt_text) if AIA.config.erb?
|
203
208
|
the_prompt_text = render_env(the_prompt_text) if AIA.config.shell?
|
204
209
|
|
205
|
-
|
210
|
+
if handle_directives(the_prompt_text)
|
211
|
+
unless directive_output.nil?
|
212
|
+
the_prompt_text = insert_terse_phrase(the_prompt_text)
|
213
|
+
the_prompt_text << directive_output
|
214
|
+
result = get_and_display_result(the_prompt_text)
|
215
|
+
|
216
|
+
log_the_follow_up(the_prompt_text, result)
|
217
|
+
speak result
|
218
|
+
end
|
219
|
+
else
|
206
220
|
the_prompt_text = insert_terse_phrase(the_prompt_text)
|
207
221
|
result = get_and_display_result(the_prompt_text)
|
208
222
|
|
data/lib/aia/prompt.rb
CHANGED
@@ -23,7 +23,9 @@ class AIA::Prompt
|
|
23
23
|
def to_s = ''
|
24
24
|
end
|
25
25
|
|
26
|
-
KW_HISTORY_MAX
|
26
|
+
KW_HISTORY_MAX = 5
|
27
|
+
COMMENT_SIGNAL = '#'
|
28
|
+
DIRECTIVE_SIGNAL = "//"
|
27
29
|
|
28
30
|
attr_reader :prompt
|
29
31
|
|
@@ -32,9 +34,7 @@ class AIA::Prompt
|
|
32
34
|
if AIA.config.role.empty?
|
33
35
|
@role = nil
|
34
36
|
else
|
35
|
-
AIA.config.
|
36
|
-
get_prompt
|
37
|
-
@role = @prompt.dup
|
37
|
+
@role = (AIA.config.roles_dir + "#{AIA.config.role}.txt").read
|
38
38
|
end
|
39
39
|
|
40
40
|
get_prompt
|
@@ -42,7 +42,7 @@ class AIA::Prompt
|
|
42
42
|
@prompt_text_before_role = @prompt.text.dup
|
43
43
|
|
44
44
|
unless @role.nil?
|
45
|
-
@prompt.text.prepend @role
|
45
|
+
@prompt.text.prepend @role
|
46
46
|
end
|
47
47
|
|
48
48
|
if build
|
@@ -200,37 +200,18 @@ class AIA::Prompt
|
|
200
200
|
|
201
201
|
def handle_multiple_prompts(found_these, while_looking_for_this)
|
202
202
|
raise ArgumentError, "Argument is not an Array" unless found_these.is_a?(Array)
|
203
|
-
|
204
|
-
#
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
# Create a temporary file to hold the list of strings
|
218
|
-
temp_file = Tempfile.new('fzf-input')
|
219
|
-
|
220
|
-
begin
|
221
|
-
# Write all strings to the temp file
|
222
|
-
temp_file.puts(found_these)
|
223
|
-
temp_file.close
|
224
|
-
|
225
|
-
# Execute fzf command-line utility to allow selection
|
226
|
-
selected = `cat #{temp_file.path} | fzf #{fzf_options}`.strip
|
227
|
-
|
228
|
-
# Check if fzf actually returned a string; if not, return nil
|
229
|
-
result = selected.empty? ? nil : selected
|
230
|
-
ensure
|
231
|
-
# Ensure that the tempfile is closed and unlinked
|
232
|
-
temp_file.unlink
|
233
|
-
end
|
203
|
+
|
204
|
+
# Create an instance of AIA::Fzf with appropriate parameters
|
205
|
+
fzf_instance = AIA::Fzf.new(
|
206
|
+
list: found_these,
|
207
|
+
directory: AIA.config.prompts_dir, # Assuming this is the correct directory
|
208
|
+
query: while_looking_for_this,
|
209
|
+
subject: 'Prompt IDs',
|
210
|
+
prompt: 'Select one: '
|
211
|
+
)
|
212
|
+
|
213
|
+
# Run the fzf instance and get the selected result
|
214
|
+
result = fzf_instance.run
|
234
215
|
|
235
216
|
exit unless result
|
236
217
|
|
@@ -238,6 +219,8 @@ class AIA::Prompt
|
|
238
219
|
end
|
239
220
|
|
240
221
|
|
222
|
+
|
223
|
+
|
241
224
|
def create_prompt(prompt_id)
|
242
225
|
@prompt = PromptManager::Prompt.create(id: prompt_id)
|
243
226
|
# TODO: consider a configurable prompt template
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# lib/aia/tools/fzf.rb
|
2
|
+
# fzf is a general-purpose command-line fuzzy finder
|
3
|
+
|
4
|
+
require 'shellwords'
|
5
|
+
require 'tempfile'
|
6
|
+
|
7
|
+
class AIA::Fzf < AIA::Tools
|
8
|
+
|
9
|
+
meta(
|
10
|
+
name: 'fzf',
|
11
|
+
role: :search_tool,
|
12
|
+
desc: "A command-line fuzzy finder",
|
13
|
+
url: "https://github.com/junegunn/fzf",
|
14
|
+
install: "brew install fzf",
|
15
|
+
)
|
16
|
+
|
17
|
+
DEFAULT_PARAMETERS = %w[
|
18
|
+
--tabstop=2
|
19
|
+
--header-first
|
20
|
+
--prompt='Search term: '
|
21
|
+
--delimiter :
|
22
|
+
--preview-window=down:50%:wrap
|
23
|
+
]
|
24
|
+
|
25
|
+
attr_reader :list, :directory, :query, :subject, :prompt, :extension, :command
|
26
|
+
|
27
|
+
def initialize(
|
28
|
+
list:, # Array of Strings (basenames of files w/o extension)
|
29
|
+
directory:, # Parent directory of the list items
|
30
|
+
query: '', # String, the thing be searched for
|
31
|
+
subject: 'Prompt IDs', # or 'Role Names'
|
32
|
+
prompt: 'Select one:',
|
33
|
+
extension: '.txt'
|
34
|
+
)
|
35
|
+
|
36
|
+
@list = list
|
37
|
+
@directory = directory
|
38
|
+
@query = query
|
39
|
+
@subject = subject
|
40
|
+
@prompt = prompt
|
41
|
+
@extension = extension
|
42
|
+
|
43
|
+
build_command
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def build_command
|
48
|
+
fzf_options = DEFAULT_PARAMETERS.dup
|
49
|
+
fzf_options << "--header='#{subject} which contain: #{query}\\nPress ESC to cancel.'"
|
50
|
+
fzf_options << "--preview='cat #{directory}/{1}#{extension}'"
|
51
|
+
fzf_options << "--prompt=#{Shellwords.escape(prompt)}"
|
52
|
+
|
53
|
+
fzf_command = "#{meta.name} #{fzf_options.join(' ')}"
|
54
|
+
|
55
|
+
@command = "cat #{tempfile_path} | #{fzf_command}"
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
def run
|
60
|
+
puts "Executing: #{@command}"
|
61
|
+
selected = `#{@command}`
|
62
|
+
selected.strip.empty? ? nil : selected.strip
|
63
|
+
ensure
|
64
|
+
unlink_tempfile
|
65
|
+
end
|
66
|
+
|
67
|
+
##############################################
|
68
|
+
private
|
69
|
+
|
70
|
+
def tempfile_path
|
71
|
+
@tempfile ||= Tempfile.new('fzf-input').tap do |file|
|
72
|
+
list.each { |item| file.puts item }
|
73
|
+
file.close
|
74
|
+
end
|
75
|
+
@tempfile.path
|
76
|
+
end
|
77
|
+
|
78
|
+
def unlink_tempfile
|
79
|
+
@tempfile&.unlink
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
__END__
|
85
|
+
|
86
|
+
$ fzf --help
|
87
|
+
|
88
|
+
USAGE
|
89
|
+
fzf [OPTIONS]
|
90
|
+
|
91
|
+
OPTIONS
|
92
|
+
-x, --extended Extended-search mode
|
93
|
+
-e, --exact Enable Exact-match
|
94
|
+
--algo=TYPE Fuzzy matching algorithm: [v1|v2] (default: v2)
|
95
|
+
+i Case-insensitive match (default: smart-case match)
|
96
|
+
+s Synchronous search for multi-staged filtering
|
97
|
+
--multi Enable multi-select with tab/shift-tab
|
98
|
+
|
99
|
+
... (Other options)
|
100
|
+
|
101
|
+
EXAMPLES
|
102
|
+
find * -type f | fzf > selected
|
103
|
+
fzf < /path/to/file_list
|
104
|
+
|
105
|
+
For full documentation, please visit https://github.com/junegunn/fzf.
|
data/lib/aia/tools.rb
CHANGED
@@ -48,5 +48,41 @@ class AIA::Tools
|
|
48
48
|
require file
|
49
49
|
end
|
50
50
|
end
|
51
|
+
|
52
|
+
|
53
|
+
def validate_tools
|
54
|
+
raise "NotImplemented"
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
def setup_backend
|
59
|
+
AIA.config.tools.backend = find_and_initialize_backend
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def find_and_initialize_backend
|
66
|
+
found = AIA::Tools.search_for(name: AIA.config.backend, role: :backend)
|
67
|
+
abort_no_backend_error if found.empty?
|
68
|
+
abort_too_many_backends_error(found) if found.size > 1
|
69
|
+
|
70
|
+
backend_klass = found.first.klass
|
71
|
+
abort "Backend not found: #{AIA.config.backend}" unless backend_klass
|
72
|
+
|
73
|
+
backend_klass.new(
|
74
|
+
text: "",
|
75
|
+
files: []
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
79
|
+
def abort_no_backend_error
|
80
|
+
abort "There are no :backend tools named #{AIA.config.backend}"
|
81
|
+
end
|
82
|
+
|
83
|
+
def abort_too_many_backends_error(found)
|
84
|
+
abort "There are #{found.size} :backend tools with the name #{AIA.config.backend}"
|
85
|
+
end
|
86
|
+
|
51
87
|
end
|
52
88
|
end
|
data/lib/aia.rb
CHANGED
@@ -20,6 +20,7 @@ tramp_require('debug_me') {
|
|
20
20
|
}
|
21
21
|
|
22
22
|
require 'hashie'
|
23
|
+
require 'os'
|
23
24
|
require 'pathname'
|
24
25
|
require 'reline'
|
25
26
|
require 'shellwords'
|
@@ -37,6 +38,7 @@ require 'prompt_manager'
|
|
37
38
|
require 'prompt_manager/storage/file_system_adapter'
|
38
39
|
|
39
40
|
require_relative "aia/version"
|
41
|
+
require_relative "aia/clause"
|
40
42
|
require_relative "aia/main"
|
41
43
|
require_relative "core_ext/string_wrap"
|
42
44
|
|
@@ -54,6 +56,12 @@ module AIA
|
|
54
56
|
|
55
57
|
AIA::Main.new(args).call
|
56
58
|
end
|
59
|
+
|
60
|
+
|
61
|
+
def speak(what)
|
62
|
+
return unless AIA.config.speak?
|
63
|
+
system "say #{Shellwords.escape(what)}" if OS.osx?
|
64
|
+
end
|
57
65
|
end
|
58
66
|
end
|
59
67
|
|
data/man/aia.1
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
.\" Generated by kramdown-man 1.0.1
|
2
2
|
.\" https://github.com/postmodern/kramdown-man#readme
|
3
|
-
.TH aia 1 "
|
3
|
+
.TH aia 1 "v0.5.11" AIA "User Manuals"
|
4
4
|
.SH NAME
|
5
5
|
.PP
|
6
6
|
aia \- command\-line interface for an AI assistant
|
@@ -81,9 +81,12 @@ Format with Markdown \- default is true
|
|
81
81
|
\fB\-o\fR, \fB\-\-\[lB]no\[rB]\-out\[ru]file\fR \fIPATH\[ru]TO\[ru]OUTPUT\[ru]FILE\fP
|
82
82
|
Out FILENAME \- default is \.\[sl]temp\.md
|
83
83
|
.TP
|
84
|
-
\fB\-p\fR, \fB\-\-prompts\fR \fIPATH\[ru]TO\[ru]DIRECTORY\fP
|
84
|
+
\fB\-p\fR, \fB\-\-prompts\[ru]dir\fR \fIPATH\[ru]TO\[ru]DIRECTORY\fP
|
85
85
|
Directory containing the prompt files \- default is \[ti]\[sl]\.prompts
|
86
86
|
.TP
|
87
|
+
\fB\-\-roles\[ru]dir\fR \fIPATH\[ru]TO\[ru]DIRECTORY\fP
|
88
|
+
Directory containing the personification prompt files \- default is \[ti]\[sl]\.prompts\[sl]roles
|
89
|
+
.TP
|
87
90
|
\fB\-r\fR, \fB\-\-role\fR \fIROLE\[ru]ID\fP
|
88
91
|
A role ID is the same as a prompt ID\. A \[lq]role\[rq] is a specialized prompt that gets pre\-pended to another prompt\. It\[cq]s purpose is to configure the LLM into a certain orientation within which to resolve its primary prompt\.
|
89
92
|
.TP
|
@@ -126,6 +129,18 @@ Detail discussion on individual prompt directives is TBD\. Most likely it will
|
|
126
129
|
.UR https:\[sl]\[sl]github\.com\[sl]MadBomber\[sl]aia
|
127
130
|
.UE
|
128
131
|
\.
|
132
|
+
.PP
|
133
|
+
Some directives are:
|
134
|
+
.RS
|
135
|
+
.IP \(bu 2
|
136
|
+
\[sl]\[sl]config item value
|
137
|
+
.IP \(bu 2
|
138
|
+
\[sl]\[sl]include path\[ru]to\[ru]file
|
139
|
+
.IP \(bu 2
|
140
|
+
\[sl]\[sl]ruby ruby\[ru]code
|
141
|
+
.IP \(bu 2
|
142
|
+
\[sl]\[sl]shell shell\[ru]command
|
143
|
+
.RE
|
129
144
|
.SH SEE ALSO
|
130
145
|
.RS
|
131
146
|
.IP \(bu 2
|
data/man/aia.1.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# aia 1 "
|
1
|
+
# aia 1 "v0.5.11" AIA "User Manuals"
|
2
2
|
|
3
3
|
## NAME
|
4
4
|
|
@@ -85,9 +85,12 @@ The aia command-line tool is an interface for interacting with an AI model backe
|
|
85
85
|
`-o`, `--[no]-out_file` *PATH_TO_OUTPUT_FILE*
|
86
86
|
: Out FILENAME - default is ./temp.md
|
87
87
|
|
88
|
-
`-p`, `--
|
88
|
+
`-p`, `--prompts_dir` *PATH_TO_DIRECTORY*
|
89
89
|
: Directory containing the prompt files - default is ~/.prompts
|
90
90
|
|
91
|
+
`--roles_dir` *PATH_TO_DIRECTORY*
|
92
|
+
: Directory containing the personification prompt files - default is ~/.prompts/roles
|
93
|
+
|
91
94
|
`-r`, `--role` *ROLE_ID*
|
92
95
|
: A role ID is the same as a prompt ID. A "role" is a specialized prompt that gets pre-pended to another prompt. It's purpose is to configure the LLM into a certain orientation within which to resolve its primary prompt.
|
93
96
|
|
@@ -131,6 +134,14 @@ Within a prompt text file any line that begins with "//" is considered a prompt
|
|
131
134
|
|
132
135
|
Detail discussion on individual prompt directives is TBD. Most likely it will be handled in the [github wiki](https://github.com/MadBomber/aia).
|
133
136
|
|
137
|
+
Some directives are:
|
138
|
+
|
139
|
+
- //config item value
|
140
|
+
- //include path_to_file
|
141
|
+
- //ruby ruby_code
|
142
|
+
- //shell shell_command
|
143
|
+
|
144
|
+
|
134
145
|
## SEE ALSO
|
135
146
|
|
136
147
|
- [OpenAI Platform Documentation](https://platform.openai.com/docs/overview) for more information on [obtaining access tokens](https://platform.openai.com/account/api-keys) and working with OpenAI models.
|
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.11
|
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-02-
|
11
|
+
date: 2024-02-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: os
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: prompt_manager
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -207,17 +221,17 @@ dependencies:
|
|
207
221
|
- !ruby/object:Gem::Version
|
208
222
|
version: '0'
|
209
223
|
description: |
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
224
|
+
A command-line AI Assistante (aia) that provides pre-compositional
|
225
|
+
template prompt management to various backend gen-AI processes.
|
226
|
+
Complete shell integration allows a prompt to access system
|
227
|
+
environment variables and execut shell commands as part of the
|
228
|
+
prompt content. In addition full embedded Ruby support is provided
|
229
|
+
given even more dynamic prompt conditional content. It is a
|
230
|
+
generalized power house that rivals specialized gen-AI tools. aia
|
231
|
+
currently supports "mods" and "sgpt" CLI tools. aia uses "ripgrep"
|
232
|
+
and "fzf" CLI utilities to search for and select prompt files to
|
233
|
+
send to the backend gen-AI tool along with supported context
|
234
|
+
files.
|
221
235
|
email:
|
222
236
|
- dvanhoozer@gmail.com
|
223
237
|
executables:
|
@@ -241,6 +255,7 @@ files:
|
|
241
255
|
- lib/aia/aia_completion.bash
|
242
256
|
- lib/aia/aia_completion.fish
|
243
257
|
- lib/aia/aia_completion.zsh
|
258
|
+
- lib/aia/clause.rb
|
244
259
|
- lib/aia/cli.rb
|
245
260
|
- lib/aia/config.rb
|
246
261
|
- lib/aia/directives.rb
|
@@ -251,6 +266,7 @@ files:
|
|
251
266
|
- lib/aia/tools.rb
|
252
267
|
- lib/aia/tools/backend_common.rb
|
253
268
|
- lib/aia/tools/editor.rb
|
269
|
+
- lib/aia/tools/fzf.rb
|
254
270
|
- lib/aia/tools/glow.rb
|
255
271
|
- lib/aia/tools/mods.rb
|
256
272
|
- lib/aia/tools/sgpt.rb
|
@@ -286,7 +302,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
286
302
|
- !ruby/object:Gem::Version
|
287
303
|
version: '0'
|
288
304
|
requirements: []
|
289
|
-
rubygems_version: 3.5.
|
305
|
+
rubygems_version: 3.5.6
|
290
306
|
signing_key:
|
291
307
|
specification_version: 4
|
292
308
|
summary: AI Assistant (aia) a command-line (CLI) utility
|