naisys 1.0.1

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 (48) hide show
  1. package/.env.example +15 -0
  2. package/LICENSE.md +7 -0
  3. package/README.md +125 -0
  4. package/agents/example.yaml +34 -0
  5. package/dist/__tests__/utils/output.test.js +22 -0
  6. package/dist/__tests__/utils/output.test.js.map +1 -0
  7. package/dist/__tests__/utils/utilities.test.js +42 -0
  8. package/dist/__tests__/utils/utilities.test.js.map +1 -0
  9. package/dist/apps/llmail.js +350 -0
  10. package/dist/apps/llmail.js.map +1 -0
  11. package/dist/apps/llmynx.js +229 -0
  12. package/dist/apps/llmynx.js.map +1 -0
  13. package/dist/command/commandHandler.js +151 -0
  14. package/dist/command/commandHandler.js.map +1 -0
  15. package/dist/command/commandLoop.js +176 -0
  16. package/dist/command/commandLoop.js.map +1 -0
  17. package/dist/command/promptBuilder.js +133 -0
  18. package/dist/command/promptBuilder.js.map +1 -0
  19. package/dist/command/shellCommand.js +36 -0
  20. package/dist/command/shellCommand.js.map +1 -0
  21. package/dist/command/shellWrapper.js +179 -0
  22. package/dist/command/shellWrapper.js.map +1 -0
  23. package/dist/config.js +46 -0
  24. package/dist/config.js.map +1 -0
  25. package/dist/llm/contextManager.js +127 -0
  26. package/dist/llm/contextManager.js.map +1 -0
  27. package/dist/llm/costTracker.js +43 -0
  28. package/dist/llm/costTracker.js.map +1 -0
  29. package/dist/llm/llModels.js +52 -0
  30. package/dist/llm/llModels.js.map +1 -0
  31. package/dist/llm/llmDtos.js +8 -0
  32. package/dist/llm/llmDtos.js.map +1 -0
  33. package/dist/llm/llmService.js +113 -0
  34. package/dist/llm/llmService.js.map +1 -0
  35. package/dist/naisys.js +7 -0
  36. package/dist/naisys.js.map +1 -0
  37. package/dist/utils/dbUtils.js +37 -0
  38. package/dist/utils/dbUtils.js.map +1 -0
  39. package/dist/utils/inputMode.js +18 -0
  40. package/dist/utils/inputMode.js.map +1 -0
  41. package/dist/utils/logService.js +116 -0
  42. package/dist/utils/logService.js.map +1 -0
  43. package/dist/utils/output.js +38 -0
  44. package/dist/utils/output.js.map +1 -0
  45. package/dist/utils/utilities.js +40 -0
  46. package/dist/utils/utilities.js.map +1 -0
  47. package/naisys.sh +56 -0
  48. package/package.json +70 -0
@@ -0,0 +1,229 @@
1
+ import { exec } from "child_process";
2
+ import * as os from "os";
3
+ import * as config from "../config.js";
4
+ import { getLLModel } from "../llm/llModels.js";
5
+ import { LlmRole } from "../llm/llmDtos.js";
6
+ import * as llmService from "../llm/llmService.js";
7
+ import * as output from "../utils/output.js";
8
+ import * as utilities from "../utils/utilities.js";
9
+ // A bad play on words, but this is like lynx but for LLMs..
10
+ let debugMode = false;
11
+ /** Links numbers are unique in the context so that `llmynx follow <linknum>` can be called on all previous output */
12
+ const _globalLinkMap = new Map();
13
+ const _globalUrlMap = new Map();
14
+ let _nextGlobalLinkNum = 1;
15
+ export async function handleCommand(cmdArgs) {
16
+ outputInDebugMode("LLMYNX DEBUG MODE IS ON");
17
+ const argParams = cmdArgs.split(" ");
18
+ const defualtTokenMax = config.tokenMax / 8;
19
+ if (!argParams[0]) {
20
+ argParams[0] = "help";
21
+ }
22
+ switch (argParams[0]) {
23
+ case "help":
24
+ return `llmynx <command> (results will be reduced to around ${defualtTokenMax})
25
+ search <query>: Search google for the given query
26
+ open <url>: Opens the given url. Links are represented as numbers in brackets which prefix the word they are linking like [123]
27
+ follow <link number>: Opens the given link number. Link numbers work across all previous outputs
28
+ links <url> <page>: Lists only the links for the given url. Use the page number to get more links`;
29
+ case "search": {
30
+ const query = argParams.slice(1).join(" ");
31
+ return await loadUrl("https://www.google.com/search?q=" + encodeURIComponent(query), config.tokenMax / 2, // Prevent form being reduced as google results are usually short anyways and we want to maintainq the links
32
+ true, true);
33
+ }
34
+ case "open": {
35
+ const url = argParams[1];
36
+ const isNumber = !isNaN(parseInt(argParams[2]));
37
+ const tokenMax = isNumber ? parseInt(argParams[2]) : defualtTokenMax;
38
+ return await loadUrl(url, tokenMax, false, true);
39
+ }
40
+ case "follow": {
41
+ const linkNum = parseInt(argParams[1]);
42
+ const isNumber = !isNaN(parseInt(argParams[2]));
43
+ const tokenMax = isNumber ? parseInt(argParams[2]) : defualtTokenMax;
44
+ const linkUrl = _globalLinkMap.get(linkNum);
45
+ if (!linkUrl) {
46
+ return "Link number not found";
47
+ }
48
+ return await loadUrl(linkUrl, tokenMax, true, false);
49
+ }
50
+ case "links": {
51
+ const url = argParams[1];
52
+ const isNumber = !isNaN(parseInt(argParams[2]));
53
+ const pageNumber = isNumber ? parseInt(argParams[2]) : 1;
54
+ return await loadUrl(url, 600, false, false, pageNumber);
55
+ }
56
+ // Secret command to toggle debug mode
57
+ case "debug":
58
+ debugMode = !debugMode;
59
+ return "Debug mode toggled " + (debugMode ? "on" : "off");
60
+ default:
61
+ return "Unknown llmynx command: " + argParams[0];
62
+ }
63
+ }
64
+ async function loadUrl(url, tokenMax, showUrl, showFollowHint, linkPageAsContent) {
65
+ let content = await runLynx(url);
66
+ let links = "";
67
+ // Reverse find 'References: ' and cut everything after it from the content
68
+ const refPos = content.lastIndexOf("References\n");
69
+ if (refPos > 0) {
70
+ links = content.slice(refPos);
71
+ content = content.slice(0, refPos);
72
+ }
73
+ if (linkPageAsContent) {
74
+ content = links;
75
+ }
76
+ // Get the token size of the output
77
+ const contentTokenSize = utilities.getTokenCount(content);
78
+ const linksTokenSize = utilities.getTokenCount(links);
79
+ outputInDebugMode(`Content Token size: ${contentTokenSize}\n` +
80
+ `Links Token size: ${linksTokenSize}`);
81
+ // Reduce content using LLM if it's over the token max
82
+ if (contentTokenSize > tokenMax) {
83
+ const model = getLLModel(config.agent.webModel);
84
+ // For example if context is 16k, and max tokens is 2k, 3k with 1.5x overrun
85
+ // That would be 3k for the current compressed content, 10k for the chunk, and 3k for the output
86
+ let tokenChunkSize = model.maxTokens - tokenMax * 2 * 1.5;
87
+ if (linkPageAsContent) {
88
+ tokenChunkSize = tokenMax;
89
+ }
90
+ outputInDebugMode(`Token max chunk size: ${tokenChunkSize}`);
91
+ const pieceCount = Math.ceil(contentTokenSize / tokenChunkSize);
92
+ const pieceSize = content.length / pieceCount;
93
+ let reducedOutput = "";
94
+ for (let i = 0; i < pieceCount; i++) {
95
+ const startPos = i * pieceSize;
96
+ const pieceStr = content.substring(startPos, startPos + pieceSize);
97
+ if (linkPageAsContent) {
98
+ if (linkPageAsContent === i + 1) {
99
+ return formatLinkPiece(pieceStr);
100
+ }
101
+ continue;
102
+ }
103
+ output.comment(`Processing Piece ${i + 1} of ${pieceCount}...`);
104
+ outputInDebugMode(` Reduced output tokens: ${utilities.getTokenCount(reducedOutput)}\n` +
105
+ ` Current Piece tokens: ${utilities.getTokenCount(pieceStr)}`);
106
+ reducedOutput = await llmReduce(url, reducedOutput, i + 1, pieceCount, pieceStr, tokenMax);
107
+ }
108
+ if (linkPageAsContent) {
109
+ return "";
110
+ }
111
+ content = reducedOutput;
112
+ const finalTokenSize = utilities.getTokenCount(reducedOutput);
113
+ output.comment(`Content reduced from ${contentTokenSize} to ${finalTokenSize} tokens`);
114
+ }
115
+ else {
116
+ output.comment(`Content is already under ${tokenMax} tokens.`);
117
+ }
118
+ // Prefix content with url if following as otherwise the url is never shown
119
+ if (showUrl) {
120
+ content = `URL: ${url}\n\n` + content;
121
+ }
122
+ if (showFollowHint) {
123
+ content +=
124
+ "\n\nLinks are in brackets. Use `llmynx follow <link number>` to follow a link.";
125
+ }
126
+ return storeMapSetLinks(content, links);
127
+ }
128
+ async function runLynx(url) {
129
+ return new Promise((resolve) => {
130
+ // Option here to output the content and links separately, might be useful in future
131
+ // mode == RunMode.Content ? "-nolist" : "-listonly";
132
+ const modeParams = "";
133
+ const ifWindows = os.platform() === "win32" ? "wsl " : "";
134
+ exec(`${ifWindows}lynx -dump ${modeParams} "${url}"`, (error, stdout, stderr) => {
135
+ if (error) {
136
+ resolve(`error: ${error.message}`);
137
+ return;
138
+ }
139
+ if (stderr) {
140
+ resolve(`stderr: ${stderr}`);
141
+ return;
142
+ }
143
+ resolve(stdout);
144
+ });
145
+ });
146
+ }
147
+ async function llmReduce(url, reducedOutput, pieceNumber, pieceTotal, pieceStr, tokenMax) {
148
+ const systemMessage = `You will be iteratively fed the web page ${url} broken into ${pieceTotal} sequential equally sized pieces.
149
+ Each piece should be reduced into the final content in order to maintain the meaning of the page while reducing verbosity and duplication.
150
+ The final output should be around ${tokenMax} tokens.
151
+ Don't remove links which are represented as numbers in brackets which prefix the word they are linking like [123].
152
+ Try to prioritize content of substance over advertising content.`;
153
+ const content = `Web page piece ${pieceNumber} of ${pieceTotal}:
154
+ ${pieceStr}
155
+
156
+ Current reduced content:
157
+ ${reducedOutput}
158
+
159
+ Please merge the new piece into the existing reduced content above while keeping the result to around ${tokenMax} tokens.
160
+
161
+ Merged reduced content:
162
+ `;
163
+ const context = {
164
+ role: LlmRole.User,
165
+ content,
166
+ };
167
+ return await llmService.query(config.agent.webModel, systemMessage, [context], "llmynx");
168
+ }
169
+ function outputInDebugMode(msg) {
170
+ if (debugMode) {
171
+ output.comment(msg);
172
+ }
173
+ }
174
+ function storeMapSetLinks(content, links) {
175
+ // Parse out links into a map link number -> url
176
+ const linkMap = new Map();
177
+ const linkLines = links.split("\n");
178
+ for (const linkLine of linkLines) {
179
+ const dotPos = linkLine.indexOf(".");
180
+ if (dotPos < 0) {
181
+ continue;
182
+ }
183
+ const linkNum = parseInt(linkLine.substring(0, dotPos));
184
+ const url = linkLine.substring(dotPos + 1).trim();
185
+ linkMap.set(linkNum, url);
186
+ }
187
+ // Replace local link numbers with global link numbers
188
+ return content.replace(/\[(\d+)\]/g, (match, linkStr) => {
189
+ const localLinkNum = parseInt(linkStr);
190
+ const url = linkMap.get(localLinkNum);
191
+ const globalLinkNum = registerUrl(url);
192
+ return `[${globalLinkNum}]`;
193
+ });
194
+ }
195
+ export function clear() {
196
+ _globalLinkMap.clear();
197
+ _globalUrlMap.clear();
198
+ _nextGlobalLinkNum = 1;
199
+ }
200
+ function registerUrl(url) {
201
+ let globalLinkNum = _globalUrlMap.get(url);
202
+ if (!globalLinkNum) {
203
+ globalLinkNum = _nextGlobalLinkNum;
204
+ _nextGlobalLinkNum++;
205
+ _globalLinkMap.set(globalLinkNum, url);
206
+ _globalUrlMap.set(url, globalLinkNum);
207
+ }
208
+ return globalLinkNum;
209
+ }
210
+ function formatLinkPiece(pieceStr) {
211
+ const alreadySeen = new Set();
212
+ const linkLines = pieceStr.split("\n");
213
+ let links = "";
214
+ for (const linkLine of linkLines) {
215
+ const dotPos = linkLine.indexOf(".");
216
+ if (dotPos < 0) {
217
+ continue;
218
+ }
219
+ const url = linkLine.substring(dotPos + 1).trim();
220
+ if (alreadySeen.has(url)) {
221
+ continue;
222
+ }
223
+ alreadySeen.add(url);
224
+ const globalLinkNum = registerUrl(url);
225
+ links += `[${globalLinkNum}]${url}\n`;
226
+ }
227
+ return links;
228
+ }
229
+ //# sourceMappingURL=llmynx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llmynx.js","sourceRoot":"","sources":["../../src/apps/llmynx.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,151 @@
1
+ import chalk from "chalk";
2
+ import * as llmail from "../apps/llmail.js";
3
+ import * as llmynx from "../apps/llmynx.js";
4
+ import * as config from "../config.js";
5
+ import * as contextManager from "../llm/contextManager.js";
6
+ import { ContentSource } from "../llm/contextManager.js";
7
+ import * as costTracker from "../llm/costTracker.js";
8
+ import * as inputMode from "../utils/inputMode.js";
9
+ import { InputMode } from "../utils/inputMode.js";
10
+ import * as logService from "../utils/logService.js";
11
+ import * as output from "../utils/output.js";
12
+ import { OutputColor } from "../utils/output.js";
13
+ import * as promptBuilder from "./promptBuilder.js";
14
+ import * as shellCommand from "./shellCommand.js";
15
+ export var NextCommandAction;
16
+ (function (NextCommandAction) {
17
+ NextCommandAction[NextCommandAction["Continue"] = 0] = "Continue";
18
+ NextCommandAction[NextCommandAction["EndSession"] = 1] = "EndSession";
19
+ NextCommandAction[NextCommandAction["ExitApplication"] = 2] = "ExitApplication";
20
+ })(NextCommandAction || (NextCommandAction = {}));
21
+ export let previousSessionNotes = await logService.getPreviousEndSessionNote();
22
+ export async function consoleInput(prompt, consoleInput) {
23
+ // We process the lines one at a time so we can support multiple commands with line breaks
24
+ let firstLine = true;
25
+ let processNextLLMpromptBlock = true;
26
+ const userHostPrompt = promptBuilder.getUserHostPrompt();
27
+ let nextCommandAction = NextCommandAction.Continue;
28
+ let nextInput = consoleInput.trim();
29
+ while (processNextLLMpromptBlock && nextInput) {
30
+ let input = "";
31
+ // if the prompt exists in the input, save if for the next run
32
+ const nextPromptPos = nextInput.indexOf(userHostPrompt);
33
+ if (nextPromptPos == 0) {
34
+ const pathPrompt = await promptBuilder.getUserHostPathPrompt();
35
+ // check working directory is the same
36
+ if (nextInput.startsWith(pathPrompt)) {
37
+ // slice nextInput after $
38
+ const endPrompt = nextInput.indexOf("$", pathPrompt.length);
39
+ nextInput = nextInput.slice(endPrompt + 1).trim();
40
+ continue;
41
+ }
42
+ // else prompt did not match, stop processing input
43
+ else {
44
+ break;
45
+ }
46
+ }
47
+ // we can't validate that the working directory in the prompt is good until the commands are processed
48
+ else if (nextPromptPos > 0) {
49
+ input = nextInput.slice(0, nextPromptPos);
50
+ nextInput = nextInput.slice(nextPromptPos).trim();
51
+ }
52
+ else {
53
+ input = nextInput;
54
+ nextInput = "";
55
+ }
56
+ if (!input.trim()) {
57
+ break;
58
+ }
59
+ // first line is special because we want to append the output to the context without a line break
60
+ if (inputMode.current == InputMode.LLM) {
61
+ if (firstLine) {
62
+ firstLine = false;
63
+ await contextManager.append(input, ContentSource.LlmPromptResponse);
64
+ output.write(prompt + chalk[OutputColor.llm](input));
65
+ }
66
+ else {
67
+ await output.commentAndLog("Optimistically continuing with the next command...");
68
+ await contextManager.append(input, ContentSource.LlmPromptResponse);
69
+ }
70
+ }
71
+ const cmdParams = input.split(" ");
72
+ const cmdArgs = input.slice(cmdParams[0].length).trim();
73
+ switch (cmdParams[0]) {
74
+ case "comment": {
75
+ await contextManager.append("Comment noted. Try running commands now to achieve your goal.");
76
+ // There may be additional commands after the comment, try to slice it out after the new line and continue
77
+ const nextNewLine = input.indexOf("\n");
78
+ nextInput = nextNewLine > 0 ? input.slice(nextNewLine).trim() : "";
79
+ break;
80
+ }
81
+ case "endsession": {
82
+ previousSessionNotes = cmdArgs;
83
+ await output.commentAndLog("------------------------------------------------------");
84
+ nextCommandAction = NextCommandAction.EndSession;
85
+ processNextLLMpromptBlock = false;
86
+ break;
87
+ }
88
+ // Hidden for now as the LLM will use this instead of llmail
89
+ case "talk": {
90
+ const talkMsg = cmdArgs;
91
+ if (inputMode.current === InputMode.LLM) {
92
+ await contextManager.append("Message sent!");
93
+ }
94
+ else if (inputMode.current === InputMode.Debug) {
95
+ inputMode.toggle(InputMode.LLM);
96
+ await contextManager.append(`Message from admin@${config.hostname}: ${talkMsg}`);
97
+ inputMode.toggle(InputMode.Debug);
98
+ }
99
+ break;
100
+ }
101
+ // With no argument, in debug mode, pause will pause forever,
102
+ // in LLM mode it will pause until a message is receieved (don't want the llm to hang itself)
103
+ // The setting only lasts for the next command, next loop it uses the agent default
104
+ case "pause": {
105
+ return {
106
+ nextCommandAction: NextCommandAction.Continue,
107
+ pauseSeconds: cmdArgs ? parseInt(cmdArgs) : 0,
108
+ wakeOnMessage: inputMode.current === InputMode.LLM,
109
+ };
110
+ }
111
+ case "cost": {
112
+ const totalCost = await costTracker.getTotalCosts();
113
+ output.comment(`Total cost so far $${totalCost.toFixed(2)} of $${config.agent.spendLimitDollars} limit`);
114
+ break;
115
+ }
116
+ case "llmynx": {
117
+ const llmynxResponse = await llmynx.handleCommand(cmdArgs);
118
+ await contextManager.append(llmynxResponse);
119
+ break;
120
+ }
121
+ case "llmail": {
122
+ const mailResponse = await llmail.handleCommand(cmdArgs);
123
+ await contextManager.append(mailResponse);
124
+ break;
125
+ }
126
+ case "context":
127
+ contextManager.printContext();
128
+ break;
129
+ default: {
130
+ const shellResponse = await shellCommand.handleCommand(input);
131
+ if (shellResponse.hasErrors && nextInput) {
132
+ await output.errorAndLog(`Error detected processing shell command:`);
133
+ processNextLLMpromptBlock = false;
134
+ }
135
+ nextCommandAction = shellResponse.terminate
136
+ ? NextCommandAction.ExitApplication
137
+ : NextCommandAction.Continue;
138
+ }
139
+ }
140
+ }
141
+ // display unprocessed lines to aid in debugging
142
+ if (nextInput.trim()) {
143
+ await output.errorAndLog(`Unprocessed LLM response:\n${nextInput}`);
144
+ }
145
+ return {
146
+ nextCommandAction,
147
+ pauseSeconds: config.agent.debugPauseSeconds,
148
+ wakeOnMessage: config.agent.wakeOnMessage,
149
+ };
150
+ }
151
+ //# sourceMappingURL=commandHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commandHandler.js","sourceRoot":"","sources":["../../src/command/commandHandler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,176 @@
1
+ import chalk from "chalk";
2
+ import * as readline from "readline";
3
+ import * as llmail from "../apps/llmail.js";
4
+ import * as llmynx from "../apps/llmynx.js";
5
+ import * as config from "../config.js";
6
+ import * as contextManager from "../llm/contextManager.js";
7
+ import { ContentSource } from "../llm/contextManager.js";
8
+ import { LlmRole } from "../llm/llmDtos.js";
9
+ import * as llmService from "../llm/llmService.js";
10
+ import * as inputMode from "../utils/inputMode.js";
11
+ import { InputMode } from "../utils/inputMode.js";
12
+ import * as logService from "../utils/logService.js";
13
+ import * as output from "../utils/output.js";
14
+ import * as utilities from "../utils/utilities.js";
15
+ import * as commandHandler from "./commandHandler.js";
16
+ import { NextCommandAction } from "./commandHandler.js";
17
+ import * as promptBuilder from "./promptBuilder.js";
18
+ const maxErrorCount = 5;
19
+ export async function run() {
20
+ // Show Agent Config exept the agent prompt
21
+ await output.commentAndLog(`Agent configured to use ${config.agent.consoleModel} model`);
22
+ // Show System Message
23
+ await output.commentAndLog("System Message:");
24
+ const systemMessage = contextManager.getSystemMessage();
25
+ output.write(systemMessage);
26
+ await logService.write({
27
+ role: LlmRole.System,
28
+ content: systemMessage,
29
+ type: "system",
30
+ });
31
+ let nextCommandAction = NextCommandAction.Continue;
32
+ let llmErrorCount = 0;
33
+ while (nextCommandAction != NextCommandAction.ExitApplication) {
34
+ inputMode.toggle(InputMode.LLM);
35
+ await output.commentAndLog("Starting Context:");
36
+ await contextManager.append("Previous Session Note:");
37
+ await contextManager.append(commandHandler.previousSessionNotes || "None");
38
+ await commandHandler.consoleInput(await promptBuilder.getPrompt(), "llmail help");
39
+ await commandHandler.consoleInput(await promptBuilder.getPrompt(), "llmail users");
40
+ inputMode.toggle(InputMode.Debug);
41
+ let pauseSeconds = config.agent.debugPauseSeconds;
42
+ let wakeOnMessage = config.agent.wakeOnMessage;
43
+ while (nextCommandAction == NextCommandAction.Continue) {
44
+ const prompt = await promptBuilder.getPrompt(pauseSeconds, wakeOnMessage);
45
+ let input = "";
46
+ // Debug command prompt
47
+ if (inputMode.current === InputMode.Debug) {
48
+ input = await promptBuilder.getInput(`${prompt}`, pauseSeconds, wakeOnMessage);
49
+ }
50
+ // LLM command prompt
51
+ else if (inputMode.current === InputMode.LLM) {
52
+ const workingMsg = prompt +
53
+ chalk[output.OutputColor.loading](`LLM (${config.agent.consoleModel}) Working...`);
54
+ try {
55
+ await displayNewMail();
56
+ await contextManager.append(prompt, ContentSource.ConsolePrompt);
57
+ process.stdout.write(workingMsg);
58
+ input = await llmService.query(config.agent.consoleModel, contextManager.getSystemMessage(), contextManager.messages, "console");
59
+ clearPromptMessage(workingMsg);
60
+ }
61
+ catch (e) {
62
+ // Can't do this in a finally because it needs to happen before the error is printed
63
+ clearPromptMessage(workingMsg);
64
+ ({ llmErrorCount, pauseSeconds, wakeOnMessage } =
65
+ await handleErrorAndSwitchToDebugMode(e, llmErrorCount, false));
66
+ continue;
67
+ }
68
+ }
69
+ else {
70
+ throw `Invalid input mode: ${inputMode.current}`;
71
+ }
72
+ // Run the command
73
+ try {
74
+ ({ nextCommandAction, pauseSeconds, wakeOnMessage } =
75
+ await commandHandler.consoleInput(prompt, input));
76
+ if (inputMode.current == InputMode.LLM) {
77
+ llmErrorCount = 0;
78
+ }
79
+ }
80
+ catch (e) {
81
+ ({ llmErrorCount, pauseSeconds, wakeOnMessage } =
82
+ await handleErrorAndSwitchToDebugMode(e, llmErrorCount, true));
83
+ continue;
84
+ }
85
+ // If the user is in debug mode and they didn't enter anything, switch to LLM
86
+ // If in LLM mode, auto switch back to debug
87
+ if ((inputMode.current == InputMode.Debug && !input) ||
88
+ inputMode.current == InputMode.LLM) {
89
+ inputMode.toggle();
90
+ }
91
+ }
92
+ if (nextCommandAction == NextCommandAction.EndSession) {
93
+ llmynx.clear();
94
+ contextManager.clear();
95
+ nextCommandAction = NextCommandAction.Continue;
96
+ }
97
+ }
98
+ }
99
+ function clearPromptMessage(waitingMessage) {
100
+ readline.moveCursor(process.stdout, -waitingMessage.length, 0);
101
+ process.stdout.write(" ".repeat(waitingMessage.length));
102
+ readline.moveCursor(process.stdout, -waitingMessage.length, 0);
103
+ }
104
+ /** Name is comically long because of a prettier formatting issue when the name is too short */
105
+ async function handleErrorAndSwitchToDebugMode(e, llmErrorCount, addToContext) {
106
+ const maxErrorLength = 200;
107
+ const errorMsg = `${e}`;
108
+ if (addToContext) {
109
+ await contextManager.append(errorMsg.slice(0, maxErrorLength));
110
+ if (errorMsg.length > maxErrorLength) {
111
+ await contextManager.append("...");
112
+ await output.errorAndLog(`Error too long for context: ${errorMsg.slice(200)}`);
113
+ }
114
+ }
115
+ else {
116
+ await output.errorAndLog(errorMsg);
117
+ }
118
+ // If llm is in some error loop then hold in debug mode
119
+ let pauseSeconds = config.agent.debugPauseSeconds;
120
+ let wakeOnMessage = config.agent.wakeOnMessage;
121
+ if (inputMode.current == InputMode.LLM) {
122
+ llmErrorCount++;
123
+ if (llmErrorCount >= maxErrorCount) {
124
+ pauseSeconds = 0;
125
+ wakeOnMessage = false;
126
+ if (llmErrorCount == maxErrorCount) {
127
+ await output.errorAndLog(`Too many LLM errors. Holding in debug mode.`);
128
+ }
129
+ }
130
+ }
131
+ inputMode.toggle(InputMode.Debug);
132
+ return {
133
+ llmErrorCount,
134
+ pauseSeconds,
135
+ wakeOnMessage,
136
+ };
137
+ }
138
+ async function displayNewMail() {
139
+ // Check for unread threads
140
+ const unreadThreads = await llmail.getUnreadThreads();
141
+ if (!unreadThreads.length) {
142
+ return;
143
+ }
144
+ // Get the new messages for each thread
145
+ const newMessages = [];
146
+ for (const { threadId, newMsgId } of unreadThreads) {
147
+ newMessages.push(await llmail.readThread(threadId, newMsgId, true));
148
+ }
149
+ // Check that token max for session will not be exceeded
150
+ const newMsgTokenCount = newMessages.reduce((acc, msg) => acc + utilities.getTokenCount(msg), 0);
151
+ const sessionTokens = contextManager.getTokenCount();
152
+ const tokenMax = config.tokenMax;
153
+ // Show full messages unless we are close to the token limit of the session
154
+ // or in simple mode, which means non-threaded messages
155
+ if (sessionTokens + newMsgTokenCount < tokenMax * 0.75) {
156
+ for (const newMessage of newMessages) {
157
+ await contextManager.append("New Message:", ContentSource.Console);
158
+ await contextManager.append(newMessage, ContentSource.Console);
159
+ }
160
+ for (const unreadThread of unreadThreads) {
161
+ await llmail.markAsRead(unreadThread.threadId);
162
+ }
163
+ }
164
+ else if (llmail.simpleMode) {
165
+ await contextManager.append(`You have new mail, but not enough context to read them.\n` +
166
+ `Finish up what you're doing. After you 'endsession' and the context resets, you will be able to read them.`, ContentSource.Console);
167
+ }
168
+ // LLM will in many cases end the session here, when the new session starts
169
+ // this code will run again, and show a full preview of the messages
170
+ else {
171
+ const threadIds = unreadThreads.map((t) => t.threadId).join(", ");
172
+ await contextManager.append(`New Messages on Thread ID ${threadIds}\n` +
173
+ `Use llmail read <id>' to read the thread, but be mindful you are close to the token limit for the session.`, ContentSource.Console);
174
+ }
175
+ }
176
+ //# sourceMappingURL=commandLoop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commandLoop.js","sourceRoot":"","sources":["../../src/command/commandLoop.ts"],"names":[],"mappings":"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"}