naisys 1.3.1 → 1.5.0
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.
- package/README.md +28 -5
- package/bin/genimg +3 -0
- package/bin/naisys +8 -5
- package/bin/trimsession +3 -0
- package/dist/command/commandHandler.js +37 -13
- package/dist/command/commandLoop.js +47 -16
- package/dist/command/promptBuilder.js +2 -1
- package/dist/command/shellCommand.js +26 -30
- package/dist/command/shellWrapper.js +76 -82
- package/dist/config.js +32 -16
- package/dist/features/genimg.js +99 -0
- package/dist/{apps → features}/llmail.js +72 -17
- package/dist/{apps → features}/llmynx.js +40 -14
- package/dist/features/subagent.js +223 -0
- package/dist/features/workspaces.js +50 -0
- package/dist/llm/contextManager.js +118 -77
- package/dist/llm/costTracker.js +30 -4
- package/dist/llm/dreamMaker.js +23 -15
- package/dist/llm/llModels.js +22 -4
- package/dist/llm/llmDtos.js +7 -0
- package/dist/llm/llmService.js +11 -13
- package/dist/llm/systemMessage.js +80 -0
- package/dist/utils/agentNames.js +62 -0
- package/dist/utils/dbUtils.js +7 -5
- package/dist/utils/logService.js +16 -21
- package/dist/utils/output.js +1 -0
- package/dist/utils/pathService.js +66 -0
- package/dist/utils/utilities.js +15 -22
- package/package.json +14 -14
package/README.md
CHANGED
|
@@ -73,7 +73,11 @@ dreamModel: claude3opus
|
|
|
73
73
|
|
|
74
74
|
# The model to use for llmynx, pre-processing websites to fit into a smaller context (use a cheaper model)
|
|
75
75
|
# defaults to the shellModel if omitted
|
|
76
|
-
webModel:
|
|
76
|
+
webModel: claude3haiku
|
|
77
|
+
|
|
78
|
+
# The model used by the 'genimg' command. If not defined then the genimg command is not available to the LLM
|
|
79
|
+
# Valid values: dalle2-256, dalle2-512, dalle2-1024, dalle3-1024, dalle3-1024-HD
|
|
80
|
+
imageModel: dalle3-1024
|
|
77
81
|
|
|
78
82
|
# A system like prompt explaining the agent's role and responsibilities
|
|
79
83
|
# You can use config variables in this string
|
|
@@ -108,6 +112,11 @@ spendLimitDollars: 2.00
|
|
|
108
112
|
# Auto: All commands are run through the separate LLM instace that will check to see if the command is safe
|
|
109
113
|
commandProtection: "none"
|
|
110
114
|
|
|
115
|
+
# The max number of subagents allowed to be started and managed. Leave out to disable.
|
|
116
|
+
# Costs by the subagent are applied to the host agent's spend limit
|
|
117
|
+
# Careful: Sub-agents can be chatty, slowing down progress.
|
|
118
|
+
subagentMax: 0
|
|
119
|
+
|
|
111
120
|
# Run these commands on session start, in the example below the agent will see how to use mail and a list of other agents
|
|
112
121
|
initialCommands:
|
|
113
122
|
- llmail users
|
|
@@ -161,10 +170,12 @@ initialCommands:
|
|
|
161
170
|
- `comment "<note>"` - The LLM is directed to use this for 'thinking out loud' which avoids 'invalid command' errors
|
|
162
171
|
- `endsession "<note>"` - Clear the context and start a new session.
|
|
163
172
|
- The LLM is directed to track it's context size and to end the session with a note before running over the context limit
|
|
164
|
-
- `pause <seconds>` - Can be used by the debug agent or the LLM to pause execution
|
|
173
|
+
- `pause <seconds>` - Can be used by the debug agent or the LLM to pause execution for a set number of seconds
|
|
165
174
|
- NAISYS apps
|
|
166
175
|
- `llmail` - A context friendly 'mail system' used for agent to agent communication
|
|
167
176
|
- `llmynx` - A context friendly wrapping on the lynx browser that can use a separate LLM to reduce the size of a large webpage into something that can fit into the LLM's context
|
|
177
|
+
- `genimg "<description>" <filepath>` - Generates an image with the given description, save at the specified fully qualified path
|
|
178
|
+
- `subagent` - A way for LLMs to start/stop their own sub-agents. Communicating with each other with `llmail`. Set the `subagentMax` in the agent config to enable.
|
|
168
179
|
|
|
169
180
|
## Running NAISYS from Source
|
|
170
181
|
|
|
@@ -185,6 +196,18 @@ initialCommands:
|
|
|
185
196
|
- Install WSL (Windows Subsystem for Linux)
|
|
186
197
|
- The `NAISYS_FOLDER` and `WEBSITE_FOLDER` should be set to the WSL path
|
|
187
198
|
- So `C:\var\naisys` should be `/mnt/c/var/naisys` in the `.env` file
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
199
|
+
|
|
200
|
+
#### Using NAISYS for a website
|
|
201
|
+
|
|
202
|
+
- Many frameworks come with their own dev server
|
|
203
|
+
- PHP for example can start a server with `php -S localhost:8000 -d display_errors=On -d error_reporting=E_ALL`
|
|
204
|
+
- Start the server and put the URL in the `.env` file
|
|
205
|
+
|
|
206
|
+
## Changelog
|
|
207
|
+
|
|
208
|
+
- 1.5: Allow agents to start their own parallel `subagents`
|
|
209
|
+
- 1.4: `genimg` command for generating images
|
|
210
|
+
- 1.3: Post-session 'dreaming' as well as a mail 'blackout' period
|
|
211
|
+
- 1.2: Created stand-in shell commands for custom Naisys commands
|
|
212
|
+
- 1.1: Added command protection settings to prevent unwanted writes
|
|
213
|
+
- 1.0: Initial release
|
package/bin/genimg
ADDED
package/bin/naisys
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
|
|
3
|
-
# Make sure to enable this script for execution with `chmod +x
|
|
3
|
+
# Make sure to enable this script for execution with `chmod +x naisys`
|
|
4
|
+
|
|
5
|
+
# Resolves the location of naisys from the bin directory
|
|
6
|
+
SCRIPT=$(readlink -f "$0" || echo "$0")
|
|
7
|
+
SCRIPT_DIR=$(dirname "$SCRIPT")/..
|
|
4
8
|
|
|
5
9
|
# Check if an argument is provided
|
|
6
10
|
if [ $# -eq 0 ]; then
|
|
11
|
+
# get version from package.json
|
|
12
|
+
VERSION=$(node -e "console.log(require('${SCRIPT_DIR}/package.json').version)")
|
|
7
13
|
echo "NAISYS: Node.js Autonomous Intelligence System"
|
|
14
|
+
echo " Version: $VERSION"
|
|
8
15
|
echo " Usage: naisys <path to agent config yaml, or directory>"
|
|
9
16
|
echo " Note: If a folder is passed then all agents will be started in a tmux session"
|
|
10
17
|
exit 1
|
|
11
18
|
fi
|
|
12
19
|
|
|
13
|
-
# Resolves the location of naisys from the bin directory
|
|
14
|
-
SCRIPT=$(readlink -f "$0" || echo "$0")
|
|
15
|
-
SCRIPT_DIR=$(dirname "$SCRIPT")/..
|
|
16
|
-
|
|
17
20
|
# if path is a yaml file then start a single agent
|
|
18
21
|
if [ -f "$1" ]; then
|
|
19
22
|
if [[ "$1" == *".yaml" ]]; then
|
package/bin/trimsession
ADDED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
-
import * as llmail from "../apps/llmail.js";
|
|
3
|
-
import * as llmynx from "../apps/llmynx.js";
|
|
4
2
|
import * as config from "../config.js";
|
|
3
|
+
import * as genimg from "../features/genimg.js";
|
|
4
|
+
import * as llmail from "../features/llmail.js";
|
|
5
|
+
import * as llmynx from "../features/llmynx.js";
|
|
6
|
+
import * as subagent from "../features/subagent.js";
|
|
5
7
|
import * as contextManager from "../llm/contextManager.js";
|
|
6
|
-
import { ContentSource } from "../llm/contextManager.js";
|
|
7
8
|
import * as costTracker from "../llm/costTracker.js";
|
|
8
9
|
import * as dreamMaker from "../llm/dreamMaker.js";
|
|
10
|
+
import { ContentSource } from "../llm/llmDtos.js";
|
|
9
11
|
import * as inputMode from "../utils/inputMode.js";
|
|
10
12
|
import { InputMode } from "../utils/inputMode.js";
|
|
11
13
|
import * as output from "../utils/output.js";
|
|
@@ -64,7 +66,18 @@ export async function processCommand(prompt, consoleInput) {
|
|
|
64
66
|
await contextManager.append("Comment noted. Try running commands now to achieve your goal.");
|
|
65
67
|
break;
|
|
66
68
|
}
|
|
69
|
+
case "trimsession": {
|
|
70
|
+
if (!config.trimSessionEnabled) {
|
|
71
|
+
throw 'The "trimsession" command is not enabled in this environment.';
|
|
72
|
+
}
|
|
73
|
+
const trimSummary = contextManager.trim(cmdArgs);
|
|
74
|
+
await contextManager.append(trimSummary);
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
67
77
|
case "endsession": {
|
|
78
|
+
if (!config.endSessionEnabled) {
|
|
79
|
+
throw 'The "trimsession" command is not enabled in this environment.';
|
|
80
|
+
}
|
|
68
81
|
// Don't need to check end line as this is the last command in the context, just read to the end
|
|
69
82
|
const endSessionNotes = utilities.trimChars(cmdArgs, '"');
|
|
70
83
|
if (!endSessionNotes) {
|
|
@@ -104,8 +117,7 @@ export async function processCommand(prompt, consoleInput) {
|
|
|
104
117
|
};
|
|
105
118
|
}
|
|
106
119
|
case "cost": {
|
|
107
|
-
|
|
108
|
-
output.comment(`Total cost so far $${totalCost.toFixed(2)} of $${config.agent.spendLimitDollars} limit`);
|
|
120
|
+
await costTracker.printCosts();
|
|
109
121
|
break;
|
|
110
122
|
}
|
|
111
123
|
case "llmynx": {
|
|
@@ -125,16 +137,24 @@ export async function processCommand(prompt, consoleInput) {
|
|
|
125
137
|
}
|
|
126
138
|
break;
|
|
127
139
|
}
|
|
140
|
+
case "genimg": {
|
|
141
|
+
const genimgResponse = await genimg.handleCommand(cmdArgs);
|
|
142
|
+
await contextManager.append(genimgResponse);
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
128
145
|
case "context":
|
|
129
|
-
|
|
146
|
+
output.comment("#####################");
|
|
147
|
+
output.comment(contextManager.printContext());
|
|
148
|
+
output.comment("#####################");
|
|
149
|
+
break;
|
|
150
|
+
case "subagent": {
|
|
151
|
+
const subagentResponse = await subagent.handleCommand(cmdArgs);
|
|
152
|
+
await contextManager.append(subagentResponse);
|
|
130
153
|
break;
|
|
154
|
+
}
|
|
131
155
|
default: {
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
await output.errorAndLog(`Error detected processing shell command:`);
|
|
135
|
-
processNextLLMpromptBlock = false;
|
|
136
|
-
}
|
|
137
|
-
nextCommandAction = shellResponse.terminate
|
|
156
|
+
const exitApp = await shellCommand.handleCommand(input);
|
|
157
|
+
nextCommandAction = exitApp
|
|
138
158
|
? NextCommandAction.ExitApplication
|
|
139
159
|
: NextCommandAction.Continue;
|
|
140
160
|
}
|
|
@@ -199,7 +219,11 @@ async function splitMultipleInputCommands(nextInput) {
|
|
|
199
219
|
}
|
|
200
220
|
}
|
|
201
221
|
// If the LLM forgets the quote on the comment, treat it as a single line comment
|
|
202
|
-
|
|
222
|
+
// Not something we want to use for multi-line commands like llmail and subagent
|
|
223
|
+
else if (newLinePos > 0 &&
|
|
224
|
+
(nextInput.startsWith("comment ") ||
|
|
225
|
+
nextInput.startsWith("genimg ") ||
|
|
226
|
+
nextInput.startsWith("trimsession "))) {
|
|
203
227
|
input = nextInput.slice(0, newLinePos);
|
|
204
228
|
nextInput = nextInput.slice(newLinePos).trim();
|
|
205
229
|
}
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import * as readline from "readline";
|
|
3
|
-
import * as llmail from "../apps/llmail.js";
|
|
4
|
-
import * as llmynx from "../apps/llmynx.js";
|
|
5
3
|
import * as config from "../config.js";
|
|
4
|
+
import * as llmail from "../features/llmail.js";
|
|
5
|
+
import * as llmynx from "../features/llmynx.js";
|
|
6
|
+
import * as subagent from "../features/subagent.js";
|
|
7
|
+
import * as workspaces from "../features/workspaces.js";
|
|
6
8
|
import * as contextManager from "../llm/contextManager.js";
|
|
7
|
-
import { ContentSource } from "../llm/contextManager.js";
|
|
8
9
|
import * as dreamMaker from "../llm/dreamMaker.js";
|
|
9
|
-
import { LlmRole } from "../llm/llmDtos.js";
|
|
10
|
+
import { ContentSource, LlmRole } from "../llm/llmDtos.js";
|
|
10
11
|
import * as llmService from "../llm/llmService.js";
|
|
12
|
+
import { systemMessage } from "../llm/systemMessage.js";
|
|
11
13
|
import * as inputMode from "../utils/inputMode.js";
|
|
12
14
|
import { InputMode } from "../utils/inputMode.js";
|
|
13
15
|
import * as logService from "../utils/logService.js";
|
|
14
16
|
import * as output from "../utils/output.js";
|
|
17
|
+
import { OutputColor } from "../utils/output.js";
|
|
15
18
|
import * as utilities from "../utils/utilities.js";
|
|
16
19
|
import * as commandHandler from "./commandHandler.js";
|
|
17
20
|
import { NextCommandAction } from "./commandHandler.js";
|
|
@@ -22,7 +25,6 @@ export async function run() {
|
|
|
22
25
|
await output.commentAndLog(`Agent configured to use ${config.agent.shellModel} model`);
|
|
23
26
|
// Show System Message
|
|
24
27
|
await output.commentAndLog("System Message:");
|
|
25
|
-
const systemMessage = contextManager.getSystemMessage();
|
|
26
28
|
output.write(systemMessage);
|
|
27
29
|
await logService.write({
|
|
28
30
|
role: LlmRole.System,
|
|
@@ -31,6 +33,7 @@ export async function run() {
|
|
|
31
33
|
});
|
|
32
34
|
let nextCommandAction = NextCommandAction.Continue;
|
|
33
35
|
let llmErrorCount = 0;
|
|
36
|
+
let nextPromptIndex = 0;
|
|
34
37
|
while (nextCommandAction != NextCommandAction.ExitApplication) {
|
|
35
38
|
inputMode.toggle(InputMode.LLM);
|
|
36
39
|
await output.commentAndLog("Starting Context:");
|
|
@@ -40,30 +43,34 @@ export async function run() {
|
|
|
40
43
|
await contextManager.append(latestDream);
|
|
41
44
|
}
|
|
42
45
|
for (const initialCommand of config.agent.initialCommands) {
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
let prompt = await promptBuilder.getPrompt(0, false);
|
|
47
|
+
prompt = setPromptIndex(prompt, ++nextPromptIndex);
|
|
48
|
+
await contextManager.append(prompt, ContentSource.ConsolePrompt, nextPromptIndex);
|
|
45
49
|
await commandHandler.processCommand(prompt, config.resolveConfigVars(initialCommand));
|
|
46
50
|
}
|
|
47
51
|
inputMode.toggle(InputMode.Debug);
|
|
48
52
|
let pauseSeconds = config.agent.debugPauseSeconds;
|
|
49
53
|
let wakeOnMessage = config.agent.wakeOnMessage;
|
|
50
54
|
while (nextCommandAction == NextCommandAction.Continue) {
|
|
51
|
-
|
|
55
|
+
let prompt = await promptBuilder.getPrompt(pauseSeconds, wakeOnMessage);
|
|
52
56
|
let consoleInput = "";
|
|
53
57
|
// Debug command prompt
|
|
54
58
|
if (inputMode.current === InputMode.Debug) {
|
|
59
|
+
subagent.unreadContextSummary();
|
|
55
60
|
consoleInput = await promptBuilder.getInput(`${prompt}`, pauseSeconds, wakeOnMessage);
|
|
56
61
|
}
|
|
57
62
|
// LLM command prompt
|
|
58
63
|
else if (inputMode.current === InputMode.LLM) {
|
|
64
|
+
prompt = setPromptIndex(prompt, ++nextPromptIndex);
|
|
59
65
|
const workingMsg = prompt +
|
|
60
|
-
chalk[
|
|
66
|
+
chalk[OutputColor.loading](`LLM (${config.agent.shellModel}) Working...`);
|
|
61
67
|
try {
|
|
62
68
|
await checkNewMailNotification();
|
|
63
69
|
await checkContextLimitWarning();
|
|
64
|
-
await
|
|
70
|
+
await workspaces.displayActive();
|
|
71
|
+
await contextManager.append(prompt, ContentSource.ConsolePrompt, nextPromptIndex);
|
|
65
72
|
process.stdout.write(workingMsg);
|
|
66
|
-
consoleInput = await llmService.query(config.agent.shellModel, contextManager.
|
|
73
|
+
consoleInput = await llmService.query(config.agent.shellModel, systemMessage, contextManager.getCombinedMessages(), "console");
|
|
67
74
|
clearPromptMessage(workingMsg);
|
|
68
75
|
}
|
|
69
76
|
catch (e) {
|
|
@@ -101,6 +108,7 @@ export async function run() {
|
|
|
101
108
|
llmynx.clear();
|
|
102
109
|
contextManager.clear();
|
|
103
110
|
nextCommandAction = NextCommandAction.Continue;
|
|
111
|
+
nextPromptIndex = 0;
|
|
104
112
|
}
|
|
105
113
|
}
|
|
106
114
|
}
|
|
@@ -178,7 +186,7 @@ async function checkNewMailNotification() {
|
|
|
178
186
|
for (const unreadThread of unreadThreads) {
|
|
179
187
|
await llmail.markAsRead(unreadThread.threadId);
|
|
180
188
|
}
|
|
181
|
-
mailBlackoutCountdown = config.mailBlackoutCycles;
|
|
189
|
+
mailBlackoutCountdown = config.agent.mailBlackoutCycles || 0;
|
|
182
190
|
}
|
|
183
191
|
else if (llmail.simpleMode) {
|
|
184
192
|
await contextManager.append(`You have new mail, but not enough context to read them.\n` +
|
|
@@ -196,11 +204,34 @@ async function checkContextLimitWarning() {
|
|
|
196
204
|
const tokenCount = contextManager.getTokenCount();
|
|
197
205
|
const tokenMax = config.agent.tokenMax;
|
|
198
206
|
if (tokenCount > tokenMax) {
|
|
199
|
-
|
|
200
|
-
|
|
207
|
+
let tokenNote = "";
|
|
208
|
+
if (config.endSessionEnabled) {
|
|
209
|
+
tokenNote += `\nUse 'endsession <note>' to clear the console and reset the session.
|
|
201
210
|
The note should help you find your bearings in the next session.
|
|
202
|
-
The note should contain your next goal, and important things should you remember
|
|
203
|
-
|
|
211
|
+
The note should contain your next goal, and important things should you remember.`;
|
|
212
|
+
}
|
|
213
|
+
if (config.trimSessionEnabled) {
|
|
214
|
+
tokenNote += `\nUse 'trimsession' to reduce the size of the session.
|
|
215
|
+
Use comments to remember important things from trimmed prompts.`;
|
|
216
|
+
}
|
|
217
|
+
await contextManager.append(`The token limit for this session has been exceeded.${tokenNote}`, ContentSource.Console);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/** Insert prompt index [Index: 1] before the $.
|
|
221
|
+
* Insert at the end of the prompt so that 'prompt splitting' still works in the command handler
|
|
222
|
+
*/
|
|
223
|
+
function setPromptIndex(prompt, index) {
|
|
224
|
+
if (!config.trimSessionEnabled) {
|
|
225
|
+
return prompt;
|
|
226
|
+
}
|
|
227
|
+
let newPrompt = prompt;
|
|
228
|
+
const endPromptPos = prompt.lastIndexOf("$");
|
|
229
|
+
if (endPromptPos != -1) {
|
|
230
|
+
newPrompt =
|
|
231
|
+
prompt.slice(0, endPromptPos) +
|
|
232
|
+
` [Index: ${index}]` +
|
|
233
|
+
prompt.slice(endPromptPos);
|
|
204
234
|
}
|
|
235
|
+
return newPrompt;
|
|
205
236
|
}
|
|
206
237
|
//# sourceMappingURL=commandLoop.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import * as events from "events";
|
|
3
3
|
import * as readline from "readline";
|
|
4
|
-
import * as llmail from "../apps/llmail.js";
|
|
5
4
|
import * as config from "../config.js";
|
|
5
|
+
import * as llmail from "../features/llmail.js";
|
|
6
6
|
import * as contextManager from "../llm/contextManager.js";
|
|
7
7
|
import * as inputMode from "../utils/inputMode.js";
|
|
8
8
|
import { InputMode } from "../utils/inputMode.js";
|
|
@@ -17,6 +17,7 @@ const _outputEmitter = new events.EventEmitter();
|
|
|
17
17
|
const _originalWrite = process.stdout.write.bind(process.stdout);
|
|
18
18
|
process.stdout.write = (...args) => {
|
|
19
19
|
_outputEmitter.emit(_writeEventName, false, ...args);
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
21
|
return _originalWrite.apply(process.stdout, args);
|
|
21
22
|
};
|
|
22
23
|
const _readlineInterface = readline.createInterface({
|
|
@@ -6,49 +6,45 @@ import * as utilities from "../utils/utilities.js";
|
|
|
6
6
|
import * as shellWrapper from "./shellWrapper.js";
|
|
7
7
|
export async function handleCommand(input) {
|
|
8
8
|
const cmdParams = input.split(" ");
|
|
9
|
-
const response = {
|
|
10
|
-
hasErrors: true,
|
|
11
|
-
};
|
|
12
9
|
// Route user to context friendly edit commands that can read/write the entire file in one go
|
|
13
10
|
// Having EOF in quotes is important as it prevents the shell from replacing $variables with bash values
|
|
14
11
|
if (["nano", "vi", "vim"].includes(cmdParams[0])) {
|
|
15
|
-
|
|
16
|
-
return response;
|
|
12
|
+
throw `${cmdParams[0]} not supported. Use \`cat\` to read a file and \`cat > filename << 'EOF'\` to write a file`;
|
|
17
13
|
}
|
|
18
14
|
if (cmdParams[0] == "lynx" && cmdParams[1] != "--dump") {
|
|
19
|
-
|
|
20
|
-
return response;
|
|
15
|
+
throw `Interactive mode with lynx is not supported. Use --dump with lynx to view a website`;
|
|
21
16
|
}
|
|
22
17
|
if (cmdParams[0] == "exit") {
|
|
23
18
|
if (inputMode.current == InputMode.LLM) {
|
|
24
|
-
|
|
19
|
+
throw "Use 'endsession' to end the session and clear the console log.";
|
|
25
20
|
}
|
|
21
|
+
// Only the debug user is allowed to exit the shell
|
|
26
22
|
else if (inputMode.current == InputMode.Debug) {
|
|
27
23
|
await shellWrapper.terminate();
|
|
28
|
-
|
|
24
|
+
return true;
|
|
29
25
|
}
|
|
30
|
-
return response;
|
|
31
26
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
27
|
+
let response = await shellWrapper.executeCommand(input);
|
|
28
|
+
let outputLimitExceeded = false;
|
|
29
|
+
const tokenCount = utilities.getTokenCount(response);
|
|
30
|
+
// Prevent too much output from blowing up the context
|
|
31
|
+
if (tokenCount > config.shellCommand.outputTokenMax) {
|
|
32
|
+
outputLimitExceeded = true;
|
|
33
|
+
const trimLength = (response.length * config.shellCommand.outputTokenMax) / tokenCount;
|
|
34
|
+
response =
|
|
35
|
+
response.slice(0, trimLength / 2) +
|
|
36
|
+
"\n\n...\n\n" +
|
|
37
|
+
response.slice(-trimLength / 2);
|
|
38
|
+
}
|
|
39
|
+
if (outputLimitExceeded) {
|
|
40
|
+
response += `\nThe shell command generated too much output (${tokenCount} tokens). Only 2,000 tokens worth are shown above.`;
|
|
41
|
+
}
|
|
42
|
+
if (response.endsWith(": command not found")) {
|
|
43
|
+
response +=
|
|
44
|
+
"Please enter a valid Linux or NAISYS command after the prompt. Use the 'comment' command for thoughts.";
|
|
50
45
|
}
|
|
51
|
-
|
|
52
|
-
|
|
46
|
+
// todo move this into the command handler to remove the context manager dependency
|
|
47
|
+
await contextManager.append(response);
|
|
48
|
+
return false;
|
|
53
49
|
}
|
|
54
50
|
//# sourceMappingURL=shellCommand.js.map
|