naisys 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -1
- package/bin/genimg +3 -0
- package/bin/naisys +1 -1
- package/dist/apps/genimg.js +97 -0
- package/dist/apps/llmail.js +2 -2
- package/dist/command/commandHandler.js +8 -1
- package/dist/command/shellCommand.js +3 -0
- package/dist/command/shellWrapper.js +8 -8
- package/dist/config.js +17 -10
- package/dist/llm/contextManager.js +7 -1
- package/dist/llm/costTracker.js +2 -2
- package/dist/llm/dreamMaker.js +7 -5
- package/dist/llm/llmService.js +2 -4
- package/dist/utils/logService.js +4 -4
- package/dist/utils/utilities.js +21 -12
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -75,6 +75,10 @@ dreamModel: claude3opus
|
|
|
75
75
|
# defaults to the shellModel if omitted
|
|
76
76
|
webModel: gemini-pro
|
|
77
77
|
|
|
78
|
+
# The model used by the 'genimg' command. If not defined then the genimg command is not available to the LLM
|
|
79
|
+
# Valid values: dalle2-256, dalle2-512, dalle2-1024, dalle3-1024, dalle3-1024-HD
|
|
80
|
+
imageModel: dalle3-1024
|
|
81
|
+
|
|
78
82
|
# A system like prompt explaining the agent's role and responsibilities
|
|
79
83
|
# You can use config variables in this string
|
|
80
84
|
agentPrompt: |
|
|
@@ -161,10 +165,11 @@ initialCommands:
|
|
|
161
165
|
- `comment "<note>"` - The LLM is directed to use this for 'thinking out loud' which avoids 'invalid command' errors
|
|
162
166
|
- `endsession "<note>"` - Clear the context and start a new session.
|
|
163
167
|
- The LLM is directed to track it's context size and to end the session with a note before running over the context limit
|
|
164
|
-
- `pause <seconds>` - Can be used by the debug agent or the LLM to pause execution
|
|
168
|
+
- `pause <seconds>` - Can be used by the debug agent or the LLM to pause execution for a set number of seconds
|
|
165
169
|
- NAISYS apps
|
|
166
170
|
- `llmail` - A context friendly 'mail system' used for agent to agent communication
|
|
167
171
|
- `llmynx` - A context friendly wrapping on the lynx browser that can use a separate LLM to reduce the size of a large webpage into something that can fit into the LLM's context
|
|
172
|
+
- `genimg "<description>" <filepath>` - Generates an image with the given description, save at the specified path
|
|
168
173
|
|
|
169
174
|
## Running NAISYS from Source
|
|
170
175
|
|
|
@@ -188,3 +193,11 @@ initialCommands:
|
|
|
188
193
|
- If you want to use NAISYS for a website
|
|
189
194
|
- Install a local web server, for example [XAMPP](https://www.apachefriends.org/) on Windows
|
|
190
195
|
- Start the server and put the URL in the `.env` file
|
|
196
|
+
|
|
197
|
+
## Changelog
|
|
198
|
+
|
|
199
|
+
- 1.4: `genimg` command for generating images
|
|
200
|
+
- 1.3: Post-session 'dreaming' as well as a mail 'blackout' period
|
|
201
|
+
- 1.2: Created stand-in shell commands for custom Naisys commands
|
|
202
|
+
- 1.1: Added command protection settings to prevent unwanted writes
|
|
203
|
+
- 1.0: Initial release
|
package/bin/genimg
ADDED
package/bin/naisys
CHANGED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import OpenAI from "openai";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import sharp from "sharp";
|
|
5
|
+
import * as config from "../config.js";
|
|
6
|
+
import * as costTracker from "../llm/costTracker.js";
|
|
7
|
+
import * as output from "../utils/output.js";
|
|
8
|
+
import { unixToHostPath } from "../utils/utilities.js";
|
|
9
|
+
/** genimg "<description>" <filepath>: Generate an image with the description and save it to the file path */
|
|
10
|
+
export async function handleCommand(args) {
|
|
11
|
+
// genimg sholdn't even be presented as an available command unless it is defined in the config
|
|
12
|
+
if (!config.agent.imageModel) {
|
|
13
|
+
throw "Agent config: Error, 'imageModel' is not defined";
|
|
14
|
+
}
|
|
15
|
+
const description = args.split('"')[1].trim();
|
|
16
|
+
const filepath = args.split('"')[2].trim();
|
|
17
|
+
if (!description) {
|
|
18
|
+
throw "Error: Description is required";
|
|
19
|
+
}
|
|
20
|
+
if (!filepath) {
|
|
21
|
+
throw "Error: Filepath is required";
|
|
22
|
+
}
|
|
23
|
+
// Check directory exists
|
|
24
|
+
const hostpath = unixToHostPath(filepath);
|
|
25
|
+
const dirname = path.dirname(hostpath);
|
|
26
|
+
if (!fs.existsSync(dirname)) {
|
|
27
|
+
throw `Error: Directory does not exist`;
|
|
28
|
+
}
|
|
29
|
+
output.comment(`Generating image with ${config.agent.imageModel}...`);
|
|
30
|
+
const openai = new OpenAI();
|
|
31
|
+
const model = getImageModel(config.agent.imageModel);
|
|
32
|
+
const response = await openai.images.generate({
|
|
33
|
+
prompt: description,
|
|
34
|
+
model: model.name,
|
|
35
|
+
size: model.size,
|
|
36
|
+
quality: model.quality,
|
|
37
|
+
response_format: "b64_json",
|
|
38
|
+
});
|
|
39
|
+
// save to filepath
|
|
40
|
+
const base64Image = response.data[0].b64_json;
|
|
41
|
+
if (!base64Image) {
|
|
42
|
+
throw 'Error: "b64_json" not found in response';
|
|
43
|
+
}
|
|
44
|
+
// Convert the base64 string to a buffer
|
|
45
|
+
const imageBuffer = Buffer.from(base64Image, "base64");
|
|
46
|
+
// Use sharp to convert the buffer and save it as a JPG file
|
|
47
|
+
//const currentPath = unixToHostPath(await shellWrapper.getCurrentPath());
|
|
48
|
+
//const filepath = path.join(currentPath, filename);
|
|
49
|
+
const fileExtension = path.extname(filepath).substring(1);
|
|
50
|
+
await sharp(imageBuffer)
|
|
51
|
+
.toFormat(fileExtension)
|
|
52
|
+
.toFile(hostpath);
|
|
53
|
+
// Record the cost
|
|
54
|
+
await costTracker.recordCost(model.cost, "genimg", model.name);
|
|
55
|
+
return "Image generated and saved to " + filepath;
|
|
56
|
+
}
|
|
57
|
+
const imageModels = [
|
|
58
|
+
{
|
|
59
|
+
key: "dalle3-1024-HD",
|
|
60
|
+
name: "dall-e-3",
|
|
61
|
+
size: "1024x1024",
|
|
62
|
+
quality: "hd",
|
|
63
|
+
cost: 0.08,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
key: "dalle3-1024",
|
|
67
|
+
name: "dall-e-3",
|
|
68
|
+
size: "1024x1024",
|
|
69
|
+
cost: 0.04,
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
key: "dalle2-1024",
|
|
73
|
+
name: "dall-e-2",
|
|
74
|
+
size: "1024x1024",
|
|
75
|
+
cost: 0.02,
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
key: "dalle2-512",
|
|
79
|
+
name: "dall-e-2",
|
|
80
|
+
size: "512x512",
|
|
81
|
+
cost: 0.018,
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
key: "dalle2-256",
|
|
85
|
+
name: "dall-e-2",
|
|
86
|
+
size: "256x256",
|
|
87
|
+
cost: 0.016,
|
|
88
|
+
},
|
|
89
|
+
];
|
|
90
|
+
function getImageModel(key) {
|
|
91
|
+
const model = imageModels.find((m) => m.key === key);
|
|
92
|
+
if (!model) {
|
|
93
|
+
throw `Error, image model not found: ${key}`;
|
|
94
|
+
}
|
|
95
|
+
return model;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=genimg.js.map
|
package/dist/apps/llmail.js
CHANGED
|
@@ -3,8 +3,8 @@ import table from "text-table";
|
|
|
3
3
|
import * as config from "../config.js";
|
|
4
4
|
import * as dbUtils from "../utils/dbUtils.js";
|
|
5
5
|
import * as utilities from "../utils/utilities.js";
|
|
6
|
-
import {
|
|
7
|
-
const _dbFilePath =
|
|
6
|
+
import { unixToHostPath } from "../utils/utilities.js";
|
|
7
|
+
const _dbFilePath = unixToHostPath(`${config.naisysFolder}/lib/llmail.db`);
|
|
8
8
|
let _myUserId = -1;
|
|
9
9
|
/** Threading is not currently used so this doesn't matter */
|
|
10
10
|
const _threadTokenMax = config.mailMessageTokenMax * 5;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
+
import * as genimg from "../apps/genimg.js";
|
|
2
3
|
import * as llmail from "../apps/llmail.js";
|
|
3
4
|
import * as llmynx from "../apps/llmynx.js";
|
|
4
5
|
import * as config from "../config.js";
|
|
@@ -125,6 +126,11 @@ export async function processCommand(prompt, consoleInput) {
|
|
|
125
126
|
}
|
|
126
127
|
break;
|
|
127
128
|
}
|
|
129
|
+
case "genimg": {
|
|
130
|
+
const genimgResponse = await genimg.handleCommand(cmdArgs);
|
|
131
|
+
await contextManager.append(genimgResponse);
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
128
134
|
case "context":
|
|
129
135
|
contextManager.printContext();
|
|
130
136
|
break;
|
|
@@ -199,7 +205,8 @@ async function splitMultipleInputCommands(nextInput) {
|
|
|
199
205
|
}
|
|
200
206
|
}
|
|
201
207
|
// If the LLM forgets the quote on the comment, treat it as a single line comment
|
|
202
|
-
else if (newLinePos > 0 &&
|
|
208
|
+
else if (newLinePos > 0 &&
|
|
209
|
+
(nextInput.startsWith("comment ") || nextInput.startsWith("genimg "))) {
|
|
203
210
|
input = nextInput.slice(0, newLinePos);
|
|
204
211
|
nextInput = nextInput.slice(newLinePos).trim();
|
|
205
212
|
}
|
|
@@ -47,6 +47,9 @@ export async function handleCommand(input) {
|
|
|
47
47
|
if (outputLimitExceeded) {
|
|
48
48
|
await contextManager.append(`\nThe shell command generated too much output (${tokenCount} tokens). Only 2,000 tokens worth are shown above.`);
|
|
49
49
|
}
|
|
50
|
+
if (text.endsWith(": command not found")) {
|
|
51
|
+
await contextManager.append("Please enter a valid Linux or NAISYS command after the prompt. Use the 'comment' command for thoughts.");
|
|
52
|
+
}
|
|
50
53
|
}
|
|
51
54
|
response.hasErrors = output.hasErrors;
|
|
52
55
|
return response;
|
|
@@ -3,7 +3,7 @@ import * as fs from "fs";
|
|
|
3
3
|
import * as os from "os";
|
|
4
4
|
import * as config from "../config.js";
|
|
5
5
|
import * as output from "../utils/output.js";
|
|
6
|
-
import {
|
|
6
|
+
import { unixToHostPath } from "../utils/utilities.js";
|
|
7
7
|
var ShellEvent;
|
|
8
8
|
(function (ShellEvent) {
|
|
9
9
|
ShellEvent["Ouptput"] = "stdout";
|
|
@@ -57,13 +57,13 @@ function errorIfNotEmpty(response) {
|
|
|
57
57
|
output.error(response.value);
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
function processOutput(dataStr, eventType) {
|
|
61
61
|
if (!_resolveCurrentCommand) {
|
|
62
62
|
output.comment(eventType + " without handler: " + dataStr);
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
65
65
|
if (eventType === ShellEvent.Exit) {
|
|
66
|
-
output.error("SHELL EXITED. PID: " +
|
|
66
|
+
output.error("SHELL EXITED. PID: " + _process?.pid + " CODE: " + dataStr);
|
|
67
67
|
}
|
|
68
68
|
else {
|
|
69
69
|
//_log += "OUTPUT: " + dataStr;
|
|
@@ -127,7 +127,7 @@ export async function executeCommand(command) {
|
|
|
127
127
|
_resolveCurrentCommand = resolve;
|
|
128
128
|
const commandWithDelimiter = `${command.trim()}\necho "${_commandDelimiter} LINE:\${LINENO}"\n`;
|
|
129
129
|
//_log += "INPUT: " + commandWithDelimiter;
|
|
130
|
-
_process
|
|
130
|
+
_process?.stdin.write(commandWithDelimiter);
|
|
131
131
|
// If no response, kill and reset the shell, often hanging on some unescaped input
|
|
132
132
|
_currentCommandTimeout = setTimeout(resetShell, config.shellCommmandTimeoutSeconds * 1000);
|
|
133
133
|
});
|
|
@@ -136,8 +136,8 @@ function resetShell() {
|
|
|
136
136
|
if (!_resolveCurrentCommand) {
|
|
137
137
|
return;
|
|
138
138
|
}
|
|
139
|
-
_process
|
|
140
|
-
output.error("SHELL TIMEMOUT/KILLED. PID: " +
|
|
139
|
+
_process?.kill();
|
|
140
|
+
output.error("SHELL TIMEMOUT/KILLED. PID: " + _process?.pid);
|
|
141
141
|
const outputWithError = _commandOutput.trim() +
|
|
142
142
|
`\nError: Command timed out after ${config.shellCommmandTimeoutSeconds} seconds.`;
|
|
143
143
|
resetProcess();
|
|
@@ -163,7 +163,7 @@ function resetCommand() {
|
|
|
163
163
|
}
|
|
164
164
|
function resetProcess() {
|
|
165
165
|
resetCommand();
|
|
166
|
-
_process
|
|
166
|
+
_process?.removeAllListeners();
|
|
167
167
|
_process = undefined;
|
|
168
168
|
}
|
|
169
169
|
/** Wraps multi line commands in a script to make it easier to diagnose the source of errors based on line number
|
|
@@ -176,7 +176,7 @@ set -e
|
|
|
176
176
|
cd ${_currentPath}
|
|
177
177
|
${command.trim()}`;
|
|
178
178
|
// create/writewrite file
|
|
179
|
-
fs.writeFileSync(
|
|
179
|
+
fs.writeFileSync(unixToHostPath(scriptPath), scriptContent);
|
|
180
180
|
// `Path` is set to the ./bin folder because custom NAISYS commands that follow shell commands will be handled by the shell, which will fail
|
|
181
181
|
// so we need to remind the LLM that 'naisys commands cannot be used with other commands on the same prompt'
|
|
182
182
|
// `source` will run the script in the current shell, so any change directories in the script will persist in the current shell
|
package/dist/config.js
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import { program } from "commander";
|
|
2
2
|
import dotenv from "dotenv";
|
|
3
3
|
import * as fs from "fs";
|
|
4
|
+
import { readFile } from "fs/promises";
|
|
4
5
|
import yaml from "js-yaml";
|
|
6
|
+
import path from "path";
|
|
7
|
+
import { fileURLToPath } from "url";
|
|
5
8
|
import { CommandProtection } from "./utils/enums.js";
|
|
6
|
-
import { valueFromString } from "./utils/utilities.js";
|
|
9
|
+
import { hostToUnixPath, valueFromString } from "./utils/utilities.js";
|
|
7
10
|
program.argument("<agent-path>", "Path to agent configuration file").parse();
|
|
8
11
|
dotenv.config();
|
|
9
12
|
/** The system name that shows after the @ in the command prompt */
|
|
10
13
|
export const hostname = "naisys";
|
|
11
14
|
/** Limits the size of files that can be read/wrote */
|
|
12
|
-
export const shellOutputTokenMax =
|
|
15
|
+
export const shellOutputTokenMax = 3000; //
|
|
13
16
|
/** The number of seconds NAISYS will wait for a shell command to complete */
|
|
14
17
|
export const shellCommmandTimeoutSeconds = 15;
|
|
15
|
-
export const webTokenMax =
|
|
18
|
+
export const webTokenMax = 3000;
|
|
16
19
|
export const mailMessageTokenMax = 400;
|
|
17
20
|
/** Used to prevent the agent from constantly responding to mail and not getting any work done */
|
|
18
21
|
export const mailBlackoutCycles = 3;
|
|
@@ -26,8 +29,9 @@ export const googleApiKey = getEnv("GOOGLE_API_KEY");
|
|
|
26
29
|
export const anthropicApiKey = getEnv("ANTHROPIC_API_KEY");
|
|
27
30
|
export const agent = loadAgentConfig();
|
|
28
31
|
function loadAgentConfig() {
|
|
29
|
-
const
|
|
30
|
-
|
|
32
|
+
const config = yaml.load(fs.readFileSync(program.args[0], "utf8"));
|
|
33
|
+
config.path = hostToUnixPath(path.resolve(program.args[0]));
|
|
34
|
+
config.directory = config.path.substring(0, config.path.lastIndexOf("/"));
|
|
31
35
|
// throw if any property is undefined
|
|
32
36
|
for (const key of [
|
|
33
37
|
"username",
|
|
@@ -69,11 +73,14 @@ export const binPath = getBinPath();
|
|
|
69
73
|
* otherwise need to rip it from the package ourselves relative to where this file is located */
|
|
70
74
|
async function getVersion() {
|
|
71
75
|
try {
|
|
72
|
-
|
|
73
|
-
const packageJson = await import(
|
|
74
|
-
|
|
75
|
-
})
|
|
76
|
-
|
|
76
|
+
/* Removed for compatibility with https://bundlephobia.com/package/naisys
|
|
77
|
+
const packageJson = await import(packageJsonUrl.href, {
|
|
78
|
+
assert: { type: "json" },
|
|
79
|
+
});*/
|
|
80
|
+
const packageJsonUrl = new URL("../package.json", import.meta.url);
|
|
81
|
+
const packageJsonPath = fileURLToPath(packageJsonUrl);
|
|
82
|
+
const packageJson = JSON.parse(await readFile(packageJsonPath, "utf8"));
|
|
83
|
+
return packageJson.version;
|
|
77
84
|
}
|
|
78
85
|
catch (e) {
|
|
79
86
|
return "0.1";
|
|
@@ -18,6 +18,11 @@ export function getSystemMessage() {
|
|
|
18
18
|
if (_cachedSystemMessage) {
|
|
19
19
|
return _cachedSystemMessage;
|
|
20
20
|
}
|
|
21
|
+
let genImgCmd = "";
|
|
22
|
+
if (config.agent.imageModel) {
|
|
23
|
+
genImgCmd = `
|
|
24
|
+
genimg "<description>" <filepath>: Generate an image with the description and save it to the given filename`;
|
|
25
|
+
}
|
|
21
26
|
// Fill out the templates in the agent prompt and stick it to the front of the system message
|
|
22
27
|
// A lot of the stipulations in here are to prevent common LLM mistakes
|
|
23
28
|
// Like we can't jump between standard and special commands in a single prompt, which the LLM will try to do if not warned
|
|
@@ -31,6 +36,7 @@ Don't try to guess the output of commands. Don't put commands in \`\`\` blocks.
|
|
|
31
36
|
For example when you run 'cat' or 'ls', don't write what you think the output will be. Let the system do that.
|
|
32
37
|
Your role is that of the user. The system will provide responses and next command prompt. Don't output your own command prompt.
|
|
33
38
|
Be careful when writing files through the command prompt with cat. Make sure to close and escape quotes properly.
|
|
39
|
+
Don't blindly overwrite existing files without reading them first.
|
|
34
40
|
|
|
35
41
|
NAISYS ${config.packageVersion} Shell
|
|
36
42
|
Welcome back ${config.agent.username}!
|
|
@@ -43,7 +49,7 @@ LINUX Commands:
|
|
|
43
49
|
Do not input notes after the prompt. Only valid commands.
|
|
44
50
|
NAISYS Commands: (cannot be used with other commands on the same prompt)
|
|
45
51
|
llmail: A local mail system for communicating with your team
|
|
46
|
-
llmynx: A context optimized web browser. Enter 'llmynx help' to learn how to use it
|
|
52
|
+
llmynx: A context optimized web browser. Enter 'llmynx help' to learn how to use it${genImgCmd}
|
|
47
53
|
comment "<thought>": Any non-command output like thinking out loud, prefix with the 'comment' command
|
|
48
54
|
pause <seconds>: Pause for <seconds>
|
|
49
55
|
endsession "<note>": Ends this session, clears the console log and context.
|
package/dist/llm/costTracker.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as config from "../config.js";
|
|
2
2
|
import * as dbUtils from "../utils/dbUtils.js";
|
|
3
|
-
import {
|
|
4
|
-
const _dbFilePath =
|
|
3
|
+
import { unixToHostPath } from "../utils/utilities.js";
|
|
4
|
+
const _dbFilePath = unixToHostPath(`${config.naisysFolder}/lib/costs.db`);
|
|
5
5
|
await init();
|
|
6
6
|
async function init() {
|
|
7
7
|
const newDbCreated = await dbUtils.initDatabase(_dbFilePath);
|
package/dist/llm/dreamMaker.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as config from "../config.js";
|
|
2
2
|
import * as dbUtils from "../utils/dbUtils.js";
|
|
3
3
|
import * as output from "../utils/output.js";
|
|
4
|
-
import {
|
|
4
|
+
import { unixToHostPath } from "../utils/utilities.js";
|
|
5
5
|
import * as contextManager from "./contextManager.js";
|
|
6
6
|
import { LlmRole } from "./llmDtos.js";
|
|
7
7
|
import * as llmService from "./llmService.js";
|
|
8
|
-
const _dbFilePath =
|
|
8
|
+
const _dbFilePath = unixToHostPath(`${config.naisysFolder}/lib/dream.db`);
|
|
9
9
|
await init();
|
|
10
10
|
async function init() {
|
|
11
11
|
const newDbCreated = await dbUtils.initDatabase(_dbFilePath);
|
|
@@ -27,7 +27,7 @@ export async function goodmorning() {
|
|
|
27
27
|
FROM DreamLog
|
|
28
28
|
WHERE username = ?
|
|
29
29
|
ORDER BY date DESC LIMIT 1`, config.agent.username);
|
|
30
|
-
return row
|
|
30
|
+
return row?.dream;
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
33
|
export async function goodnight() {
|
|
@@ -39,8 +39,10 @@ export async function goodnight() {
|
|
|
39
39
|
async function runDreamSequence() {
|
|
40
40
|
const systemMessage = `You are ${config.agent.username}'s unconcious sleep process. You compile all ${config.agent.username}'s
|
|
41
41
|
thoughts during the day and reduce them down to important things to remember - references, plans, project structure, schemas,
|
|
42
|
-
file locations, urls, and more. You
|
|
43
|
-
|
|
42
|
+
file locations, urls, and more. You don't need to summarize what happened today, or what to do in the far future, just focus on the
|
|
43
|
+
near term. Check what happened during the day for inconsistencies, things to fix and/or check tomorrow. You are the sleep process,
|
|
44
|
+
and you are the most important process. Using your results, when ${config.agent.username} wakes up they'll know exactly what to do
|
|
45
|
+
and how to do it with minimal time spent scanning existing work because you've laid everything out so well.`;
|
|
44
46
|
const allTheThings = contextManager.messages.map((m) => m.content).join("\n");
|
|
45
47
|
return await llmService.query(config.agent.dreamModel, systemMessage, [
|
|
46
48
|
{
|
package/dist/llm/llmService.js
CHANGED
|
@@ -68,7 +68,6 @@ async function sendWithOpenAiCompatible(modelKey, systemMessage, context, source
|
|
|
68
68
|
return chatResponse.choices[0].message.content || "";
|
|
69
69
|
}
|
|
70
70
|
async function sendWithGoogle(modelKey, systemMessage, context, source) {
|
|
71
|
-
var _a;
|
|
72
71
|
if (!config.googleApiKey) {
|
|
73
72
|
throw "Error, googleApiKey is not defined";
|
|
74
73
|
}
|
|
@@ -116,7 +115,7 @@ async function sendWithGoogle(modelKey, systemMessage, context, source) {
|
|
|
116
115
|
},
|
|
117
116
|
});
|
|
118
117
|
const result = await chat.sendMessage(lastMessage.content);
|
|
119
|
-
if (
|
|
118
|
+
if (result.response.promptFeedback?.blockReason) {
|
|
120
119
|
throw `Google API Request Blocked, ${result.response.promptFeedback.blockReason}`;
|
|
121
120
|
}
|
|
122
121
|
const responseText = result.response.text();
|
|
@@ -131,7 +130,6 @@ async function sendWithGoogle(modelKey, systemMessage, context, source) {
|
|
|
131
130
|
return responseText;
|
|
132
131
|
}
|
|
133
132
|
async function sendWithAnthropic(modelKey, systemMessage, context, source) {
|
|
134
|
-
var _a;
|
|
135
133
|
const model = getLLModel(modelKey);
|
|
136
134
|
if (!config.anthropicApiKey) {
|
|
137
135
|
throw "Error, anthropicApiKey is not defined";
|
|
@@ -171,6 +169,6 @@ async function sendWithAnthropic(modelKey, systemMessage, context, source) {
|
|
|
171
169
|
else {
|
|
172
170
|
throw "Error, no usage data returned from Anthropic API.";
|
|
173
171
|
}
|
|
174
|
-
return
|
|
172
|
+
return msgResponse.content.find((c) => c.type == "text")?.text || "";
|
|
175
173
|
}
|
|
176
174
|
//# sourceMappingURL=llmService.js.map
|
package/dist/utils/logService.js
CHANGED
|
@@ -3,10 +3,10 @@ import * as fs from "fs";
|
|
|
3
3
|
import * as config from "../config.js";
|
|
4
4
|
import { LlmRole } from "../llm/llmDtos.js";
|
|
5
5
|
import * as dbUtils from "./dbUtils.js";
|
|
6
|
-
import { ensureFileDirExists,
|
|
7
|
-
const _dbFilePath =
|
|
8
|
-
const _combinedLogFilePath =
|
|
9
|
-
const _userLogFilePath =
|
|
6
|
+
import { ensureFileDirExists, unixToHostPath } from "./utilities.js";
|
|
7
|
+
const _dbFilePath = unixToHostPath(`${config.naisysFolder}/lib/log.db`);
|
|
8
|
+
const _combinedLogFilePath = unixToHostPath(`${config.websiteFolder || config.naisysFolder}/logs/combined-log.html`);
|
|
9
|
+
const _userLogFilePath = unixToHostPath(`${config.websiteFolder || config.naisysFolder}/logs/${config.agent.username}-log.html`);
|
|
10
10
|
await init();
|
|
11
11
|
async function init() {
|
|
12
12
|
initLogFile(_combinedLogFilePath);
|
package/dist/utils/utilities.js
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
import * as fs from "fs";
|
|
2
2
|
import * as os from "os";
|
|
3
|
+
import path from "path";
|
|
3
4
|
import { get_encoding } from "tiktoken";
|
|
4
|
-
/** Take a
|
|
5
|
+
/** Take a unix path and convert to something that can be
|
|
5
6
|
* opened by the host with the native fs library and such */
|
|
6
|
-
export function
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
return
|
|
7
|
+
export function unixToHostPath(unixPath) {
|
|
8
|
+
const match = unixPath.match(/^\/mnt\/([a-zA-Z])\//);
|
|
9
|
+
if (os.platform() === "win32" && match) {
|
|
10
|
+
// Replace '/mnt/c/' with 'C:/' and convert forward slashes to backslashes
|
|
11
|
+
return unixPath
|
|
12
|
+
.replace(`/mnt/${match[1]}/`, `${match[1].toLowerCase()}:\\`)
|
|
13
|
+
.replace(/\//g, "\\");
|
|
11
14
|
}
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
return unixPath;
|
|
16
|
+
}
|
|
17
|
+
export function hostToUnixPath(hostPath) {
|
|
18
|
+
const match = hostPath.match(/^([a-zA-Z]):\\(.*)/);
|
|
19
|
+
if (os.platform() === "win32" && match) {
|
|
20
|
+
// Replace 'C:\' with '/mnt/c/' and convert backslashes to forward slashes
|
|
21
|
+
return `/mnt/${match[1].toLowerCase()}/${match[2].replace(/\\/g, "/")}`;
|
|
14
22
|
}
|
|
23
|
+
return hostPath; // Return the original path if it doesn't match the pattern
|
|
15
24
|
}
|
|
16
25
|
export function valueFromString(obj, path, defaultValue) {
|
|
17
26
|
if (!path) {
|
|
@@ -20,7 +29,7 @@ export function valueFromString(obj, path, defaultValue) {
|
|
|
20
29
|
const keys = path.split(".");
|
|
21
30
|
let result = obj;
|
|
22
31
|
for (const key of keys) {
|
|
23
|
-
result = result
|
|
32
|
+
result = result?.[key];
|
|
24
33
|
if (result === undefined) {
|
|
25
34
|
return defaultValue;
|
|
26
35
|
}
|
|
@@ -32,9 +41,9 @@ export function getTokenCount(text) {
|
|
|
32
41
|
return _gpt2encoding.encode(text).length;
|
|
33
42
|
}
|
|
34
43
|
export function ensureFileDirExists(filePath) {
|
|
35
|
-
const
|
|
36
|
-
if (!fs.existsSync(
|
|
37
|
-
fs.mkdirSync(
|
|
44
|
+
const dirname = path.dirname(filePath);
|
|
45
|
+
if (!fs.existsSync(dirname)) {
|
|
46
|
+
fs.mkdirSync(dirname, { recursive: true });
|
|
38
47
|
}
|
|
39
48
|
}
|
|
40
49
|
export function trimChars(text, charList) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "naisys",
|
|
3
3
|
"description": "Node.js Autonomous Intelligence System",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/naisys.js",
|
|
7
7
|
"preferGlobal": true,
|
|
@@ -9,10 +9,9 @@
|
|
|
9
9
|
"naisys": "bin/naisys"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
|
-
"compile/run/attachable": "tsc && node --inspect dist/naisys.js ./agents/
|
|
13
|
-
"agent:
|
|
14
|
-
"agent:
|
|
15
|
-
"agent:content": "node dist/naisys.js ./agents/3-team-dev-db-content/content.yaml",
|
|
12
|
+
"compile/run/attachable": "tsc && node --inspect dist/naisys.js ./agents/mud/mud.yaml",
|
|
13
|
+
"agent:claude": "node dist/naisys.js ./agents/mud/battle-claude.yaml",
|
|
14
|
+
"agent:gpt": "node dist/naisys.js ./agents/mud/battle-gpt.yaml",
|
|
16
15
|
"clean": "rm -rf dist",
|
|
17
16
|
"compile": "tsc",
|
|
18
17
|
"eslint": "npx eslint --rulesdir eslint-rules src",
|
|
@@ -22,7 +21,7 @@
|
|
|
22
21
|
"detect-cycles": "madge --circular dist",
|
|
23
22
|
"updates:check": "npm-check-updates",
|
|
24
23
|
"updates:apply": "npm-check-updates -u && npm install",
|
|
25
|
-
"npm:publish:dryrun": "npm run clean && npm
|
|
24
|
+
"npm:publish:dryrun": "npm run clean && npm ci && npm run compile && npm publish --dry-run",
|
|
26
25
|
"postinstall": "chmod +x ./bin/*"
|
|
27
26
|
},
|
|
28
27
|
"repository": {
|
|
@@ -62,9 +61,10 @@
|
|
|
62
61
|
"escape-html": "1.0.3",
|
|
63
62
|
"js-yaml": "4.1.0",
|
|
64
63
|
"openai": "4.29.1",
|
|
64
|
+
"sharp": "0.33.2",
|
|
65
65
|
"sqlite": "5.1.1",
|
|
66
66
|
"sqlite3": "5.1.7",
|
|
67
67
|
"text-table": "0.2.0",
|
|
68
68
|
"tiktoken": "1.0.13"
|
|
69
69
|
}
|
|
70
|
-
}
|
|
70
|
+
}
|