naisys 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/.env.example +15 -0
  2. package/LICENSE.md +7 -0
  3. package/README.md +125 -0
  4. package/agents/example.yaml +34 -0
  5. package/dist/__tests__/utils/output.test.js +22 -0
  6. package/dist/__tests__/utils/output.test.js.map +1 -0
  7. package/dist/__tests__/utils/utilities.test.js +42 -0
  8. package/dist/__tests__/utils/utilities.test.js.map +1 -0
  9. package/dist/apps/llmail.js +350 -0
  10. package/dist/apps/llmail.js.map +1 -0
  11. package/dist/apps/llmynx.js +229 -0
  12. package/dist/apps/llmynx.js.map +1 -0
  13. package/dist/command/commandHandler.js +151 -0
  14. package/dist/command/commandHandler.js.map +1 -0
  15. package/dist/command/commandLoop.js +176 -0
  16. package/dist/command/commandLoop.js.map +1 -0
  17. package/dist/command/promptBuilder.js +133 -0
  18. package/dist/command/promptBuilder.js.map +1 -0
  19. package/dist/command/shellCommand.js +36 -0
  20. package/dist/command/shellCommand.js.map +1 -0
  21. package/dist/command/shellWrapper.js +179 -0
  22. package/dist/command/shellWrapper.js.map +1 -0
  23. package/dist/config.js +46 -0
  24. package/dist/config.js.map +1 -0
  25. package/dist/llm/contextManager.js +127 -0
  26. package/dist/llm/contextManager.js.map +1 -0
  27. package/dist/llm/costTracker.js +43 -0
  28. package/dist/llm/costTracker.js.map +1 -0
  29. package/dist/llm/llModels.js +52 -0
  30. package/dist/llm/llModels.js.map +1 -0
  31. package/dist/llm/llmDtos.js +8 -0
  32. package/dist/llm/llmDtos.js.map +1 -0
  33. package/dist/llm/llmService.js +113 -0
  34. package/dist/llm/llmService.js.map +1 -0
  35. package/dist/naisys.js +7 -0
  36. package/dist/naisys.js.map +1 -0
  37. package/dist/utils/dbUtils.js +37 -0
  38. package/dist/utils/dbUtils.js.map +1 -0
  39. package/dist/utils/inputMode.js +18 -0
  40. package/dist/utils/inputMode.js.map +1 -0
  41. package/dist/utils/logService.js +116 -0
  42. package/dist/utils/logService.js.map +1 -0
  43. package/dist/utils/output.js +38 -0
  44. package/dist/utils/output.js.map +1 -0
  45. package/dist/utils/utilities.js +40 -0
  46. package/dist/utils/utilities.js.map +1 -0
  47. package/naisys.sh +56 -0
  48. package/package.json +70 -0
@@ -0,0 +1,52 @@
1
+ import * as config from "../config.js";
2
+ export var LlmApiType;
3
+ (function (LlmApiType) {
4
+ LlmApiType["OpenAI"] = "openai";
5
+ LlmApiType["Google"] = "google";
6
+ })(LlmApiType || (LlmApiType = {}));
7
+ const llmModels = [
8
+ {
9
+ key: "gpt4turbo",
10
+ name: "gpt-4-0125-preview",
11
+ apiType: LlmApiType.OpenAI,
12
+ maxTokens: 128000,
13
+ // Prices are per 1000 tokens
14
+ inputCost: 0.01,
15
+ outputCost: 0.03,
16
+ },
17
+ {
18
+ key: "gpt3turbo",
19
+ name: "gpt-3.5-turbo-0125",
20
+ apiType: LlmApiType.OpenAI,
21
+ maxTokens: 16000,
22
+ // Prices are per 1000 tokens
23
+ inputCost: 0.0005,
24
+ outputCost: 0.0015,
25
+ },
26
+ {
27
+ key: "local",
28
+ name: config.localLlmName || "local",
29
+ baseUrl: config.localLlmUrl,
30
+ apiType: LlmApiType.OpenAI,
31
+ maxTokens: 8000,
32
+ inputCost: 0,
33
+ outputCost: 0,
34
+ },
35
+ {
36
+ key: "google",
37
+ name: "gemini-pro",
38
+ apiType: LlmApiType.Google,
39
+ maxTokens: 8000,
40
+ // 60 queries per minute free then the prices below are per 1000 characters
41
+ inputCost: 0.000125,
42
+ outputCost: 0.000375,
43
+ },
44
+ ];
45
+ export function getLLModel(key) {
46
+ const model = llmModels.find((m) => m.key === key);
47
+ if (!model) {
48
+ throw `Error, model not found: ${key}`;
49
+ }
50
+ return model;
51
+ }
52
+ //# sourceMappingURL=llModels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llModels.js","sourceRoot":"","sources":["../../src/llm/llModels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AAEvC,MAAM,CAAN,IAAY,UAGX;AAHD,WAAY,UAAU;IACpB,+BAAiB,CAAA;IACjB,+BAAiB,CAAA;AACnB,CAAC,EAHW,UAAU,KAAV,UAAU,QAGrB;AAYD,MAAM,SAAS,GAAe;IAC5B;QACE,GAAG,EAAE,WAAW;QAChB,IAAI,EAAE,oBAAoB;QAC1B,OAAO,EAAE,UAAU,CAAC,MAAM;QAC1B,SAAS,EAAE,MAAO;QAClB,6BAA6B;QAC7B,SAAS,EAAE,IAAI;QACf,UAAU,EAAE,IAAI;KACjB;IACD;QACE,GAAG,EAAE,WAAW;QAChB,IAAI,EAAE,oBAAoB;QAC1B,OAAO,EAAE,UAAU,CAAC,MAAM;QAC1B,SAAS,EAAE,KAAM;QACjB,6BAA6B;QAC7B,SAAS,EAAE,MAAM;QACjB,UAAU,EAAE,MAAM;KACnB;IACD;QACE,GAAG,EAAE,OAAO;QACZ,IAAI,EAAE,MAAM,CAAC,YAAY,IAAI,OAAO;QACpC,OAAO,EAAE,MAAM,CAAC,WAAW;QAC3B,OAAO,EAAE,UAAU,CAAC,MAAM;QAC1B,SAAS,EAAE,IAAK;QAChB,SAAS,EAAE,CAAC;QACZ,UAAU,EAAE,CAAC;KACd;IACD;QACE,GAAG,EAAE,QAAQ;QACb,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,UAAU,CAAC,MAAM;QAC1B,SAAS,EAAE,IAAK;QAChB,2EAA2E;QAC3E,SAAS,EAAE,QAAQ;QACnB,UAAU,EAAE,QAAQ;KACrB;CACF,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;IAEnD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,2BAA2B,GAAG,EAAE,CAAC;IACzC,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,8 @@
1
+ export var LlmRole;
2
+ (function (LlmRole) {
3
+ LlmRole["Assistant"] = "assistant";
4
+ LlmRole["User"] = "user";
5
+ /** Not supported by Google API */
6
+ LlmRole["System"] = "system";
7
+ })(LlmRole || (LlmRole = {}));
8
+ //# sourceMappingURL=llmDtos.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llmDtos.js","sourceRoot":"","sources":["../../src/llm/llmDtos.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,OAKX;AALD,WAAY,OAAO;IACjB,kCAAuB,CAAA;IACvB,wBAAa,CAAA;IACb,kCAAkC;IAClC,4BAAiB,CAAA;AACnB,CAAC,EALW,OAAO,KAAP,OAAO,QAKlB"}
@@ -0,0 +1,113 @@
1
+ import { GoogleGenerativeAI } from "@google/generative-ai";
2
+ import OpenAI from "openai";
3
+ import * as config from "../config.js";
4
+ import * as costTracker from "./costTracker.js";
5
+ import { LlmApiType, getLLModel } from "./llModels.js";
6
+ import { LlmRole } from "./llmDtos.js";
7
+ export async function query(modelKey, systemMessage, context, source) {
8
+ const currentTotalCost = await costTracker.getTotalCosts();
9
+ if (config.agent.spendLimitDollars < currentTotalCost) {
10
+ throw `LLM Spend limit of $${config.agent.spendLimitDollars} reached`;
11
+ }
12
+ const model = getLLModel(modelKey);
13
+ if (model.apiType == LlmApiType.Google) {
14
+ return sendWithGoogle(modelKey, systemMessage, context, source);
15
+ }
16
+ else if (model.apiType == LlmApiType.OpenAI) {
17
+ return sendWithOpenAiCompatible(modelKey, systemMessage, context, source);
18
+ }
19
+ else {
20
+ throw `Error, unknown LLM API type ${model.apiType}`;
21
+ }
22
+ }
23
+ async function sendWithOpenAiCompatible(modelKey, systemMessage, context, source) {
24
+ const model = getLLModel(modelKey);
25
+ if (model.key === "local") {
26
+ if (!model.baseUrl) {
27
+ throw "Error, local model baseUrl is not defined";
28
+ }
29
+ }
30
+ else if (!config.openaiApiKey) {
31
+ throw "Error, openaiApiKey is not defined";
32
+ }
33
+ const openAI = new OpenAI({
34
+ baseURL: model.baseUrl,
35
+ apiKey: config.openaiApiKey,
36
+ });
37
+ // Assert the last message on the context is a user message
38
+ const lastMessage = context[context.length - 1];
39
+ if (lastMessage.role !== LlmRole.User) {
40
+ throw "Error, last message on context is not a user message";
41
+ }
42
+ const chatCompletion = await openAI.chat.completions.create({
43
+ model: model.name,
44
+ messages: [
45
+ {
46
+ role: LlmRole.System,
47
+ content: systemMessage,
48
+ },
49
+ ...context.map((m) => ({
50
+ content: m.content,
51
+ role: m.role,
52
+ })),
53
+ ],
54
+ });
55
+ // Total up costs, prices are per 1000 tokens
56
+ if (chatCompletion.usage) {
57
+ const cost = chatCompletion.usage.prompt_tokens * model.inputCost +
58
+ chatCompletion.usage.completion_tokens * model.outputCost;
59
+ await costTracker.recordCost(cost / 1000, source, model.name);
60
+ }
61
+ else {
62
+ throw "Error, no usage data returned from OpenAI API.";
63
+ }
64
+ return chatCompletion.choices[0].message.content || "";
65
+ }
66
+ async function sendWithGoogle(modelKey, systemMessage, context, source) {
67
+ var _a;
68
+ if (!config.googleApiKey) {
69
+ throw "Error, googleApiKey is not defined";
70
+ }
71
+ const model = getLLModel(modelKey);
72
+ const googleAI = new GoogleGenerativeAI(config.googleApiKey);
73
+ const googleModel = googleAI.getGenerativeModel({ model: model.name });
74
+ // Assert the last message on the context is a user message
75
+ const lastMessage = context[context.length - 1];
76
+ if (lastMessage.role !== LlmRole.User) {
77
+ throw "Error, last message on context is not a user message";
78
+ }
79
+ const history = [
80
+ {
81
+ role: LlmRole.User, // System role is not supported by Google API
82
+ parts: systemMessage,
83
+ },
84
+ {
85
+ role: "model",
86
+ parts: "Understood",
87
+ },
88
+ ...context
89
+ .filter((m) => m != lastMessage)
90
+ .map((m) => ({
91
+ role: m.role == LlmRole.Assistant ? "model" : LlmRole.User,
92
+ parts: m.content,
93
+ })),
94
+ ];
95
+ const chat = googleModel.startChat({
96
+ history: history,
97
+ generationConfig: {
98
+ maxOutputTokens: 2000,
99
+ },
100
+ });
101
+ const result = await chat.sendMessage(lastMessage.content);
102
+ if ((_a = result.response.promptFeedback) === null || _a === void 0 ? void 0 : _a.blockReason) {
103
+ throw `Google API Request Blocked, ${result.response.promptFeedback.blockReason}`;
104
+ }
105
+ const responseText = result.response.text();
106
+ // Total up cost, per 1000 characters with google
107
+ // todo: take into account google allows 60 queries per minute for free
108
+ const cost = lastMessage.content.length * model.inputCost +
109
+ responseText.length * model.outputCost;
110
+ await costTracker.recordCost(cost / 1000, source, model.name);
111
+ return responseText;
112
+ }
113
+ //# sourceMappingURL=llmService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llmService.js","sourceRoot":"","sources":["../../src/llm/llmService.ts"],"names":[],"mappings":"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"}
package/dist/naisys.js ADDED
@@ -0,0 +1,7 @@
1
+ import * as commandLoop from "./command/commandLoop.js";
2
+ import * as output from "./utils/output.js";
3
+ await output.commentAndLog(`NAISYS STARTED`);
4
+ await commandLoop.run();
5
+ await output.commentAndLog(`NAISYS TERMINATED`);
6
+ process.exit(0);
7
+ //# sourceMappingURL=naisys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naisys.js","sourceRoot":"","sources":["../src/naisys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,0BAA0B,CAAC;AACxD,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAE5C,MAAM,MAAM,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;AAE7C,MAAM,WAAW,CAAC,GAAG,EAAE,CAAC;AAExB,MAAM,MAAM,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC;AAEhD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,37 @@
1
+ import * as fs from "fs";
2
+ import { open } from "sqlite";
3
+ import sqlite3 from "sqlite3";
4
+ import { ensureFileDirExists } from "./utilities.js";
5
+ export async function initDatabase(filepath) {
6
+ if (fs.existsSync(filepath)) {
7
+ return false;
8
+ }
9
+ ensureFileDirExists(filepath);
10
+ const db = await open({
11
+ filename: filepath,
12
+ driver: sqlite3.Database,
13
+ mode: sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE,
14
+ });
15
+ await db.close();
16
+ return true;
17
+ }
18
+ export async function openDatabase(filepath) {
19
+ const db = await open({
20
+ filename: filepath,
21
+ driver: sqlite3.Database,
22
+ mode: sqlite3.OPEN_READWRITE,
23
+ });
24
+ // Turn foreign key constraints on
25
+ await db.exec("PRAGMA foreign_keys = ON");
26
+ return db;
27
+ }
28
+ export async function usingDatabase(filepath, run) {
29
+ const db = await openDatabase(filepath);
30
+ try {
31
+ return await run(db);
32
+ }
33
+ finally {
34
+ await db.close();
35
+ }
36
+ }
37
+ //# sourceMappingURL=dbUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dbUtils.js","sourceRoot":"","sources":["../../src/utils/dbUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAY,IAAI,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAErD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAE9B,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC;QACpB,QAAQ,EAAE,QAAQ;QAClB,MAAM,EAAE,OAAO,CAAC,QAAQ;QACxB,IAAI,EAAE,OAAO,CAAC,cAAc,GAAG,OAAO,CAAC,WAAW;KACnD,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;IAEjB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC;QACpB,QAAQ,EAAE,QAAQ;QAClB,MAAM,EAAE,OAAO,CAAC,QAAQ;QACxB,IAAI,EAAE,OAAO,CAAC,cAAc;KAC7B,CAAC,CAAC;IAEH,kCAAkC;IAClC,MAAM,EAAE,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAE1C,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAAgB,EAChB,GAAiC;IAEjC,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;IAExC,IAAI,CAAC;QACH,OAAO,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC;IACvB,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;AACH,CAAC"}
@@ -0,0 +1,18 @@
1
+ export var InputMode;
2
+ (function (InputMode) {
3
+ InputMode["Debug"] = "debug";
4
+ InputMode["LLM"] = "llm";
5
+ })(InputMode || (InputMode = {}));
6
+ export let current = InputMode.Debug;
7
+ export function toggle(forceMode) {
8
+ if (forceMode) {
9
+ current = forceMode;
10
+ }
11
+ else if (current == InputMode.Debug) {
12
+ current = InputMode.LLM;
13
+ }
14
+ else if (current == InputMode.LLM) {
15
+ current = InputMode.Debug;
16
+ }
17
+ }
18
+ //# sourceMappingURL=inputMode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inputMode.js","sourceRoot":"","sources":["../../src/utils/inputMode.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,SAGX;AAHD,WAAY,SAAS;IACnB,4BAAe,CAAA;IACf,wBAAW,CAAA;AACb,CAAC,EAHW,SAAS,KAAT,SAAS,QAGpB;AAED,MAAM,CAAC,IAAI,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC;AAErC,MAAM,UAAU,MAAM,CAAC,SAAqB;IAC1C,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,GAAG,SAAS,CAAC;IACtB,CAAC;SAAM,IAAI,OAAO,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;QACtC,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC;IAC1B,CAAC;SAAM,IAAI,OAAO,IAAI,SAAS,CAAC,GAAG,EAAE,CAAC;QACpC,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC;IAC5B,CAAC;AACH,CAAC"}
@@ -0,0 +1,116 @@
1
+ import escapeHtml from "escape-html";
2
+ import * as fs from "fs";
3
+ import * as config from "../config.js";
4
+ import { LlmRole } from "../llm/llmDtos.js";
5
+ import * as dbUtils from "./dbUtils.js";
6
+ import { ensureFileDirExists, naisysToHostPath } from "./utilities.js";
7
+ const _dbFilePath = naisysToHostPath(`${config.naisysFolder}/lib/log.db`);
8
+ const _combinedLogFilePath = naisysToHostPath(`${config.websiteFolder || config.naisysFolder}/logs/combined-log.html`);
9
+ const _userLogFilePath = naisysToHostPath(`${config.websiteFolder || config.naisysFolder}/logs/${config.agent.username}-log.html`);
10
+ await init();
11
+ async function init() {
12
+ initLogFile(_combinedLogFilePath);
13
+ initLogFile(_userLogFilePath);
14
+ // Init log database
15
+ const newDbCreated = await dbUtils.initDatabase(_dbFilePath);
16
+ await usingDatabase(async (db) => {
17
+ if (!newDbCreated) {
18
+ return;
19
+ }
20
+ const createTables = [
21
+ `CREATE TABLE ContextLog (
22
+ id INTEGER PRIMARY KEY,
23
+ username TEXT NOT NULL,
24
+ source TEXT NOT NULL,
25
+ type TEXT NOT NULL,
26
+ message TEXT NOT NULL,
27
+ date TEXT NOT NULL
28
+ )`,
29
+ ];
30
+ for (const createTable of createTables) {
31
+ await db.exec(createTable);
32
+ }
33
+ });
34
+ }
35
+ function initLogFile(filePath) {
36
+ ensureFileDirExists(filePath);
37
+ if (fs.existsSync(filePath)) {
38
+ return;
39
+ }
40
+ // Start html file with table: date, user, role, messages
41
+ fs.writeFileSync(filePath, `<html>
42
+ <head><title>Context Log</title></head>
43
+ <style>
44
+ body { font-family: monospace; background-color: black; color: white; }
45
+ table { border-collapse: collapse; width: 100%; }
46
+ th, td { border: 1px solid grey; padding: 8px; }
47
+ th { text-align: left; }
48
+ td { vertical-align: top; }
49
+ .date { white-space: nowrap; }
50
+ .llm { color: magenta; }
51
+ .error { color: red; }
52
+ .comment { color: green; }
53
+ </style>
54
+ <body>
55
+ <table border="1">
56
+ <tr><th>Date</th><th>User</th><th>Source</th><th>Message</th></tr>`);
57
+ }
58
+ export async function write(message) {
59
+ const insertedId = await usingDatabase(async (db) => {
60
+ const inserted = await db.run("INSERT INTO ContextLog (username, source, type, message, date) VALUES (?, ?, ?, ?, ?)", config.agent.username, roleToSource(message.role), message.type || "", message.content, new Date().toISOString());
61
+ return inserted.lastID;
62
+ });
63
+ appendToLogFile(_combinedLogFilePath, message);
64
+ appendToLogFile(_userLogFilePath, message);
65
+ return insertedId;
66
+ }
67
+ export async function update(message, appendedText) {
68
+ await usingDatabase(async (db) => {
69
+ await db.run("UPDATE ContextLog SET message = ? WHERE id = ?", message.content, message.logId);
70
+ });
71
+ // Can't rewrite the log like we can the db, so just log the appended text
72
+ const appendedMessage = {
73
+ role: message.role,
74
+ content: appendedText,
75
+ };
76
+ appendToLogFile(_combinedLogFilePath, appendedMessage);
77
+ appendToLogFile(_userLogFilePath, appendedMessage);
78
+ }
79
+ function appendToLogFile(filepath, message) {
80
+ const source = roleToSource(message.role);
81
+ fs.appendFileSync(filepath, `<tr>
82
+ <td class='date'>${new Date().toLocaleString()}</td>
83
+ <td>${config.agent.username}</td>
84
+ <td>${source}</td>
85
+ <td class='${source.toLocaleLowerCase()} ${message.type}'>
86
+ <pre>${escapeHtml(message.content)}</pre>
87
+ </td>
88
+ </tr>`);
89
+ }
90
+ export function getPreviousEndSessionNote() {
91
+ // Find the most recent message in the log that starts with 'endsession' for the local user
92
+ return usingDatabase(async (db) => {
93
+ const result = await db.get(`SELECT message
94
+ FROM ContextLog
95
+ WHERE username = ? AND message LIKE 'endsession %'
96
+ ORDER BY id DESC
97
+ LIMIT 1`, [config.agent.username]);
98
+ const endSessionMsg = result === null || result === void 0 ? void 0 : result.message;
99
+ // Trim endsession prefix
100
+ return (endSessionMsg === null || endSessionMsg === void 0 ? void 0 : endSessionMsg.slice("endsession ".length)) || "";
101
+ });
102
+ }
103
+ async function usingDatabase(run) {
104
+ return dbUtils.usingDatabase(_dbFilePath, run);
105
+ }
106
+ function roleToSource(role) {
107
+ switch (role) {
108
+ case LlmRole.Assistant:
109
+ return "LLM";
110
+ case LlmRole.User:
111
+ return "NAISYS";
112
+ case LlmRole.System:
113
+ return "NAISYS";
114
+ }
115
+ }
116
+ //# sourceMappingURL=logService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logService.js","sourceRoot":"","sources":["../../src/utils/logService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import chalk from "chalk";
2
+ import { LlmRole } from "../llm/llmDtos.js";
3
+ import * as logService from "./logService.js";
4
+ export var OutputColor;
5
+ (function (OutputColor) {
6
+ OutputColor["comment"] = "greenBright";
7
+ OutputColor["error"] = "redBright";
8
+ OutputColor["llm"] = "magenta";
9
+ OutputColor["console"] = "white";
10
+ OutputColor["loading"] = "yellow";
11
+ })(OutputColor || (OutputColor = {}));
12
+ // color available on chalk
13
+ export function write(msg, color = OutputColor.console) {
14
+ console.log(chalk[color](msg));
15
+ }
16
+ /** Meant for non-content output we show in the console, but is not added to the context */
17
+ export function comment(msg) {
18
+ write(msg, OutputColor.comment);
19
+ }
20
+ export async function commentAndLog(msg) {
21
+ comment(msg);
22
+ await writeDbLog(msg, "comment");
23
+ }
24
+ export function error(msg) {
25
+ write(msg, OutputColor.error);
26
+ }
27
+ export async function errorAndLog(msg) {
28
+ error(msg);
29
+ await writeDbLog(msg, "error");
30
+ }
31
+ async function writeDbLog(msg, type) {
32
+ await logService.write({
33
+ role: LlmRole.User,
34
+ content: msg,
35
+ type,
36
+ });
37
+ }
38
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAC;AAE9C,MAAM,CAAN,IAAY,WAMX;AAND,WAAY,WAAW;IACrB,sCAAuB,CAAA;IACvB,kCAAmB,CAAA;IACnB,8BAAe,CAAA;IACf,gCAAiB,CAAA;IACjB,iCAAkB,CAAA;AACpB,CAAC,EANW,WAAW,KAAX,WAAW,QAMtB;AAED,2BAA2B;AAC3B,MAAM,UAAU,KAAK,CAAC,GAAW,EAAE,QAAqB,WAAW,CAAC,OAAO;IACzE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AACjC,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,KAAK,CAAC,GAAG,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAW;IAC7C,OAAO,CAAC,GAAG,CAAC,CAAC;IAEb,MAAM,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,GAAW;IAC/B,KAAK,CAAC,GAAG,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW;IAC3C,KAAK,CAAC,GAAG,CAAC,CAAC;IAEX,MAAM,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AACjC,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,GAAW,EAAE,IAAY;IACjD,MAAM,UAAU,CAAC,KAAK,CAAC;QACrB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE,GAAG;QACZ,IAAI;KACL,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,40 @@
1
+ import * as fs from "fs";
2
+ import * as os from "os";
3
+ import { get_encoding } from "tiktoken";
4
+ /** Take a NAISYS path and convert to something that can be
5
+ * opened by the host with the native fs library and such */
6
+ export function naisysToHostPath(filePath) {
7
+ if (os.platform() === "win32" && filePath.startsWith("/mnt/")) {
8
+ // "/mnt/c/" -> "c:/"
9
+ filePath = filePath.substring(5);
10
+ return filePath[0] + ":" + filePath.substring(1);
11
+ }
12
+ else {
13
+ return filePath;
14
+ }
15
+ }
16
+ export function valueFromString(obj, path, defaultValue) {
17
+ if (!path) {
18
+ return obj;
19
+ }
20
+ const keys = path.split(".");
21
+ let result = obj;
22
+ for (const key of keys) {
23
+ result = result === null || result === void 0 ? void 0 : result[key];
24
+ if (result === undefined) {
25
+ return defaultValue;
26
+ }
27
+ }
28
+ return result;
29
+ }
30
+ const _gpt2encoding = get_encoding("gpt2");
31
+ export function getTokenCount(text) {
32
+ return _gpt2encoding.encode(text).length;
33
+ }
34
+ export function ensureFileDirExists(filePath) {
35
+ const dir = filePath.split("/").slice(0, -1).join("/");
36
+ if (!fs.existsSync(dir)) {
37
+ fs.mkdirSync(dir, { recursive: true });
38
+ }
39
+ }
40
+ //# sourceMappingURL=utilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utilities.js","sourceRoot":"","sources":["../../src/utils/utilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC;6DAC6D;AAC7D,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,IAAI,EAAE,CAAC,QAAQ,EAAE,KAAK,OAAO,IAAI,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9D,qBAAqB;QACrB,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACjC,OAAO,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC;SAAM,CAAC;QACN,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAQ,EAAE,IAAY,EAAE,YAAqB;IAC3E,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,GAAG,CAAC;IACb,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,MAAM,GAAG,GAAG,CAAC;IACjB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,GAAG,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAG,GAAG,CAAC,CAAC;QACvB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,YAAY,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,aAAa,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;AAE3C,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,QAAgB;IAClD,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;AACH,CAAC"}
package/naisys.sh ADDED
@@ -0,0 +1,56 @@
1
+ #!/bin/bash
2
+
3
+ # Make sure to enable this script for execution with `chmod +x runteam.sh`
4
+
5
+ # Check if an argument is provided
6
+ if [ $# -eq 0 ]; then
7
+ echo "Runs an entire team of agents in a tmux session"
8
+ echo " Usage: naisys <path_to_agent_directory>"
9
+ echo " Note: The folder the agents are in will be treated as the tmux session name"
10
+ exit 1
11
+ fi
12
+
13
+ # TODO: In the future should implement a max agents per window in the session
14
+ # Will require an outer loop to create new windows
15
+ # How many agents per window
16
+ # AGENTS_PER_WINDOW=4
17
+
18
+ # Resolves the location of naisys from the bin directory
19
+ SCRIPT=$(readlink -f "$0" || echo "$0")
20
+ SCRIPT_DIR=$(dirname "$SCRIPT")
21
+
22
+ # Directory containing agent files
23
+ AGENT_DIR="$1"
24
+ TEAM_NAME=$(basename "$AGENT_DIR")
25
+
26
+ # Start a new tmux session detached
27
+ tmux new-session -d -s $TEAM_NAME
28
+
29
+ # Get a list of agent paths
30
+ AGENT_FILES=($(find $AGENT_DIR -type f)) # This will list all files in the directory
31
+
32
+ # Split the window into panes and start agents
33
+ for ((i = 0; i < ${#AGENT_FILES[@]}; i++)); do
34
+ echo "Starting agent $((i + 1)) of ${#AGENT_FILES[@]}..."
35
+ sleep $((i == 0 ? 3 : 1)) # Sleep longer for the first agent
36
+
37
+ # For the first agent, no split is needed
38
+ if [ $i -eq 0 ]; then
39
+ tmux send-keys -t $TEAM_NAME:0.0 "node $SCRIPT_DIR/dist/naisys.js '${AGENT_FILES[i]}'" C-m # Quote the path
40
+ else
41
+ # Determine pane split direction based on odd/even pane index
42
+ if [ $((i % 2)) -eq 0 ]; then
43
+ tmux split-window -v -t $TEAM_NAME:0
44
+ else
45
+ tmux split-window -h -t $TEAM_NAME:0
46
+ fi
47
+ tmux send-keys "node $SCRIPT_DIR/dist/naisys.js '${AGENT_FILES[i]}'" C-m # Quote the path
48
+ tmux last-pane # Move focus back to the last pane to ensure correct targeting in the next iteration
49
+ fi
50
+ done
51
+
52
+ # Optionally, you can balance the panes if you want
53
+ tmux select-layout -t $TEAM_NAME tiled
54
+
55
+ # Attach to the session
56
+ tmux attach-session -t $TEAM_NAME
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "naisys",
3
+ "description": "Node.js Autonomous Intelligence System",
4
+ "version": "1.0.1",
5
+ "main": "dist/naisys.js",
6
+ "type": "module",
7
+ "scripts": {
8
+ "compile/run/attachable": "tsc && node --inspect dist/naisys.js ./agents/example.yaml",
9
+ "run agent:dev": "node dist/naisys.js ./agents/eva-site-2-team/dev.yaml",
10
+ "run agent:admin": "node dist/naisys.js ./agents/eva-site-2-team/admin.yaml",
11
+ "clean": "rm -rf dist",
12
+ "clean:win": "wsl rm -rf dist",
13
+ "compile": "tsc",
14
+ "eslint": "npx eslint --rulesdir eslint-rules src",
15
+ "test": "tsc && node --experimental-vm-modules node_modules/jest/bin/jest.js --testPathPattern=dist/__tests__",
16
+ "prettier": "npx prettier --write .",
17
+ "dependency-graph": "madge --image dependency-graph.png dist",
18
+ "detect-cycles": "madge --circular dist",
19
+ "updates:check": "npm-check-updates",
20
+ "updates:apply": "npm-check-updates -u && npm update"
21
+ },
22
+ "bin": {
23
+ "naisys": "naisys.sh"
24
+ },
25
+ "files": [
26
+ "agents/example.yaml",
27
+ "dist/**/*",
28
+ ".env.example"
29
+ ],
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/swax/NAISYS.git"
33
+ },
34
+ "keywords": [
35
+ "ai",
36
+ "agent",
37
+ "automation",
38
+ "cli-tools",
39
+ "devops-tools",
40
+ "naisys"
41
+ ],
42
+ "author": "John Marshall",
43
+ "license": "MIT",
44
+ "devDependencies": {
45
+ "@types/escape-html": "1.0.4",
46
+ "@types/js-yaml": "4.0.9",
47
+ "@types/node": "20.11.22",
48
+ "@types/text-table": "0.2.5",
49
+ "@typescript-eslint/eslint-plugin": "7.1.0",
50
+ "@typescript-eslint/parser": "7.1.0",
51
+ "eslint": "8.57.0",
52
+ "jest": "29.7.0",
53
+ "prettier": "3.2.5",
54
+ "ts-node": "10.9.2",
55
+ "typescript": "5.3.3"
56
+ },
57
+ "dependencies": {
58
+ "@google/generative-ai": "0.2.1",
59
+ "chalk": "5.3.0",
60
+ "commander": "12.0.0",
61
+ "dotenv": "16.4.5",
62
+ "escape-html": "1.0.3",
63
+ "js-yaml": "4.1.0",
64
+ "openai": "4.28.4",
65
+ "sqlite": "5.1.1",
66
+ "sqlite3": "5.1.7",
67
+ "text-table": "0.2.0",
68
+ "tiktoken": "1.0.13"
69
+ }
70
+ }