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.
- package/.env.example +15 -0
- package/LICENSE.md +7 -0
- package/README.md +125 -0
- package/agents/example.yaml +34 -0
- package/dist/__tests__/utils/output.test.js +22 -0
- package/dist/__tests__/utils/output.test.js.map +1 -0
- package/dist/__tests__/utils/utilities.test.js +42 -0
- package/dist/__tests__/utils/utilities.test.js.map +1 -0
- package/dist/apps/llmail.js +350 -0
- package/dist/apps/llmail.js.map +1 -0
- package/dist/apps/llmynx.js +229 -0
- package/dist/apps/llmynx.js.map +1 -0
- package/dist/command/commandHandler.js +151 -0
- package/dist/command/commandHandler.js.map +1 -0
- package/dist/command/commandLoop.js +176 -0
- package/dist/command/commandLoop.js.map +1 -0
- package/dist/command/promptBuilder.js +133 -0
- package/dist/command/promptBuilder.js.map +1 -0
- package/dist/command/shellCommand.js +36 -0
- package/dist/command/shellCommand.js.map +1 -0
- package/dist/command/shellWrapper.js +179 -0
- package/dist/command/shellWrapper.js.map +1 -0
- package/dist/config.js +46 -0
- package/dist/config.js.map +1 -0
- package/dist/llm/contextManager.js +127 -0
- package/dist/llm/contextManager.js.map +1 -0
- package/dist/llm/costTracker.js +43 -0
- package/dist/llm/costTracker.js.map +1 -0
- package/dist/llm/llModels.js +52 -0
- package/dist/llm/llModels.js.map +1 -0
- package/dist/llm/llmDtos.js +8 -0
- package/dist/llm/llmDtos.js.map +1 -0
- package/dist/llm/llmService.js +113 -0
- package/dist/llm/llmService.js.map +1 -0
- package/dist/naisys.js +7 -0
- package/dist/naisys.js.map +1 -0
- package/dist/utils/dbUtils.js +37 -0
- package/dist/utils/dbUtils.js.map +1 -0
- package/dist/utils/inputMode.js +18 -0
- package/dist/utils/inputMode.js.map +1 -0
- package/dist/utils/logService.js +116 -0
- package/dist/utils/logService.js.map +1 -0
- package/dist/utils/output.js +38 -0
- package/dist/utils/output.js.map +1 -0
- package/dist/utils/utilities.js +40 -0
- package/dist/utils/utilities.js.map +1 -0
- package/naisys.sh +56 -0
- 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":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AACvC,OAAO,KAAK,cAAc,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,WAAW,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAC;AAElD,MAAM,CAAN,IAAY,iBAIX;AAJD,WAAY,iBAAiB;IAC3B,iEAAQ,CAAA;IACR,qEAAU,CAAA;IACV,+EAAe,CAAA;AACjB,CAAC,EAJW,iBAAiB,KAAjB,iBAAiB,QAI5B;AAQD,MAAM,CAAC,IAAI,oBAAoB,GAAG,MAAM,UAAU,CAAC,yBAAyB,EAAE,CAAC;AAE/E,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAc,EACd,YAAoB;IAEpB,0FAA0F;IAC1F,IAAI,SAAS,GAAG,IAAI,CAAC;IACrB,IAAI,yBAAyB,GAAG,IAAI,CAAC;IACrC,MAAM,cAAc,GAAG,aAAa,CAAC,iBAAiB,EAAE,CAAC;IAEzD,IAAI,iBAAiB,GAAG,iBAAiB,CAAC,QAAQ,CAAC;IAEnD,IAAI,SAAS,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC;IAEpC,OAAO,yBAAyB,IAAI,SAAS,EAAE,CAAC;QAC9C,IAAI,KAAK,GAAG,EAAE,CAAC;QAEf,8DAA8D;QAC9D,MAAM,aAAa,GAAG,SAAS,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAExD,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;YACvB,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,qBAAqB,EAAE,CAAC;YAE/D,sCAAsC;YACtC,IAAI,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBACrC,0BAA0B;gBAC1B,MAAM,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;gBAC5D,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBAClD,SAAS;YACX,CAAC;YACD,mDAAmD;iBAC9C,CAAC;gBACJ,MAAM;YACR,CAAC;QACH,CAAC;QACD,sGAAsG;aACjG,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;YAC3B,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;YAC1C,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,CAAC;QACpD,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,SAAS,CAAC;YAClB,SAAS,GAAG,EAAE,CAAC;QACjB,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YAClB,MAAM;QACR,CAAC;QAED,iGAAiG;QACjG,IAAI,SAAS,CAAC,OAAO,IAAI,SAAS,CAAC,GAAG,EAAE,CAAC;YACvC,IAAI,SAAS,EAAE,CAAC;gBACd,SAAS,GAAG,KAAK,CAAC;gBAClB,MAAM,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;gBACpE,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YACvD,CAAC;iBAAM,CAAC;gBACN,MAAM,MAAM,CAAC,aAAa,CACxB,oDAAoD,CACrD,CAAC;gBACF,MAAM,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAExD,QAAQ,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;YACrB,KAAK,SAAS,CAAC,CAAC,CAAC;gBACf,MAAM,cAAc,CAAC,MAAM,CACzB,+DAA+D,CAChE,CAAC;gBAEF,0GAA0G;gBAC1G,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACxC,SAAS,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAEnE,MAAM;YACR,CAAC;YACD,KAAK,YAAY,CAAC,CAAC,CAAC;gBAClB,oBAAoB,GAAG,OAAO,CAAC;gBAC/B,MAAM,MAAM,CAAC,aAAa,CACxB,wDAAwD,CACzD,CAAC;gBACF,iBAAiB,GAAG,iBAAiB,CAAC,UAAU,CAAC;gBACjD,yBAAyB,GAAG,KAAK,CAAC;gBAClC,MAAM;YACR,CAAC;YAED,4DAA4D;YAC5D,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,MAAM,OAAO,GAAG,OAAO,CAAC;gBAExB,IAAI,SAAS,CAAC,OAAO,KAAK,SAAS,CAAC,GAAG,EAAE,CAAC;oBACxC,MAAM,cAAc,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;gBAC/C,CAAC;qBAAM,IAAI,SAAS,CAAC,OAAO,KAAK,SAAS,CAAC,KAAK,EAAE,CAAC;oBACjD,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;oBAChC,MAAM,cAAc,CAAC,MAAM,CACzB,sBAAsB,MAAM,CAAC,QAAQ,KAAK,OAAO,EAAE,CACpD,CAAC;oBACF,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gBACpC,CAAC;gBAED,MAAM;YACR,CAAC;YAED,6DAA6D;YAC7D,6FAA6F;YAC7F,mFAAmF;YACnF,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,OAAO;oBACL,iBAAiB,EAAE,iBAAiB,CAAC,QAAQ;oBAC7C,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC7C,aAAa,EAAE,SAAS,CAAC,OAAO,KAAK,SAAS,CAAC,GAAG;iBACnD,CAAC;YACJ,CAAC;YAED,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,MAAM,SAAS,GAAG,MAAM,WAAW,CAAC,aAAa,EAAE,CAAC;gBACpD,MAAM,CAAC,OAAO,CACZ,sBAAsB,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,MAAM,CAAC,KAAK,CAAC,iBAAiB,QAAQ,CACzF,CAAC;gBACF,MAAM;YACR,CAAC;YAED,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,MAAM,cAAc,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;gBAC3D,MAAM,cAAc,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;gBAC5C,MAAM;YACR,CAAC;YAED,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;gBACzD,MAAM,cAAc,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;gBAC1C,MAAM;YACR,CAAC;YAED,KAAK,SAAS;gBACZ,cAAc,CAAC,YAAY,EAAE,CAAC;gBAC9B,MAAM;YAER,OAAO,CAAC,CAAC,CAAC;gBACR,MAAM,aAAa,GAAG,MAAM,YAAY,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;gBAE9D,IAAI,aAAa,CAAC,SAAS,IAAI,SAAS,EAAE,CAAC;oBACzC,MAAM,MAAM,CAAC,WAAW,CAAC,0CAA0C,CAAC,CAAC;oBACrE,yBAAyB,GAAG,KAAK,CAAC;gBACpC,CAAC;gBAED,iBAAiB,GAAG,aAAa,CAAC,SAAS;oBACzC,CAAC,CAAC,iBAAiB,CAAC,eAAe;oBACnC,CAAC,CAAC,iBAAiB,CAAC,QAAQ,CAAC;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IAED,gDAAgD;IAChD,IAAI,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;QACrB,MAAM,MAAM,CAAC,WAAW,CAAC,8BAA8B,SAAS,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,OAAO;QACL,iBAAiB;QACjB,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,iBAAiB;QAC5C,aAAa,EAAE,MAAM,CAAC,KAAK,CAAC,aAAa;KAC1C,CAAC;AACJ,CAAC"}
|
|
@@ -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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"}
|