augure 0.3.0 → 0.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/dist/bin.js +343 -34
- package/package.json +9 -9
package/dist/bin.js
CHANGED
|
@@ -6,7 +6,7 @@ import { defineCommand as defineCommand4, runMain } from "citty";
|
|
|
6
6
|
|
|
7
7
|
// src/commands/start.ts
|
|
8
8
|
import { defineCommand } from "citty";
|
|
9
|
-
import { resolve as resolve2 } from "path";
|
|
9
|
+
import { resolve as resolve2, dirname as dirname4, join as join6 } from "path";
|
|
10
10
|
|
|
11
11
|
// ../core/dist/config.js
|
|
12
12
|
import { readFile } from "fs/promises";
|
|
@@ -35,7 +35,8 @@ var AppConfigSchema = z.object({
|
|
|
35
35
|
telegram: z.object({
|
|
36
36
|
enabled: z.boolean(),
|
|
37
37
|
botToken: z.string(),
|
|
38
|
-
allowedUsers: z.array(z.number())
|
|
38
|
+
allowedUsers: z.array(z.number()),
|
|
39
|
+
rejectMessage: z.string().optional()
|
|
39
40
|
}).optional(),
|
|
40
41
|
whatsapp: z.object({ enabled: z.boolean() }).optional(),
|
|
41
42
|
web: z.object({ enabled: z.boolean(), port: z.number() }).optional()
|
|
@@ -120,6 +121,17 @@ var AppConfigSchema = z.object({
|
|
|
120
121
|
}).optional(),
|
|
121
122
|
persona: z.object({
|
|
122
123
|
path: z.string().min(1).default("./config/personas")
|
|
124
|
+
}).optional(),
|
|
125
|
+
updates: z.object({
|
|
126
|
+
skills: z.object({
|
|
127
|
+
enabled: z.boolean().default(true),
|
|
128
|
+
checkInterval: z.string().min(1).default("6h")
|
|
129
|
+
}).optional(),
|
|
130
|
+
cli: z.object({
|
|
131
|
+
enabled: z.boolean().default(true),
|
|
132
|
+
checkInterval: z.string().min(1).default("24h"),
|
|
133
|
+
notifyChannel: z.string().min(1).default("telegram")
|
|
134
|
+
}).optional()
|
|
123
135
|
}).optional()
|
|
124
136
|
});
|
|
125
137
|
function interpolateEnvVars(raw) {
|
|
@@ -150,7 +162,7 @@ var OpenRouterClient = class {
|
|
|
150
162
|
this.maxTokens = config.maxTokens;
|
|
151
163
|
this.baseUrl = config.baseUrl ?? "https://openrouter.ai/api/v1";
|
|
152
164
|
}
|
|
153
|
-
async chat(messages) {
|
|
165
|
+
async chat(messages, tools) {
|
|
154
166
|
const response = await fetch(`${this.baseUrl}/chat/completions`, {
|
|
155
167
|
method: "POST",
|
|
156
168
|
headers: {
|
|
@@ -163,8 +175,19 @@ var OpenRouterClient = class {
|
|
|
163
175
|
messages: messages.map((m) => ({
|
|
164
176
|
role: m.role,
|
|
165
177
|
content: m.content,
|
|
166
|
-
...m.toolCallId ? { tool_call_id: m.toolCallId } : {}
|
|
167
|
-
|
|
178
|
+
...m.toolCallId ? { tool_call_id: m.toolCallId } : {},
|
|
179
|
+
...m.toolCalls?.length ? {
|
|
180
|
+
tool_calls: m.toolCalls.map((tc) => ({
|
|
181
|
+
id: tc.id,
|
|
182
|
+
type: "function",
|
|
183
|
+
function: {
|
|
184
|
+
name: tc.name,
|
|
185
|
+
arguments: JSON.stringify(tc.arguments)
|
|
186
|
+
}
|
|
187
|
+
}))
|
|
188
|
+
} : {}
|
|
189
|
+
})),
|
|
190
|
+
...tools?.length ? { tools } : {}
|
|
168
191
|
})
|
|
169
192
|
});
|
|
170
193
|
if (!response.ok) {
|
|
@@ -190,7 +213,7 @@ var OpenRouterClient = class {
|
|
|
190
213
|
|
|
191
214
|
// ../core/dist/context.js
|
|
192
215
|
function assembleContext(input) {
|
|
193
|
-
const { systemPrompt, memoryContent,
|
|
216
|
+
const { systemPrompt, memoryContent, conversationHistory, persona } = input;
|
|
194
217
|
let system = systemPrompt;
|
|
195
218
|
if (persona) {
|
|
196
219
|
system += `
|
|
@@ -203,13 +226,6 @@ ${persona}`;
|
|
|
203
226
|
|
|
204
227
|
## Memory
|
|
205
228
|
${memoryContent}`;
|
|
206
|
-
}
|
|
207
|
-
if (toolSchemas.length > 0) {
|
|
208
|
-
const toolList = toolSchemas.map((s) => `- **${s.function.name}**: ${s.function.description}`).join("\n");
|
|
209
|
-
system += `
|
|
210
|
-
|
|
211
|
-
## Available Tools
|
|
212
|
-
${toolList}`;
|
|
213
229
|
}
|
|
214
230
|
const messages = [{ role: "system", content: system }];
|
|
215
231
|
messages.push(...conversationHistory);
|
|
@@ -258,7 +274,7 @@ var NullAuditLogger = class {
|
|
|
258
274
|
// ../core/dist/agent.js
|
|
259
275
|
var Agent = class {
|
|
260
276
|
config;
|
|
261
|
-
|
|
277
|
+
conversations = /* @__PURE__ */ new Map();
|
|
262
278
|
state = "running";
|
|
263
279
|
constructor(config) {
|
|
264
280
|
this.config = config;
|
|
@@ -277,30 +293,33 @@ var Agent = class {
|
|
|
277
293
|
return "Agent is in emergency stop mode. Send /resume to reactivate.";
|
|
278
294
|
}
|
|
279
295
|
const start = Date.now();
|
|
280
|
-
|
|
296
|
+
const userId = incoming.userId;
|
|
297
|
+
let history = this.conversations.get(userId) ?? [];
|
|
298
|
+
history.push({
|
|
281
299
|
role: "user",
|
|
282
300
|
content: incoming.text
|
|
283
301
|
});
|
|
284
302
|
if (this.config.guard) {
|
|
285
|
-
|
|
303
|
+
history = this.config.guard.compact(history);
|
|
286
304
|
}
|
|
305
|
+
this.conversations.set(userId, history);
|
|
287
306
|
let memoryContent = this.config.memoryContent;
|
|
288
307
|
if (this.config.retriever) {
|
|
289
308
|
memoryContent = await this.config.retriever.retrieve();
|
|
290
309
|
}
|
|
291
310
|
const maxLoops = this.config.maxToolLoops ?? 10;
|
|
292
311
|
let loopCount = 0;
|
|
312
|
+
const toolSchemas = this.config.tools.toFunctionSchemas();
|
|
293
313
|
while (loopCount < maxLoops) {
|
|
294
314
|
const messages = assembleContext({
|
|
295
315
|
systemPrompt: this.config.systemPrompt,
|
|
296
316
|
memoryContent,
|
|
297
|
-
|
|
298
|
-
conversationHistory: this.conversationHistory,
|
|
317
|
+
conversationHistory: history,
|
|
299
318
|
persona: this.config.persona
|
|
300
319
|
});
|
|
301
|
-
const response = await this.config.llm.chat(messages);
|
|
320
|
+
const response = await this.config.llm.chat(messages, toolSchemas);
|
|
302
321
|
if (response.toolCalls.length === 0) {
|
|
303
|
-
|
|
322
|
+
history.push({
|
|
304
323
|
role: "assistant",
|
|
305
324
|
content: response.content
|
|
306
325
|
});
|
|
@@ -321,18 +340,19 @@ var Agent = class {
|
|
|
321
340
|
});
|
|
322
341
|
}
|
|
323
342
|
if (this.config.ingester) {
|
|
324
|
-
this.config.ingester.ingest(
|
|
343
|
+
this.config.ingester.ingest(history).catch((err2) => console.error("[augure] Ingestion error:", err2));
|
|
325
344
|
}
|
|
326
345
|
return response.content;
|
|
327
346
|
}
|
|
328
|
-
|
|
347
|
+
history.push({
|
|
329
348
|
role: "assistant",
|
|
330
|
-
content: response.content || ""
|
|
349
|
+
content: response.content || "",
|
|
350
|
+
toolCalls: response.toolCalls
|
|
331
351
|
});
|
|
332
352
|
for (const toolCall of response.toolCalls) {
|
|
333
353
|
const toolStart = Date.now();
|
|
334
354
|
const result = await this.config.tools.execute(toolCall.name, toolCall.arguments);
|
|
335
|
-
|
|
355
|
+
history.push({
|
|
336
356
|
role: "tool",
|
|
337
357
|
content: result.output,
|
|
338
358
|
toolCallId: toolCall.id
|
|
@@ -354,11 +374,22 @@ var Agent = class {
|
|
|
354
374
|
}
|
|
355
375
|
return "Max tool call loops reached. Please try again.";
|
|
356
376
|
}
|
|
357
|
-
getConversationHistory() {
|
|
358
|
-
|
|
377
|
+
getConversationHistory(userId) {
|
|
378
|
+
if (userId) {
|
|
379
|
+
return [...this.conversations.get(userId) ?? []];
|
|
380
|
+
}
|
|
381
|
+
const all = [];
|
|
382
|
+
for (const msgs of this.conversations.values()) {
|
|
383
|
+
all.push(...msgs);
|
|
384
|
+
}
|
|
385
|
+
return all;
|
|
359
386
|
}
|
|
360
|
-
clearHistory() {
|
|
361
|
-
|
|
387
|
+
clearHistory(userId) {
|
|
388
|
+
if (userId) {
|
|
389
|
+
this.conversations.delete(userId);
|
|
390
|
+
} else {
|
|
391
|
+
this.conversations.clear();
|
|
392
|
+
}
|
|
362
393
|
}
|
|
363
394
|
};
|
|
364
395
|
|
|
@@ -528,19 +559,259 @@ var ContextGuard = class {
|
|
|
528
559
|
}
|
|
529
560
|
};
|
|
530
561
|
|
|
531
|
-
// ../channels/dist/telegram.js
|
|
562
|
+
// ../channels/dist/telegram/telegram.js
|
|
532
563
|
import { Bot } from "grammy";
|
|
564
|
+
|
|
565
|
+
// ../channels/dist/pipeline.js
|
|
566
|
+
function createOutgoingPipeline(middlewares, send) {
|
|
567
|
+
return async (message) => {
|
|
568
|
+
let index = 0;
|
|
569
|
+
const next = async () => {
|
|
570
|
+
if (index < middlewares.length) {
|
|
571
|
+
const mw = middlewares[index++];
|
|
572
|
+
await mw(message, next);
|
|
573
|
+
} else {
|
|
574
|
+
await send(message);
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
await next();
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
// ../channels/dist/middleware/escape-markdown.js
|
|
582
|
+
var SPECIAL_CHARS = /* @__PURE__ */ new Set([".", "!", ">", "#", "+", "-", "=", "|", "{", "}", "~"]);
|
|
583
|
+
function escapeMarkdownV2(text) {
|
|
584
|
+
if (!text)
|
|
585
|
+
return "";
|
|
586
|
+
const parts = [];
|
|
587
|
+
let i = 0;
|
|
588
|
+
while (i < text.length) {
|
|
589
|
+
if (text.startsWith("```", i)) {
|
|
590
|
+
const endIdx = text.indexOf("```", i + 3);
|
|
591
|
+
if (endIdx !== -1) {
|
|
592
|
+
parts.push(text.slice(i, endIdx + 3));
|
|
593
|
+
i = endIdx + 3;
|
|
594
|
+
continue;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
if (text[i] === "`") {
|
|
598
|
+
const endIdx = text.indexOf("`", i + 1);
|
|
599
|
+
if (endIdx !== -1) {
|
|
600
|
+
parts.push(text.slice(i, endIdx + 1));
|
|
601
|
+
i = endIdx + 1;
|
|
602
|
+
continue;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
if (text[i] === "*" || text[i] === "_") {
|
|
606
|
+
parts.push(text[i]);
|
|
607
|
+
i++;
|
|
608
|
+
continue;
|
|
609
|
+
}
|
|
610
|
+
if (text[i] === "[" || text[i] === "(") {
|
|
611
|
+
parts.push(text[i]);
|
|
612
|
+
i++;
|
|
613
|
+
continue;
|
|
614
|
+
}
|
|
615
|
+
if (text[i] === "]") {
|
|
616
|
+
parts.push(text[i]);
|
|
617
|
+
i++;
|
|
618
|
+
continue;
|
|
619
|
+
}
|
|
620
|
+
const char = text[i];
|
|
621
|
+
if (SPECIAL_CHARS.has(char)) {
|
|
622
|
+
parts.push(`\\${char}`);
|
|
623
|
+
} else {
|
|
624
|
+
parts.push(char);
|
|
625
|
+
}
|
|
626
|
+
i++;
|
|
627
|
+
}
|
|
628
|
+
return parts.join("");
|
|
629
|
+
}
|
|
630
|
+
function createEscapeMarkdownMiddleware() {
|
|
631
|
+
return async (message, next) => {
|
|
632
|
+
message.text = escapeMarkdownV2(message.text);
|
|
633
|
+
await next();
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
// ../channels/dist/middleware/split-message.js
|
|
638
|
+
var TELEGRAM_MAX = 4096;
|
|
639
|
+
function splitText(text, maxLength) {
|
|
640
|
+
if (text.length <= maxLength)
|
|
641
|
+
return [text];
|
|
642
|
+
const chunks = [];
|
|
643
|
+
let remaining = text;
|
|
644
|
+
let openCodeBlock = null;
|
|
645
|
+
while (remaining.length > 0) {
|
|
646
|
+
const prefix2 = openCodeBlock ? `${openCodeBlock}
|
|
647
|
+
` : "";
|
|
648
|
+
const effectiveMax = maxLength - prefix2.length;
|
|
649
|
+
if (remaining.length <= effectiveMax) {
|
|
650
|
+
chunks.push(prefix2 + remaining);
|
|
651
|
+
break;
|
|
652
|
+
}
|
|
653
|
+
let splitAt = -1;
|
|
654
|
+
const searchArea = remaining.slice(0, effectiveMax);
|
|
655
|
+
const paraIdx = searchArea.lastIndexOf("\n\n");
|
|
656
|
+
if (paraIdx > effectiveMax * 0.3) {
|
|
657
|
+
splitAt = paraIdx;
|
|
658
|
+
}
|
|
659
|
+
if (splitAt === -1) {
|
|
660
|
+
const newlineIdx = searchArea.lastIndexOf("\n");
|
|
661
|
+
if (newlineIdx > effectiveMax * 0.3) {
|
|
662
|
+
splitAt = newlineIdx;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
if (splitAt === -1) {
|
|
666
|
+
splitAt = effectiveMax;
|
|
667
|
+
}
|
|
668
|
+
let chunk = remaining.slice(0, splitAt);
|
|
669
|
+
remaining = remaining.slice(splitAt).replace(/^\n+/, "");
|
|
670
|
+
const fenceMatches = chunk.match(/```/g);
|
|
671
|
+
const fenceCount = fenceMatches ? fenceMatches.length : 0;
|
|
672
|
+
if (openCodeBlock) {
|
|
673
|
+
chunk = prefix2 + chunk;
|
|
674
|
+
if (fenceCount % 2 === 1) {
|
|
675
|
+
openCodeBlock = null;
|
|
676
|
+
} else {
|
|
677
|
+
chunk += "\n```";
|
|
678
|
+
}
|
|
679
|
+
} else {
|
|
680
|
+
if (fenceCount % 2 === 1) {
|
|
681
|
+
const lastFenceIdx = chunk.lastIndexOf("```");
|
|
682
|
+
const afterFence = chunk.slice(lastFenceIdx + 3);
|
|
683
|
+
const langMatch = afterFence.match(/^(\w*)/);
|
|
684
|
+
openCodeBlock = "```" + (langMatch?.[1] ?? "");
|
|
685
|
+
chunk += "\n```";
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
chunks.push(chunk);
|
|
689
|
+
}
|
|
690
|
+
return chunks.length === 0 ? [""] : chunks;
|
|
691
|
+
}
|
|
692
|
+
function createSplitMessageMiddleware(sendFn, maxLength = TELEGRAM_MAX) {
|
|
693
|
+
return async (message, next) => {
|
|
694
|
+
const chunks = splitText(message.text, maxLength);
|
|
695
|
+
if (chunks.length <= 1) {
|
|
696
|
+
await next();
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
700
|
+
await sendFn({
|
|
701
|
+
...message,
|
|
702
|
+
text: chunks[i],
|
|
703
|
+
replyTo: i === 0 ? message.replyTo : void 0
|
|
704
|
+
});
|
|
705
|
+
if (i < chunks.length - 1) {
|
|
706
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
// ../channels/dist/middleware/error-handler.js
|
|
713
|
+
function isRetryable(error) {
|
|
714
|
+
if (error instanceof Error) {
|
|
715
|
+
const status = error.status;
|
|
716
|
+
if (status === 429 || status !== void 0 && status >= 500)
|
|
717
|
+
return true;
|
|
718
|
+
if (status !== void 0 && status >= 400 && status < 500)
|
|
719
|
+
return false;
|
|
720
|
+
return true;
|
|
721
|
+
}
|
|
722
|
+
return false;
|
|
723
|
+
}
|
|
724
|
+
async function withRetry(fn, options) {
|
|
725
|
+
let lastError;
|
|
726
|
+
for (let attempt = 0; attempt <= options.maxRetries; attempt++) {
|
|
727
|
+
try {
|
|
728
|
+
return await fn();
|
|
729
|
+
} catch (err2) {
|
|
730
|
+
lastError = err2;
|
|
731
|
+
if (!isRetryable(err2) || attempt === options.maxRetries) {
|
|
732
|
+
throw err2;
|
|
733
|
+
}
|
|
734
|
+
const delay = options.baseDelayMs * Math.pow(2, attempt);
|
|
735
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
throw lastError;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
// ../channels/dist/telegram/media.js
|
|
742
|
+
function registerMediaHandlers(bot, isAllowed, handlers, onRejected) {
|
|
743
|
+
bot.on("message:photo", async (ctx) => {
|
|
744
|
+
const userId = ctx.from.id;
|
|
745
|
+
if (!isAllowed(userId)) {
|
|
746
|
+
onRejected?.(userId, new Date(ctx.message.date * 1e3));
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
const photos = ctx.message.photo;
|
|
750
|
+
const largest = photos[photos.length - 1];
|
|
751
|
+
const attachment = {
|
|
752
|
+
type: "photo",
|
|
753
|
+
fileId: largest.file_id,
|
|
754
|
+
caption: ctx.message.caption ?? void 0
|
|
755
|
+
};
|
|
756
|
+
const incoming = {
|
|
757
|
+
id: String(ctx.message.message_id),
|
|
758
|
+
channelType: "telegram",
|
|
759
|
+
userId: String(userId),
|
|
760
|
+
text: ctx.message.caption ?? "[Photo]",
|
|
761
|
+
timestamp: new Date(ctx.message.date * 1e3),
|
|
762
|
+
replyTo: ctx.message.reply_to_message ? String(ctx.message.reply_to_message.message_id) : void 0,
|
|
763
|
+
attachments: [attachment]
|
|
764
|
+
};
|
|
765
|
+
for (const handler of handlers) {
|
|
766
|
+
await handler(incoming);
|
|
767
|
+
}
|
|
768
|
+
});
|
|
769
|
+
bot.on("message:document", async (ctx) => {
|
|
770
|
+
const userId = ctx.from.id;
|
|
771
|
+
if (!isAllowed(userId)) {
|
|
772
|
+
onRejected?.(userId, new Date(ctx.message.date * 1e3));
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
775
|
+
const doc = ctx.message.document;
|
|
776
|
+
const attachment = {
|
|
777
|
+
type: "document",
|
|
778
|
+
fileId: doc.file_id,
|
|
779
|
+
fileName: doc.file_name ?? void 0,
|
|
780
|
+
mimeType: doc.mime_type ?? void 0,
|
|
781
|
+
caption: ctx.message.caption ?? void 0
|
|
782
|
+
};
|
|
783
|
+
const incoming = {
|
|
784
|
+
id: String(ctx.message.message_id),
|
|
785
|
+
channelType: "telegram",
|
|
786
|
+
userId: String(userId),
|
|
787
|
+
text: ctx.message.caption ?? `[Document: ${doc.file_name ?? "unknown"}]`,
|
|
788
|
+
timestamp: new Date(ctx.message.date * 1e3),
|
|
789
|
+
replyTo: ctx.message.reply_to_message ? String(ctx.message.reply_to_message.message_id) : void 0,
|
|
790
|
+
attachments: [attachment]
|
|
791
|
+
};
|
|
792
|
+
for (const handler of handlers) {
|
|
793
|
+
await handler(incoming);
|
|
794
|
+
}
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
// ../channels/dist/telegram/telegram.js
|
|
533
799
|
var TelegramChannel = class {
|
|
534
800
|
type = "telegram";
|
|
535
801
|
bot;
|
|
536
802
|
allowedUsers;
|
|
537
803
|
handlers = [];
|
|
804
|
+
sendPipeline;
|
|
538
805
|
constructor(config) {
|
|
539
806
|
this.bot = new Bot(config.botToken);
|
|
540
807
|
this.allowedUsers = new Set(config.allowedUsers);
|
|
808
|
+
this.bot.catch((err2) => {
|
|
809
|
+
console.error("[augure:telegram] Bot error:", err2.message ?? err2);
|
|
810
|
+
});
|
|
541
811
|
this.bot.on("message:text", async (ctx) => {
|
|
542
812
|
const userId = ctx.from.id;
|
|
543
813
|
if (!this.isUserAllowed(userId)) {
|
|
814
|
+
this.handleRejected(userId, ctx.message.date, config.rejectMessage);
|
|
544
815
|
return;
|
|
545
816
|
}
|
|
546
817
|
const incoming = {
|
|
@@ -555,10 +826,35 @@ var TelegramChannel = class {
|
|
|
555
826
|
await handler(incoming);
|
|
556
827
|
}
|
|
557
828
|
});
|
|
829
|
+
registerMediaHandlers(this.bot, (id) => this.isUserAllowed(id), this.handlers, (userId, ts) => this.handleRejected(userId, Math.floor(ts.getTime() / 1e3), config.rejectMessage));
|
|
830
|
+
const rawSend = async (msg) => {
|
|
831
|
+
await withRetry(() => this.bot.api.sendMessage(Number(msg.userId), msg.text, {
|
|
832
|
+
parse_mode: "MarkdownV2",
|
|
833
|
+
...msg.replyTo ? { reply_parameters: { message_id: Number(msg.replyTo) } } : {}
|
|
834
|
+
}), { maxRetries: 3, baseDelayMs: 500 }).catch(async () => {
|
|
835
|
+
await this.bot.api.sendMessage(Number(msg.userId), msg.text, {
|
|
836
|
+
...msg.replyTo ? { reply_parameters: { message_id: Number(msg.replyTo) } } : {}
|
|
837
|
+
}).catch((fallbackErr) => {
|
|
838
|
+
console.error("[augure:telegram] Fallback send also failed:", fallbackErr);
|
|
839
|
+
throw fallbackErr;
|
|
840
|
+
});
|
|
841
|
+
});
|
|
842
|
+
};
|
|
843
|
+
this.sendPipeline = createOutgoingPipeline([
|
|
844
|
+
createEscapeMarkdownMiddleware(),
|
|
845
|
+
createSplitMessageMiddleware(rawSend)
|
|
846
|
+
], rawSend);
|
|
558
847
|
}
|
|
559
848
|
isUserAllowed(userId) {
|
|
560
849
|
return this.allowedUsers.has(userId);
|
|
561
850
|
}
|
|
851
|
+
handleRejected(userId, unixTimestamp, rejectMessage) {
|
|
852
|
+
console.warn(`[augure:telegram] Rejected message from unauthorized user ${userId} at ${new Date(unixTimestamp * 1e3).toISOString()}`);
|
|
853
|
+
if (rejectMessage) {
|
|
854
|
+
this.bot.api.sendMessage(userId, rejectMessage).catch(() => {
|
|
855
|
+
});
|
|
856
|
+
}
|
|
857
|
+
}
|
|
562
858
|
onMessage(handler) {
|
|
563
859
|
this.handlers.push(handler);
|
|
564
860
|
}
|
|
@@ -569,10 +865,7 @@ var TelegramChannel = class {
|
|
|
569
865
|
await this.bot.stop();
|
|
570
866
|
}
|
|
571
867
|
async send(message) {
|
|
572
|
-
await this.
|
|
573
|
-
parse_mode: "Markdown",
|
|
574
|
-
...message.replyTo ? { reply_parameters: { message_id: Number(message.replyTo) } } : {}
|
|
575
|
-
});
|
|
868
|
+
await this.sendPipeline(message);
|
|
576
869
|
}
|
|
577
870
|
};
|
|
578
871
|
|
|
@@ -2886,6 +3179,7 @@ function resolveLLMClient(config, usage) {
|
|
|
2886
3179
|
async function startAgent(configPath) {
|
|
2887
3180
|
const config = await loadConfig(configPath);
|
|
2888
3181
|
console.log(`[augure] Loaded config: ${config.identity.name}`);
|
|
3182
|
+
let telegramChannel;
|
|
2889
3183
|
const llm = resolveLLMClient(config.llm, "default");
|
|
2890
3184
|
const ingestionLLM = resolveLLMClient(config.llm, "ingestion");
|
|
2891
3185
|
const monitoringLLM = resolveLLMClient(config.llm, "monitoring");
|
|
@@ -2989,7 +3283,8 @@ async function startAgent(configPath) {
|
|
|
2989
3283
|
if (config.channels.telegram?.enabled) {
|
|
2990
3284
|
const telegram = new TelegramChannel({
|
|
2991
3285
|
botToken: config.channels.telegram.botToken,
|
|
2992
|
-
allowedUsers: config.channels.telegram.allowedUsers
|
|
3286
|
+
allowedUsers: config.channels.telegram.allowedUsers,
|
|
3287
|
+
rejectMessage: config.channels.telegram.rejectMessage
|
|
2993
3288
|
});
|
|
2994
3289
|
const commandCtx = {
|
|
2995
3290
|
scheduler,
|
|
@@ -3030,6 +3325,7 @@ async function startAgent(configPath) {
|
|
|
3030
3325
|
}
|
|
3031
3326
|
});
|
|
3032
3327
|
await telegram.start();
|
|
3328
|
+
telegramChannel = telegram;
|
|
3033
3329
|
console.log("[augure] Telegram bot started. Waiting for messages...");
|
|
3034
3330
|
}
|
|
3035
3331
|
const heartbeatIntervalMs = parseInterval(config.scheduler.heartbeatInterval);
|
|
@@ -3056,6 +3352,8 @@ async function startAgent(configPath) {
|
|
|
3056
3352
|
console.log("\n[augure] Shutting down...");
|
|
3057
3353
|
heartbeat.stop();
|
|
3058
3354
|
scheduler.stop();
|
|
3355
|
+
if (telegramChannel)
|
|
3356
|
+
await telegramChannel.stop();
|
|
3059
3357
|
await pool.destroyAll();
|
|
3060
3358
|
await audit.close();
|
|
3061
3359
|
console.log("[augure] All containers destroyed");
|
|
@@ -3087,10 +3385,21 @@ var startCommand = defineCommand({
|
|
|
3087
3385
|
description: "Path to config file",
|
|
3088
3386
|
alias: "c",
|
|
3089
3387
|
default: "./augure.json5"
|
|
3388
|
+
},
|
|
3389
|
+
env: {
|
|
3390
|
+
type: "string",
|
|
3391
|
+
description: "Path to .env file",
|
|
3392
|
+
alias: "e"
|
|
3090
3393
|
}
|
|
3091
3394
|
},
|
|
3092
3395
|
async run({ args }) {
|
|
3093
3396
|
const configPath = resolve2(args.config);
|
|
3397
|
+
const envPath = args.env ? resolve2(args.env) : join6(dirname4(configPath), ".env");
|
|
3398
|
+
try {
|
|
3399
|
+
process.loadEnvFile(envPath);
|
|
3400
|
+
console.log(`${prefix} Loaded env from ${dim(envPath)}`);
|
|
3401
|
+
} catch {
|
|
3402
|
+
}
|
|
3094
3403
|
console.log(`${prefix} Starting with config: ${dim(configPath)}`);
|
|
3095
3404
|
try {
|
|
3096
3405
|
await startAgent(configPath);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "augure",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Augure — your proactive AI agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -27,14 +27,14 @@
|
|
|
27
27
|
"@types/dockerode": "^4.0.1",
|
|
28
28
|
"@types/node-cron": "^3.0.11",
|
|
29
29
|
"tsup": "^8.5.1",
|
|
30
|
-
"@augure/
|
|
31
|
-
"@augure/memory": "0.0.
|
|
32
|
-
"@augure/sandbox": "0.0.
|
|
33
|
-
"@augure/
|
|
34
|
-
"@augure/scheduler": "0.0.
|
|
35
|
-
"@augure/
|
|
36
|
-
"@augure/types": "0.0
|
|
37
|
-
"@augure/
|
|
30
|
+
"@augure/core": "0.1.0",
|
|
31
|
+
"@augure/memory": "0.0.2",
|
|
32
|
+
"@augure/sandbox": "0.0.2",
|
|
33
|
+
"@augure/channels": "0.1.0",
|
|
34
|
+
"@augure/scheduler": "0.0.2",
|
|
35
|
+
"@augure/tools": "0.0.2",
|
|
36
|
+
"@augure/types": "0.1.0",
|
|
37
|
+
"@augure/skills": "0.1.0"
|
|
38
38
|
},
|
|
39
39
|
"keywords": [
|
|
40
40
|
"ai",
|