@cosmicstack/mercury-agent 0.2.1 → 0.2.3
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/dist/index.js +84 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -848,6 +848,7 @@ You can override this:
|
|
|
848
848
|
});
|
|
849
849
|
}
|
|
850
850
|
this.capabilities.setChannelContext(msg.channelId, msg.channelType);
|
|
851
|
+
this.capabilities.permissions.setCurrentChannelType(msg.channelType);
|
|
851
852
|
const fallbackIterator = this.providers.getFallbackIterator();
|
|
852
853
|
let result = null;
|
|
853
854
|
let usedProvider = null;
|
|
@@ -1720,7 +1721,7 @@ var CLIChannel = class extends BaseChannel {
|
|
|
1720
1721
|
// src/channels/telegram.ts
|
|
1721
1722
|
import fs2 from "fs";
|
|
1722
1723
|
import path2 from "path";
|
|
1723
|
-
import { Bot, InputFile } from "grammy";
|
|
1724
|
+
import { Bot, InputFile, InlineKeyboard } from "grammy";
|
|
1724
1725
|
import { autoRetry } from "@grammyjs/auto-retry";
|
|
1725
1726
|
var MAX_MESSAGE_LENGTH = 4096;
|
|
1726
1727
|
var TelegramChannel = class extends BaseChannel {
|
|
@@ -1734,6 +1735,7 @@ var TelegramChannel = class extends BaseChannel {
|
|
|
1734
1735
|
ownerChatId = null;
|
|
1735
1736
|
typingInterval = null;
|
|
1736
1737
|
chatCommandContext;
|
|
1738
|
+
pendingApprovals = /* @__PURE__ */ new Map();
|
|
1737
1739
|
setChatCommandContext(ctx) {
|
|
1738
1740
|
this.chatCommandContext = ctx;
|
|
1739
1741
|
}
|
|
@@ -1762,6 +1764,18 @@ var TelegramChannel = class extends BaseChannel {
|
|
|
1762
1764
|
};
|
|
1763
1765
|
this.emit(msg);
|
|
1764
1766
|
});
|
|
1767
|
+
bot.on("callback_query:data", async (ctx) => {
|
|
1768
|
+
const data = ctx.callbackQuery.data;
|
|
1769
|
+
const resolver = this.pendingApprovals.get(data);
|
|
1770
|
+
if (!resolver) {
|
|
1771
|
+
await ctx.answerCallbackQuery({ text: "Expired" });
|
|
1772
|
+
return;
|
|
1773
|
+
}
|
|
1774
|
+
this.pendingApprovals.delete(data);
|
|
1775
|
+
const action = data.split(":")[1];
|
|
1776
|
+
resolver(action);
|
|
1777
|
+
await ctx.answerCallbackQuery({ text: action === "no" ? "Denied" : "Approved" });
|
|
1778
|
+
});
|
|
1765
1779
|
bot.catch((err) => {
|
|
1766
1780
|
logger.error({ err: err.message }, "Telegram bot error");
|
|
1767
1781
|
});
|
|
@@ -1945,6 +1959,34 @@ var TelegramChannel = class extends BaseChannel {
|
|
|
1945
1959
|
this.stopTypingLoop();
|
|
1946
1960
|
}
|
|
1947
1961
|
}
|
|
1962
|
+
async askPermission(prompt, targetId) {
|
|
1963
|
+
const chatId = this.parseChatId(targetId);
|
|
1964
|
+
if (!chatId || !this.bot) return "no";
|
|
1965
|
+
const id = `perm_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
1966
|
+
const keyboard = new InlineKeyboard().text("Allow", `${id}:yes`).text("Always", `${id}:always`).text("Deny", `${id}:no`);
|
|
1967
|
+
const html = mdToTelegram(prompt);
|
|
1968
|
+
try {
|
|
1969
|
+
await this.bot.api.sendMessage(chatId, html, {
|
|
1970
|
+
parse_mode: "HTML",
|
|
1971
|
+
reply_markup: keyboard
|
|
1972
|
+
});
|
|
1973
|
+
} catch {
|
|
1974
|
+
await this.bot.api.sendMessage(chatId, this.stripHtml(html), {
|
|
1975
|
+
reply_markup: keyboard
|
|
1976
|
+
});
|
|
1977
|
+
}
|
|
1978
|
+
return new Promise((resolve9) => {
|
|
1979
|
+
this.pendingApprovals.set(`${id}:yes`, () => resolve9("yes"));
|
|
1980
|
+
this.pendingApprovals.set(`${id}:always`, () => resolve9("always"));
|
|
1981
|
+
this.pendingApprovals.set(`${id}:no`, () => resolve9("no"));
|
|
1982
|
+
setTimeout(() => {
|
|
1983
|
+
this.pendingApprovals.delete(`${id}:yes`);
|
|
1984
|
+
this.pendingApprovals.delete(`${id}:always`);
|
|
1985
|
+
this.pendingApprovals.delete(`${id}:no`);
|
|
1986
|
+
resolve9("no");
|
|
1987
|
+
}, 12e4);
|
|
1988
|
+
});
|
|
1989
|
+
}
|
|
1948
1990
|
escapeHtml(text) {
|
|
1949
1991
|
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
1950
1992
|
}
|
|
@@ -2258,10 +2300,17 @@ var PermissionManager = class {
|
|
|
2258
2300
|
autoApproveAll = false;
|
|
2259
2301
|
elevatedCommands = /* @__PURE__ */ new Set();
|
|
2260
2302
|
pendingApprovals = /* @__PURE__ */ new Set();
|
|
2303
|
+
currentChannelType = "cli";
|
|
2261
2304
|
constructor() {
|
|
2262
2305
|
this.cwd = process.cwd();
|
|
2263
2306
|
this.manifest = this.load();
|
|
2264
2307
|
}
|
|
2308
|
+
setCurrentChannelType(type) {
|
|
2309
|
+
this.currentChannelType = type;
|
|
2310
|
+
}
|
|
2311
|
+
getCurrentChannelType() {
|
|
2312
|
+
return this.currentChannelType;
|
|
2313
|
+
}
|
|
2265
2314
|
onAsk(handler) {
|
|
2266
2315
|
this.askHandler = handler;
|
|
2267
2316
|
}
|
|
@@ -2390,9 +2439,31 @@ var PermissionManager = class {
|
|
|
2390
2439
|
}
|
|
2391
2440
|
for (const pattern of shell.needsApproval) {
|
|
2392
2441
|
if (this.matchPattern(trimmed, pattern)) {
|
|
2442
|
+
if (this.currentChannelType === "telegram" && this.askHandler) {
|
|
2443
|
+
const result = await this.askHandler(`Run command: ${trimmed}`);
|
|
2444
|
+
if (result === "yes") {
|
|
2445
|
+
return { allowed: true, needsApproval: false };
|
|
2446
|
+
}
|
|
2447
|
+
if (result === "always") {
|
|
2448
|
+
this.addApprovedCommand(baseCmd);
|
|
2449
|
+
return { allowed: true, needsApproval: false };
|
|
2450
|
+
}
|
|
2451
|
+
return { allowed: false, reason: `User denied: ${trimmed}`, needsApproval: false };
|
|
2452
|
+
}
|
|
2393
2453
|
return { allowed: false, reason: `Command requires approval: matches "${pattern}"`, needsApproval: true };
|
|
2394
2454
|
}
|
|
2395
2455
|
}
|
|
2456
|
+
if (this.currentChannelType === "telegram" && this.askHandler) {
|
|
2457
|
+
const result = await this.askHandler(`Run command: ${trimmed}`);
|
|
2458
|
+
if (result === "yes") {
|
|
2459
|
+
return { allowed: true, needsApproval: false };
|
|
2460
|
+
}
|
|
2461
|
+
if (result === "always") {
|
|
2462
|
+
this.addApprovedCommand(baseCmd);
|
|
2463
|
+
return { allowed: true, needsApproval: false };
|
|
2464
|
+
}
|
|
2465
|
+
return { allowed: false, reason: `User denied: ${trimmed}`, needsApproval: false };
|
|
2466
|
+
}
|
|
2396
2467
|
return { allowed: false, reason: "Command not in auto-approve list \u2014 requires approval", needsApproval: true };
|
|
2397
2468
|
}
|
|
2398
2469
|
isGitReadAllowed() {
|
|
@@ -4198,7 +4269,7 @@ function banner() {
|
|
|
4198
4269
|
}
|
|
4199
4270
|
console.log("");
|
|
4200
4271
|
console.log(chalk6.white(" an AI agent for personal tasks"));
|
|
4201
|
-
console.log(chalk6.dim(" v0.2.
|
|
4272
|
+
console.log(chalk6.dim(" v0.2.3 \xB7 by Cosmic Stack \xB7 mercury.cosmicstack.org"));
|
|
4202
4273
|
console.log("");
|
|
4203
4274
|
}
|
|
4204
4275
|
function splashScreen() {
|
|
@@ -4441,11 +4512,17 @@ async function runAgent(isDaemon = false) {
|
|
|
4441
4512
|
await agent.birth();
|
|
4442
4513
|
await agent.wake();
|
|
4443
4514
|
const cliChannel = channels.get("cli");
|
|
4444
|
-
|
|
4445
|
-
|
|
4515
|
+
const tgChannel = channels.get("telegram");
|
|
4516
|
+
capabilities.permissions.onAsk(async (prompt) => {
|
|
4517
|
+
const channelType = capabilities.permissions.getCurrentChannelType();
|
|
4518
|
+
if (channelType === "telegram" && tgChannel) {
|
|
4519
|
+
return tgChannel.askPermission(prompt);
|
|
4520
|
+
}
|
|
4521
|
+
if (cliChannel) {
|
|
4446
4522
|
return cliChannel.askPermission(prompt);
|
|
4447
|
-
}
|
|
4448
|
-
|
|
4523
|
+
}
|
|
4524
|
+
return "no";
|
|
4525
|
+
});
|
|
4449
4526
|
const activeCh = channels.getActiveChannels();
|
|
4450
4527
|
const toolNames = capabilities.getToolNames();
|
|
4451
4528
|
if (!isDaemon) {
|
|
@@ -4478,7 +4555,7 @@ async function runAgent(isDaemon = false) {
|
|
|
4478
4555
|
process.on("SIGTERM", shutdown);
|
|
4479
4556
|
}
|
|
4480
4557
|
var program = new Command();
|
|
4481
|
-
program.name("mercury").description("Mercury \u2014 Soul-driven AI agent with permission-hardened tools, token budgets, and multi-channel access.").version("0.2.
|
|
4558
|
+
program.name("mercury").description("Mercury \u2014 Soul-driven AI agent with permission-hardened tools, token budgets, and multi-channel access.").version("0.2.3").option("-v, --verbose", "Show debug logs").action(async () => {
|
|
4482
4559
|
if (!isSetupComplete()) {
|
|
4483
4560
|
await configure();
|
|
4484
4561
|
autoDaemonize();
|