aia 0.9.13 → 0.9.14
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 +44 -0
- data/README.md +62 -2
- data/docs/directives-reference.md +75 -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/session.rb +29 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 91bd0c834c03dafa5c71d9d5e608db37ecd398c897e806361069aabee36d8abc
|
4
|
+
data.tar.gz: d275ec9393e55f3b39978fffd97a9eecf36021786ef579cdae0746488b0fe401
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2f00745bd78ffba8a434497946aa4a2116b7d0cfe805f8a5b132869af70e6698b490f8361a7589da875dc8d64a9869cd5c22b588347cabeefa10b0f8585e196
|
7
|
+
data.tar.gz: e4334b5fb5d25851aa3a1c29af391f82b6fc9ecbf1f6bc52edf999475e29b62ecf40395c246200f5ff525c1e0d8d3dd51330a4738d4b2b20f08594c9d0969431
|
data/.version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.
|
1
|
+
0.9.14
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,50 @@
|
|
3
3
|
|
4
4
|
## Released
|
5
5
|
|
6
|
+
### [0.9.14] 2025-09-19
|
7
|
+
|
8
|
+
#### New Features
|
9
|
+
- **NEW FEATURE**: Added `//checkpoint` directive to create named snapshots of conversation context
|
10
|
+
- **NEW FEATURE**: Added `//restore` directive to restore context to a previous checkpoint
|
11
|
+
- **NEW FEATURE**: Enhanced `//context` (and `//review`) directive to display checkpoint markers in conversation history
|
12
|
+
- **NEW FEATURE**: Added `//cp` alias for checkpoint directive
|
13
|
+
|
14
|
+
#### Improvements
|
15
|
+
- **ENHANCEMENT**: Context manager now tracks checkpoint positions for better context visualization
|
16
|
+
- **ENHANCEMENT**: Checkpoint system uses auto-incrementing integer names when no name is provided
|
17
|
+
- **ENHANCEMENT**: Restore directive defaults to last checkpoint when no name specified
|
18
|
+
- **ENHANCEMENT**: Clear context now also clears all checkpoints
|
19
|
+
|
20
|
+
#### Bug Fixes
|
21
|
+
- **BUG FIX**: Fixed `//help` directive that was showing empty list of directives
|
22
|
+
- **BUG FIX**: Help directive now displays all directives from all registered modules
|
23
|
+
- **BUG FIX**: Help directive now shows proper descriptions and aliases for all directives
|
24
|
+
- **BUG FIX**: Help directive organizes directives by category for better readability
|
25
|
+
|
26
|
+
#### Technical Changes
|
27
|
+
- Enhanced ContextManager with checkpoint storage and restoration capabilities
|
28
|
+
- Added checkpoint_positions method to track checkpoint locations in context
|
29
|
+
- Refactored help directive to collect directives from all registered modules
|
30
|
+
- Added comprehensive test coverage for checkpoint and restore functionality
|
31
|
+
|
32
|
+
### [0.9.13] 2025-09-02
|
33
|
+
#### New Features
|
34
|
+
- **NEW FEATURE**: Added `--metrics` flag to show token counts for each model
|
35
|
+
- **NEW FEATURE**: Added `--cost` flag to enable cost estimation for each model
|
36
|
+
|
37
|
+
#### Improvements
|
38
|
+
- **DEPENDENCY**: Removed versionaire dependency, simplifying version management
|
39
|
+
- **ENHANCEMENT**: Improved test suite reliability and coverage
|
40
|
+
- **ENHANCEMENT**: Updated Gemfile.lock with latest dependency versions
|
41
|
+
|
42
|
+
#### Bug Fixes
|
43
|
+
- **BUG FIX**: Fixed version handling issues by removing external versioning dependency
|
44
|
+
|
45
|
+
#### Technical Changes
|
46
|
+
- Simplified version management by removing versionaire gem
|
47
|
+
- Enhanced test suite with improved assertions and coverage
|
48
|
+
- Updated various gem dependencies to latest stable versions
|
49
|
+
|
6
50
|
### [0.9.12] 2025-08-28
|
7
51
|
|
8
52
|
#### New Features
|
data/README.md
CHANGED
@@ -334,7 +334,9 @@ 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` |
|
339
341
|
| `//shell` | Execute shell commands | `//shell ls -la` |
|
340
342
|
| `//robot` | Show the pet robot ASCII art w/versions | `//robot` |
|
@@ -346,7 +348,7 @@ Directives are special commands in prompt files that begin with `//` and provide
|
|
346
348
|
| `//model` | Show current model configuration | `//model` |
|
347
349
|
| `//available_models` | List available models | `//available_models` |
|
348
350
|
| `//tools` | Show a list of available tools and their description | `//tools` |
|
349
|
-
| `//review` | Review current context | `//review` |
|
351
|
+
| `//review` | Review current context with checkpoint markers | `//review` |
|
350
352
|
|
351
353
|
Directives can also be used in the interactive chat sessions.
|
352
354
|
|
@@ -379,6 +381,64 @@ Your prompt content here...
|
|
379
381
|
Analyze the above information and provide insights.
|
380
382
|
```
|
381
383
|
|
384
|
+
#### Context Management with Checkpoints
|
385
|
+
|
386
|
+
AIA provides powerful context management capabilities in chat mode through checkpoint and restore directives:
|
387
|
+
|
388
|
+
```bash
|
389
|
+
# Create a checkpoint with automatic naming (1, 2, 3...)
|
390
|
+
//checkpoint
|
391
|
+
|
392
|
+
# Create a named checkpoint
|
393
|
+
//checkpoint important_decision
|
394
|
+
|
395
|
+
# Restore to the last checkpoint
|
396
|
+
//restore
|
397
|
+
|
398
|
+
# Restore to a specific checkpoint
|
399
|
+
//restore important_decision
|
400
|
+
|
401
|
+
# View context with checkpoint markers
|
402
|
+
//context
|
403
|
+
```
|
404
|
+
|
405
|
+
**Example Chat Session:**
|
406
|
+
```
|
407
|
+
You: Tell me about Ruby programming
|
408
|
+
AI: Ruby is a dynamic programming language...
|
409
|
+
|
410
|
+
You: //checkpoint ruby_basics
|
411
|
+
|
412
|
+
You: Now explain object-oriented programming
|
413
|
+
AI: Object-oriented programming (OOP) is...
|
414
|
+
|
415
|
+
You: //checkpoint oop_concepts
|
416
|
+
|
417
|
+
You: Actually, let's go back to Ruby basics
|
418
|
+
You: //restore ruby_basics
|
419
|
+
|
420
|
+
You: //context
|
421
|
+
=== Chat Context ===
|
422
|
+
Total messages: 4
|
423
|
+
Checkpoints: ruby_basics, oop_concepts
|
424
|
+
|
425
|
+
1. [System]: You are a helpful assistant
|
426
|
+
2. [User]: Tell me about Ruby programming
|
427
|
+
3. [Assistant]: Ruby is a dynamic programming language...
|
428
|
+
|
429
|
+
📍 [Checkpoint: ruby_basics]
|
430
|
+
----------------------------------------
|
431
|
+
4. [User]: Now explain object-oriented programming
|
432
|
+
=== End of Context ===
|
433
|
+
```
|
434
|
+
|
435
|
+
**Key Features:**
|
436
|
+
- **Auto-naming**: Checkpoints without names use incrementing integers (1, 2, 3...)
|
437
|
+
- **Named checkpoints**: Use meaningful names like `//checkpoint before_refactor`
|
438
|
+
- **Default restore**: `//restore` without a name restores to the last checkpoint
|
439
|
+
- **Context visualization**: `//context` shows checkpoint markers in conversation history
|
440
|
+
- **Clean slate**: `//clear` removes all context and checkpoints
|
441
|
+
|
382
442
|
#### Custom Directive Examples
|
383
443
|
|
384
444
|
You can extend AIA with custom directives by creating Ruby files that define new directive methods:
|
@@ -271,21 +271,93 @@ Inserts a fun ASCII robot character for visual breaks in prompts.
|
|
271
271
|
|
272
272
|
## Context Management Directives
|
273
273
|
|
274
|
+
### `//checkpoint`
|
275
|
+
Create a named checkpoint of the current conversation context.
|
276
|
+
|
277
|
+
**Syntax**: `//checkpoint [name]`
|
278
|
+
|
279
|
+
**Examples**:
|
280
|
+
```markdown
|
281
|
+
//checkpoint # Auto-named checkpoint (1, 2, 3...)
|
282
|
+
//checkpoint important_decision # Named checkpoint
|
283
|
+
//checkpoint before_refactor # Descriptive name
|
284
|
+
```
|
285
|
+
|
286
|
+
**Features**:
|
287
|
+
- **Auto-naming**: If no name provided, uses incrementing integers (1, 2, 3...)
|
288
|
+
- **Named checkpoints**: Use meaningful names for easy identification
|
289
|
+
- **Deep copying**: Safely stores complete conversation state
|
290
|
+
- **Chat mode only**: Only available during interactive chat sessions
|
291
|
+
|
292
|
+
**Usage**:
|
293
|
+
- `//checkpoint` - Create an auto-named checkpoint
|
294
|
+
- `//checkpoint name` - Create a checkpoint with specific name
|
295
|
+
|
296
|
+
**Aliases**: `//cp`
|
297
|
+
|
298
|
+
### `//restore`
|
299
|
+
Restore conversation context to a previously saved checkpoint.
|
300
|
+
|
301
|
+
**Syntax**: `//restore [name]`
|
302
|
+
|
303
|
+
**Examples**:
|
304
|
+
```markdown
|
305
|
+
//restore # Restore to last checkpoint
|
306
|
+
//restore important_decision # Restore to named checkpoint
|
307
|
+
//restore 1 # Restore to auto-named checkpoint
|
308
|
+
```
|
309
|
+
|
310
|
+
**Features**:
|
311
|
+
- **Default behavior**: Without a name, restores to the most recent checkpoint
|
312
|
+
- **Named restoration**: Restore to any previously saved checkpoint
|
313
|
+
- **Context truncation**: Removes all messages added after the checkpoint
|
314
|
+
- **Client refresh**: Automatically refreshes AI client context
|
315
|
+
|
316
|
+
**Usage**:
|
317
|
+
- `//restore` - Restore to the last checkpoint created
|
318
|
+
- `//restore name` - Restore to a specific named checkpoint
|
319
|
+
- Returns error message if checkpoint doesn't exist
|
320
|
+
|
274
321
|
### `//clear`
|
275
322
|
Clear conversation context in chat mode.
|
276
323
|
|
277
324
|
**Syntax**: `//clear`
|
278
325
|
|
279
|
-
**Usage**: Only available during chat sessions. Clears the conversation history while keeping the session active.
|
326
|
+
**Usage**: Only available during chat sessions. Clears the conversation history and all checkpoints while keeping the session active.
|
280
327
|
|
281
328
|
### `//review`
|
282
|
-
Display current conversation context.
|
329
|
+
Display current conversation context with checkpoint markers.
|
283
330
|
|
284
331
|
**Syntax**: `//review`
|
285
332
|
|
286
333
|
**Aliases**: `//context`
|
287
334
|
|
288
|
-
|
335
|
+
**Example Output**:
|
336
|
+
```
|
337
|
+
=== Chat Context ===
|
338
|
+
Total messages: 5
|
339
|
+
Checkpoints: ruby_basics, oop_concepts
|
340
|
+
|
341
|
+
1. [System]: You are a helpful assistant
|
342
|
+
2. [User]: Tell me about Ruby programming
|
343
|
+
3. [Assistant]: Ruby is a dynamic programming language...
|
344
|
+
|
345
|
+
📍 [Checkpoint: ruby_basics]
|
346
|
+
----------------------------------------
|
347
|
+
4. [User]: Now explain object-oriented programming
|
348
|
+
5. [Assistant]: Object-oriented programming (OOP) is...
|
349
|
+
|
350
|
+
📍 [Checkpoint: oop_concepts]
|
351
|
+
----------------------------------------
|
352
|
+
=== End of Context ===
|
353
|
+
```
|
354
|
+
|
355
|
+
**Features**:
|
356
|
+
- Shows complete conversation history with message numbers
|
357
|
+
- Displays checkpoint markers (📍) at their exact positions
|
358
|
+
- Lists all available checkpoints
|
359
|
+
- Truncates long messages for readability (200 characters)
|
360
|
+
- Shows total message count and checkpoint summary
|
289
361
|
|
290
362
|
## Model and Information Directives
|
291
363
|
|
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
|
|
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.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dewayne VanHoozer
|
@@ -433,7 +433,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
433
433
|
- !ruby/object:Gem::Version
|
434
434
|
version: '0'
|
435
435
|
requirements: []
|
436
|
-
rubygems_version: 3.
|
436
|
+
rubygems_version: 3.6.9
|
437
437
|
specification_version: 4
|
438
438
|
summary: Multi-model AI CLI with dynamic prompts, consensus responses, shell & Ruby
|
439
439
|
integration, and seamless chat workflows.
|