aia 0.9.13 → 0.9.15
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 +53 -1
- data/README.md +66 -2
- data/docs/advanced-prompting.md +29 -0
- data/docs/directives-reference.md +93 -3
- data/docs/guides/chat.md +59 -7
- data/lib/aia/context_manager.rb +61 -1
- data/lib/aia/directives/configuration.rb +77 -4
- data/lib/aia/directives/models.rb +150 -17
- data/lib/aia/directives/web_and_file.rb +12 -1
- data/lib/aia/session.rb +29 -2
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: acca553714c1fe19ed2a152a5ca500691d0435817369e60a1d773b9996d02802
|
4
|
+
data.tar.gz: f97fd1bc43cf1d8d1a8d2364313ad59a89462c31b71648c28828faa3ddc36ab9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b54ffdbcc2268e9a509f4c144182249c2d02cc520b0f1f37d7ebe8a4e79400cd2e23a96f77660019c5fb205a0bdf5df8eff14c3809f24c58886aee1fbde306f
|
7
|
+
data.tar.gz: 57a0a68ddedd0bdd69a5f25802cb9a09f8c300829d2e48c2f6025147eae3b29c861d47004614dc33108cf3a403605ee98ad9c0c239aae47e05afb8def40fb738
|
data/.version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.
|
1
|
+
0.9.15
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,59 @@
|
|
1
1
|
# Changelog
|
2
2
|
## [Unreleased]
|
3
|
-
|
4
3
|
## Released
|
4
|
+
### [0.9.15] 2025-09-21
|
5
|
+
|
6
|
+
#### New Features
|
7
|
+
- **NEW FEATURE**: Added `//paste` directive to insert clipboard contents into prompts
|
8
|
+
- **NEW FEATURE**: Added `//clipboard` alias for the paste directive
|
9
|
+
|
10
|
+
#### Technical Changes
|
11
|
+
- Enhanced DirectiveProcessor with clipboard integration using the clipboard gem
|
12
|
+
- Added comprehensive test coverage for paste directive functionality
|
13
|
+
|
14
|
+
### [0.9.14] 2025-09-19
|
15
|
+
|
16
|
+
#### New Features
|
17
|
+
- **NEW FEATURE**: Added `//checkpoint` directive to create named snapshots of conversation context
|
18
|
+
- **NEW FEATURE**: Added `//restore` directive to restore context to a previous checkpoint
|
19
|
+
- **NEW FEATURE**: Enhanced `//context` (and `//review`) directive to display checkpoint markers in conversation history
|
20
|
+
- **NEW FEATURE**: Added `//cp` alias for checkpoint directive
|
21
|
+
|
22
|
+
#### Improvements
|
23
|
+
- **ENHANCEMENT**: Context manager now tracks checkpoint positions for better context visualization
|
24
|
+
- **ENHANCEMENT**: Checkpoint system uses auto-incrementing integer names when no name is provided
|
25
|
+
- **ENHANCEMENT**: Restore directive defaults to last checkpoint when no name specified
|
26
|
+
- **ENHANCEMENT**: Clear context now also clears all checkpoints
|
27
|
+
|
28
|
+
#### Bug Fixes
|
29
|
+
- **BUG FIX**: Fixed `//help` directive that was showing empty list of directives
|
30
|
+
- **BUG FIX**: Help directive now displays all directives from all registered modules
|
31
|
+
- **BUG FIX**: Help directive now shows proper descriptions and aliases for all directives
|
32
|
+
- **BUG FIX**: Help directive organizes directives by category for better readability
|
33
|
+
|
34
|
+
#### Technical Changes
|
35
|
+
- Enhanced ContextManager with checkpoint storage and restoration capabilities
|
36
|
+
- Added checkpoint_positions method to track checkpoint locations in context
|
37
|
+
- Refactored help directive to collect directives from all registered modules
|
38
|
+
- Added comprehensive test coverage for checkpoint and restore functionality
|
39
|
+
|
40
|
+
### [0.9.13] 2025-09-02
|
41
|
+
#### New Features
|
42
|
+
- **NEW FEATURE**: Added `--metrics` flag to show token counts for each model
|
43
|
+
- **NEW FEATURE**: Added `--cost` flag to enable cost estimation for each model
|
44
|
+
|
45
|
+
#### Improvements
|
46
|
+
- **DEPENDENCY**: Removed versionaire dependency, simplifying version management
|
47
|
+
- **ENHANCEMENT**: Improved test suite reliability and coverage
|
48
|
+
- **ENHANCEMENT**: Updated Gemfile.lock with latest dependency versions
|
49
|
+
|
50
|
+
#### Bug Fixes
|
51
|
+
- **BUG FIX**: Fixed version handling issues by removing external versioning dependency
|
52
|
+
|
53
|
+
#### Technical Changes
|
54
|
+
- Simplified version management by removing versionaire gem
|
55
|
+
- Enhanced test suite with improved assertions and coverage
|
56
|
+
- Updated various gem dependencies to latest stable versions
|
5
57
|
|
6
58
|
### [0.9.12] 2025-08-28
|
7
59
|
|
data/README.md
CHANGED
@@ -334,8 +334,11 @@ Directives are special commands in prompt files that begin with `//` and provide
|
|
334
334
|
| Directive | Description | Example |
|
335
335
|
|-----------|-------------|---------|
|
336
336
|
| `//config` | Set configuration values | `//config model = gpt-4` |
|
337
|
-
| `//context` | Show context for this conversation | `//context` |
|
337
|
+
| `//context` | Show context for this conversation with checkpoint markers | `//context` |
|
338
|
+
| `//checkpoint` | Create a named checkpoint of current context | `//checkpoint save_point` |
|
339
|
+
| `//restore` | Restore context to a previous checkpoint | `//restore save_point` |
|
338
340
|
| `//include` | Insert file contents | `//include path/to/file.txt` |
|
341
|
+
| `//paste` | Insert clipboard contents | `//paste` |
|
339
342
|
| `//shell` | Execute shell commands | `//shell ls -la` |
|
340
343
|
| `//robot` | Show the pet robot ASCII art w/versions | `//robot` |
|
341
344
|
| `//ruby` | Execute Ruby code | `//ruby puts "Hello World"` |
|
@@ -346,7 +349,7 @@ Directives are special commands in prompt files that begin with `//` and provide
|
|
346
349
|
| `//model` | Show current model configuration | `//model` |
|
347
350
|
| `//available_models` | List available models | `//available_models` |
|
348
351
|
| `//tools` | Show a list of available tools and their description | `//tools` |
|
349
|
-
| `//review` | Review current context | `//review` |
|
352
|
+
| `//review` | Review current context with checkpoint markers | `//review` |
|
350
353
|
|
351
354
|
Directives can also be used in the interactive chat sessions.
|
352
355
|
|
@@ -370,6 +373,9 @@ Your prompt content here...
|
|
370
373
|
# Include file contents
|
371
374
|
//include ~/project/README.md
|
372
375
|
|
376
|
+
# Paste clipboard contents
|
377
|
+
//paste
|
378
|
+
|
373
379
|
# Execute shell commands
|
374
380
|
//shell git log --oneline -10
|
375
381
|
|
@@ -379,6 +385,64 @@ Your prompt content here...
|
|
379
385
|
Analyze the above information and provide insights.
|
380
386
|
```
|
381
387
|
|
388
|
+
#### Context Management with Checkpoints
|
389
|
+
|
390
|
+
AIA provides powerful context management capabilities in chat mode through checkpoint and restore directives:
|
391
|
+
|
392
|
+
```bash
|
393
|
+
# Create a checkpoint with automatic naming (1, 2, 3...)
|
394
|
+
//checkpoint
|
395
|
+
|
396
|
+
# Create a named checkpoint
|
397
|
+
//checkpoint important_decision
|
398
|
+
|
399
|
+
# Restore to the last checkpoint
|
400
|
+
//restore
|
401
|
+
|
402
|
+
# Restore to a specific checkpoint
|
403
|
+
//restore important_decision
|
404
|
+
|
405
|
+
# View context with checkpoint markers
|
406
|
+
//context
|
407
|
+
```
|
408
|
+
|
409
|
+
**Example Chat Session:**
|
410
|
+
```
|
411
|
+
You: Tell me about Ruby programming
|
412
|
+
AI: Ruby is a dynamic programming language...
|
413
|
+
|
414
|
+
You: //checkpoint ruby_basics
|
415
|
+
|
416
|
+
You: Now explain object-oriented programming
|
417
|
+
AI: Object-oriented programming (OOP) is...
|
418
|
+
|
419
|
+
You: //checkpoint oop_concepts
|
420
|
+
|
421
|
+
You: Actually, let's go back to Ruby basics
|
422
|
+
You: //restore ruby_basics
|
423
|
+
|
424
|
+
You: //context
|
425
|
+
=== Chat Context ===
|
426
|
+
Total messages: 4
|
427
|
+
Checkpoints: ruby_basics, oop_concepts
|
428
|
+
|
429
|
+
1. [System]: You are a helpful assistant
|
430
|
+
2. [User]: Tell me about Ruby programming
|
431
|
+
3. [Assistant]: Ruby is a dynamic programming language...
|
432
|
+
|
433
|
+
📍 [Checkpoint: ruby_basics]
|
434
|
+
----------------------------------------
|
435
|
+
4. [User]: Now explain object-oriented programming
|
436
|
+
=== End of Context ===
|
437
|
+
```
|
438
|
+
|
439
|
+
**Key Features:**
|
440
|
+
- **Auto-naming**: Checkpoints without names use incrementing integers (1, 2, 3...)
|
441
|
+
- **Named checkpoints**: Use meaningful names like `//checkpoint before_refactor`
|
442
|
+
- **Default restore**: `//restore` without a name restores to the last checkpoint
|
443
|
+
- **Context visualization**: `//context` shows checkpoint markers in conversation history
|
444
|
+
- **Clean slate**: `//clear` removes all context and checkpoints
|
445
|
+
|
382
446
|
#### Custom Directive Examples
|
383
447
|
|
384
448
|
You can extend AIA with custom directives by creating Ruby files that define new directive methods:
|
data/docs/advanced-prompting.md
CHANGED
@@ -160,6 +160,30 @@ if File.exist?(history_file)
|
|
160
160
|
Now analyze <%= task %> using all available context layers.
|
161
161
|
```
|
162
162
|
|
163
|
+
### Clipboard Integration
|
164
|
+
Quick data insertion from clipboard:
|
165
|
+
|
166
|
+
```markdown
|
167
|
+
# Code Review with Clipboard Content
|
168
|
+
|
169
|
+
## Code to Review
|
170
|
+
//paste
|
171
|
+
|
172
|
+
## Review Guidelines
|
173
|
+
- Check for best practices
|
174
|
+
- Identify security vulnerabilities
|
175
|
+
- Suggest performance improvements
|
176
|
+
- Validate error handling
|
177
|
+
|
178
|
+
Please provide detailed feedback on the code above.
|
179
|
+
```
|
180
|
+
|
181
|
+
This is particularly useful for:
|
182
|
+
- Quick code reviews when you've copied code from an IDE
|
183
|
+
- Analyzing error messages or logs copied from terminals
|
184
|
+
- Including data from spreadsheets or other applications
|
185
|
+
- Rapid prototyping with copied examples
|
186
|
+
|
163
187
|
### Context Filtering and Summarization
|
164
188
|
Manage large contexts intelligently:
|
165
189
|
|
@@ -237,6 +261,11 @@ Generate an academic document with:
|
|
237
261
|
<% end %>
|
238
262
|
<% end %>
|
239
263
|
|
264
|
+
## Clipboard Content (if applicable)
|
265
|
+
<% if include_clipboard %>
|
266
|
+
//paste
|
267
|
+
<% end %>
|
268
|
+
|
240
269
|
Target audience: <%= audience || "general professional" %>
|
241
270
|
Document length: <%= length || "2000-3000 words" %>
|
242
271
|
```
|
@@ -111,6 +111,24 @@ Include content from files or websites.
|
|
111
111
|
|
112
112
|
**Aliases**: `//import`
|
113
113
|
|
114
|
+
### `//paste`
|
115
|
+
Insert content from the system clipboard.
|
116
|
+
|
117
|
+
**Syntax**: `//paste`
|
118
|
+
|
119
|
+
**Examples**:
|
120
|
+
```markdown
|
121
|
+
//paste
|
122
|
+
```
|
123
|
+
|
124
|
+
**Features**:
|
125
|
+
- Inserts the current clipboard contents directly into the prompt
|
126
|
+
- Useful for quickly including copied text, code, or data
|
127
|
+
- Works across different platforms (macOS, Linux, Windows)
|
128
|
+
- Handles multi-line clipboard content
|
129
|
+
|
130
|
+
**Aliases**: `//clipboard`
|
131
|
+
|
114
132
|
### `//webpage`
|
115
133
|
Include content from web pages (requires PUREMD_API_KEY).
|
116
134
|
|
@@ -271,21 +289,93 @@ Inserts a fun ASCII robot character for visual breaks in prompts.
|
|
271
289
|
|
272
290
|
## Context Management Directives
|
273
291
|
|
292
|
+
### `//checkpoint`
|
293
|
+
Create a named checkpoint of the current conversation context.
|
294
|
+
|
295
|
+
**Syntax**: `//checkpoint [name]`
|
296
|
+
|
297
|
+
**Examples**:
|
298
|
+
```markdown
|
299
|
+
//checkpoint # Auto-named checkpoint (1, 2, 3...)
|
300
|
+
//checkpoint important_decision # Named checkpoint
|
301
|
+
//checkpoint before_refactor # Descriptive name
|
302
|
+
```
|
303
|
+
|
304
|
+
**Features**:
|
305
|
+
- **Auto-naming**: If no name provided, uses incrementing integers (1, 2, 3...)
|
306
|
+
- **Named checkpoints**: Use meaningful names for easy identification
|
307
|
+
- **Deep copying**: Safely stores complete conversation state
|
308
|
+
- **Chat mode only**: Only available during interactive chat sessions
|
309
|
+
|
310
|
+
**Usage**:
|
311
|
+
- `//checkpoint` - Create an auto-named checkpoint
|
312
|
+
- `//checkpoint name` - Create a checkpoint with specific name
|
313
|
+
|
314
|
+
**Aliases**: `//cp`
|
315
|
+
|
316
|
+
### `//restore`
|
317
|
+
Restore conversation context to a previously saved checkpoint.
|
318
|
+
|
319
|
+
**Syntax**: `//restore [name]`
|
320
|
+
|
321
|
+
**Examples**:
|
322
|
+
```markdown
|
323
|
+
//restore # Restore to last checkpoint
|
324
|
+
//restore important_decision # Restore to named checkpoint
|
325
|
+
//restore 1 # Restore to auto-named checkpoint
|
326
|
+
```
|
327
|
+
|
328
|
+
**Features**:
|
329
|
+
- **Default behavior**: Without a name, restores to the most recent checkpoint
|
330
|
+
- **Named restoration**: Restore to any previously saved checkpoint
|
331
|
+
- **Context truncation**: Removes all messages added after the checkpoint
|
332
|
+
- **Client refresh**: Automatically refreshes AI client context
|
333
|
+
|
334
|
+
**Usage**:
|
335
|
+
- `//restore` - Restore to the last checkpoint created
|
336
|
+
- `//restore name` - Restore to a specific named checkpoint
|
337
|
+
- Returns error message if checkpoint doesn't exist
|
338
|
+
|
274
339
|
### `//clear`
|
275
340
|
Clear conversation context in chat mode.
|
276
341
|
|
277
342
|
**Syntax**: `//clear`
|
278
343
|
|
279
|
-
**Usage**: Only available during chat sessions. Clears the conversation history while keeping the session active.
|
344
|
+
**Usage**: Only available during chat sessions. Clears the conversation history and all checkpoints while keeping the session active.
|
280
345
|
|
281
346
|
### `//review`
|
282
|
-
Display current conversation context.
|
347
|
+
Display current conversation context with checkpoint markers.
|
283
348
|
|
284
349
|
**Syntax**: `//review`
|
285
350
|
|
286
351
|
**Aliases**: `//context`
|
287
352
|
|
288
|
-
|
353
|
+
**Example Output**:
|
354
|
+
```
|
355
|
+
=== Chat Context ===
|
356
|
+
Total messages: 5
|
357
|
+
Checkpoints: ruby_basics, oop_concepts
|
358
|
+
|
359
|
+
1. [System]: You are a helpful assistant
|
360
|
+
2. [User]: Tell me about Ruby programming
|
361
|
+
3. [Assistant]: Ruby is a dynamic programming language...
|
362
|
+
|
363
|
+
📍 [Checkpoint: ruby_basics]
|
364
|
+
----------------------------------------
|
365
|
+
4. [User]: Now explain object-oriented programming
|
366
|
+
5. [Assistant]: Object-oriented programming (OOP) is...
|
367
|
+
|
368
|
+
📍 [Checkpoint: oop_concepts]
|
369
|
+
----------------------------------------
|
370
|
+
=== End of Context ===
|
371
|
+
```
|
372
|
+
|
373
|
+
**Features**:
|
374
|
+
- Shows complete conversation history with message numbers
|
375
|
+
- Displays checkpoint markers (📍) at their exact positions
|
376
|
+
- Lists all available checkpoints
|
377
|
+
- Truncates long messages for readability (200 characters)
|
378
|
+
- Shows total message count and checkpoint summary
|
289
379
|
|
290
380
|
## Model and Information Directives
|
291
381
|
|
data/docs/guides/chat.md
CHANGED
@@ -112,19 +112,71 @@ You: How do I handle user authentication?
|
|
112
112
|
AI: For your Flask application, here are several authentication options...
|
113
113
|
```
|
114
114
|
|
115
|
+
#### Context Checkpoints
|
116
|
+
Create savepoints in your conversation to easily return to specific moments:
|
117
|
+
|
118
|
+
```
|
119
|
+
You: Let's explore different authentication approaches for Flask.
|
120
|
+
AI: I can help you explore various authentication methods...
|
121
|
+
|
122
|
+
You: //checkpoint auth_start
|
123
|
+
|
124
|
+
You: Tell me about JWT authentication.
|
125
|
+
AI: JWT (JSON Web Tokens) authentication is a stateless approach...
|
126
|
+
|
127
|
+
You: //checkpoint jwt_discussion
|
128
|
+
|
129
|
+
You: What about OAuth integration?
|
130
|
+
AI: OAuth provides a robust framework for authentication...
|
131
|
+
|
132
|
+
You: Actually, let's go back to the JWT discussion
|
133
|
+
You: //restore jwt_discussion
|
134
|
+
|
135
|
+
You: //context
|
136
|
+
=== Chat Context ===
|
137
|
+
Total messages: 6
|
138
|
+
Checkpoints: auth_start, jwt_discussion
|
139
|
+
|
140
|
+
1. [System]: You are a helpful assistant
|
141
|
+
2. [User]: Let's explore different authentication approaches for Flask.
|
142
|
+
3. [Assistant]: I can help you explore various authentication methods...
|
143
|
+
|
144
|
+
📍 [Checkpoint: auth_start]
|
145
|
+
----------------------------------------
|
146
|
+
4. [User]: Tell me about JWT authentication.
|
147
|
+
5. [Assistant]: JWT (JSON Web Tokens) authentication is a stateless approach...
|
148
|
+
|
149
|
+
📍 [Checkpoint: jwt_discussion]
|
150
|
+
----------------------------------------
|
151
|
+
=== End of Context ===
|
152
|
+
```
|
153
|
+
|
154
|
+
**Checkpoint Commands**:
|
155
|
+
- `//checkpoint` - Create auto-numbered checkpoint (1, 2, 3...)
|
156
|
+
- `//checkpoint name` - Create named checkpoint
|
157
|
+
- `//restore` - Restore to last checkpoint
|
158
|
+
- `//restore name` - Restore to specific checkpoint
|
159
|
+
- `//cp name` - Short alias for checkpoint
|
160
|
+
|
161
|
+
**Use Cases for Checkpoints**:
|
162
|
+
- **Exploring alternatives**: Save before trying different approaches
|
163
|
+
- **Debugging conversations**: Return to working state after errors
|
164
|
+
- **Session branching**: Explore multiple conversation paths
|
165
|
+
- **Learning sessions**: Bookmark important explanations
|
166
|
+
|
115
167
|
#### Context Inspection
|
116
168
|
```
|
117
|
-
You:
|
118
|
-
# Shows current conversation history
|
169
|
+
You: //context
|
170
|
+
# Shows current conversation history with checkpoint markers
|
171
|
+
|
172
|
+
You: //review
|
173
|
+
# Alternative command for context inspection
|
119
174
|
```
|
120
175
|
|
121
176
|
#### Context Clearing
|
122
177
|
```
|
123
|
-
You:
|
124
|
-
# Clears conversation history while keeping session active
|
125
|
-
|
126
|
-
You: /new
|
127
|
-
# Starts a completely fresh session
|
178
|
+
You: //clear
|
179
|
+
# Clears conversation history and all checkpoints while keeping session active
|
128
180
|
```
|
129
181
|
|
130
182
|
### Tool Integration in Chat
|
data/lib/aia/context_manager.rb
CHANGED
@@ -3,11 +3,13 @@
|
|
3
3
|
module AIA
|
4
4
|
# Manages the conversation context for chat sessions.
|
5
5
|
class ContextManager
|
6
|
-
attr_reader :context
|
6
|
+
attr_reader :context, :checkpoints
|
7
7
|
|
8
8
|
# Initializes the ContextManager with an optional system prompt.
|
9
9
|
def initialize(system_prompt: nil)
|
10
10
|
@context = []
|
11
|
+
@checkpoints = {}
|
12
|
+
@checkpoint_counter = 0
|
11
13
|
add_system_prompt(system_prompt) if system_prompt && !system_prompt.strip.empty?
|
12
14
|
end
|
13
15
|
|
@@ -43,6 +45,10 @@ module AIA
|
|
43
45
|
@context = []
|
44
46
|
end
|
45
47
|
|
48
|
+
# Clear all checkpoints when clearing context
|
49
|
+
@checkpoints.clear
|
50
|
+
@checkpoint_counter = 0
|
51
|
+
|
46
52
|
# Attempt to clear the LLM client's context as well
|
47
53
|
begin
|
48
54
|
if AIA.config.client && AIA.config.client.respond_to?(:clear_context)
|
@@ -61,6 +67,60 @@ module AIA
|
|
61
67
|
end
|
62
68
|
end
|
63
69
|
|
70
|
+
# Creates a checkpoint of the current context with an optional name.
|
71
|
+
#
|
72
|
+
# @param name [String, nil] The name of the checkpoint. If nil, uses an incrementing integer.
|
73
|
+
# @return [String] The name of the created checkpoint.
|
74
|
+
def create_checkpoint(name: nil)
|
75
|
+
if name.nil?
|
76
|
+
@checkpoint_counter += 1
|
77
|
+
name = @checkpoint_counter.to_s
|
78
|
+
end
|
79
|
+
|
80
|
+
# Store a deep copy of the current context and its position
|
81
|
+
@checkpoints[name] = {
|
82
|
+
context: @context.map(&:dup),
|
83
|
+
position: @context.size
|
84
|
+
}
|
85
|
+
@last_checkpoint_name = name
|
86
|
+
name
|
87
|
+
end
|
88
|
+
|
89
|
+
# Restores the context to a previously saved checkpoint.
|
90
|
+
#
|
91
|
+
# @param name [String, nil] The name of the checkpoint to restore. If nil, uses the last checkpoint.
|
92
|
+
# @return [Boolean] True if restore was successful, false otherwise.
|
93
|
+
def restore_checkpoint(name: nil)
|
94
|
+
name = @last_checkpoint_name if name.nil?
|
95
|
+
|
96
|
+
return false if name.nil? || !@checkpoints.key?(name)
|
97
|
+
|
98
|
+
# Restore the context from the checkpoint
|
99
|
+
checkpoint_data = @checkpoints[name]
|
100
|
+
@context = checkpoint_data[:context].map(&:dup)
|
101
|
+
true
|
102
|
+
end
|
103
|
+
|
104
|
+
# Returns the list of available checkpoint names.
|
105
|
+
#
|
106
|
+
# @return [Array<String>] The names of all checkpoints.
|
107
|
+
def checkpoint_names
|
108
|
+
@checkpoints.keys
|
109
|
+
end
|
110
|
+
|
111
|
+
# Returns checkpoint information mapped to context positions.
|
112
|
+
#
|
113
|
+
# @return [Hash<Integer, Array<String>>] Position to checkpoint names mapping.
|
114
|
+
def checkpoint_positions
|
115
|
+
positions = {}
|
116
|
+
@checkpoints.each do |name, data|
|
117
|
+
position = data[:position]
|
118
|
+
positions[position] ||= []
|
119
|
+
positions[position] << name
|
120
|
+
end
|
121
|
+
positions
|
122
|
+
end
|
123
|
+
|
64
124
|
private
|
65
125
|
|
66
126
|
# Adds or replaces the system prompt at the beginning of the context.
|
@@ -34,7 +34,7 @@ module AIA
|
|
34
34
|
# Display details for all configured models
|
35
35
|
puts
|
36
36
|
models = Array(AIA.config.model)
|
37
|
-
|
37
|
+
|
38
38
|
if models.size == 1
|
39
39
|
puts "Current Model:"
|
40
40
|
puts "=============="
|
@@ -48,10 +48,10 @@ module AIA
|
|
48
48
|
puts
|
49
49
|
puts "Model Details:"
|
50
50
|
puts "-" * 50
|
51
|
-
|
51
|
+
|
52
52
|
models.each_with_index do |model_name, index|
|
53
53
|
puts "#{index + 1}. #{model_name}#{index == 0 ? ' (primary)' : ''}"
|
54
|
-
|
54
|
+
|
55
55
|
# Try to get model details if available
|
56
56
|
begin
|
57
57
|
# Access the model details from RubyLLM's model registry
|
@@ -98,16 +98,89 @@ module AIA
|
|
98
98
|
end
|
99
99
|
|
100
100
|
def self.review(args, context_manager = nil)
|
101
|
-
|
101
|
+
return "Error: Context manager not available for //review directive." if context_manager.nil?
|
102
|
+
|
103
|
+
context = context_manager.get_context
|
104
|
+
checkpoint_positions = context_manager.checkpoint_positions
|
105
|
+
|
106
|
+
# Display context with checkpoint markers
|
107
|
+
puts "\n=== Chat Context ==="
|
108
|
+
puts "Total messages: #{context.size}"
|
109
|
+
|
110
|
+
if checkpoint_positions.any?
|
111
|
+
puts "Checkpoints: #{context_manager.checkpoint_names.join(', ')}"
|
112
|
+
end
|
113
|
+
|
114
|
+
puts "\n"
|
115
|
+
|
116
|
+
context.each_with_index do |message, index|
|
117
|
+
# Check if there's a checkpoint at this position
|
118
|
+
if checkpoint_positions[index]
|
119
|
+
checkpoint_names = checkpoint_positions[index].join(', ')
|
120
|
+
puts "📍 [Checkpoint: #{checkpoint_names}]"
|
121
|
+
puts "-" * 40
|
122
|
+
end
|
123
|
+
|
124
|
+
# Display the message
|
125
|
+
role_display = message[:role].capitalize
|
126
|
+
content_preview = message[:content].to_s
|
127
|
+
|
128
|
+
# Truncate long content for display
|
129
|
+
if content_preview.length > 200
|
130
|
+
content_preview = content_preview[0..197] + "..."
|
131
|
+
end
|
132
|
+
|
133
|
+
puts "#{index + 1}. [#{role_display}]: #{content_preview}"
|
134
|
+
puts ""
|
135
|
+
end
|
136
|
+
|
137
|
+
# Check if there's a checkpoint at the end (after all messages)
|
138
|
+
if checkpoint_positions[context.size]
|
139
|
+
checkpoint_names = checkpoint_positions[context.size].join(', ')
|
140
|
+
puts "📍 [Checkpoint: #{checkpoint_names}]"
|
141
|
+
puts "-" * 40
|
142
|
+
end
|
143
|
+
|
144
|
+
puts "=== End of Context ==="
|
102
145
|
''
|
103
146
|
end
|
104
147
|
|
148
|
+
def self.checkpoint(args, context_manager = nil)
|
149
|
+
if context_manager.nil?
|
150
|
+
return "Error: Context manager not available for //checkpoint directive."
|
151
|
+
end
|
152
|
+
|
153
|
+
name = args.empty? ? nil : args.join(' ').strip
|
154
|
+
checkpoint_name = context_manager.create_checkpoint(name: name)
|
155
|
+
"Checkpoint '#{checkpoint_name}' created."
|
156
|
+
end
|
157
|
+
|
158
|
+
def self.restore(args, context_manager = nil)
|
159
|
+
if context_manager.nil?
|
160
|
+
return "Error: Context manager not available for //restore directive."
|
161
|
+
end
|
162
|
+
|
163
|
+
name = args.empty? ? nil : args.join(' ').strip
|
164
|
+
|
165
|
+
if context_manager.restore_checkpoint(name: name)
|
166
|
+
restored_name = name || context_manager.checkpoint_names.last
|
167
|
+
"Context restored to checkpoint '#{restored_name}'."
|
168
|
+
else
|
169
|
+
if name
|
170
|
+
"Error: Checkpoint '#{name}' not found. Available checkpoints: #{context_manager.checkpoint_names.join(', ')}"
|
171
|
+
else
|
172
|
+
"Error: No checkpoints available to restore."
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
105
177
|
# Set up aliases - these work on the module's singleton class
|
106
178
|
class << self
|
107
179
|
alias_method :cfg, :config
|
108
180
|
alias_method :temp, :temperature
|
109
181
|
alias_method :topp, :top_p
|
110
182
|
alias_method :context, :review
|
183
|
+
alias_method :ckp, :checkpoint
|
111
184
|
end
|
112
185
|
end
|
113
186
|
end
|
@@ -85,30 +85,163 @@ module AIA
|
|
85
85
|
puts "===================="
|
86
86
|
puts
|
87
87
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
88
|
+
# Manual descriptions for all directives
|
89
|
+
directive_descriptions = {
|
90
|
+
# Configuration directives
|
91
|
+
'config' => 'View or set configuration values',
|
92
|
+
'model' => 'View or change the AI model',
|
93
|
+
'temperature' => 'Set the temperature parameter for AI responses',
|
94
|
+
'top_p' => 'Set the top_p parameter for AI responses',
|
95
|
+
'clear' => 'Clear the conversation context',
|
96
|
+
'review' => 'Display the current conversation context with checkpoint markers',
|
97
|
+
'checkpoint' => 'Create a named checkpoint of the current context',
|
98
|
+
'restore' => 'Restore context to a previous checkpoint',
|
99
|
+
|
100
|
+
# Utility directives
|
101
|
+
'tools' => 'List available tools',
|
102
|
+
'next' => 'Set the next prompt in the sequence',
|
103
|
+
'pipeline' => 'Set or view the prompt workflow sequence',
|
104
|
+
'terse' => 'Add instruction for concise responses',
|
105
|
+
'robot' => 'Display ASCII robot art',
|
106
|
+
|
107
|
+
# Execution directives
|
108
|
+
'ruby' => 'Execute Ruby code',
|
109
|
+
'shell' => 'Execute shell commands',
|
110
|
+
'say' => 'Use text-to-speech to speak the text',
|
111
|
+
|
112
|
+
# Web and File directives
|
113
|
+
'webpage' => 'Fetch and include content from a webpage',
|
114
|
+
'include' => 'Include content from a file',
|
115
|
+
'include_file' => 'Include file content (internal use)',
|
116
|
+
'included_files' => 'List files that have been included',
|
117
|
+
'included_files=' => 'Set the list of included files',
|
118
|
+
|
119
|
+
# Model directives
|
120
|
+
'available_models' => 'List all available AI models',
|
121
|
+
'compare' => 'Compare responses from multiple models',
|
122
|
+
'help' => 'Show this help message',
|
123
|
+
|
124
|
+
# Aliases (these get their descriptions from main directive)
|
125
|
+
'cfg' => nil, # alias for config
|
126
|
+
'temp' => nil, # alias for temperature
|
127
|
+
'topp' => nil, # alias for top_p
|
128
|
+
'context' => nil, # alias for review
|
129
|
+
'cp' => nil, # alias for checkpoint
|
130
|
+
'workflow' => nil, # alias for pipeline
|
131
|
+
'rb' => nil, # alias for ruby
|
132
|
+
'sh' => nil, # alias for shell
|
133
|
+
'web' => nil, # alias for webpage
|
134
|
+
'website' => nil, # alias for webpage
|
135
|
+
'import' => nil, # alias for include
|
136
|
+
'models' => nil, # alias for available_models
|
137
|
+
'all_models' => nil, # alias for available_models
|
138
|
+
'am' => nil, # alias for available_models
|
139
|
+
'llms' => nil, # alias for available_models
|
140
|
+
'available' => nil, # alias for available_models
|
141
|
+
'cmp' => nil, # alias for compare
|
142
|
+
}
|
143
|
+
|
144
|
+
# Get all registered directive modules from the Registry
|
145
|
+
all_modules = [
|
146
|
+
AIA::Directives::WebAndFile,
|
147
|
+
AIA::Directives::Utility,
|
148
|
+
AIA::Directives::Configuration,
|
149
|
+
AIA::Directives::Execution,
|
150
|
+
AIA::Directives::Models
|
151
|
+
]
|
152
|
+
|
153
|
+
all_directives = {}
|
154
|
+
excluded_methods = ['run', 'initialize', 'private?', 'descriptions', 'aliases', 'build_aliases',
|
155
|
+
'desc', 'method_added', 'register_directive_module', 'process',
|
156
|
+
'directive?', 'prefix_size']
|
157
|
+
|
158
|
+
# Collect directives from all modules
|
159
|
+
all_modules.each do |mod|
|
160
|
+
methods = mod.methods(false).map(&:to_s).reject { |m| excluded_methods.include?(m) }
|
161
|
+
|
162
|
+
methods.each do |method|
|
163
|
+
# Skip if this is an alias (has nil description)
|
164
|
+
next if directive_descriptions.key?(method) && directive_descriptions[method].nil?
|
165
|
+
|
166
|
+
description = directive_descriptions[method] || method.gsub('_', ' ').capitalize
|
167
|
+
|
168
|
+
all_directives[method] = {
|
169
|
+
module: mod.name.split('::').last,
|
170
|
+
description: description,
|
171
|
+
aliases: []
|
172
|
+
}
|
173
|
+
end
|
174
|
+
end
|
93
175
|
|
94
|
-
|
95
|
-
|
176
|
+
# Manually map known aliases
|
177
|
+
alias_mappings = {
|
178
|
+
'config' => ['cfg'],
|
179
|
+
'temperature' => ['temp'],
|
180
|
+
'top_p' => ['topp'],
|
181
|
+
'review' => ['context'],
|
182
|
+
'checkpoint' => ['cp'],
|
183
|
+
'pipeline' => ['workflow'],
|
184
|
+
'ruby' => ['rb'],
|
185
|
+
'shell' => ['sh'],
|
186
|
+
'webpage' => ['web', 'website'],
|
187
|
+
'include' => ['import'],
|
188
|
+
'available_models' => ['models', 'all_models', 'am', 'llms', 'available'],
|
189
|
+
'compare' => ['cmp']
|
190
|
+
}
|
191
|
+
|
192
|
+
# Apply alias mappings
|
193
|
+
alias_mappings.each do |directive, aliases|
|
194
|
+
if all_directives[directive]
|
195
|
+
all_directives[directive][:aliases] = aliases
|
196
|
+
end
|
197
|
+
end
|
96
198
|
|
97
|
-
|
199
|
+
# Sort and display directives by category
|
200
|
+
categories = {
|
201
|
+
'Configuration' => ['config', 'model', 'temperature', 'top_p', 'clear', 'review', 'checkpoint', 'restore'],
|
202
|
+
'Utility' => ['tools', 'next', 'pipeline', 'terse', 'robot', 'help'],
|
203
|
+
'Execution' => ['ruby', 'shell', 'say'],
|
204
|
+
'Web & Files' => ['webpage', 'include'],
|
205
|
+
'Models' => ['available_models', 'compare']
|
206
|
+
}
|
207
|
+
|
208
|
+
categories.each do |category, directives|
|
209
|
+
puts "#{category}:"
|
210
|
+
puts "-" * category.length
|
211
|
+
|
212
|
+
directives.each do |directive|
|
213
|
+
info = all_directives[directive]
|
214
|
+
next unless info
|
215
|
+
|
216
|
+
if info[:aliases] && !info[:aliases].empty?
|
217
|
+
with_prefix = info[:aliases].map { |m| PromptManager::Prompt::DIRECTIVE_SIGNAL + m }
|
218
|
+
alias_text = " (aliases: #{with_prefix.join(', ')})"
|
219
|
+
else
|
220
|
+
alias_text = ""
|
221
|
+
end
|
98
222
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
with_prefix = others.map { |m| PromptManager::Prompt::DIRECTIVE_SIGNAL + m }
|
103
|
-
others_line = "\tAliases:#{with_prefix.join(' ')}\n"
|
223
|
+
puts " //#{directive}#{alias_text}"
|
224
|
+
puts " #{info[:description]}"
|
225
|
+
puts
|
104
226
|
end
|
227
|
+
end
|
105
228
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
229
|
+
# Show any uncategorized directives
|
230
|
+
categorized = categories.values.flatten
|
231
|
+
uncategorized = all_directives.keys - categorized - ['include_file', 'included_files', 'included_files=']
|
232
|
+
|
233
|
+
if uncategorized.any?
|
234
|
+
puts "Other:"
|
235
|
+
puts "------"
|
236
|
+
uncategorized.sort.each do |directive|
|
237
|
+
info = all_directives[directive]
|
238
|
+
puts " //#{directive}"
|
239
|
+
puts " #{info[:description]}"
|
240
|
+
puts
|
241
|
+
end
|
110
242
|
end
|
111
243
|
|
244
|
+
puts "\nTotal: #{all_directives.size} directives available"
|
112
245
|
""
|
113
246
|
end
|
114
247
|
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'faraday'
|
4
4
|
require 'active_support/all'
|
5
|
+
require 'clipboard'
|
5
6
|
|
6
7
|
module AIA
|
7
8
|
module Directives
|
@@ -60,11 +61,21 @@ module AIA
|
|
60
61
|
@included_files = files
|
61
62
|
end
|
62
63
|
|
64
|
+
def self.paste(args = [], context_manager = nil)
|
65
|
+
begin
|
66
|
+
content = Clipboard.paste
|
67
|
+
content.to_s
|
68
|
+
rescue => e
|
69
|
+
"Error: Unable to paste from clipboard - #{e.message}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
63
73
|
# Set up aliases - these work on the module's singleton class
|
64
74
|
class << self
|
65
75
|
alias_method :website, :webpage
|
66
|
-
alias_method :web, :webpage
|
76
|
+
alias_method :web, :webpage
|
67
77
|
alias_method :import, :include
|
78
|
+
alias_method :clipboard, :paste
|
68
79
|
end
|
69
80
|
end
|
70
81
|
end
|
data/lib/aia/session.rb
CHANGED
@@ -407,10 +407,12 @@ module AIA
|
|
407
407
|
|
408
408
|
def process_chat_directive(follow_up_prompt)
|
409
409
|
directive_output = @directive_processor.process(follow_up_prompt, @context_manager)
|
410
|
-
|
410
|
+
|
411
411
|
return handle_clear_directive if follow_up_prompt.strip.start_with?("//clear")
|
412
|
+
return handle_checkpoint_directive(directive_output) if follow_up_prompt.strip.start_with?("//checkpoint")
|
413
|
+
return handle_restore_directive(directive_output) if follow_up_prompt.strip.start_with?("//restore")
|
412
414
|
return handle_empty_directive_output if directive_output.nil? || directive_output.strip.empty?
|
413
|
-
|
415
|
+
|
414
416
|
handle_successful_directive(follow_up_prompt, directive_output)
|
415
417
|
end
|
416
418
|
|
@@ -438,6 +440,31 @@ module AIA
|
|
438
440
|
nil
|
439
441
|
end
|
440
442
|
|
443
|
+
def handle_checkpoint_directive(directive_output)
|
444
|
+
@ui_presenter.display_info(directive_output)
|
445
|
+
nil
|
446
|
+
end
|
447
|
+
|
448
|
+
def handle_restore_directive(directive_output)
|
449
|
+
# If the restore was successful, we also need to refresh the client's context
|
450
|
+
if directive_output.start_with?("Context restored")
|
451
|
+
# Try to clear and rebuild the client's context
|
452
|
+
if AIA.config.client && AIA.config.client.respond_to?(:clear_context)
|
453
|
+
AIA.config.client.clear_context
|
454
|
+
end
|
455
|
+
|
456
|
+
# Optionally reinitialize the client for a clean state
|
457
|
+
begin
|
458
|
+
AIA.config.client = AIA::RubyLLMAdapter.new
|
459
|
+
rescue => e
|
460
|
+
STDERR.puts "Error reinitializing client after restore: #{e.message}"
|
461
|
+
end
|
462
|
+
end
|
463
|
+
|
464
|
+
@ui_presenter.display_info(directive_output)
|
465
|
+
nil
|
466
|
+
end
|
467
|
+
|
441
468
|
def handle_empty_directive_output
|
442
469
|
nil
|
443
470
|
end
|
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.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dewayne VanHoozer
|
@@ -51,6 +51,20 @@ dependencies:
|
|
51
51
|
- - ">="
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: '0'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: clipboard
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
type: :runtime
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
54
68
|
- !ruby/object:Gem::Dependency
|
55
69
|
name: faraday
|
56
70
|
requirement: !ruby/object:Gem::Requirement
|
@@ -433,7 +447,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
433
447
|
- !ruby/object:Gem::Version
|
434
448
|
version: '0'
|
435
449
|
requirements: []
|
436
|
-
rubygems_version: 3.7.
|
450
|
+
rubygems_version: 3.7.2
|
437
451
|
specification_version: 4
|
438
452
|
summary: Multi-model AI CLI with dynamic prompts, consensus responses, shell & Ruby
|
439
453
|
integration, and seamless chat workflows.
|