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,133 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import * as events from "events";
|
|
3
|
+
import * as readline from "readline";
|
|
4
|
+
import * as llmail from "../apps/llmail.js";
|
|
5
|
+
import * as config from "../config.js";
|
|
6
|
+
import * as contextManager from "../llm/contextManager.js";
|
|
7
|
+
import * as inputMode from "../utils/inputMode.js";
|
|
8
|
+
import { InputMode } from "../utils/inputMode.js";
|
|
9
|
+
import * as output from "../utils/output.js";
|
|
10
|
+
import * as shellWrapper from "./shellWrapper.js";
|
|
11
|
+
// When actual output is entered by the user we want to cancel any auto-continue timers and/or wake on message
|
|
12
|
+
// We don't want to cancel if the user is entering a chords like ctrl+b then down arrow, when using tmux
|
|
13
|
+
// This is why we can't put the event listener on the standard process.stdin/keypress event.
|
|
14
|
+
// There is no 'data entered' output event so this monkey patch does that
|
|
15
|
+
const _writeEventName = "write";
|
|
16
|
+
const _outputEmitter = new events.EventEmitter();
|
|
17
|
+
const _originalWrite = process.stdout.write.bind(process.stdout);
|
|
18
|
+
process.stdout.write = (...args) => {
|
|
19
|
+
_outputEmitter.emit(_writeEventName, false, ...args);
|
|
20
|
+
return _originalWrite.apply(process.stdout, args);
|
|
21
|
+
};
|
|
22
|
+
const _readlineInterface = readline.createInterface({
|
|
23
|
+
input: process.stdin,
|
|
24
|
+
output: process.stdout,
|
|
25
|
+
});
|
|
26
|
+
// Happens when ctrl+c is pressed
|
|
27
|
+
let readlineInterfaceClosed = false;
|
|
28
|
+
_readlineInterface.on("close", () => {
|
|
29
|
+
readlineInterfaceClosed = true;
|
|
30
|
+
output.error("Readline interface closed");
|
|
31
|
+
});
|
|
32
|
+
export async function getPrompt(pauseSeconds, wakeOnMessage) {
|
|
33
|
+
const promptSuffix = inputMode.current == InputMode.Debug ? "#" : "$";
|
|
34
|
+
const tokenMax = config.tokenMax;
|
|
35
|
+
const usedTokens = contextManager.getTokenCount();
|
|
36
|
+
const tokenSuffix = ` [Tokens: ${usedTokens}/${tokenMax}]`;
|
|
37
|
+
let pause = "";
|
|
38
|
+
if (inputMode.current == InputMode.Debug) {
|
|
39
|
+
if (pauseSeconds) {
|
|
40
|
+
pause += ` [Paused: ${pauseSeconds}s]`;
|
|
41
|
+
}
|
|
42
|
+
if (wakeOnMessage) {
|
|
43
|
+
pause += " [WakeOnMsg]";
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return `${await getUserHostPathPrompt()}${tokenSuffix}${pause}${promptSuffix} `;
|
|
47
|
+
}
|
|
48
|
+
export async function getUserHostPathPrompt() {
|
|
49
|
+
const currentPath = await shellWrapper.getCurrentPath();
|
|
50
|
+
return `${getUserHostPrompt()}:${currentPath}`;
|
|
51
|
+
}
|
|
52
|
+
export function getUserHostPrompt() {
|
|
53
|
+
const username = inputMode.current == InputMode.Debug ? "debug" : config.agent.username;
|
|
54
|
+
return `${username}@${config.hostname}`;
|
|
55
|
+
}
|
|
56
|
+
export function getInput(commandPrompt, pauseSeconds, wakeOnMessage) {
|
|
57
|
+
return new Promise((resolve) => {
|
|
58
|
+
const questionController = new AbortController();
|
|
59
|
+
let timeout;
|
|
60
|
+
let interval;
|
|
61
|
+
let timeoutCancelled = false;
|
|
62
|
+
if (readlineInterfaceClosed) {
|
|
63
|
+
output.error("Hanging because readline interface is closed.");
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
/** Cancels waiting for user input */
|
|
67
|
+
function onStdinWrite_cancelTimers(questionAborted, buffer) {
|
|
68
|
+
// Don't allow console escape commands like \x1B[1G to cancel the timeout
|
|
69
|
+
if (timeoutCancelled || (buffer && !/^[a-zA-Z0-9 ]+$/.test(buffer))) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
timeoutCancelled = true;
|
|
73
|
+
_outputEmitter.off(_writeEventName, onStdinWrite_cancelTimers);
|
|
74
|
+
clearTimeout(timeout);
|
|
75
|
+
clearInterval(interval);
|
|
76
|
+
timeout = undefined;
|
|
77
|
+
interval = undefined;
|
|
78
|
+
if (questionAborted) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// Else timeout interrupted by user input, clear out the timeout information from the prompt
|
|
82
|
+
// to prevent the user from thinking the timeout still applies
|
|
83
|
+
let pausePos = commandPrompt.indexOf("[Paused:");
|
|
84
|
+
pausePos =
|
|
85
|
+
pausePos == -1 ? commandPrompt.indexOf("[WakeOnMsg]") : pausePos;
|
|
86
|
+
if (pausePos > 0) {
|
|
87
|
+
// BUG: When the user hits delete, the prompt is reset to the original which is confusing as user will think timeout is still active
|
|
88
|
+
// Fix is probably to reset the entire the question when the timeout is interrupted
|
|
89
|
+
const charsBack = commandPrompt.length - pausePos - 1; // pluse 1 for the space after the #
|
|
90
|
+
readline.moveCursor(process.stdout, -charsBack, 0);
|
|
91
|
+
process.stdout.write("-".repeat(charsBack - 3));
|
|
92
|
+
readline.moveCursor(process.stdout, 3, 0);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
_readlineInterface.question(chalk.greenBright(commandPrompt), { signal: questionController.signal }, (answer) => {
|
|
96
|
+
resolve(answer);
|
|
97
|
+
});
|
|
98
|
+
// If user starts typing in prompt, cancel any auto timeouts or wake on msg
|
|
99
|
+
_outputEmitter.on(_writeEventName, onStdinWrite_cancelTimers);
|
|
100
|
+
const abortQuestion = () => {
|
|
101
|
+
onStdinWrite_cancelTimers(true);
|
|
102
|
+
questionController.abort();
|
|
103
|
+
resolve("");
|
|
104
|
+
};
|
|
105
|
+
if (pauseSeconds) {
|
|
106
|
+
timeout = setTimeout(() => {
|
|
107
|
+
abortQuestion();
|
|
108
|
+
}, pauseSeconds * 1000);
|
|
109
|
+
}
|
|
110
|
+
if (wakeOnMessage) {
|
|
111
|
+
// Break timeout if new message is received
|
|
112
|
+
let firstError = true;
|
|
113
|
+
interval = setInterval(() => {
|
|
114
|
+
// setInterval does not support async/await, but that's okay as this call easily runs within the 3s interval
|
|
115
|
+
llmail
|
|
116
|
+
.getUnreadThreads()
|
|
117
|
+
.then((unreadThreadIds) => {
|
|
118
|
+
if (unreadThreadIds.length) {
|
|
119
|
+
abortQuestion();
|
|
120
|
+
}
|
|
121
|
+
})
|
|
122
|
+
// Catch and log errors, but don't break the interval on hopefully an intermittent error
|
|
123
|
+
.catch((e) => {
|
|
124
|
+
if (firstError) {
|
|
125
|
+
output.error(`Mail interval check error: ${e}`);
|
|
126
|
+
firstError = false;
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}, 3000);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=promptBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promptBuilder.js","sourceRoot":"","sources":["../../src/command/promptBuilder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as contextManager from "../llm/contextManager.js";
|
|
2
|
+
import * as inputMode from "../utils/inputMode.js";
|
|
3
|
+
import { InputMode } from "../utils/inputMode.js";
|
|
4
|
+
import * as shellWrapper from "./shellWrapper.js";
|
|
5
|
+
export async function handleCommand(input) {
|
|
6
|
+
const cmdParams = input.split(" ");
|
|
7
|
+
const response = {
|
|
8
|
+
hasErrors: true,
|
|
9
|
+
};
|
|
10
|
+
// Route user to context friendly edit commands that can read/write the entire file in one go
|
|
11
|
+
if (["nano", "vi", "vim"].includes(cmdParams[0])) {
|
|
12
|
+
await contextManager.append(`${cmdParams[0]} not supported. Use 'cat' to view a file and 'cat > filename << EOF' to write a file`);
|
|
13
|
+
return response;
|
|
14
|
+
}
|
|
15
|
+
if (cmdParams[0] == "lynx" && cmdParams[1] != "--dump") {
|
|
16
|
+
await contextManager.append(`Interactive mode with lynx is not supported. Use --dump with lynx to view a website`);
|
|
17
|
+
return response;
|
|
18
|
+
}
|
|
19
|
+
if (cmdParams[0] == "exit") {
|
|
20
|
+
if (inputMode.current == InputMode.LLM) {
|
|
21
|
+
await contextManager.append("Use 'endsession' to end the session and clear the console log.");
|
|
22
|
+
}
|
|
23
|
+
else if (inputMode.current == InputMode.Debug) {
|
|
24
|
+
await shellWrapper.terminate();
|
|
25
|
+
response.terminate = true;
|
|
26
|
+
}
|
|
27
|
+
return response;
|
|
28
|
+
}
|
|
29
|
+
const output = await shellWrapper.executeCommand(input);
|
|
30
|
+
if (output.value) {
|
|
31
|
+
await contextManager.append(output.value);
|
|
32
|
+
}
|
|
33
|
+
response.hasErrors = output.hasErrors;
|
|
34
|
+
return response;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=shellCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shellCommand.js","sourceRoot":"","sources":["../../src/command/shellCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,cAAc,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAC;AAOlD,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,KAAa;IAEb,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,QAAQ,GAA+B;QAC3C,SAAS,EAAE,IAAI;KAChB,CAAC;IAEF,6FAA6F;IAC7F,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,MAAM,cAAc,CAAC,MAAM,CACzB,GAAG,SAAS,CAAC,CAAC,CAAC,sFAAsF,CACtG,CAAC;QAEF,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,IAAI,SAAS,CAAC,CAAC,CAAC,IAAI,MAAM,IAAI,SAAS,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC;QACvD,MAAM,cAAc,CAAC,MAAM,CACzB,qFAAqF,CACtF,CAAC;QAEF,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,IAAI,SAAS,CAAC,CAAC,CAAC,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,SAAS,CAAC,OAAO,IAAI,SAAS,CAAC,GAAG,EAAE,CAAC;YACvC,MAAM,cAAc,CAAC,MAAM,CACzB,gEAAgE,CACjE,CAAC;QACJ,CAAC;aAAM,IAAI,SAAS,CAAC,OAAO,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;YAChD,MAAM,YAAY,CAAC,SAAS,EAAE,CAAC;YAC/B,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC;QAC5B,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAExD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC;IAED,QAAQ,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IAEtC,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { spawn } from "child_process";
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import * as os from "os";
|
|
4
|
+
import * as config from "../config.js";
|
|
5
|
+
import * as output from "../utils/output.js";
|
|
6
|
+
import { naisysToHostPath } from "../utils/utilities.js";
|
|
7
|
+
var ShellEvent;
|
|
8
|
+
(function (ShellEvent) {
|
|
9
|
+
ShellEvent["Ouptput"] = "stdout";
|
|
10
|
+
ShellEvent["Error"] = "stderr";
|
|
11
|
+
ShellEvent["Exit"] = "exit";
|
|
12
|
+
})(ShellEvent || (ShellEvent = {}));
|
|
13
|
+
let _process;
|
|
14
|
+
//let _log = "";
|
|
15
|
+
let _commandOutput = "";
|
|
16
|
+
let _hasErrors = false;
|
|
17
|
+
let _currentPath;
|
|
18
|
+
let _resolveCurrentCommand;
|
|
19
|
+
let _currentCommandTimeout;
|
|
20
|
+
const _commandDelimiter = "__COMMAND_END_X7YUTT__";
|
|
21
|
+
async function ensureOpen() {
|
|
22
|
+
if (_process) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
//_log = "";
|
|
26
|
+
resetCommand();
|
|
27
|
+
const spawnProcess = os.platform() === "win32" ? "wsl" : "bash";
|
|
28
|
+
_process = spawn(spawnProcess, [], { stdio: "pipe" });
|
|
29
|
+
_process.stdout.on("data", (data) => {
|
|
30
|
+
processOutput(data.toString(), ShellEvent.Ouptput);
|
|
31
|
+
});
|
|
32
|
+
_process.stderr.on("data", (data) => {
|
|
33
|
+
processOutput(data.toString(), ShellEvent.Error);
|
|
34
|
+
});
|
|
35
|
+
_process.on("close", (code) => {
|
|
36
|
+
processOutput(`${code}`, ShellEvent.Exit);
|
|
37
|
+
_process = undefined;
|
|
38
|
+
});
|
|
39
|
+
// Init users home dir on first run, on shell crash/rerun go back to the current path
|
|
40
|
+
if (!_currentPath) {
|
|
41
|
+
output.comment("NEW SHELL OPENED. PID: " + _process.pid);
|
|
42
|
+
commentIfNotEmpty(await executeCommand(`mkdir -p ${config.naisysFolder}/home/` + config.agent.username));
|
|
43
|
+
commentIfNotEmpty(await executeCommand(`cd ${config.naisysFolder}/home/` + config.agent.username));
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
output.comment("SHELL RESTORED. PID: " + _process.pid);
|
|
47
|
+
commentIfNotEmpty(await executeCommand("cd " + _currentPath));
|
|
48
|
+
}
|
|
49
|
+
// Stop running commands if one fails
|
|
50
|
+
// Often the LLM will give us back all kinds of invalid commands, we want to break on the first one
|
|
51
|
+
// Unfortunately this also causes the shell to exit on failures, so we need to handle that
|
|
52
|
+
//commentIfNotEmpty(await executeCommand("set -e"));
|
|
53
|
+
}
|
|
54
|
+
/** Basically don't show anything in the console unless there is an error */
|
|
55
|
+
function commentIfNotEmpty(response) {
|
|
56
|
+
if (response.value) {
|
|
57
|
+
output.comment(response.value);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export function processOutput(dataStr, eventType) {
|
|
61
|
+
if (!_resolveCurrentCommand) {
|
|
62
|
+
output.comment(eventType + " without handler: " + dataStr);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (eventType === ShellEvent.Exit) {
|
|
66
|
+
output.error("SHELL EXITED. PID: " + (_process === null || _process === void 0 ? void 0 : _process.pid) + " CODE: " + dataStr);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
//_log += "OUTPUT: " + dataStr;
|
|
70
|
+
_commandOutput += dataStr;
|
|
71
|
+
}
|
|
72
|
+
if (eventType === ShellEvent.Error) {
|
|
73
|
+
_hasErrors = true;
|
|
74
|
+
//output += "stderr: ";
|
|
75
|
+
// parse out the line number from '-bash: line 999: '
|
|
76
|
+
/*if (dataStr.startsWith("-bash: line ")) {
|
|
77
|
+
output.error(dataStr);
|
|
78
|
+
|
|
79
|
+
const lineNum = dataStr.slice(11, dataStr.indexOf(": ", 11));
|
|
80
|
+
output.error(`Detected error on line ${lineNum} of output`);
|
|
81
|
+
|
|
82
|
+
// display the same line of _output
|
|
83
|
+
const logLines = _log.split("\n");
|
|
84
|
+
const lineIndex = parseInt(lineNum) - 1;
|
|
85
|
+
if (logLines.length > lineIndex) {
|
|
86
|
+
output.error(`Line ${lineIndex} in log: ` + logLines[lineIndex]);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// output all lines for debugging
|
|
90
|
+
for (let i = 0; i < logLines.length; i++) {
|
|
91
|
+
// if withing 10 lines of the error, show the line
|
|
92
|
+
//if (Math.abs(i - lineIndex) < 10) {
|
|
93
|
+
const lineStr = logLines[i].replace(/\n/g, "");
|
|
94
|
+
output.error(`${i}: ${lineStr}`);
|
|
95
|
+
//}
|
|
96
|
+
}
|
|
97
|
+
}*/
|
|
98
|
+
}
|
|
99
|
+
const delimiterIndex = _commandOutput.indexOf(_commandDelimiter);
|
|
100
|
+
if (delimiterIndex != -1 || eventType === ShellEvent.Exit) {
|
|
101
|
+
// trim everything after delimiter
|
|
102
|
+
_commandOutput = _commandOutput.slice(0, delimiterIndex);
|
|
103
|
+
const response = {
|
|
104
|
+
value: _commandOutput.trim(),
|
|
105
|
+
hasErrors: _hasErrors,
|
|
106
|
+
};
|
|
107
|
+
resetCommand();
|
|
108
|
+
_resolveCurrentCommand(response);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
export async function executeCommand(command) {
|
|
112
|
+
/*if (command == "shelllog") {
|
|
113
|
+
_log.split("\n").forEach((line, i) => {
|
|
114
|
+
output.comment(`${i}. ${line}`);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
return <CommandResponse>{
|
|
118
|
+
value: "",
|
|
119
|
+
hasErrors: false,
|
|
120
|
+
};
|
|
121
|
+
}*/
|
|
122
|
+
await ensureOpen();
|
|
123
|
+
if (_currentPath && command.trim().split("\n").length > 1) {
|
|
124
|
+
command = await runCommandFromScript(command);
|
|
125
|
+
}
|
|
126
|
+
return new Promise((resolve) => {
|
|
127
|
+
_resolveCurrentCommand = resolve;
|
|
128
|
+
const commandWithDelimiter = `${command.trim()}\necho "${_commandDelimiter} LINE:\${LINENO}"\n`;
|
|
129
|
+
//_log += "INPUT: " + commandWithDelimiter;
|
|
130
|
+
_process === null || _process === void 0 ? void 0 : _process.stdin.write(commandWithDelimiter);
|
|
131
|
+
// If no response after 5 seconds, kill and reset the shell, often hanging on some unescaped input
|
|
132
|
+
const timeoutSeconds = 5;
|
|
133
|
+
_currentCommandTimeout = setTimeout(() => {
|
|
134
|
+
if (_resolveCurrentCommand) {
|
|
135
|
+
_process === null || _process === void 0 ? void 0 : _process.kill();
|
|
136
|
+
output.error("SHELL TIMEMOUT/KILLED. PID: " + (_process === null || _process === void 0 ? void 0 : _process.pid));
|
|
137
|
+
resetProcess();
|
|
138
|
+
_resolveCurrentCommand({
|
|
139
|
+
value: `Error: Command timed out after ${timeoutSeconds} seconds.`,
|
|
140
|
+
hasErrors: true,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}, timeoutSeconds * 1000);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
export async function getCurrentPath() {
|
|
147
|
+
await ensureOpen();
|
|
148
|
+
_currentPath = (await executeCommand("pwd")).value;
|
|
149
|
+
return _currentPath;
|
|
150
|
+
}
|
|
151
|
+
export async function terminate() {
|
|
152
|
+
/*const exitCode = */ await executeCommand("exit");
|
|
153
|
+
// For some reason showing the exit code clears the console
|
|
154
|
+
resetProcess();
|
|
155
|
+
}
|
|
156
|
+
function resetCommand() {
|
|
157
|
+
_commandOutput = "";
|
|
158
|
+
_hasErrors = false;
|
|
159
|
+
clearTimeout(_currentCommandTimeout);
|
|
160
|
+
}
|
|
161
|
+
function resetProcess() {
|
|
162
|
+
resetCommand();
|
|
163
|
+
_process === null || _process === void 0 ? void 0 : _process.removeAllListeners();
|
|
164
|
+
_process = undefined;
|
|
165
|
+
}
|
|
166
|
+
/** Wraps multi line commands in a script to make it easier to diagnose the source of errors based on line number
|
|
167
|
+
* May also help with common escaping errors */
|
|
168
|
+
function runCommandFromScript(command) {
|
|
169
|
+
const scriptPath = `${config.naisysFolder}/home/${config.agent.username}/.command.tmp.sh`;
|
|
170
|
+
// set -e causes the script to exit on any error
|
|
171
|
+
const scriptContent = `#!/bin/bash
|
|
172
|
+
set -e
|
|
173
|
+
cd ${_currentPath}
|
|
174
|
+
${command.trim()}`;
|
|
175
|
+
// create/writewrite file
|
|
176
|
+
fs.writeFileSync(naisysToHostPath(scriptPath), scriptContent);
|
|
177
|
+
return `bash ${scriptPath}`;
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=shellWrapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shellWrapper.js","sourceRoot":"","sources":["../../src/command/shellWrapper.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { program } from "commander";
|
|
2
|
+
import dotenv from "dotenv";
|
|
3
|
+
import * as fs from "fs";
|
|
4
|
+
import yaml from "js-yaml";
|
|
5
|
+
import { valueFromString } from "./utils/utilities.js";
|
|
6
|
+
program.argument("<agent-path>", "Path to agent configuration file").parse();
|
|
7
|
+
dotenv.config();
|
|
8
|
+
/** The system name that shows after the @ in the command prompt */
|
|
9
|
+
export const hostname = "naisys";
|
|
10
|
+
/** The number of tokens you want to limit a session to, independent of the LLM token max */
|
|
11
|
+
export const tokenMax = 4000;
|
|
12
|
+
/* .env is used for global configs across naisys, while agent configs for the specific agent */
|
|
13
|
+
export const naisysFolder = getEnv("NAISYS_FOLDER", true);
|
|
14
|
+
export const websiteFolder = getEnv("WEBSITE_FOLDER");
|
|
15
|
+
export const localLlmUrl = getEnv("LOCAL_LLM_URL");
|
|
16
|
+
export const localLlmName = getEnv("LOCAL_LLM_NAME");
|
|
17
|
+
export const openaiApiKey = getEnv("OPENAI_API_KEY");
|
|
18
|
+
export const googleApiKey = getEnv("GOOGLE_API_KEY");
|
|
19
|
+
export const agent = loadAgentConfig();
|
|
20
|
+
function getEnv(key, required) {
|
|
21
|
+
const value = process.env[key];
|
|
22
|
+
if (!value && required) {
|
|
23
|
+
throw `Config: Error, .env ${key} is not defined`;
|
|
24
|
+
}
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
function loadAgentConfig() {
|
|
28
|
+
const agentPath = program.args[0];
|
|
29
|
+
const checkAgentConfig = yaml.load(fs.readFileSync(agentPath, "utf8"));
|
|
30
|
+
// throw if any property is undefined
|
|
31
|
+
for (const key of [
|
|
32
|
+
"username",
|
|
33
|
+
"title",
|
|
34
|
+
"consoleModel",
|
|
35
|
+
"webModel",
|
|
36
|
+
"agentPrompt",
|
|
37
|
+
"spendLimitDollars",
|
|
38
|
+
// debugPauseSeconds and wakeOnMessage can be undefined
|
|
39
|
+
]) {
|
|
40
|
+
if (!valueFromString(checkAgentConfig, key)) {
|
|
41
|
+
throw `Agent config: Error, ${key} is not defined`;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return checkAgentConfig;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,CAAC,QAAQ,CAAC,cAAc,EAAE,kCAAkC,CAAC,CAAC,KAAK,EAAE,CAAC;AAE7E,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,mEAAmE;AACnE,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAEjC,4FAA4F;AAC5F,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC;AAE7B,+FAA+F;AAE/F,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;AAC1D,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAEtD,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;AACnD,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAErD,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AACrD,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAErD,MAAM,CAAC,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;AAEvC,SAAS,MAAM,CAAC,GAAW,EAAE,QAAkB;IAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,KAAK,IAAI,QAAQ,EAAE,CAAC;QACvB,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;IACpD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAcD,SAAS,eAAe;IACtB,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAElC,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAChC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CACpB,CAAC;IAEjB,qCAAqC;IACrC,KAAK,MAAM,GAAG,IAAI;QAChB,UAAU;QACV,OAAO;QACP,cAAc;QACd,UAAU;QACV,aAAa;QACb,mBAAmB;QACnB,uDAAuD;KACxD,EAAE,CAAC;QACF,IAAI,CAAC,eAAe,CAAC,gBAAgB,EAAE,GAAG,CAAC,EAAE,CAAC;YAC5C,MAAM,wBAAwB,GAAG,iBAAiB,CAAC;QACrD,CAAC;IACH,CAAC;IAED,OAAO,gBAAgB,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import * as config from "../config.js";
|
|
2
|
+
import * as inputMode from "../utils/inputMode.js";
|
|
3
|
+
import { InputMode } from "../utils/inputMode.js";
|
|
4
|
+
import * as logService from "../utils/logService.js";
|
|
5
|
+
import * as output from "../utils/output.js";
|
|
6
|
+
import { OutputColor } from "../utils/output.js";
|
|
7
|
+
import * as utilities from "../utils/utilities.js";
|
|
8
|
+
import { valueFromString } from "../utils/utilities.js";
|
|
9
|
+
import { LlmRole } from "./llmDtos.js";
|
|
10
|
+
export var ContentSource;
|
|
11
|
+
(function (ContentSource) {
|
|
12
|
+
ContentSource["ConsolePrompt"] = "startPrompt";
|
|
13
|
+
ContentSource["LlmPromptResponse"] = "endPrompt";
|
|
14
|
+
ContentSource["Console"] = "console";
|
|
15
|
+
ContentSource["LLM"] = "llm";
|
|
16
|
+
})(ContentSource || (ContentSource = {}));
|
|
17
|
+
let _cachedSystemMessage = "";
|
|
18
|
+
export function getSystemMessage() {
|
|
19
|
+
if (_cachedSystemMessage) {
|
|
20
|
+
return _cachedSystemMessage;
|
|
21
|
+
}
|
|
22
|
+
// Fill out the templates in the agent prompt and stick it to the front of the system message
|
|
23
|
+
// A lot of the stipulations in here are to prevent common LLM mistakes
|
|
24
|
+
// Like we can't jump between standard and special commands in a single prompt, which the LLM will try to do if not warned
|
|
25
|
+
let agentPrompt = config.agent.agentPrompt;
|
|
26
|
+
agentPrompt = resolveTemplateVars(agentPrompt, "agent", config.agent);
|
|
27
|
+
agentPrompt = resolveTemplateVars(agentPrompt, "env", process.env);
|
|
28
|
+
const systemMessage = `${agentPrompt.trim()}
|
|
29
|
+
|
|
30
|
+
This is a command line interface presenting you with the next command prompt.
|
|
31
|
+
Make sure the read the command line rules in the MOTD carefully.
|
|
32
|
+
Don't try to guess the output of commands. Don't put commands in \`\`\` blocks.
|
|
33
|
+
For example when you run 'cat' or 'ls', don't write what you think the output will be. Let the system do that.
|
|
34
|
+
Your role is that of the user. The system will provide responses and next command prompt. Don't output your own command prompt.
|
|
35
|
+
Be careful when writing files through the command prompt with cat. Make sure to close and escape quotes properly.
|
|
36
|
+
|
|
37
|
+
NAISYS ${process.env.npm_package_version} Shell
|
|
38
|
+
Welcome back ${config.agent.username}!
|
|
39
|
+
MOTD:
|
|
40
|
+
Date: ${new Date().toLocaleString()}
|
|
41
|
+
Commands:
|
|
42
|
+
Standard Unix commands are available
|
|
43
|
+
vi and nano are not supported
|
|
44
|
+
Read/write entire files in a single command with cat
|
|
45
|
+
Do not input notes after the prompt. Only valid commands.
|
|
46
|
+
Special Commands: (Don't mix with standard commands on the same prompt)
|
|
47
|
+
llmail: A local mail system for communicating with your team
|
|
48
|
+
llmynx: A context optimized web browser. Enter 'llmynx help' to learn how to use it
|
|
49
|
+
comment <thought>: Any non-command output like thinking out loud, prefix with the 'comment' command
|
|
50
|
+
pause <seconds>: Pause for <seconds> or indeterminite if no argument is provided. Auto wake up on new mail message
|
|
51
|
+
endsession <note>: Ends this session, clears the console log and context.
|
|
52
|
+
The note should help you prevent from having to find your bearings in the next session.
|
|
53
|
+
The note should contain your next goal. Important things should you remember. Maybe a task list.
|
|
54
|
+
Try to keep the note around 400 tokens.
|
|
55
|
+
Tokens:
|
|
56
|
+
The console log can only hold a certain number of 'tokens' that is specified in the prompt
|
|
57
|
+
Make sure to call endsession before the limit is hit so you can continue your work with a fresh console`;
|
|
58
|
+
_cachedSystemMessage = systemMessage;
|
|
59
|
+
return systemMessage;
|
|
60
|
+
}
|
|
61
|
+
function resolveTemplateVars(templateString, allowedVarString, mappedVar) {
|
|
62
|
+
const pattern = new RegExp(`\\$\\{${allowedVarString}\\.([^}]+)\\}`, "g");
|
|
63
|
+
return templateString.replace(pattern, (match, key) => {
|
|
64
|
+
const value = valueFromString(mappedVar, key);
|
|
65
|
+
if (value === undefined) {
|
|
66
|
+
throw `Agent config: Error, ${key} is not defined`;
|
|
67
|
+
}
|
|
68
|
+
return value;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
export let messages = [];
|
|
72
|
+
export async function append(text, source = ContentSource.Console) {
|
|
73
|
+
// Debug runs in a shadow mode where their activity is not recorded in the context
|
|
74
|
+
// Mark with a # to make it clear that it is not part of the context
|
|
75
|
+
if (inputMode.current === InputMode.Debug) {
|
|
76
|
+
output.comment(text);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
// Else otherwise we're running in LLM mode
|
|
80
|
+
const role = source == ContentSource.ConsolePrompt || source == ContentSource.Console
|
|
81
|
+
? LlmRole.User
|
|
82
|
+
: source == ContentSource.LlmPromptResponse || source == ContentSource.LLM
|
|
83
|
+
? LlmRole.Assistant
|
|
84
|
+
: undefined;
|
|
85
|
+
if (!role) {
|
|
86
|
+
throw new Error("Invalid source");
|
|
87
|
+
}
|
|
88
|
+
// If last message is the same role then combine - Googl API requires alterntating roles
|
|
89
|
+
// TODO: Maybe dont do this here, but in the google api call
|
|
90
|
+
let combined = false;
|
|
91
|
+
if (messages.length > 0) {
|
|
92
|
+
const lastMessage = messages[messages.length - 1];
|
|
93
|
+
if (lastMessage.role == role) {
|
|
94
|
+
lastMessage.content += `\n${text}`;
|
|
95
|
+
combined = true;
|
|
96
|
+
await logService.update(lastMessage, text);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (!combined) {
|
|
100
|
+
const llmMessage = { role, content: text };
|
|
101
|
+
llmMessage.logId = await logService.write(llmMessage);
|
|
102
|
+
messages.push(llmMessage);
|
|
103
|
+
}
|
|
104
|
+
// Prompts are manually added to the console log
|
|
105
|
+
if (source != ContentSource.ConsolePrompt &&
|
|
106
|
+
source != ContentSource.LlmPromptResponse) {
|
|
107
|
+
output.write(text, source == "llm" ? OutputColor.llm : OutputColor.console);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export function clear() {
|
|
111
|
+
messages = [];
|
|
112
|
+
}
|
|
113
|
+
export function getTokenCount() {
|
|
114
|
+
const sytemMessageTokens = utilities.getTokenCount(getSystemMessage());
|
|
115
|
+
return messages.reduce((acc, message) => {
|
|
116
|
+
return acc + utilities.getTokenCount(message.content);
|
|
117
|
+
}, sytemMessageTokens);
|
|
118
|
+
}
|
|
119
|
+
export function printContext() {
|
|
120
|
+
output.comment("#####################");
|
|
121
|
+
// output.comment(content);
|
|
122
|
+
messages.forEach((message) => {
|
|
123
|
+
output.comment(`${message.role}: ${message.content}`);
|
|
124
|
+
});
|
|
125
|
+
output.comment("#####################");
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=contextManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contextManager.js","sourceRoot":"","sources":["../../src/llm/contextManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as config from "../config.js";
|
|
2
|
+
import * as dbUtils from "../utils/dbUtils.js";
|
|
3
|
+
import { naisysToHostPath } from "../utils/utilities.js";
|
|
4
|
+
const _dbFilePath = naisysToHostPath(`${config.naisysFolder}/lib/costs.db`);
|
|
5
|
+
await init();
|
|
6
|
+
async function init() {
|
|
7
|
+
const newDbCreated = await dbUtils.initDatabase(_dbFilePath);
|
|
8
|
+
await usingDatabase(async (db) => {
|
|
9
|
+
if (!newDbCreated) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const createTables = [
|
|
13
|
+
`CREATE TABLE Costs (
|
|
14
|
+
id INTEGER PRIMARY KEY,
|
|
15
|
+
date TEXT NOT NULL,
|
|
16
|
+
username TEXT NOT NULL,
|
|
17
|
+
source TEXT NOT NULL,
|
|
18
|
+
model TEXT NOT NULL,
|
|
19
|
+
cost REAL NOT NULL
|
|
20
|
+
)`,
|
|
21
|
+
];
|
|
22
|
+
for (const createTable of createTables) {
|
|
23
|
+
await db.exec(createTable);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
export async function recordCost(cost, source, modelName) {
|
|
28
|
+
await usingDatabase(async (db) => {
|
|
29
|
+
await db.run(`INSERT INTO Costs (date, username, source, model, cost) VALUES (datetime('now'), ?, ?, ?, ?)`, [config.agent.username, source, modelName, cost]);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
export async function getTotalCosts() {
|
|
33
|
+
return usingDatabase(async (db) => {
|
|
34
|
+
const result = await db.get(`SELECT sum(cost) as total
|
|
35
|
+
FROM Costs
|
|
36
|
+
WHERE username = ?`, [config.agent.username]);
|
|
37
|
+
return result.total;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
async function usingDatabase(run) {
|
|
41
|
+
return dbUtils.usingDatabase(_dbFilePath, run);
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=costTracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"costTracker.js","sourceRoot":"","sources":["../../src/llm/costTracker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AACvC,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,MAAM,WAAW,GAAG,gBAAgB,CAAC,GAAG,MAAM,CAAC,YAAY,eAAe,CAAC,CAAC;AAE5E,MAAM,IAAI,EAAE,CAAC;AAEb,KAAK,UAAU,IAAI;IACjB,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;IAE7D,MAAM,aAAa,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QAC/B,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QAED,MAAM,YAAY,GAAG;YACnB;;;;;;;QAOE;SACH,CAAC;QAEF,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;YACvC,MAAM,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAY,EACZ,MAAc,EACd,SAAiB;IAEjB,MAAM,aAAa,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QAC/B,MAAM,EAAE,CAAC,GAAG,CACV,8FAA8F,EAC9F,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,CACjD,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,OAAO,aAAa,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QAChC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,CACzB;;2BAEqB,EACrB,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CACxB,CAAC;QAEF,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,aAAa,CAAI,GAAiC;IAC/D,OAAO,OAAO,CAAC,aAAa,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;AACjD,CAAC"}
|