@tyvm/knowhow 0.0.55 → 0.0.56

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.
Files changed (93) hide show
  1. package/docs/input-queue-manager.md +142 -0
  2. package/docs/multi-worker-management.md +142 -0
  3. package/package.json +1 -1
  4. package/scripts/README.md +119 -0
  5. package/scripts/restore_keys.sh +59 -0
  6. package/scripts/unset_keys.sh +60 -0
  7. package/src/agents/tools/askHuman.ts +2 -0
  8. package/src/agents/tools/startAgentTask.ts +2 -2
  9. package/src/ai.ts +3 -1
  10. package/src/chat/CliChatService.ts +2 -2
  11. package/src/chat/modules/AgentModule.ts +25 -2
  12. package/src/chat-old.ts +2 -2
  13. package/src/cli.ts +56 -3
  14. package/src/clients/anthropic.ts +7 -5
  15. package/src/clients/knowhow.ts +2 -2
  16. package/src/index.ts +6 -6
  17. package/src/microphone.ts +12 -4
  18. package/src/services/DockerService.ts +473 -0
  19. package/src/services/KnowhowClient.ts +4 -1
  20. package/src/services/index.ts +5 -1
  21. package/src/types.ts +6 -0
  22. package/src/utils/InputQueueManager.ts +324 -0
  23. package/src/utils/index.ts +5 -152
  24. package/src/worker.ts +158 -9
  25. package/src/workerRegistry.ts +152 -0
  26. package/tests/clients/AIClient.test.ts +177 -92
  27. package/tests/manual/test-concurrent-ask.ts +43 -0
  28. package/tests/services/DockerService.test.ts +24 -0
  29. package/tests/unit/input-queue.test.ts +80 -0
  30. package/ts_build/package.json +1 -1
  31. package/ts_build/src/agents/tools/askHuman.d.ts +1 -1
  32. package/ts_build/src/agents/tools/askHuman.js.map +1 -1
  33. package/ts_build/src/agents/tools/startAgentTask.js +2 -1
  34. package/ts_build/src/agents/tools/startAgentTask.js.map +1 -1
  35. package/ts_build/src/ai.js +3 -1
  36. package/ts_build/src/ai.js.map +1 -1
  37. package/ts_build/src/chat/CliChatService.js +1 -1
  38. package/ts_build/src/chat/CliChatService.js.map +1 -1
  39. package/ts_build/src/chat/modules/AgentModule.js +11 -1
  40. package/ts_build/src/chat/modules/AgentModule.js.map +1 -1
  41. package/ts_build/src/chat-old.js +1 -1
  42. package/ts_build/src/chat-old.js.map +1 -1
  43. package/ts_build/src/cli.js +46 -3
  44. package/ts_build/src/cli.js.map +1 -1
  45. package/ts_build/src/clients/anthropic.js +7 -5
  46. package/ts_build/src/clients/anthropic.js.map +1 -1
  47. package/ts_build/src/clients/knowhow.js +1 -1
  48. package/ts_build/src/clients/knowhow.js.map +1 -1
  49. package/ts_build/src/dockerWorker.d.ts +22 -0
  50. package/ts_build/src/dockerWorker.js +210 -0
  51. package/ts_build/src/dockerWorker.js.map +1 -0
  52. package/ts_build/src/index.js +4 -4
  53. package/ts_build/src/index.js.map +1 -1
  54. package/ts_build/src/microphone.js +8 -3
  55. package/ts_build/src/microphone.js.map +1 -1
  56. package/ts_build/src/services/DockerService.d.ts +26 -0
  57. package/ts_build/src/services/DockerService.js +363 -0
  58. package/ts_build/src/services/DockerService.js.map +1 -0
  59. package/ts_build/src/services/KnowhowClient.d.ts +1 -1
  60. package/ts_build/src/services/KnowhowClient.js +1 -1
  61. package/ts_build/src/services/KnowhowClient.js.map +1 -1
  62. package/ts_build/src/services/index.d.ts +3 -0
  63. package/ts_build/src/services/index.js +4 -1
  64. package/ts_build/src/services/index.js.map +1 -1
  65. package/ts_build/src/types.d.ts +4 -0
  66. package/ts_build/src/types.js +3 -0
  67. package/ts_build/src/types.js.map +1 -1
  68. package/ts_build/src/utils/InputQueueManager.d.ts +19 -0
  69. package/ts_build/src/utils/InputQueueManager.js +234 -0
  70. package/ts_build/src/utils/InputQueueManager.js.map +1 -0
  71. package/ts_build/src/utils/index.d.ts +1 -3
  72. package/ts_build/src/utils/index.js +4 -114
  73. package/ts_build/src/utils/index.js.map +1 -1
  74. package/ts_build/src/worker-entrypoint.d.ts +2 -0
  75. package/ts_build/src/worker-entrypoint.js +39 -0
  76. package/ts_build/src/worker-entrypoint.js.map +1 -0
  77. package/ts_build/src/worker.d.ts +7 -1
  78. package/ts_build/src/worker.js +117 -9
  79. package/ts_build/src/worker.js.map +1 -1
  80. package/ts_build/src/workerRegistry.d.ts +11 -0
  81. package/ts_build/src/workerRegistry.js +143 -0
  82. package/ts_build/src/workerRegistry.js.map +1 -0
  83. package/ts_build/tests/clients/AIClient.test.js +88 -42
  84. package/ts_build/tests/clients/AIClient.test.js.map +1 -1
  85. package/ts_build/tests/manual/test-concurrent-ask.d.ts +1 -0
  86. package/ts_build/tests/manual/test-concurrent-ask.js +22 -0
  87. package/ts_build/tests/manual/test-concurrent-ask.js.map +1 -0
  88. package/ts_build/tests/services/DockerService.test.d.ts +1 -0
  89. package/ts_build/tests/services/DockerService.test.js +22 -0
  90. package/ts_build/tests/services/DockerService.test.js.map +1 -0
  91. package/ts_build/tests/unit/input-queue.test.d.ts +1 -0
  92. package/ts_build/tests/unit/input-queue.test.js +32 -0
  93. package/ts_build/tests/unit/input-queue.test.js.map +1 -0
@@ -0,0 +1,142 @@
1
+ # Input Queue Manager
2
+
3
+ ## Problem
4
+
5
+ When multiple `ask()` calls (used by `askHuman` tool and `ChatService.getInput`) are made concurrently before any resolve, each call would create its own readline interface listening to `process.stdin`. This caused input duplication - each character typed would be processed by multiple listeners, appearing doubled or tripled in the terminal.
6
+
7
+ ### Example Scenario
8
+
9
+ ```typescript
10
+ // Agent asks a question
11
+ const answer1 = ask("What is your name?");
12
+
13
+ // Before user responds, agent asks another question
14
+ const answer2 = ask("What is your age?");
15
+
16
+ // Problem: User sees both questions and typed characters appear multiple times
17
+ ```
18
+
19
+ ## Solution
20
+
21
+ Implemented a singleton `InputQueueManager` class that:
22
+
23
+ 1. **Queues all concurrent asks**: When multiple `ask()` calls happen, they're added to a queue
24
+ 2. **Maintains a single input stream**: Only one readline interface is active at a time
25
+ 3. **Updates the display**: When a new question is asked while waiting, the display updates to show the most recent question
26
+ 4. **Resolves all pending promises**: When the user presses Enter, all queued promises resolve with the same answer
27
+
28
+ ### Key Features
29
+
30
+ - **Single input stream**: Only one `process.stdin` listener is active at any time
31
+ - **Dynamic question updates**: The displayed question updates to the most recent one
32
+ - **Preserved user input**: When the question changes, the user's typed text is preserved
33
+ - **Cursor position maintained**: Cursor position is maintained relative to the typed text
34
+ - **Autocomplete support**: Tab completion uses options from the most recent question
35
+ - **History support**: Arrow key navigation uses history from the most recent question
36
+
37
+ ## Implementation Details
38
+
39
+ ```typescript
40
+ class InputQueueManager {
41
+ private queue: Array<{
42
+ question: string;
43
+ options: string[];
44
+ history: string[];
45
+ resolve: (value: string) => void;
46
+ }> = [];
47
+ private currentReadline: any = null;
48
+ private isProcessing = false;
49
+ private currentLine = "";
50
+ private cursorPos = 0;
51
+
52
+ async ask(question, options, history): Promise<string> {
53
+ return new Promise((resolve) => {
54
+ this.queue.push({ question, options, history, resolve });
55
+
56
+ if (!this.isProcessing) {
57
+ this.processNext();
58
+ } else {
59
+ this.updateDisplay(); // Update to show new question
60
+ }
61
+ });
62
+ }
63
+
64
+ private updateDisplay(): void {
65
+ // Clear line and show most recent question
66
+ const current = this.queue[this.queue.length - 1];
67
+ process.stdout.write('\r\x1b[K');
68
+ process.stdout.write(current.question + this.currentLine);
69
+ }
70
+
71
+ private async processNext(): Promise<void> {
72
+ // Process most recent question
73
+ const current = this.queue[this.queue.length - 1];
74
+
75
+ // Set up single readline interface
76
+ this.currentReadline = readline.createInterface({...});
77
+
78
+ // Handle input
79
+ process.stdin.on("data", dataHandler);
80
+ }
81
+
82
+ // On Enter press
83
+ private handleSubmit(answer: string): void {
84
+ // Resolve ALL pending promises with the same answer
85
+ while (this.queue.length > 0) {
86
+ const item = this.queue.shift();
87
+ item.resolve(answer);
88
+ }
89
+
90
+ // Clean up and process next if any
91
+ cleanup();
92
+ this.processNext();
93
+ }
94
+ }
95
+ ```
96
+
97
+ ## Usage
98
+
99
+ The `ask()` function now automatically uses the singleton queue:
100
+
101
+ ```typescript
102
+ import { ask } from "./utils";
103
+
104
+ // Multiple concurrent calls are now safe
105
+ const promise1 = ask("Question 1?");
106
+ const promise2 = ask("Question 2?"); // Display updates to this
107
+ const promise3 = ask("Question 3?"); // Display updates to this
108
+
109
+ // User types "answer" and presses Enter
110
+ // All three promises resolve with "answer"
111
+ const [a1, a2, a3] = await Promise.all([promise1, promise2, promise3]);
112
+ console.log(a1, a2, a3); // "answer", "answer", "answer"
113
+ ```
114
+
115
+ ## Testing
116
+
117
+ Run the manual test to verify the behavior:
118
+
119
+ ```bash
120
+ npx ts-node tests/manual/test-concurrent-ask.ts
121
+ ```
122
+
123
+ Expected behavior:
124
+ - You should see only the most recent question
125
+ - Typing should not duplicate characters
126
+ - Both promises resolve with the same answer
127
+
128
+ ## Benefits
129
+
130
+ 1. **No input duplication**: Characters appear once, as expected
131
+ 2. **Clean user experience**: User always sees the most relevant question
132
+ 3. **Backward compatible**: Existing code using `ask()` works without changes
133
+ 4. **Handles edge cases**: Properly cleans up resources and handles Ctrl+C
134
+ 5. **Maintains features**: Autocomplete, history, and cursor control all work correctly
135
+
136
+ ## Related Files
137
+
138
+ - `src/utils/index.ts` - Implementation of InputQueueManager
139
+ - `src/agents/tools/askHuman.ts` - Uses `ask()` via the queue
140
+ - `src/chat/CliChatService.ts` - Uses `ask()` via the queue
141
+ - `tests/unit/input-queue.test.ts` - Unit tests documenting behavior
142
+ - `tests/manual/test-concurrent-ask.ts` - Manual test to verify fix
@@ -0,0 +1,142 @@
1
+ # Multi-Worker Management
2
+
3
+ This feature allows you to manage and start multiple knowhow workers from different directories using a centralized registry.
4
+
5
+ ## Overview
6
+
7
+ The multi-worker management system provides:
8
+ - Registration of worker directories in a global config (`~/.knowhow/workers.json`)
9
+ - A single command to start all registered workers simultaneously
10
+ - Management commands to list, register, and unregister workers
11
+
12
+ ## Usage
13
+
14
+ ### Register a Worker
15
+
16
+ Navigate to a project directory and register it as a worker:
17
+
18
+ ```bash
19
+ cd /path/to/project1
20
+ knowhow worker --register
21
+ ```
22
+
23
+ This will:
24
+ 1. Register the current directory in `~/.knowhow/workers.json`
25
+ 2. Ensure the worker configuration is set up in the local `.knowhow/knowhow.json`
26
+
27
+ ### Start All Workers
28
+
29
+ Start all registered workers at once:
30
+
31
+ ```bash
32
+ knowhow workers
33
+ ```
34
+
35
+ This command will:
36
+ - Read all registered worker paths from the global config
37
+ - Start each worker by executing `knowhow worker` in its directory
38
+ - Keep all workers running until you press Ctrl+C
39
+ - Gracefully shut down all workers on exit
40
+
41
+ ### List Registered Workers
42
+
43
+ View all registered worker paths:
44
+
45
+ ```bash
46
+ knowhow workers --list
47
+ ```
48
+
49
+ Output example:
50
+ ```
51
+ Registered workers (3):
52
+ 1. /Users/username/project1
53
+ 2. /Users/username/project2
54
+ 3. /Users/username/project3
55
+ ```
56
+
57
+ ### Unregister a Worker
58
+
59
+ Remove a worker from the registry:
60
+
61
+ ```bash
62
+ knowhow workers --unregister /path/to/project
63
+ ```
64
+
65
+ ### Clear All Workers
66
+
67
+ Remove all registered workers:
68
+
69
+ ```bash
70
+ knowhow workers --clear
71
+ ```
72
+
73
+ ## Configuration
74
+
75
+ The worker registry is stored in:
76
+ ```
77
+ ~/.knowhow/workers.json
78
+ ```
79
+
80
+ Example format:
81
+ ```json
82
+ {
83
+ "workers": [
84
+ "/Users/username/project1",
85
+ "/Users/username/project2",
86
+ "/Users/username/project3"
87
+ ]
88
+ }
89
+ ```
90
+
91
+ ## Typical Workflow
92
+
93
+ 1. **Set up multiple projects as workers:**
94
+ ```bash
95
+ cd ~/project1
96
+ knowhow worker --register
97
+
98
+ cd ~/project2
99
+ knowhow worker --register
100
+
101
+ cd ~/project3
102
+ knowhow worker --register
103
+ ```
104
+
105
+ 2. **Start all workers:**
106
+ ```bash
107
+ knowhow workers
108
+ ```
109
+
110
+ 3. **Check worker status:**
111
+ ```bash
112
+ knowhow workers --list
113
+ ```
114
+
115
+ 4. **Stop all workers:**
116
+ Press `Ctrl+C` in the terminal where workers are running
117
+
118
+ ## Benefits
119
+
120
+ - **Centralized Management**: Manage multiple workers from a single command
121
+ - **Simplified Deployment**: No need to manually start workers in each directory
122
+ - **Persistent Configuration**: Worker registrations persist across sessions
123
+ - **Graceful Shutdown**: All workers shut down cleanly when stopped
124
+
125
+ ## Implementation Details
126
+
127
+ ### Files Created
128
+
129
+ - `src/workerRegistry.ts` - Core registry management functions
130
+ - `~/.knowhow/workers.json` - Global worker registry storage
131
+
132
+ ### CLI Commands Modified
133
+
134
+ - `knowhow worker` - Added `--register` flag to register current directory
135
+ - `knowhow workers` - New command with subcommands for management and starting workers
136
+
137
+ ### Process Management
138
+
139
+ - Each worker runs as a child process
140
+ - Workers inherit stdio from the parent process (you see all logs)
141
+ - SIGINT/SIGTERM signals are properly handled for graceful shutdown
142
+ - Workers are not detached, so they stop when the parent process stops
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tyvm/knowhow",
3
- "version": "0.0.55",
3
+ "version": "0.0.56",
4
4
  "description": "ai cli with plugins and agents",
5
5
  "main": "ts_build/src/index.js",
6
6
  "bin": {
@@ -0,0 +1,119 @@
1
+ # AI Keys Management Scripts
2
+
3
+ These bash scripts help you temporarily unset and restore AI API keys in your terminal session. This is useful for testing CLI behavior without authentication or when you want to work in a clean environment.
4
+
5
+ ## Installation
6
+
7
+ Add these functions to your `~/.bashrc` or `~/.zshrc`:
8
+
9
+ ```bash
10
+ # AI Keys Management
11
+ unset_keys() {
12
+ source /path/to/knowhow/scripts/unset_keys.sh
13
+ }
14
+
15
+ restore_keys() {
16
+ source /path/to/knowhow/scripts/restore_keys.sh
17
+ }
18
+ ```
19
+
20
+ Replace `/path/to/knowhow` with the actual path to your knowhow repository.
21
+
22
+ Then reload your shell:
23
+ ```bash
24
+ source ~/.bashrc # or source ~/.zshrc
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ ### Unset Keys
30
+
31
+ Temporarily remove AI API keys from your current shell session:
32
+
33
+ ```bash
34
+ unset_keys
35
+ ```
36
+
37
+ This will:
38
+ - Backup all your API keys to `BACKUP_*` environment variables
39
+ - Unset the following environment variables:
40
+ - `OPENAI_KEY`
41
+ - `OPENAI_API_KEY`
42
+ - `ANTHROPIC_API_KEY`
43
+ - `ANTHROPIC_KEY`
44
+ - `GEMINI_API_KEY`
45
+ - `GOOGLE_API_KEY`
46
+ - `XAI_API_KEY`
47
+
48
+ ### Restore Keys
49
+
50
+ Restore your API keys from the backup:
51
+
52
+ ```bash
53
+ restore_keys
54
+ ```
55
+
56
+ This will:
57
+ - Read the backup from `BACKUP_*` environment variables
58
+ - Restore all previously unset environment variables
59
+ - Clear the `BACKUP_*` environment variables
60
+
61
+ ## Example Workflow
62
+
63
+ ```bash
64
+ # Check that you have keys set
65
+ echo $OPENAI_KEY
66
+ # Output: sk-proj-...
67
+
68
+ # Unset the keys for testing
69
+ unset_keys
70
+ # Output: ✓ Successfully backed up and unset 5 API key(s)
71
+
72
+ # Verify keys are unset
73
+ echo $OPENAI_KEY
74
+ # Output: (empty)
75
+
76
+ # Test your CLI without keys
77
+ knowhow --help
78
+
79
+ # Restore your keys when done
80
+ restore_keys
81
+ # Output: ✓ Successfully restored 5 API key(s)
82
+
83
+ # Verify keys are restored
84
+ echo $OPENAI_KEY
85
+ # Output: sk-proj-...
86
+ ```
87
+
88
+ ## Notes
89
+
90
+ - These commands only affect the **current terminal session**
91
+ - The backup variables (`BACKUP_*`) are stored in the current shell session only
92
+ - If you close your terminal before running `restore_keys`, the backups are **lost** and you'll need to restart your terminal or re-source your shell configuration to get your keys back from your original bashrc/zshrc
93
+ - The scripts must be **sourced** (not executed) to affect your current shell environment
94
+
95
+ ## Troubleshooting
96
+
97
+ ### Keys lost after closing terminal
98
+
99
+ If you close your terminal after running `unset_keys`, the backup environment variables are lost. To restore your keys, simply open a new terminal (which will reload your bashrc/zshrc with the original key values) or run:
100
+
101
+ ```bash
102
+ source ~/.bashrc # or source ~/.zshrc
103
+ ```
104
+
105
+ ### Permission denied
106
+
107
+ Make sure the scripts are executable:
108
+
109
+ ```bash
110
+ chmod +x scripts/unset_keys.sh scripts/restore_keys.sh
111
+ ```
112
+
113
+ ### Commands not found
114
+
115
+ Make sure you've added the functions to your shell configuration and reloaded it:
116
+
117
+ ```bash
118
+ source ~/.bashrc # or source ~/.zshrc
119
+ ```
@@ -0,0 +1,59 @@
1
+ #!/bin/bash
2
+
3
+ # restore_keys - Restore AI API keys that were backed up by unset_keys
4
+ # Usage: source restore_keys.sh OR restore_keys (if added to bashrc)
5
+ #
6
+ # This script restores environment variables from BACKUP_* environment variables
7
+ # created by unset_keys
8
+
9
+ # Colors for output
10
+ RED='\033[0;31m'
11
+ GREEN='\033[0;32m'
12
+ YELLOW='\033[1;33m'
13
+ BLUE='\033[0;34m'
14
+ NC='\033[0m' # No Color
15
+
16
+ restore_keys() {
17
+ echo -e "${BLUE}Restoring AI API keys...${NC}"
18
+
19
+ # List of environment variables to restore
20
+ local keys=(
21
+ "OPENAI_KEY"
22
+ "OPENAI_API_KEY"
23
+ "ANTHROPIC_API_KEY"
24
+ "ANTHROPIC_KEY"
25
+ "GEMINI_API_KEY"
26
+ "GOOGLE_API_KEY"
27
+ "XAI_API_KEY"
28
+ )
29
+
30
+ local restored=0
31
+
32
+ # Restore each key from its BACKUP_* variable
33
+ for key in "${keys[@]}"; do
34
+ local backup_var="BACKUP_${key}"
35
+ if [ -n "${!backup_var}" ]; then
36
+ export "${key}=${!backup_var}"
37
+ unset "$backup_var"
38
+ restored=$((restored + 1))
39
+ fi
40
+ done
41
+
42
+ if [ $restored -eq 0 ]; then
43
+ echo -e "${YELLOW}No backed up keys found to restore${NC}"
44
+ echo -e "${YELLOW}Run 'unset_keys' first to create backups${NC}"
45
+ else
46
+ echo -e "${GREEN}✓ Successfully restored ${restored} API key(s)${NC}"
47
+ echo -e "${BLUE}BACKUP_* variables cleared${NC}"
48
+ fi
49
+ }
50
+
51
+ # If script is sourced, run the function
52
+ if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
53
+ restore_keys
54
+ else
55
+ echo -e "${RED}ERROR: This script must be sourced, not executed${NC}"
56
+ echo "Usage: source ${BASH_SOURCE[0]}"
57
+ echo "Or add to bashrc and run: restore_keys"
58
+ exit 1
59
+ fi
@@ -0,0 +1,60 @@
1
+ #!/bin/bash
2
+
3
+ # unset_keys - Temporarily unset AI API keys in current shell session
4
+ # Usage: source unset_keys.sh OR unset_keys (if added to bashrc)
5
+ #
6
+ # This script backs up your current AI API keys to BACKUP_* environment variables
7
+ # and then unsets the original keys, allowing you to test
8
+ # CLI behavior without authentication.
9
+
10
+ # Colors for output
11
+ RED='\033[0;31m'
12
+ GREEN='\033[0;32m'
13
+ YELLOW='\033[1;33m'
14
+ BLUE='\033[0;34m'
15
+ NC='\033[0m' # No Color
16
+
17
+ unset_keys() {
18
+ echo -e "${BLUE}Backing up AI API keys to BACKUP_* variables and unsetting originals...${NC}"
19
+
20
+ # List of environment variables to backup and unset
21
+ local keys=(
22
+ "OPENAI_KEY"
23
+ "OPENAI_API_KEY"
24
+ "ANTHROPIC_API_KEY"
25
+ "ANTHROPIC_KEY"
26
+ "GEMINI_API_KEY"
27
+ "GOOGLE_API_KEY"
28
+ "XAI_API_KEY"
29
+ )
30
+
31
+ local backed_up=0
32
+
33
+ # Backup and unset each key
34
+ for key in "${keys[@]}"; do
35
+ if [ -n "${!key}" ]; then
36
+ # Save the key value to BACKUP_* environment variable
37
+ export "BACKUP_${key}=${!key}"
38
+ unset "$key"
39
+ backed_up=$((backed_up + 1))
40
+ fi
41
+ done
42
+
43
+ if [ $backed_up -eq 0 ]; then
44
+ echo -e "${YELLOW}No AI keys found to unset${NC}"
45
+ else
46
+ echo -e "${GREEN}✓ Successfully backed up and unset ${backed_up} API key(s)${NC}"
47
+ echo -e "${BLUE}Keys backed up to BACKUP_* environment variables${NC}"
48
+ echo -e "${YELLOW}Run 'restore_keys' to restore them${NC}"
49
+ fi
50
+ }
51
+
52
+ # If script is sourced, run the function
53
+ if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
54
+ unset_keys
55
+ else
56
+ echo -e "${RED}ERROR: This script must be sourced, not executed${NC}"
57
+ echo "Usage: source ${BASH_SOURCE[0]}"
58
+ echo "Or add to bashrc and run: unset_keys"
59
+ exit 1
60
+ fi
@@ -1,6 +1,8 @@
1
1
  import Marked from "marked";
2
2
  import { ask } from "../../utils";
3
3
 
4
+ // Simple, CLI-agnostic implementation
5
+ // CLI-specific behavior is handled via ToolsService override in AgentModule
4
6
  export async function askHuman(question: string) {
5
7
  console.log("AI has asked: ");
6
8
  console.log(Marked.parse(question), "\n");
@@ -59,7 +59,8 @@ export async function startAgentTask(params: StartAgentTaskParams) {
59
59
  command += ` --max-spend-limit ${maxSpendLimit}`;
60
60
  }
61
61
 
62
- return execCommand(command, 60000, true);
62
+ const timeout = maxTimeLimit || 60000;
63
+ return execCommand(command, timeout, true);
63
64
  }
64
65
 
65
66
  export const startAgentTaskDefinition: Tool = {
@@ -106,4 +107,3 @@ export const startAgentTaskDefinition: Tool = {
106
107
  },
107
108
  },
108
109
  };
109
-
package/src/ai.ts CHANGED
@@ -73,7 +73,9 @@ export async function summarizeTexts(
73
73
 
74
74
  console.log(content);
75
75
 
76
- const summary = await singlePrompt(content, model, agent);
76
+ const summary = await singlePrompt(content, model, agent).catch((err) => {
77
+ return `Text of length ${text.length} could not be summarized due to error: ${err.message}`;
78
+ });
77
79
  summaries.push(summary);
78
80
  }
79
81
 
@@ -206,8 +206,8 @@ export class CliChatService implements ChatService {
206
206
  value = await editor({ message: prompt });
207
207
  this.context.multilineMode = false; // Disable after use like original
208
208
  } else {
209
- // Use saved input history for scrollback instead of current chat history
210
- const history = this.inputHistory.slice().reverse();
209
+ // Use saved input history for scrollback (InputQueueManager handles reverse access)
210
+ const history = this.inputHistory.slice();
211
211
  value = await ask(prompt, options, history);
212
212
  }
213
213
 
@@ -1,7 +1,10 @@
1
1
  /**
2
2
  * Agent Chat Module - Handles agent interactions
3
3
  */
4
- import { KnowhowSimpleClient } from "../../services/KnowhowClient";
4
+ import {
5
+ KnowhowSimpleClient,
6
+ KNOWHOW_API_URL,
7
+ } from "../../services/KnowhowClient";
5
8
  import * as fs from "fs";
6
9
  import * as path from "path";
7
10
 
@@ -641,7 +644,7 @@ ${reason}
641
644
  this.saveSession(taskId, taskInfo, []);
642
645
 
643
646
  // Create Knowhow chat task if messageId provided
644
- const baseUrl = process.env.KNOWHOW_API_URL;
647
+ const baseUrl = KNOWHOW_API_URL;
645
648
  console.log(
646
649
  `Base URL for Knowhow API: ${baseUrl}, Message ID: ${options.messageId}`
647
650
  );
@@ -706,6 +709,26 @@ ${reason}
706
709
 
707
710
  // Set up message processors like in original startAgent
708
711
 
712
+ // Register an override for askHuman to use CLI input method
713
+ // This keeps the askHuman tool CLI-agnostic while enabling CLI-specific behavior
714
+ // through the override system, achieving better separation of concerns
715
+ agent.tools.registerOverride(
716
+ "askHuman",
717
+ async (originalArgs: any[], originalTool: any) => {
718
+ const question = originalArgs[0];
719
+
720
+ // Use CLI-specific input method from CliChatService
721
+ const chatService = this.chatService;
722
+ if (!chatService) {
723
+ throw new Error("ChatService not available in tools context");
724
+ }
725
+ console.log("AI has asked: ");
726
+ console.log(Marked.parse(question), "\n");
727
+ return await chatService.getInput("response: ");
728
+ },
729
+ 10 // Priority level
730
+ );
731
+
709
732
  agent.messageProcessor.setProcessors("pre_call", [
710
733
  new ToolResponseCache(agent.tools).createProcessor(),
711
734
  new TokenCompressor(agent.tools).createProcessor((msg) =>
package/src/chat-old.ts CHANGED
@@ -152,7 +152,7 @@ export async function getInput(
152
152
  value = await editor({ message: question });
153
153
  Flags.disable(ChatFlags.multi);
154
154
  } else {
155
- const history = chatHistory.map((c) => c.input).reverse();
155
+ const history = chatHistory.map((c) => c.input);
156
156
  value = await ask(question, options, history);
157
157
  }
158
158
 
@@ -248,7 +248,7 @@ export async function chatLoop<E extends GptQuestionEmbedding>(
248
248
  provider = await ask(
249
249
  `\n\nCurrent Provider: ${provider}\nCurrent Model: ${model}\n\nWhich provider would you like to use: `,
250
250
  providers
251
- );
251
+ ) as keyof typeof Clients.clients;
252
252
  model =
253
253
  ChatModelDefaults[provider] ||
254
254
  (await Clients.getRegisteredModels(provider))[0];