aia 0.9.6 → 0.9.7
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 +4 -4
- data/.version +1 -1
- data/CHANGELOG.md +14 -0
- data/README.md +90 -45
- data/examples/headlines +24 -15
- data/examples/tools/run_shell_command.rb +16 -4
- data/lib/aia/chat_processor_service.rb +1 -1
- data/lib/aia/config.rb +96 -4
- data/lib/aia/directive_processor.rb +34 -2
- data/lib/aia/ruby_llm_adapter.rb +2 -0
- data/lib/aia/session.rb +12 -3
- data/lib/aia/ui_presenter.rb +1 -1
- data/lib/aia.rb +4 -2
- metadata +14 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21134c8c9fa3664309baf0c3d1bce2857dffd3dd1ad8c554c7cb15ac48b57634
|
4
|
+
data.tar.gz: 46f64bdbefe73eede9add530bad3a4957f6b7033706a1d1daf5aa6bef1fb6084
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc1273757619b1962986e1dfac94b8d10b2c493ff0cf0d01d0938c65a902700d96484d42e661770328a4f6f904a1265f6a136964fb8c31218ed22135fed806dc
|
7
|
+
data.tar.gz: edc7124424b74f7d167a78635abd7302eb05cd4208058947dd8700e5e05c1200eba47346d1f0beea0ed9ea37a5875ca7cb585d40752dbcf88c64063dc278e398
|
data/.version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.
|
1
|
+
0.9.7
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,21 @@
|
|
1
1
|
# Changelog
|
2
2
|
## [Unreleased]
|
3
|
+
|
4
|
+
### [0.9.8] WIP
|
5
|
+
|
3
6
|
## Released
|
4
7
|
|
8
|
+
### [0.9.7] 2025-06-20
|
9
|
+
|
10
|
+
- **NEW FEATURE**: Added `--available_models` CLI option to list all available AI models
|
11
|
+
- **NEW FEATURE**: Added `//tools` to show a list of available tools and their description
|
12
|
+
- **BUG FIX**: Fixed SharedTools compatibility issue with models that don't support function calling
|
13
|
+
- **BUG FIX**: Fixed problem with piped text through STDIN not being handled correctly.
|
14
|
+
- **BUG FIX**: Fixed issue with output going to the default out_file evenhen --no-out_file is specified.
|
15
|
+
- **BUG FIX**: Fixed issue with executable prompt files by adding the --exec option
|
16
|
+
- **DOCUMENTATION**: Updated README for better clarity and structure
|
17
|
+
- **DEPENDENCY**: Updated Gemfile.lock with latest dependency versions
|
18
|
+
|
5
19
|
### [0.9.6] 2025-06-13
|
6
20
|
- fixed issue 84 with the //llms directive
|
7
21
|
- changed the monkey patch to the RubyLLM::Model::Modalities class at the suggestions of the RubyLLM author in prep for a PR against that gem.
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
AIA is a command-line utility that facilitates interaction with AI models through dynamic prompt management. It automates the management of pre-compositional prompts and executes generative AI commands with enhanced features including embedded directives, shell integration, embedded Ruby, history management, interactive chat, and prompt workflows.
|
8
8
|
|
9
|
-
AIA leverages the [prompt_manager gem](https://github.com/madbomber/prompt_manager) to manage prompts, utilizes the [CLI tool fzf](https://github.com/junegunn/fzf) for prompt selection, and
|
9
|
+
AIA leverages the [prompt_manager gem](https://github.com/madbomber/prompt_manager) to manage prompts, utilizes the [CLI tool fzf](https://github.com/junegunn/fzf) for prompt selection, and can use the [shared_tools gem](https://github.com/madbomber/shared_tools) which provides a collection of common ready-to-use functions for use with LLMs that support tools.
|
10
10
|
|
11
11
|
**Wiki**: [Checkout the AIA Wiki](https://github.com/MadBomber/aia/wiki)
|
12
12
|
|
@@ -25,12 +25,12 @@ AIA leverages the [prompt_manager gem](https://github.com/madbomber/prompt_manag
|
|
25
25
|
3. **Create your first prompt:**
|
26
26
|
```bash
|
27
27
|
mkdir -p ~/.prompts
|
28
|
-
echo "What is [TOPIC]?" > ~/.prompts/
|
28
|
+
echo "What is [TOPIC]?" > ~/.prompts/what_is.txt
|
29
29
|
```
|
30
30
|
|
31
31
|
4. **Run your prompt:**
|
32
32
|
```bash
|
33
|
-
aia
|
33
|
+
aia what_is
|
34
34
|
```
|
35
35
|
You'll be prompted to enter a value for `[TOPIC]`, then AIA will send your question to the AI model.
|
36
36
|
|
@@ -40,43 +40,76 @@ AIA leverages the [prompt_manager gem](https://github.com/madbomber/prompt_manag
|
|
40
40
|
```
|
41
41
|
|
42
42
|
```plain
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
(
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
43
|
+
|
44
|
+
, ,
|
45
|
+
(\____/) AI Assistant (v0.9.7) is Online
|
46
|
+
(_oo_) gpt-4o-mini
|
47
|
+
(O) using ruby_llm (v1.3.1)
|
48
|
+
__||__ \) model db was last refreshed on
|
49
|
+
[/______\] / 2025-06-18
|
50
|
+
/ \__AI__/ \/ You can share my tools
|
51
|
+
/ /__\
|
52
|
+
(\ /____\
|
53
|
+
|
52
54
|
```
|
53
55
|
|
54
56
|
<!-- Tocer[start]: Auto-generated, don't remove. -->
|
55
57
|
|
56
58
|
## Table of Contents
|
57
59
|
|
58
|
-
- [Quick Start](#quick-start)
|
59
60
|
- [Installation & Prerequisites](#installation--prerequisites)
|
61
|
+
- [Requirements](#requirements)
|
62
|
+
- [Installation](#installation)
|
63
|
+
- [Setup Shell Completion](#setup-shell-completion)
|
60
64
|
- [Basic Usage](#basic-usage)
|
65
|
+
- [Command Line Interface](#command-line-interface)
|
66
|
+
- [Key Command-Line Options](#key-command-line-options)
|
67
|
+
- [Directory Structure](#directory-structure)
|
61
68
|
- [Configuration](#configuration)
|
62
69
|
- [Essential Configuration Options](#essential-configuration-options)
|
63
70
|
- [Configuration Precedence](#configuration-precedence)
|
71
|
+
- [Configuration Methods](#configuration-methods)
|
64
72
|
- [Complete Configuration Reference](#complete-configuration-reference)
|
65
73
|
- [Advanced Features](#advanced-features)
|
66
74
|
- [Prompt Directives](#prompt-directives)
|
75
|
+
- [Configuration Directive Examples](#configuration-directive-examples)
|
76
|
+
- [Dynamic Content Examples](#dynamic-content-examples)
|
67
77
|
- [Shell Integration](#shell-integration)
|
68
78
|
- [Embedded Ruby (ERB)](#embedded-ruby-erb)
|
69
79
|
- [Prompt Sequences](#prompt-sequences)
|
80
|
+
- [Using --next](#using---next)
|
81
|
+
- [Using --pipeline](#using---pipeline)
|
82
|
+
- [Example Workflow](#example-workflow)
|
70
83
|
- [Roles and System Prompts](#roles-and-system-prompts)
|
71
84
|
- [RubyLLM::Tool Support](#rubyllmtool-support)
|
72
85
|
- [Examples & Tips](#examples--tips)
|
73
86
|
- [Practical Examples](#practical-examples)
|
87
|
+
- [Code Review Prompt](#code-review-prompt)
|
88
|
+
- [Meeting Notes Processor](#meeting-notes-processor)
|
89
|
+
- [Documentation Generator](#documentation-generator)
|
74
90
|
- [Executable Prompts](#executable-prompts)
|
75
91
|
- [Tips from the Author](#tips-from-the-author)
|
92
|
+
- [The run Prompt](#the-run-prompt)
|
93
|
+
- [The Ad Hoc One-shot Prompt](#the-ad-hoc-one-shot-prompt)
|
94
|
+
- [Recommended Shell Setup](#recommended-shell-setup)
|
95
|
+
- [Prompt Directory Organization](#prompt-directory-organization)
|
76
96
|
- [Security Considerations](#security-considerations)
|
97
|
+
- [Shell Command Execution](#shell-command-execution)
|
98
|
+
- [Safe Practices](#safe-practices)
|
99
|
+
- [Recommended Security Setup](#recommended-security-setup)
|
77
100
|
- [Troubleshooting](#troubleshooting)
|
101
|
+
- [Common Issues](#common-issues)
|
102
|
+
- [Error Messages](#error-messages)
|
103
|
+
- [Debug Mode](#debug-mode)
|
104
|
+
- [Performance Issues](#performance-issues)
|
78
105
|
- [Development](#development)
|
106
|
+
- [Testing](#testing)
|
107
|
+
- [Building](#building)
|
108
|
+
- [Architecture Notes](#architecture-notes)
|
79
109
|
- [Contributing](#contributing)
|
110
|
+
- [Reporting Issues](#reporting-issues)
|
111
|
+
- [Development Setup](#development-setup)
|
112
|
+
- [Areas for Improvement](#areas-for-improvement)
|
80
113
|
- [Roadmap](#roadmap)
|
81
114
|
- [License](#license)
|
82
115
|
|
@@ -281,16 +314,21 @@ Directives are special commands in prompt files that begin with `//` and provide
|
|
281
314
|
| Directive | Description | Example |
|
282
315
|
|-----------|-------------|---------|
|
283
316
|
| `//config` | Set configuration values | `//config model = gpt-4` |
|
317
|
+
| `//context` | Show context for this conversation | `//context` |
|
284
318
|
| `//include` | Insert file contents | `//include path/to/file.txt` |
|
285
319
|
| `//shell` | Execute shell commands | `//shell ls -la` |
|
320
|
+
| `//robot` | Show the pet robot ASCII art w/versions | `//robot` |
|
286
321
|
| `//ruby` | Execute Ruby code | `//ruby puts "Hello World"` |
|
287
322
|
| `//next` | Set next prompt in sequence | `//next summary` |
|
288
323
|
| `//pipeline` | Set prompt workflow | `//pipeline analyze,summarize,report` |
|
289
324
|
| `//clear` | Clear conversation history | `//clear` |
|
290
325
|
| `//help` | Show available directives | `//help` |
|
291
326
|
| `//available_models` | List available models | `//available_models` |
|
327
|
+
| `//tools` | Show a list of available tools and their description | `//tools` |
|
292
328
|
| `//review` | Review current context | `//review` |
|
293
329
|
|
330
|
+
Directives can also be used in the interactive chat sessions.
|
331
|
+
|
294
332
|
#### Configuration Directive Examples
|
295
333
|
|
296
334
|
```bash
|
@@ -462,22 +500,20 @@ aia --tools ~/tools/ --rejected_tools deprecated
|
|
462
500
|
- Data processing utilities
|
463
501
|
|
464
502
|
**Shared Tools Collection:**
|
465
|
-
AIA
|
503
|
+
AIA can use the [shared_tools gem](https://github.com/madbomber/shared_tools) which provides a curated collection of commonly-used tools (aka functions) via the --require option.
|
466
504
|
|
467
505
|
```bash
|
468
506
|
# Access shared tools automatically (included with AIA)
|
469
|
-
aia --
|
507
|
+
aia --require shared_tools/ruby_llm --chat
|
470
508
|
|
471
|
-
#
|
472
|
-
aia --
|
509
|
+
# To access just one specific shared tool
|
510
|
+
aia --require shared_tools/ruby_llm/edit_file --chat
|
511
|
+
|
512
|
+
# Combine with your own local custom RubyLLM-based tools
|
513
|
+
aia --require shared_tools/ruby_llm --tools ~/my-tools/ --chat
|
473
514
|
```
|
474
515
|
|
475
|
-
|
476
|
-
- **File operations**: read, write, edit, search files
|
477
|
-
- **Web utilities**: fetch web pages, parse HTML/JSON
|
478
|
-
- **System tools**: execute commands, get system info
|
479
|
-
- **Data processing**: CSV/JSON manipulation, text analysis
|
480
|
-
- **API helpers**: HTTP requests, common API patterns
|
516
|
+
The above examples show the shared_tools being used within an interactive chat session. They are also available in batch prompts as well using the same --require option. You can also use the //ruby directive to require the shared_tools as well and using a require statement within an ERB block.
|
481
517
|
|
482
518
|
## Examples & Tips
|
483
519
|
|
@@ -486,7 +522,7 @@ Available shared tools include:
|
|
486
522
|
#### Code Review Prompt
|
487
523
|
```bash
|
488
524
|
# ~/.prompts/code_review.txt
|
489
|
-
//config model = gpt-
|
525
|
+
//config model = gpt-4o-mini
|
490
526
|
//config temperature = 0.3
|
491
527
|
|
492
528
|
Review this code for:
|
@@ -496,7 +532,6 @@ Review this code for:
|
|
496
532
|
- Maintainability concerns
|
497
533
|
|
498
534
|
Code to review:
|
499
|
-
//include [CODE_FILE]
|
500
535
|
```
|
501
536
|
|
502
537
|
Usage: `aia code_review mycode.rb`
|
@@ -516,7 +551,7 @@ Please clean up and structure these meeting notes.
|
|
516
551
|
#### Documentation Generator
|
517
552
|
```bash
|
518
553
|
# ~/.prompts/document.txt
|
519
|
-
//config model = gpt-
|
554
|
+
//config model = gpt-4o-mini
|
520
555
|
//shell find [PROJECT_DIR] -name "*.rb" | head -10
|
521
556
|
|
522
557
|
Generate documentation for the Ruby project shown above.
|
@@ -525,48 +560,62 @@ Include: API references, usage examples, and setup instructions.
|
|
525
560
|
|
526
561
|
### Executable Prompts
|
527
562
|
|
528
|
-
|
563
|
+
The `--exec` flag is used to create executable prompts. If it is not present on the shebang line then the prompt file will be treated like any other context file. That means that the file will be included as context in the prompt but no dynamic content integration or directives will be processed. All other AIA options are, well, optional. All you need is an initial prompt ID and the --exec flag.
|
564
|
+
|
565
|
+
In the example below the option `--no-out_file` is used to direct the output from the LLM processing of the prompt to STDOUT. This way the executable prompts can be good citizens on the *nix command line receiving piped in input via STDIN and send its output to STDOUT.
|
566
|
+
|
567
|
+
Create executable prompts:
|
529
568
|
|
530
569
|
**weather_report** (make executable with `chmod +x`):
|
531
570
|
```bash
|
532
|
-
#!/usr/bin/env aia run --no-out_file
|
533
|
-
# Get current
|
571
|
+
#!/usr/bin/env aia run --no-out_file --exec
|
572
|
+
# Get current storm activity for the east and south coast of the US
|
573
|
+
|
574
|
+
Summarize the tropical storm outlook fpr the Atlantic, Caribbean Sea and Gulf of America.
|
534
575
|
|
535
|
-
|
536
|
-
Include temperature, conditions, and 3-day forecast.
|
537
|
-
Format as a brief, readable summary.
|
576
|
+
//webpage https://www.nhc.noaa.gov/text/refresh/MIATWOAT+shtml/201724_MIATWOAT.shtml
|
538
577
|
```
|
539
578
|
|
540
579
|
Usage:
|
541
580
|
```bash
|
542
581
|
./weather_report
|
543
|
-
#
|
544
|
-
|
545
|
-
./weather_report | glow # Render with glow
|
582
|
+
./weather_report | glow # Render the markdown with glow
|
546
583
|
```
|
547
584
|
|
548
585
|
### Tips from the Author
|
549
586
|
|
550
|
-
|
587
|
+
#### The run Prompt
|
588
|
+
```bash
|
589
|
+
# ~/.prompts/run.txt
|
590
|
+
# Desc: A configuration only prompt file for use with executable prompts
|
591
|
+
# Put whatever you want here to setup the configuration desired.
|
592
|
+
# You could also add a system prompt to preface your intended prompt
|
593
|
+
```
|
594
|
+
|
595
|
+
Usage: `echo "What is the meaning of life?" | aia run`
|
596
|
+
|
597
|
+
#### The Ad Hoc One-shot Prompt
|
551
598
|
```bash
|
552
599
|
# ~/.prompts/ad_hoc.txt
|
553
600
|
[WHAT_NOW_HUMAN]
|
554
601
|
```
|
555
|
-
Usage: `aia ad_hoc` - perfect for any quick question without cluttering shell history.
|
602
|
+
Usage: `aia ad_hoc` - perfect for any quick one-shot question without cluttering shell history.
|
556
603
|
|
557
|
-
|
604
|
+
#### Recommended Shell Setup
|
558
605
|
```bash
|
559
606
|
# ~/.bashrc_aia
|
560
607
|
export AIA_PROMPTS_DIR=~/.prompts
|
561
608
|
export AIA_OUT_FILE=./temp.md
|
562
609
|
export AIA_MODEL=gpt-4o-mini
|
563
|
-
export AIA_VERBOSE=true # Shows spinner while waiting
|
610
|
+
export AIA_VERBOSE=true # Shows spinner while waiting for LLM response
|
564
611
|
|
565
612
|
alias chat='aia --chat --terse'
|
566
|
-
|
613
|
+
ask() { echo "$1" | aia run --no-out_file; }
|
567
614
|
```
|
568
615
|
|
569
|
-
|
616
|
+
The `chat` alias and the `ask` function (shown above in HASH) are two powerful tools for interacting with the AI assistant. The `chat` alias allows you to engage in an interactive conversation with the AI assistant, while the `ask` function allows you to ask a question and receive a response. Later in this document the `run` prompt ID is discussed. Besides using the run prompt ID here its also used in making executable prompt files.
|
617
|
+
|
618
|
+
#### Prompt Directory Organization
|
570
619
|
```
|
571
620
|
~/.prompts/
|
572
621
|
├── daily/ # Daily workflow prompts
|
@@ -611,10 +660,6 @@ AIA executes shell commands and Ruby code embedded in prompts. This provides pow
|
|
611
660
|
# Set restrictive permissions on prompts directory
|
612
661
|
chmod 700 ~/.prompts
|
613
662
|
chmod 600 ~/.prompts/*.txt
|
614
|
-
|
615
|
-
# Use separate prompts directory for shared/untrusted prompts
|
616
|
-
export AIA_PROMPTS_DIR_SHARED=~/shared-prompts
|
617
|
-
chmod 755 ~/shared-prompts
|
618
663
|
```
|
619
664
|
|
620
665
|
## Troubleshooting
|
data/examples/headlines
CHANGED
@@ -1,21 +1,30 @@
|
|
1
|
-
#!/usr/bin/env aia run --no-out_file
|
2
|
-
#
|
1
|
+
#!/usr/bin/env aia run --no-out_file --exec
|
2
|
+
# NOTE: the --exec option is REQUIRED to run this executable prompt file
|
3
|
+
# This option signals that the contents of this file are to be appended
|
4
|
+
# to the contents of the given prompt ID file. In this case it is the
|
5
|
+
# "run" prompt ID's text file.
|
6
|
+
#
|
7
|
+
# All other AIA options are, well, optional. The --no-out_file is
|
8
|
+
# used here to cause the response to this executable prompt to be
|
9
|
+
# sent to STDOUT like a good little *nix CLI tool. Its not necessary.
|
10
|
+
# if you do not use it, the output will go to the default out_file.
|
11
|
+
# You could also specify a specific file to write the output to built
|
12
|
+
# but it is more convential to use the *nix STDOUT redirect "> output.md"
|
13
|
+
#
|
3
14
|
# Desc: retrieves the news.google.com website
|
4
15
|
# extracts and formats the headlines
|
5
|
-
# and prints them to
|
16
|
+
# and prints them to STDOUT
|
17
|
+
#
|
18
|
+
# Method:
|
19
|
+
# There are several ways you can accomplish this task using
|
20
|
+
# the shell or ERB integration. For this example lets use
|
21
|
+
# a built-in directive.
|
6
22
|
|
7
|
-
|
8
|
-
# //config
|
23
|
+
Extract and summarize the headlines from the following markdown:
|
9
24
|
|
10
|
-
|
11
|
-
# //shell wget2 https://news.google.com
|
25
|
+
//webpage https://news.google.com
|
12
26
|
|
13
|
-
|
27
|
+
__END__
|
14
28
|
|
15
|
-
|
16
|
-
|
17
|
-
//config speak = true
|
18
|
-
|
19
|
-
Extract and summarize the headlines from the following text:
|
20
|
-
|
21
|
-
$(html2text index.html)
|
29
|
+
The //webpage directive makes use of the website https://pure.md
|
30
|
+
to convert any given URL to a markdown file.
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# experiments/ai_misc/coding_agent_with_ruby_llm/tools/run_shell_command.rb
|
2
2
|
|
3
|
+
require "io/console"
|
3
4
|
require "ruby_llm/tool"
|
4
5
|
|
5
6
|
module Tools
|
@@ -8,10 +9,21 @@ module Tools
|
|
8
9
|
param :command, desc: "The command to execute"
|
9
10
|
|
10
11
|
def execute(command:)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
print "\n\n"
|
13
|
+
puts "AI wants to execute the following shell command:"
|
14
|
+
puts "="*command.size
|
15
|
+
puts command
|
16
|
+
puts "="*command.size
|
17
|
+
print "\n\n"
|
18
|
+
|
19
|
+
sleep 0.5
|
20
|
+
print "Execute the command? (y/N):"
|
21
|
+
allowed = STDIN.getch == "y"
|
22
|
+
|
23
|
+
unless allowed
|
24
|
+
print "Command aborted" + " "*30 if defined?(AIA)
|
25
|
+
return { error: "User declined to execute the command" }
|
26
|
+
end
|
15
27
|
|
16
28
|
`#{command}`
|
17
29
|
rescue => e
|
data/lib/aia/config.rb
CHANGED
@@ -124,6 +124,17 @@ module AIA
|
|
124
124
|
remaining_args = config.remaining_args.dup
|
125
125
|
config.remaining_args = nil
|
126
126
|
|
127
|
+
# Check for STDIN content
|
128
|
+
stdin_content = nil
|
129
|
+
if !STDIN.tty? && !STDIN.closed?
|
130
|
+
begin
|
131
|
+
stdin_content = STDIN.read
|
132
|
+
STDIN.reopen('/dev/tty') # Reopen STDIN for interactive use
|
133
|
+
rescue => _
|
134
|
+
# If we can't reopen, continue without error
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
127
138
|
# Is first remaining argument a prompt ID?
|
128
139
|
unless remaining_args.empty?
|
129
140
|
maybe_id = remaining_args.first
|
@@ -134,6 +145,11 @@ module AIA
|
|
134
145
|
end
|
135
146
|
end
|
136
147
|
|
148
|
+
# Store STDIN content for later processing in session.rb
|
149
|
+
if stdin_content && !stdin_content.strip.empty?
|
150
|
+
config.stdin_content = stdin_content
|
151
|
+
end
|
152
|
+
|
137
153
|
unless remaining_args.empty?
|
138
154
|
bad_files = remaining_args.reject { |filename| AIA.good_file?(filename) }
|
139
155
|
if bad_files.any?
|
@@ -141,9 +157,21 @@ module AIA
|
|
141
157
|
exit 1
|
142
158
|
end
|
143
159
|
|
144
|
-
config.context_files
|
160
|
+
config.context_files ||= []
|
161
|
+
config.context_files += remaining_args
|
162
|
+
end
|
163
|
+
|
164
|
+
# Check if the last context file is an executable prompt
|
165
|
+
if config.executable_prompt &&
|
166
|
+
config.context_files &&
|
167
|
+
!config.context_files.empty?
|
168
|
+
config.executable_prompt_file = config.context_files.pop
|
145
169
|
end
|
146
170
|
|
171
|
+
# TODO: Consider that if there is no prompt ID but there is an executable prompt
|
172
|
+
# then maybe that is all that is needed.
|
173
|
+
|
174
|
+
|
147
175
|
if config.prompt_id.nil? && !config.chat && !config.fuzzy
|
148
176
|
STDERR.puts "Error: A prompt ID is required unless using --chat, --fuzzy, or providing context files. Use -h or --help for help."
|
149
177
|
exit 1
|
@@ -325,10 +353,68 @@ module AIA
|
|
325
353
|
end
|
326
354
|
end
|
327
355
|
|
356
|
+
opts.on('--available_models [QUERY]', 'List (then exit) available models that match the optional query - a comma separated list of AND components like: openai,mini') do |query|
|
357
|
+
|
358
|
+
# SMELL: mostly duplications the code in the vailable_models directive
|
359
|
+
# assumes that the adapter is for the ruby_llm gem
|
360
|
+
# should this be moved to the Utilities class as a common method?
|
361
|
+
|
362
|
+
if query.nil?
|
363
|
+
query = []
|
364
|
+
else
|
365
|
+
query = query.split(',')
|
366
|
+
end
|
367
|
+
|
368
|
+
header = "\nAvailable LLMs"
|
369
|
+
header += " for #{query.join(' and ')}" if query
|
370
|
+
|
371
|
+
puts header + ':'
|
372
|
+
puts
|
373
|
+
|
374
|
+
q1 = query.select{|q| q.include?('_to_')}.map{|q| ':'==q[0] ? q[1...] : q}
|
375
|
+
q2 = query.reject{|q| q.include?('_to_')}
|
376
|
+
|
377
|
+
|
378
|
+
# query = nil
|
379
|
+
counter = 0
|
380
|
+
|
381
|
+
RubyLLM.models.all.each do |llm|
|
382
|
+
inputs = llm.modalities.input.join(',')
|
383
|
+
outputs = llm.modalities.output.join(',')
|
384
|
+
entry = "- #{llm.id} (#{llm.provider}) #{inputs} to #{outputs}"
|
385
|
+
|
386
|
+
if query.nil? || query.empty?
|
387
|
+
counter += 1
|
388
|
+
puts entry
|
389
|
+
next
|
390
|
+
end
|
391
|
+
|
392
|
+
show_it = true
|
393
|
+
q1.each{|q| show_it &&= llm.modalities.send("#{q}?")}
|
394
|
+
q2.each{|q| show_it &&= entry.include?(q)}
|
395
|
+
|
396
|
+
if show_it
|
397
|
+
counter += 1
|
398
|
+
puts entry
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
puts if counter > 0
|
403
|
+
puts "#{counter} LLMs matching your query"
|
404
|
+
puts
|
405
|
+
|
406
|
+
exit
|
407
|
+
end
|
408
|
+
|
328
409
|
opts.on("-m MODEL", "--model MODEL", "Name of the LLM model to use") do |model|
|
329
410
|
config.model = model
|
330
411
|
end
|
331
412
|
|
413
|
+
opts.on("-x", "--[no-]exec", "Used to designate an executable prompt file") do |value|
|
414
|
+
config.executable_prompt = value
|
415
|
+
end
|
416
|
+
|
417
|
+
|
332
418
|
opts.on("--terse", "Adds a special instruction to the prompt asking the AI to keep responses short and to the point") do
|
333
419
|
config.terse = true
|
334
420
|
end
|
@@ -383,7 +469,13 @@ module AIA
|
|
383
469
|
end
|
384
470
|
|
385
471
|
opts.on("-o", "--[no-]out_file [FILE]", "Output file (default: temp.md)") do |file|
|
386
|
-
|
472
|
+
if file == false # --no-out_file was used
|
473
|
+
config.out_file = nil
|
474
|
+
elsif file.nil? # No argument provided
|
475
|
+
config.out_file = 'temp.md'
|
476
|
+
else # File name provided
|
477
|
+
config.out_file = File.expand_path(file, Dir.pwd)
|
478
|
+
end
|
387
479
|
end
|
388
480
|
|
389
481
|
opts.on("-a", "--[no-]append", "Append to output file instead of overwriting") do |append|
|
@@ -422,8 +514,8 @@ module AIA
|
|
422
514
|
config.debug = $DEBUG_ME = false
|
423
515
|
end
|
424
516
|
|
425
|
-
opts.on("-v", "--verbose", "Be verbose") do
|
426
|
-
config.verbose =
|
517
|
+
opts.on("-v", "--[no-]verbose", "Be verbose") do |value|
|
518
|
+
config.verbose = value
|
427
519
|
end
|
428
520
|
|
429
521
|
opts.on("--speak", "Simple implementation. Uses the speech model to convert text to audio, then plays the audio. Fun with --chat. Supports configuration of speech model and voice.") do
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# lib/aia/directive_processor.rb
|
2
2
|
|
3
|
+
require 'active_support/all'
|
3
4
|
require 'faraday'
|
5
|
+
require 'word_wrapper' # Pure ruby word wrapping
|
4
6
|
|
5
7
|
module AIA
|
6
8
|
class DirectiveProcessor
|
@@ -145,7 +147,7 @@ module AIA
|
|
145
147
|
end
|
146
148
|
|
147
149
|
desc "Specify the next prompt ID to process after this one"
|
148
|
-
def next(args = [])
|
150
|
+
def next(args = [], context_manager=nil)
|
149
151
|
if args.empty?
|
150
152
|
ap AIA.config.next
|
151
153
|
else
|
@@ -154,8 +156,33 @@ module AIA
|
|
154
156
|
''
|
155
157
|
end
|
156
158
|
|
159
|
+
desc "Show a list of tools and their description"
|
160
|
+
def tools(args = [], context_manager=nil)
|
161
|
+
indent = 4
|
162
|
+
spaces = " "*indent
|
163
|
+
width = TTY::Screen.width - indent - 2
|
164
|
+
|
165
|
+
if !AIA.config.tools.empty?
|
166
|
+
puts
|
167
|
+
puts "Available Tools"
|
168
|
+
puts "==============="
|
169
|
+
|
170
|
+
AIA.config.tools.split(',').map(&:strip).each do |tool|
|
171
|
+
klass = tool.constantize
|
172
|
+
puts "\n#{klass.name}"
|
173
|
+
puts "-"*klass.name.size
|
174
|
+
puts WordWrapper::MinimumRaggedness.new(width, klass.description).wrap.split("\n").map{|s| spaces+s+"\n"}.join
|
175
|
+
end
|
176
|
+
else
|
177
|
+
puts "No tools configured"
|
178
|
+
end
|
179
|
+
puts
|
180
|
+
|
181
|
+
''
|
182
|
+
end
|
183
|
+
|
157
184
|
desc "Specify a sequence pf prompt IDs to process after this one"
|
158
|
-
def pipeline(args = [])
|
185
|
+
def pipeline(args = [], context_manager=nil)
|
159
186
|
if args.empty?
|
160
187
|
ap AIA.config.pipeline
|
161
188
|
else
|
@@ -299,6 +326,11 @@ module AIA
|
|
299
326
|
desc "All Available models or query on [partial LLM or provider name] Examples: //llms ; //llms openai ; //llms claude"
|
300
327
|
def available_models( args=nil, context_manager=nil)
|
301
328
|
query = args
|
329
|
+
|
330
|
+
if 1 == query.size
|
331
|
+
query = query.first.split(',')
|
332
|
+
end
|
333
|
+
|
302
334
|
header = "\nAvailable LLMs"
|
303
335
|
header += " for #{query.join(' and ')}" if query
|
304
336
|
|
data/lib/aia/ruby_llm_adapter.rb
CHANGED
data/lib/aia/session.rb
CHANGED
@@ -41,7 +41,7 @@ module AIA
|
|
41
41
|
@directive_processor = DirectiveProcessor.new
|
42
42
|
@chat_processor = ChatProcessorService.new(@ui_presenter, @directive_processor)
|
43
43
|
|
44
|
-
if AIA.config.out_file && !AIA.append? && File.exist?(AIA.config.out_file)
|
44
|
+
if AIA.config.out_file && !AIA.config.out_file.nil? && !AIA.append? && File.exist?(AIA.config.out_file)
|
45
45
|
File.open(AIA.config.out_file, 'w') {} # Truncate the file
|
46
46
|
end
|
47
47
|
end
|
@@ -111,8 +111,17 @@ module AIA
|
|
111
111
|
prompt.text << TERSE_PROMPT
|
112
112
|
end
|
113
113
|
|
114
|
-
|
115
|
-
|
114
|
+
if AIA.config.stdin_content && !AIA.config.stdin_content.strip.empty?
|
115
|
+
prompt.text << "\n\n" << AIA.config.stdin_content
|
116
|
+
end
|
117
|
+
|
118
|
+
if AIA.config.executable_prompt_file
|
119
|
+
prompt.text << "\n\n" << File.read(AIA.config.executable_prompt_file)
|
120
|
+
.lines[1..]
|
121
|
+
.join
|
122
|
+
end
|
123
|
+
|
124
|
+
# Substitute variables, execute dynamic content and get final prompt text
|
116
125
|
prompt_text = prompt.to_s
|
117
126
|
|
118
127
|
# Add context files if any
|
data/lib/aia/ui_presenter.rb
CHANGED
data/lib/aia.rb
CHANGED
@@ -6,8 +6,6 @@
|
|
6
6
|
|
7
7
|
require 'ruby_llm'
|
8
8
|
require 'ruby_llm/mcp'
|
9
|
-
require 'shared_tools'
|
10
|
-
require 'shared_tools/ruby_llm'
|
11
9
|
require 'prompt_manager'
|
12
10
|
|
13
11
|
|
@@ -41,6 +39,10 @@ require_relative 'aia/session'
|
|
41
39
|
module AIA
|
42
40
|
at_exit do
|
43
41
|
STDERR.puts "Exiting AIA application..."
|
42
|
+
# Clean up temporary STDIN file if it exists
|
43
|
+
if @config&.stdin_temp_file && File.exist?(@config.stdin_temp_file)
|
44
|
+
File.unlink(@config.stdin_temp_file)
|
45
|
+
end
|
44
46
|
end
|
45
47
|
|
46
48
|
@config = nil
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dewayne VanHoozer
|
@@ -10,7 +10,7 @@ cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
|
-
name:
|
13
|
+
name: activesupport
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
15
15
|
requirements:
|
16
16
|
- - ">="
|
@@ -24,7 +24,7 @@ dependencies:
|
|
24
24
|
- !ruby/object:Gem::Version
|
25
25
|
version: '0'
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
|
-
name:
|
27
|
+
name: amazing_print
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
29
29
|
requirements:
|
30
30
|
- - ">="
|
@@ -38,49 +38,49 @@ dependencies:
|
|
38
38
|
- !ruby/object:Gem::Version
|
39
39
|
version: '0'
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
|
-
name:
|
41
|
+
name: faraday
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: 0
|
46
|
+
version: '0'
|
47
47
|
type: :runtime
|
48
48
|
prerelease: false
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
51
|
- - ">="
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 0
|
53
|
+
version: '0'
|
54
54
|
- !ruby/object:Gem::Dependency
|
55
|
-
name:
|
55
|
+
name: prompt_manager
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version:
|
60
|
+
version: 0.5.6
|
61
61
|
type: :runtime
|
62
62
|
prerelease: false
|
63
63
|
version_requirements: !ruby/object:Gem::Requirement
|
64
64
|
requirements:
|
65
65
|
- - ">="
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version:
|
67
|
+
version: 0.5.6
|
68
68
|
- !ruby/object:Gem::Dependency
|
69
|
-
name: ruby_llm
|
69
|
+
name: ruby_llm
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
72
|
- - ">="
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version:
|
74
|
+
version: 1.3.1
|
75
75
|
type: :runtime
|
76
76
|
prerelease: false
|
77
77
|
version_requirements: !ruby/object:Gem::Requirement
|
78
78
|
requirements:
|
79
79
|
- - ">="
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version:
|
81
|
+
version: 1.3.1
|
82
82
|
- !ruby/object:Gem::Dependency
|
83
|
-
name:
|
83
|
+
name: ruby_llm-mcp
|
84
84
|
requirement: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
86
|
- - ">="
|
@@ -94,7 +94,7 @@ dependencies:
|
|
94
94
|
- !ruby/object:Gem::Version
|
95
95
|
version: '0'
|
96
96
|
- !ruby/object:Gem::Dependency
|
97
|
-
name:
|
97
|
+
name: reline
|
98
98
|
requirement: !ruby/object:Gem::Requirement
|
99
99
|
requirements:
|
100
100
|
- - ">="
|