omnikey-cli 1.5.7 → 1.5.8
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/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public",
|
|
5
5
|
"registry": "https://registry.npmjs.org/"
|
|
6
6
|
},
|
|
7
|
-
"version": "1.5.
|
|
7
|
+
"version": "1.5.8",
|
|
8
8
|
"description": "CLI for onboarding users to Omnikey AI and configuring OPENAI_API_KEY. Use Yarn for install/build.",
|
|
9
9
|
"engines": {
|
|
10
10
|
"node": ">=14.0.0",
|
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.AgentAbortError = void 0;
|
|
7
|
+
exports.getSessionMessages = getSessionMessages;
|
|
7
8
|
exports.listRecentSessions = listRecentSessions;
|
|
8
9
|
exports.listTaskTemplates = listTaskTemplates;
|
|
9
10
|
exports.setDefaultTaskTemplate = setDefaultTaskTemplate;
|
|
@@ -18,6 +19,27 @@ const path_1 = __importDefault(require("path"));
|
|
|
18
19
|
const crypto_1 = require("crypto");
|
|
19
20
|
const config_1 = require("./config");
|
|
20
21
|
const omnikeyAuth_1 = require("./omnikeyAuth");
|
|
22
|
+
/**
|
|
23
|
+
* Fetch the typed message transcript for a session.
|
|
24
|
+
* Returns null when the session does not exist (404), throws on other errors.
|
|
25
|
+
*/
|
|
26
|
+
async function getSessionMessages(logger, sessionId) {
|
|
27
|
+
const token = await (0, omnikeyAuth_1.fetchJwtToken)(logger);
|
|
28
|
+
const url = `${(0, config_1.omnikeyBaseUrl)()}/api/agent/sessions/${encodeURIComponent(sessionId)}/messages`;
|
|
29
|
+
try {
|
|
30
|
+
const resp = await axios_1.default.get(url, {
|
|
31
|
+
timeout: 10000,
|
|
32
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
33
|
+
});
|
|
34
|
+
return resp.data?.messages ?? [];
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
if (axios_1.default.isAxiosError(err) && err.response?.status === 404) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
throw err;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
21
43
|
async function listRecentSessions(logger, limit = 5) {
|
|
22
44
|
const token = await (0, omnikeyAuth_1.fetchJwtToken)(logger);
|
|
23
45
|
const url = `${(0, config_1.omnikeyBaseUrl)()}/api/agent/sessions`;
|
|
@@ -11,7 +11,6 @@ const crypto_1 = require("crypto");
|
|
|
11
11
|
const winston_1 = __importDefault(require("winston"));
|
|
12
12
|
const zod_1 = require("zod");
|
|
13
13
|
const notifyTelegram_1 = require("./notifyTelegram");
|
|
14
|
-
const db_1 = require("./db");
|
|
15
14
|
exports.logger = winston_1.default.createLogger({
|
|
16
15
|
level: process.env.LOG_LEVEL || "info",
|
|
17
16
|
defaultMeta: { conId: (0, crypto_1.randomUUID)() },
|
|
@@ -24,12 +23,6 @@ exports.logger = winston_1.default.createLogger({
|
|
|
24
23
|
});
|
|
25
24
|
const app = (0, express_1.default)();
|
|
26
25
|
const port = process.env.PORT ? parseInt(process.env.PORT, 10) : 6666;
|
|
27
|
-
try {
|
|
28
|
-
(0, db_1.initDb)(exports.logger);
|
|
29
|
-
}
|
|
30
|
-
catch (e) {
|
|
31
|
-
exports.logger.error("Failed to open omnikey SQLite database:", e);
|
|
32
|
-
}
|
|
33
26
|
const botToken = process.env.TELEGRAM_BOT_TOKEN ?? "";
|
|
34
27
|
if (botToken) {
|
|
35
28
|
try {
|
|
@@ -87,11 +80,9 @@ app.listen(port, () => {
|
|
|
87
80
|
});
|
|
88
81
|
process.on("SIGINT", () => {
|
|
89
82
|
exports.logger.info("Received SIGINT. Exiting...");
|
|
90
|
-
(0, db_1.closeDb)(exports.logger);
|
|
91
83
|
process.exit(0);
|
|
92
84
|
});
|
|
93
85
|
process.on("SIGTERM", () => {
|
|
94
86
|
exports.logger.info("Received SIGTERM. Exiting...");
|
|
95
|
-
(0, db_1.closeDb)(exports.logger);
|
|
96
87
|
process.exit(0);
|
|
97
88
|
});
|
|
@@ -8,7 +8,6 @@ exports.notify = notify;
|
|
|
8
8
|
exports.setupMessageListener = setupMessageListener;
|
|
9
9
|
const node_telegram_bot_api_1 = __importDefault(require("node-telegram-bot-api"));
|
|
10
10
|
const agentClient_1 = require("./agentClient");
|
|
11
|
-
const db_1 = require("./db");
|
|
12
11
|
let bot = null;
|
|
13
12
|
function initTelegram(botToken) {
|
|
14
13
|
if (!botToken)
|
|
@@ -428,12 +427,26 @@ async function handleTaskCommand(logger, chatId) {
|
|
|
428
427
|
}
|
|
429
428
|
// 2. Otherwise show final answer from the most recent completed session.
|
|
430
429
|
try {
|
|
431
|
-
const
|
|
430
|
+
const sessions = await (0, agentClient_1.listRecentSessions)(logger, 1);
|
|
431
|
+
const session = sessions[0];
|
|
432
432
|
if (!session) {
|
|
433
433
|
await notify(logger, "🗒️ No sessions found.", { chatId });
|
|
434
434
|
return;
|
|
435
435
|
}
|
|
436
|
-
const
|
|
436
|
+
const messages = await (0, agentClient_1.getSessionMessages)(logger, session.id);
|
|
437
|
+
let finalAnswer = null;
|
|
438
|
+
if (messages) {
|
|
439
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
440
|
+
const msg = messages[i];
|
|
441
|
+
if (msg.role !== "assistant")
|
|
442
|
+
continue;
|
|
443
|
+
const block = msg.blocks?.find((b) => b.kind === "finalAnswer");
|
|
444
|
+
if (block) {
|
|
445
|
+
finalAnswer = block.text;
|
|
446
|
+
break;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
437
450
|
if (!finalAnswer) {
|
|
438
451
|
await notify(logger, `🗒️ Most recent session \`${session.id}\` has no final answer yet.`, { chatId });
|
|
439
452
|
return;
|
|
@@ -884,8 +897,8 @@ function setupMessageListener(logger, bot) {
|
|
|
884
897
|
return;
|
|
885
898
|
}
|
|
886
899
|
if (pending.sessionId) {
|
|
887
|
-
const
|
|
888
|
-
if (
|
|
900
|
+
const messages = await (0, agentClient_1.getSessionMessages)(logger, pending.sessionId);
|
|
901
|
+
if (messages === null) {
|
|
889
902
|
pendingPrompts.delete(chatId);
|
|
890
903
|
await notify(logger, "❌ Selected session no longer exists.", {
|
|
891
904
|
chatId,
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.initDb = initDb;
|
|
7
|
-
exports.closeDb = closeDb;
|
|
8
|
-
exports.getRecentSessions = getRecentSessions;
|
|
9
|
-
exports.getSessionById = getSessionById;
|
|
10
|
-
exports.getMostRecentSession = getMostRecentSession;
|
|
11
|
-
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
|
|
12
|
-
const config_1 = require("./config");
|
|
13
|
-
let dbInstance = null;
|
|
14
|
-
function initDb(logger) {
|
|
15
|
-
if (dbInstance)
|
|
16
|
-
return dbInstance;
|
|
17
|
-
const { sqlitePath } = (0, config_1.loadOmnikeyConfig)();
|
|
18
|
-
dbInstance = new better_sqlite3_1.default(sqlitePath, {
|
|
19
|
-
readonly: true,
|
|
20
|
-
fileMustExist: true,
|
|
21
|
-
});
|
|
22
|
-
// WAL is set by the writer; we only read. Set busy timeout so concurrent
|
|
23
|
-
// writes from omnikey-ai never throw SQLITE_BUSY at us.
|
|
24
|
-
dbInstance.pragma("busy_timeout = 5000");
|
|
25
|
-
logger.info("Opened SQLite database (read-only)", { path: sqlitePath });
|
|
26
|
-
return dbInstance;
|
|
27
|
-
}
|
|
28
|
-
function closeDb(logger) {
|
|
29
|
-
if (!dbInstance)
|
|
30
|
-
return;
|
|
31
|
-
try {
|
|
32
|
-
dbInstance.close();
|
|
33
|
-
logger?.info("Closed SQLite database");
|
|
34
|
-
}
|
|
35
|
-
catch (err) {
|
|
36
|
-
logger?.warn("Error closing SQLite database", {
|
|
37
|
-
error: err.message,
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
finally {
|
|
41
|
-
dbInstance = null;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
function getRecentSessions(limit) {
|
|
45
|
-
const db = dbInstance;
|
|
46
|
-
if (!db)
|
|
47
|
-
throw new Error("Database not initialised. Call initDb() first.");
|
|
48
|
-
const rows = db
|
|
49
|
-
.prepare(`SELECT id, title, turns, last_active_at AS lastActiveAt, group_name AS groupName
|
|
50
|
-
FROM agent_sessions
|
|
51
|
-
ORDER BY last_active_at DESC
|
|
52
|
-
LIMIT ?`)
|
|
53
|
-
.all(limit);
|
|
54
|
-
return rows;
|
|
55
|
-
}
|
|
56
|
-
function getSessionById(sessionId) {
|
|
57
|
-
const db = dbInstance;
|
|
58
|
-
if (!db)
|
|
59
|
-
throw new Error("Database not initialised. Call initDb() first.");
|
|
60
|
-
const row = db
|
|
61
|
-
.prepare(`SELECT id, title, turns, last_active_at AS lastActiveAt, group_name AS groupName, history_json AS historyJson
|
|
62
|
-
FROM agent_sessions
|
|
63
|
-
WHERE id = ?`)
|
|
64
|
-
.get(sessionId);
|
|
65
|
-
return row ?? null;
|
|
66
|
-
}
|
|
67
|
-
function getMostRecentSession() {
|
|
68
|
-
const db = dbInstance;
|
|
69
|
-
if (!db)
|
|
70
|
-
throw new Error("Database not initialised. Call initDb() first.");
|
|
71
|
-
const row = db
|
|
72
|
-
.prepare(`SELECT id, title, turns, last_active_at AS lastActiveAt, group_name AS groupName, history_json AS historyJson
|
|
73
|
-
FROM agent_sessions
|
|
74
|
-
ORDER BY last_active_at DESC
|
|
75
|
-
LIMIT 1`)
|
|
76
|
-
.get();
|
|
77
|
-
return row ?? null;
|
|
78
|
-
}
|