blun-king-cli 9.1.124 → 9.1.126
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/LIESMICH.txt +12 -0
- package/README.md +12 -0
- package/bin/mistake-relevance-policy.cjs +152 -0
- package/bin/telegram-remote-status-policy.cjs +41 -0
- package/blun.mjs +25 -10
- package/package.json +1 -1
- package/telegram-plugin/dist/bridge.mjs +30 -3
package/LIESMICH.txt
CHANGED
|
@@ -125,6 +125,8 @@ Ab BLUN King 9.1.122 wird die vollständige integrierte Designrichtlinie nicht m
|
|
|
125
125
|
|
|
126
126
|
Ab BLUN King 9.1.123 entlastet die Modellprojektion zusätzlich die Argumente älterer, bereits abgeschlossener Werkzeugaufrufe. Name, Kennung und Ergebnis bleiben erhalten; nur die wiederholte Übertragung großer alter JSON-Argumente entfällt. Unbeantwortete Werkzeugaufrufe, ungültige JSON-Argumente und die neuesten 20 Nachrichten bleiben vollständig. Der gespeicherte Rohverlauf und Exporte werden nicht verändert. In Fredriks gemessener Projektion sank der Anfrageumfang dadurch von 101.459 auf 94.026 Zeichen, also um etwa 1.859 geschätzte Token je Anfrage.
|
|
127
127
|
|
|
128
|
+
Ab BLUN King 9.1.126 wird die laufzeitweite `Mistake.md` nicht mehr bei jedem Zug vollständig mitgesendet. King wählt deterministisch bis zu fünf Abschnitte aus, die zu den letzten vier Nutzernachrichten passen, und bevorzugt dabei wiederverwendbare Regeln, Bedingungen und Gegenproben. Die Auswahl ist auf 6.000 Zeichen begrenzt und ersetzt den vorherigen Hinweis, statt weitere Kopien anzusammeln. Die vollständige Datei, ihr Register, ihr Archiv und ihr Schreibweg bleiben unverändert. Dafür ist kein zusätzlicher Modell-, Einbettungs- oder Netzwerkaufruf nötig. In der aktuell gemessenen laufzeitweiten Datei sank die Modellsicht abhängig von der Anfrage von 13.470 Zeichen auf 2.921 bis 4.819 Zeichen.
|
|
129
|
+
|
|
128
130
|
Verliert ein delegierter Einzelagent oder ein Mitglied eines Agentenschwarms die Provider-Verbindung, erhält es eine leere Provider-Antwort, bricht sein Stream wegen Leerlaufs ab oder meldet der Server HTTP 408/500/502/503/504, setzt BLUN King denselben Agenten anhand seines dauerhaften Verlaufs fort. Bei Einzelagenten sowie bei Schwarm-Unterbrechungen außerhalb von HTTP 429 wartet die erste Fortsetzung zwei Sekunden und die zweite fünf Sekunden; danach bleibt der ursprüngliche Fehler sichtbar. HTTP 429 behält im Schwarm seine getrennte, längere Überlastungsregel. Authentifizierungs-, Zahlungs- oder Kontingent-, Richtlinien-, Kontext-, Werkzeug- und Codefehler sowie manuelle Abbrüche lösen keine automatische Fortsetzung aus. Jeder Fortsetzungsversuch verwendet die bestehende Agenten-ID, damit bereits abgeschlossene Arbeit nicht wiederholt wird.
|
|
129
131
|
|
|
130
132
|
Rein lesende Sitzungsdiagnose
|
|
@@ -226,6 +228,16 @@ Im automatisch angebundenen Telegram-Kanal werden ausschließlich /loop, /goal,
|
|
|
226
228
|
sie in der Warteschlange. Andere Slash-Eingaben werden aus Sicherheitsgründen
|
|
227
229
|
als normale Chatnachrichten behandelt.
|
|
228
230
|
|
|
231
|
+
Rechner aus Telegram prüfen
|
|
232
|
+
----------------------------
|
|
233
|
+
Der Telegram-Befehl /status prüft die lokale Verbindung ohne Modellaufruf. Er
|
|
234
|
+
zeigt den Rechnernamen, die installierte BLUN-Version, die Laufzeit der
|
|
235
|
+
Telegram-Brücke, die Verbindung zur Konsole, den aktuellen Zustellweg und die
|
|
236
|
+
Größe der Eingangswarteschlange. Damit bleibt der Zustand auch dann abfragbar,
|
|
237
|
+
wenn die Konsole hängt oder der Modellanbieter ausgelastet ist. Die Ausgabe enthält keine
|
|
238
|
+
Chat-IDs, Dateipfade, Zugangsdaten oder Nachrichteninhalte. Nicht verbundene
|
|
239
|
+
Absender erhalten weiterhin nur die Kopplungsanweisung.
|
|
240
|
+
|
|
229
241
|
Nachweisbare Arbeitsabläufe
|
|
230
242
|
---------------------------
|
|
231
243
|
|
package/README.md
CHANGED
|
@@ -131,6 +131,8 @@ Ab BLUN King 9.1.122 wird die vollständige integrierte Designrichtlinie nicht m
|
|
|
131
131
|
|
|
132
132
|
Ab BLUN King 9.1.123 entlastet die Modellprojektion zusätzlich die Argumente älterer, bereits abgeschlossener Werkzeugaufrufe. Name, Kennung und Ergebnis bleiben erhalten; nur die wiederholte Übertragung großer alter JSON-Argumente entfällt. Unbeantwortete Werkzeugaufrufe, ungültige JSON-Argumente und die neuesten 20 Nachrichten bleiben vollständig. Der gespeicherte Rohverlauf und Exporte werden nicht verändert. In Fredriks gemessener Projektion sank der Anfrageumfang dadurch von 101.459 auf 94.026 Zeichen, also um etwa 1.859 geschätzte Token je Anfrage.
|
|
133
133
|
|
|
134
|
+
Ab BLUN King 9.1.126 wird die laufzeitweite `Mistake.md` nicht mehr bei jedem Zug vollständig mitgesendet. King wählt deterministisch bis zu fünf Abschnitte aus, die zu den letzten vier Nutzernachrichten passen, und bevorzugt dabei wiederverwendbare Regeln, Bedingungen und Gegenproben. Die Auswahl ist auf 6.000 Zeichen begrenzt und ersetzt den vorherigen Hinweis, statt weitere Kopien anzusammeln. Die vollständige Datei, ihr Register, ihr Archiv und ihr Schreibweg bleiben unverändert. Dafür ist kein zusätzlicher Modell-, Einbettungs- oder Netzwerkaufruf nötig. In der aktuell gemessenen laufzeitweiten Datei sank die Modellsicht abhängig von der Anfrage von 13.470 Zeichen auf 2.921 bis 4.819 Zeichen.
|
|
135
|
+
|
|
134
136
|
Ab BLUN King 9.1.99 werden auch direkt aufeinanderfolgende reine Textergebnisse als Stapel betrachtet. Enthalten sie zusammen mehr als 12.000 Zeichen, obwohl kein einzelnes Ergebnis diese Grenze überschreitet, speichert King so viele der größten geeigneten Ergebnisse wie nötig in privaten Dateien. In der Modellprojektion verbleiben lesbare Verweise. Der unveränderte Sitzungsrohverlauf bleibt vollständig erhalten. Gemischte Medienergebnisse, einzelne Ergebnisse unter 3.000 Zeichen und Stapel bis einschließlich 12.000 Zeichen bleiben unverändert. Beispiel: Bei zwei Suchergebnissen mit 7.000 und 6.000 Zeichen wird das größere Ergebnis privat gespeichert; Anfang, Ende, ausgelassene Zeichenzahl und `output_path` bleiben für den Agenten sichtbar.
|
|
135
137
|
|
|
136
138
|
Ab BLUN King 9.1.100 beendet eine begrenzte Grep-Inhaltssuche ripgrep, sobald der Versatz, die angeforderten Zeilen und eine zusätzliche Vorschauzeile vollständig vorliegen. Die Vorschauzeile belegt, ob eine weitere Seite existiert, ohne vorher bis zu 10 MB einzulesen. Unbegrenzte Suchen, Trefferzählungen und nach Änderungszeit sortierte Dateilisten laufen weiterhin vollständig durch.
|
|
@@ -242,6 +244,16 @@ Im automatisch angebundenen Telegram-Kanal werden ausschließlich `/loop`,
|
|
|
242
244
|
beschäftigt, bleiben sie in der Warteschlange. Andere Slash-Eingaben werden aus
|
|
243
245
|
Sicherheitsgründen als normale Chatnachrichten behandelt.
|
|
244
246
|
|
|
247
|
+
### Rechner aus Telegram prüfen
|
|
248
|
+
|
|
249
|
+
Der Telegram-Befehl `/status` prüft die lokale Verbindung ohne Modellaufruf.
|
|
250
|
+
Er zeigt den Rechnernamen, die installierte BLUN-Version, die Laufzeit der
|
|
251
|
+
Telegram-Brücke, die Verbindung zur Konsole, den aktuellen Zustellweg und die
|
|
252
|
+
Größe der Eingangswarteschlange. Damit bleibt der Zustand auch dann abfragbar,
|
|
253
|
+
wenn die Konsole hängt oder der Modellanbieter ausgelastet ist. Die Ausgabe enthält keine
|
|
254
|
+
Chat-IDs, Dateipfade, Zugangsdaten oder Nachrichteninhalte. Nicht verbundene
|
|
255
|
+
Absender erhalten weiterhin nur die Kopplungsanweisung.
|
|
256
|
+
|
|
245
257
|
Beim ersten Start werden das Telegram-Plugin und die mitgelieferten Skills
|
|
246
258
|
eingerichtet. Die Anmeldung erfolgt anschließend in der
|
|
247
259
|
Konsole mit `/login` über den BLUN-OAuth-Server. Das Paket erzeugt keine
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const DEFAULT_MAX_CHARS = 6_000;
|
|
4
|
+
const DEFAULT_MAX_SECTIONS = 5;
|
|
5
|
+
const RECENT_USER_MESSAGES = 4;
|
|
6
|
+
const STOP_WORDS = new Set([
|
|
7
|
+
'aber', 'alle', 'alles', 'auch', 'eine', 'einem', 'einen', 'einer', 'eines',
|
|
8
|
+
'fuer', 'haben', 'hier', 'immer', 'jetzt', 'kann', 'machen', 'mehr', 'mich',
|
|
9
|
+
'nicht', 'noch', 'oder', 'sein', 'sind', 'soll', 'und', 'uns', 'von', 'was',
|
|
10
|
+
'wenn', 'werden', 'wie', 'with', 'that', 'this', 'from', 'have', 'into',
|
|
11
|
+
'your', 'you', 'the', 'and', 'for', 'are', 'not', 'but', 'all', 'can',
|
|
12
|
+
]);
|
|
13
|
+
const REUSABLE_HEADING = /\b(rule|regel|condition|bedingung|countercheck|gegenprobe|trigger|ausloeser|auslöser)\b/iu;
|
|
14
|
+
|
|
15
|
+
function normalizeText(value) {
|
|
16
|
+
return String(value || '').normalize('NFKD').replace(/\p{M}/gu, '').toLowerCase();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function terms(value) {
|
|
20
|
+
return [...new Set(normalizeText(value).match(/[\p{L}\p{N}_-]{3,}/gu) || [])]
|
|
21
|
+
.filter((term) => !STOP_WORDS.has(term));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function textFromMessage(message) {
|
|
25
|
+
if (typeof message?.content === 'string') return message.content.trim();
|
|
26
|
+
if (!Array.isArray(message?.content)) return '';
|
|
27
|
+
return message.content
|
|
28
|
+
.filter((part) => part?.type === 'text' && typeof part.text === 'string')
|
|
29
|
+
.map((part) => part.text.trim())
|
|
30
|
+
.filter(Boolean)
|
|
31
|
+
.join('\n');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function recentUserText(history, limit = RECENT_USER_MESSAGES) {
|
|
35
|
+
if (!Array.isArray(history)) return '';
|
|
36
|
+
return history
|
|
37
|
+
.filter((message) => message?.role === 'user')
|
|
38
|
+
.map(textFromMessage)
|
|
39
|
+
.filter(Boolean)
|
|
40
|
+
.slice(-Math.max(1, Number(limit) || RECENT_USER_MESSAGES))
|
|
41
|
+
.join('\n');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function splitSections(source) {
|
|
45
|
+
const text = String(source || '').replace(/\r\n?/gu, '\n').trim();
|
|
46
|
+
if (!text) return [];
|
|
47
|
+
const headings = [...text.matchAll(/^#{2,3}\s+.+$/gmu)];
|
|
48
|
+
const sections = [];
|
|
49
|
+
let parent = '';
|
|
50
|
+
const preambleEnd = headings[0]?.index ?? text.length;
|
|
51
|
+
const preamble = text.slice(0, preambleEnd).trim();
|
|
52
|
+
if (preamble) {
|
|
53
|
+
const separator = preamble.indexOf('\n---');
|
|
54
|
+
const body = separator >= 0 ? preamble.slice(separator + 4).trim() : '';
|
|
55
|
+
if (body) sections.push({ heading: '# Mistake.md', parent: '', body, index: -1 });
|
|
56
|
+
}
|
|
57
|
+
headings.forEach((match, index) => {
|
|
58
|
+
const heading = match[0].trim();
|
|
59
|
+
const level = heading.startsWith('### ') ? 3 : 2;
|
|
60
|
+
if (level === 2) parent = heading;
|
|
61
|
+
const start = match.index + match[0].length;
|
|
62
|
+
const end = headings[index + 1]?.index ?? text.length;
|
|
63
|
+
sections.push({
|
|
64
|
+
heading,
|
|
65
|
+
parent: level === 3 ? parent : '',
|
|
66
|
+
body: text.slice(start, end).trim(),
|
|
67
|
+
index,
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
return sections;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function scoreSection(section, queryTerms) {
|
|
74
|
+
const heading = normalizeText(`${section.parent} ${section.heading}`);
|
|
75
|
+
const body = normalizeText(section.body);
|
|
76
|
+
let score = REUSABLE_HEADING.test(section.heading) ? 1 : 0;
|
|
77
|
+
for (const term of queryTerms) {
|
|
78
|
+
if (heading.includes(term)) score += 6;
|
|
79
|
+
if (body.includes(term)) score += 4;
|
|
80
|
+
}
|
|
81
|
+
return score;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function compactSection(section, maxChars) {
|
|
85
|
+
const title = section.parent && section.parent !== section.heading
|
|
86
|
+
? `${section.parent}\n${section.heading}`
|
|
87
|
+
: section.heading;
|
|
88
|
+
const full = `${title}\n${section.body}`.trim();
|
|
89
|
+
if (full.length <= maxChars) return full;
|
|
90
|
+
const marker = '\n\n[section shortened deterministically]\n\n';
|
|
91
|
+
const available = Math.max(0, maxChars - marker.length);
|
|
92
|
+
const headChars = Math.ceil(available * 0.55);
|
|
93
|
+
const tailChars = Math.floor(available * 0.45);
|
|
94
|
+
return `${full.slice(0, headChars).trimEnd()}${marker}${full.slice(-tailChars).trimStart()}`;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function selectRelevantMistakeContent(source, query, options = {}) {
|
|
98
|
+
const maxChars = Math.max(256, Number(options.maxChars) || DEFAULT_MAX_CHARS);
|
|
99
|
+
const maxSections = Math.max(1, Number(options.maxSections) || DEFAULT_MAX_SECTIONS);
|
|
100
|
+
const sourceText = String(source || '').trim();
|
|
101
|
+
const sections = splitSections(sourceText);
|
|
102
|
+
const queryTerms = terms(query);
|
|
103
|
+
const ranked = sections.map((section) => ({
|
|
104
|
+
...section,
|
|
105
|
+
score: scoreSection(section, queryTerms),
|
|
106
|
+
}));
|
|
107
|
+
const hasMatch = ranked.some((section) => section.score > (REUSABLE_HEADING.test(section.heading) ? 1 : 0));
|
|
108
|
+
ranked.sort((left, right) => {
|
|
109
|
+
if (hasMatch && right.score !== left.score) return right.score - left.score;
|
|
110
|
+
const rightReusable = REUSABLE_HEADING.test(right.heading) ? 1 : 0;
|
|
111
|
+
const leftReusable = REUSABLE_HEADING.test(left.heading) ? 1 : 0;
|
|
112
|
+
if (rightReusable !== leftReusable) return rightReusable - leftReusable;
|
|
113
|
+
return right.index - left.index;
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
const header = '# Mistake.md\n\nRelevant verified lessons for the current turn.';
|
|
117
|
+
const selected = [];
|
|
118
|
+
let remaining = maxChars - header.length - 2;
|
|
119
|
+
const perSectionMax = Math.max(
|
|
120
|
+
160,
|
|
121
|
+
Math.floor(remaining / Math.min(maxSections, 3)),
|
|
122
|
+
);
|
|
123
|
+
for (const section of ranked) {
|
|
124
|
+
if (selected.length >= maxSections || remaining < 64) break;
|
|
125
|
+
if (hasMatch && section.score === 0) continue;
|
|
126
|
+
const rendered = compactSection(section, Math.min(remaining, perSectionMax));
|
|
127
|
+
if (!rendered) continue;
|
|
128
|
+
selected.push({ ...section, rendered });
|
|
129
|
+
remaining -= rendered.length + 2;
|
|
130
|
+
}
|
|
131
|
+
if (selected.length === 0 && sections.length > 0) {
|
|
132
|
+
const fallback = sections.at(-1);
|
|
133
|
+
selected.push({ ...fallback, rendered: compactSection(fallback, remaining) });
|
|
134
|
+
}
|
|
135
|
+
selected.sort((left, right) => left.index - right.index);
|
|
136
|
+
const text = [header, ...selected.map((section) => section.rendered)].join('\n\n').slice(0, maxChars);
|
|
137
|
+
return {
|
|
138
|
+
selectedChars: text.length,
|
|
139
|
+
selectedSections: selected.length,
|
|
140
|
+
text,
|
|
141
|
+
totalChars: sourceText.length,
|
|
142
|
+
totalSections: sections.length,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
module.exports = {
|
|
147
|
+
DEFAULT_MAX_CHARS,
|
|
148
|
+
DEFAULT_MAX_SECTIONS,
|
|
149
|
+
RECENT_USER_MESSAGES,
|
|
150
|
+
recentUserText,
|
|
151
|
+
selectRelevantMistakeContent,
|
|
152
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function formatDuration(seconds) {
|
|
4
|
+
const minutes = Math.max(0, Math.floor(Number(seconds) / 60));
|
|
5
|
+
if (minutes < 60) return `${minutes} min`;
|
|
6
|
+
const hours = Math.floor(minutes / 60);
|
|
7
|
+
return `${hours} h ${minutes % 60} min`;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function formatBytes(bytes) {
|
|
11
|
+
const value = Math.max(0, Number(bytes) || 0);
|
|
12
|
+
if (value < 1024) return `${Math.round(value)} B`;
|
|
13
|
+
if (value < 1024 * 1024) return `${(value / 1024).toFixed(1)} KB`;
|
|
14
|
+
return `${(value / (1024 * 1024)).toFixed(1)} MB`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function buildTelegramRemoteStatus(input) {
|
|
18
|
+
if (!input?.access?.allowFrom?.includes(String(input.senderId))) {
|
|
19
|
+
return 'Nicht verbunden. Sende eine Nachricht, um einen Verbindungscode zu erhalten.';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const username = input.username ? `@${String(input.username).replace(/^@/u, '')}` : 'verbundener Nutzer';
|
|
23
|
+
const tui = input.tuiFresh
|
|
24
|
+
? `verbunden${Number.isInteger(input.tuiPid) ? ` (PID ${input.tuiPid})` : ''}`
|
|
25
|
+
: 'nicht verbunden';
|
|
26
|
+
const delivery = input.deliveryTarget === 'tui'
|
|
27
|
+
? 'Konsolen-Warteschlange'
|
|
28
|
+
: 'Brücke ohne Konsole';
|
|
29
|
+
return [
|
|
30
|
+
`BLUN-Fernstatus für ${username}`,
|
|
31
|
+
`Rechner: ${input.machineName || 'unbekannt'}`,
|
|
32
|
+
`Version: ${input.version || 'unbekannt'}`,
|
|
33
|
+
`Brücke: aktiv (PID ${input.bridgePid}, ${formatDuration(input.bridgeUptimeSeconds)})`,
|
|
34
|
+
`Konsole: ${tui}`,
|
|
35
|
+
`Zustellung: ${delivery}`,
|
|
36
|
+
`Warteschlange: ${formatBytes(input.queueBytes)}`,
|
|
37
|
+
`Gemessen: ${input.capturedAt}`,
|
|
38
|
+
].join('\n');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
module.exports = { buildTelegramRemoteStatus, formatBytes, formatDuration };
|
package/blun.mjs
CHANGED
|
@@ -231442,13 +231442,16 @@ var init_mistake_md_writer = __esmMin((() => {
|
|
|
231442
231442
|
* Nach jedem Turn kann der Writer neue Eintraege an Mistake.md anhaengen.
|
|
231443
231443
|
* Der Writer laeuft NACH dem Lesen, nie waehrend (C3).
|
|
231444
231444
|
*/
|
|
231445
|
-
|
|
231445
|
+
function isMistakeMdReminder(message) {
|
|
231446
|
+
return message.origin?.kind === "injection" && message.origin.variant === "mistake_md";
|
|
231447
|
+
}
|
|
231448
|
+
var MistakeMdInjector, recentUserText, selectRelevantMistakeContent;
|
|
231446
231449
|
var init_mistake_md = __esmMin((() => {
|
|
231447
231450
|
init_injector();
|
|
231448
231451
|
init_mistake_md_writer();
|
|
231452
|
+
({ recentUserText, selectRelevantMistakeContent } = createRequire(import.meta.url)("./bin/mistake-relevance-policy.cjs"));
|
|
231449
231453
|
MistakeMdInjector = class extends DynamicInjector {
|
|
231450
231454
|
injectionVariant = "mistake_md";
|
|
231451
|
-
lastHash = null;
|
|
231452
231455
|
reserveChecked = false;
|
|
231453
231456
|
mistakeDir;
|
|
231454
231457
|
mistakeFile;
|
|
@@ -231459,12 +231462,24 @@ var init_mistake_md = __esmMin((() => {
|
|
|
231459
231462
|
}
|
|
231460
231463
|
onContextClear() {
|
|
231461
231464
|
super.onContextClear();
|
|
231462
|
-
this.lastHash = null;
|
|
231463
231465
|
this.reserveChecked = false;
|
|
231464
231466
|
}
|
|
231465
|
-
|
|
231466
|
-
|
|
231467
|
-
|
|
231467
|
+
async inject() {
|
|
231468
|
+
const injection = await this.getInjection();
|
|
231469
|
+
const existing = this.agent.context.history.filter(isMistakeMdReminder);
|
|
231470
|
+
if (!injection) {
|
|
231471
|
+
if (existing.length > 0) this.agent.context.removeSystemRemindersMatching(isMistakeMdReminder);
|
|
231472
|
+
return;
|
|
231473
|
+
}
|
|
231474
|
+
const expected = wrapSystemReminder(injection);
|
|
231475
|
+
if (existing.length === 1 && reminderText(existing[0]) === expected) return;
|
|
231476
|
+
this.agent.context.removeSystemRemindersMatching(isMistakeMdReminder);
|
|
231477
|
+
this.injectedAt = this.agent.context.history.length;
|
|
231478
|
+
this.lastInjection = injection;
|
|
231479
|
+
this.agent.context.appendSystemReminder(injection, {
|
|
231480
|
+
kind: "injection",
|
|
231481
|
+
variant: this.injectionVariant
|
|
231482
|
+
});
|
|
231468
231483
|
}
|
|
231469
231484
|
async getInjection() {
|
|
231470
231485
|
try {
|
|
@@ -231477,16 +231492,16 @@ var init_mistake_md = __esmMin((() => {
|
|
|
231477
231492
|
}
|
|
231478
231493
|
const trimmed = content.trim();
|
|
231479
231494
|
if (trimmed.length === 0) return void 0;
|
|
231480
|
-
const
|
|
231481
|
-
|
|
231482
|
-
|
|
231495
|
+
const query = recentUserText(this.agent.context.history);
|
|
231496
|
+
const selected = selectRelevantMistakeContent(trimmed, query);
|
|
231497
|
+
if (!selected.text) return void 0;
|
|
231483
231498
|
let prefix = "";
|
|
231484
231499
|
if (!this.reserveChecked) {
|
|
231485
231500
|
this.reserveChecked = true;
|
|
231486
231501
|
const reserveWarning = await checkReserve(this.mistakeDir);
|
|
231487
231502
|
if (reserveWarning) prefix = `<!-- D2a: ${reserveWarning} -->\n\n`;
|
|
231488
231503
|
}
|
|
231489
|
-
return prefix +
|
|
231504
|
+
return prefix + selected.text;
|
|
231490
231505
|
});
|
|
231491
231506
|
} catch {
|
|
231492
231507
|
return;
|
package/package.json
CHANGED
|
@@ -5,6 +5,9 @@ import { randomBytes } from "node:crypto";
|
|
|
5
5
|
import { spawn } from "node:child_process";
|
|
6
6
|
import { Readable, Writable } from "node:stream";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
|
+
import { hostname } from "node:os";
|
|
9
|
+
import remoteStatusPolicy from "../../bin/telegram-remote-status-policy.cjs";
|
|
10
|
+
const { buildTelegramRemoteStatus } = remoteStatusPolicy;
|
|
8
11
|
//#region ../../node_modules/pathe/dist/shared/pathe.M-eThtNZ.mjs
|
|
9
12
|
const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
|
|
10
13
|
function normalizeWindowsPath(input = "") {
|
|
@@ -4451,7 +4454,7 @@ async function pollWithBackoff(bot, isShuttingDown, onStarted) {
|
|
|
4451
4454
|
},
|
|
4452
4455
|
{
|
|
4453
4456
|
command: "status",
|
|
4454
|
-
description: "Check
|
|
4457
|
+
description: "Check machine and delivery status"
|
|
4455
4458
|
}
|
|
4456
4459
|
], { scope: { type: "all_private_chats" } }).catch(() => {});
|
|
4457
4460
|
} });
|
|
@@ -4672,8 +4675,32 @@ bot.command("status", async (ctx) => {
|
|
|
4672
4675
|
if (gated === null) return;
|
|
4673
4676
|
const { access, senderId } = gated;
|
|
4674
4677
|
if (access.allowFrom.includes(senderId)) {
|
|
4675
|
-
|
|
4676
|
-
|
|
4678
|
+
let version = "unbekannt";
|
|
4679
|
+
let tuiPid;
|
|
4680
|
+
let queueBytes = 0;
|
|
4681
|
+
try {
|
|
4682
|
+
version = JSON.parse(readFileSync(join(dirname(KING_ENTRY), "package.json"), "utf8")).version ?? version;
|
|
4683
|
+
} catch {}
|
|
4684
|
+
try {
|
|
4685
|
+
tuiPid = parseInt(readFileSync(tuiPidFile(), "utf8"), 10);
|
|
4686
|
+
} catch {}
|
|
4687
|
+
try {
|
|
4688
|
+
queueBytes = statSync(tuiInboundQueueFile()).size;
|
|
4689
|
+
} catch {}
|
|
4690
|
+
await ctx.reply(buildTelegramRemoteStatus({
|
|
4691
|
+
access,
|
|
4692
|
+
bridgePid: process.pid,
|
|
4693
|
+
bridgeUptimeSeconds: process.uptime(),
|
|
4694
|
+
capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4695
|
+
deliveryTarget: deliveryTarget(),
|
|
4696
|
+
machineName: hostname(),
|
|
4697
|
+
queueBytes,
|
|
4698
|
+
senderId,
|
|
4699
|
+
tuiFresh: isTuiLeaseFresh(),
|
|
4700
|
+
tuiPid: Number.isInteger(tuiPid) ? tuiPid : void 0,
|
|
4701
|
+
username: ctx.from?.username,
|
|
4702
|
+
version
|
|
4703
|
+
}));
|
|
4677
4704
|
return;
|
|
4678
4705
|
}
|
|
4679
4706
|
for (const [code, pending] of Object.entries(access.pending)) if (pending.senderId === senderId) {
|