@integrity-labs/agt-cli 0.28.449 → 0.28.451
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/agt.js +3 -3
- package/dist/{chunk-MDD7H7EP.js → chunk-MY5HPJUW.js} +2 -2
- package/dist/lib/manager-worker.js +27 -4
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/slack-channel.js +538 -152
- package/dist/mcp/telegram-channel.js +488 -103
- package/package.json +1 -1
- /package/dist/{chunk-MDD7H7EP.js.map → chunk-MY5HPJUW.js.map} +0 -0
|
@@ -18870,7 +18870,7 @@ var require_filters = __commonJS({
|
|
|
18870
18870
|
return r.copySafeness(str, res);
|
|
18871
18871
|
}
|
|
18872
18872
|
_exports.indent = indent;
|
|
18873
|
-
function
|
|
18873
|
+
function join17(arr, del, attr) {
|
|
18874
18874
|
del = del || "";
|
|
18875
18875
|
if (attr) {
|
|
18876
18876
|
arr = lib.map(arr, function(v) {
|
|
@@ -18879,7 +18879,7 @@ var require_filters = __commonJS({
|
|
|
18879
18879
|
}
|
|
18880
18880
|
return arr.join(del);
|
|
18881
18881
|
}
|
|
18882
|
-
_exports.join =
|
|
18882
|
+
_exports.join = join17;
|
|
18883
18883
|
function last(arr) {
|
|
18884
18884
|
return arr[arr.length - 1];
|
|
18885
18885
|
}
|
|
@@ -22480,11 +22480,11 @@ async function waitForResolution(cfg, callbackId, opts) {
|
|
|
22480
22480
|
}
|
|
22481
22481
|
} catch {
|
|
22482
22482
|
}
|
|
22483
|
-
await
|
|
22483
|
+
await sleep2(interval);
|
|
22484
22484
|
}
|
|
22485
22485
|
return { kind: "timeout" };
|
|
22486
22486
|
}
|
|
22487
|
-
function
|
|
22487
|
+
function sleep2(ms) {
|
|
22488
22488
|
return new Promise((r) => setTimeout(r, ms));
|
|
22489
22489
|
}
|
|
22490
22490
|
function generateOptionToken() {
|
|
@@ -30085,7 +30085,7 @@ var StdioServerTransport = class {
|
|
|
30085
30085
|
|
|
30086
30086
|
// src/telegram-channel.ts
|
|
30087
30087
|
import https from "https";
|
|
30088
|
-
import { createHash as
|
|
30088
|
+
import { createHash as createHash3, randomUUID as randomUUID3 } from "crypto";
|
|
30089
30089
|
import {
|
|
30090
30090
|
closeSync,
|
|
30091
30091
|
createWriteStream,
|
|
@@ -30093,18 +30093,18 @@ import {
|
|
|
30093
30093
|
ftruncateSync,
|
|
30094
30094
|
mkdirSync as mkdirSync9,
|
|
30095
30095
|
openSync,
|
|
30096
|
-
readFileSync as
|
|
30097
|
-
readdirSync as
|
|
30096
|
+
readFileSync as readFileSync16,
|
|
30097
|
+
readdirSync as readdirSync5,
|
|
30098
30098
|
realpathSync,
|
|
30099
30099
|
renameSync as renameSync7,
|
|
30100
|
-
statSync as
|
|
30100
|
+
statSync as statSync4,
|
|
30101
30101
|
unlinkSync as unlinkSync8,
|
|
30102
30102
|
watch,
|
|
30103
30103
|
writeFileSync as writeFileSync11,
|
|
30104
30104
|
writeSync
|
|
30105
30105
|
} from "fs";
|
|
30106
|
-
import { homedir as
|
|
30107
|
-
import { basename, extname, join as
|
|
30106
|
+
import { homedir as homedir7 } from "os";
|
|
30107
|
+
import { basename, extname, join as join16, resolve as resolve2 } from "path";
|
|
30108
30108
|
|
|
30109
30109
|
// src/channel-attachments.ts
|
|
30110
30110
|
import { homedir } from "os";
|
|
@@ -30695,6 +30695,40 @@ function resolveGhostReplyMode(opts) {
|
|
|
30695
30695
|
if (cached2 !== void 0) return cached2;
|
|
30696
30696
|
return "off";
|
|
30697
30697
|
}
|
|
30698
|
+
var USAGE_LIMIT_REACTIVE_FLAG_KEY = "usage-limit-reactive-notice";
|
|
30699
|
+
function parseUsageLimitReactiveMode(raw) {
|
|
30700
|
+
if (raw === void 0) return void 0;
|
|
30701
|
+
const v = raw.trim().toLowerCase();
|
|
30702
|
+
if (v === "") return void 0;
|
|
30703
|
+
if (v === "off" || v === "shadow" || v === "enforce") return v;
|
|
30704
|
+
const b = envBoolean(raw);
|
|
30705
|
+
if (b === true) return "enforce";
|
|
30706
|
+
if (b === false) return "off";
|
|
30707
|
+
return void 0;
|
|
30708
|
+
}
|
|
30709
|
+
function cachedUsageLimitReactiveMode(path) {
|
|
30710
|
+
try {
|
|
30711
|
+
if (!existsSync2(path)) return void 0;
|
|
30712
|
+
const parsed = JSON.parse(readFileSync3(path, "utf8"));
|
|
30713
|
+
if (!parsed || typeof parsed !== "object") return void 0;
|
|
30714
|
+
const flags = parsed.flags;
|
|
30715
|
+
if (!flags || typeof flags !== "object") return void 0;
|
|
30716
|
+
const value = flags[USAGE_LIMIT_REACTIVE_FLAG_KEY];
|
|
30717
|
+
if (typeof value === "string") return parseUsageLimitReactiveMode(value);
|
|
30718
|
+
if (typeof value === "boolean") return value ? "enforce" : "off";
|
|
30719
|
+
return void 0;
|
|
30720
|
+
} catch {
|
|
30721
|
+
return void 0;
|
|
30722
|
+
}
|
|
30723
|
+
}
|
|
30724
|
+
function resolveUsageLimitReactiveMode(opts) {
|
|
30725
|
+
const env2 = opts?.env ?? process.env;
|
|
30726
|
+
const modeOverride = parseUsageLimitReactiveMode(env2["AGT_USAGE_LIMIT_REACTIVE_MODE"]);
|
|
30727
|
+
if (modeOverride !== void 0) return modeOverride;
|
|
30728
|
+
const cached2 = cachedUsageLimitReactiveMode(opts?.cachePath ?? defaultFlagsCachePath());
|
|
30729
|
+
if (cached2 !== void 0) return cached2;
|
|
30730
|
+
return "off";
|
|
30731
|
+
}
|
|
30698
30732
|
|
|
30699
30733
|
// src/maintenance-mode.ts
|
|
30700
30734
|
var FLAG_KEY = "platform-maintenance-mode";
|
|
@@ -34036,7 +34070,113 @@ var BANNER_PATTERNS = [
|
|
|
34036
34070
|
// pct=100.
|
|
34037
34071
|
new RegExp(`${SUBJECT}hit\\s+your\\s+(?:[a-z0-9-]+\\s+)?limit${SEP}resets\\s+(${RESET_DATE})`, "i")
|
|
34038
34072
|
];
|
|
34073
|
+
function parseUsageBanner(text, now = /* @__PURE__ */ new Date()) {
|
|
34074
|
+
let bestIndex = -1;
|
|
34075
|
+
let best = null;
|
|
34076
|
+
for (let i = 0; i < BANNER_PATTERNS.length; i++) {
|
|
34077
|
+
const pattern = new RegExp(BANNER_PATTERNS[i].source, "gi");
|
|
34078
|
+
let match;
|
|
34079
|
+
while ((match = pattern.exec(text)) !== null) {
|
|
34080
|
+
if (match.index === pattern.lastIndex)
|
|
34081
|
+
pattern.lastIndex++;
|
|
34082
|
+
let pct;
|
|
34083
|
+
let resetStr;
|
|
34084
|
+
if (i === 0) {
|
|
34085
|
+
pct = Number.parseInt(match[1], 10);
|
|
34086
|
+
resetStr = match[2];
|
|
34087
|
+
} else {
|
|
34088
|
+
pct = 100;
|
|
34089
|
+
resetStr = match[1];
|
|
34090
|
+
}
|
|
34091
|
+
if (!Number.isFinite(pct) || pct < 0 || pct > 100)
|
|
34092
|
+
continue;
|
|
34093
|
+
const nextChar = text[match.index + match[0].length];
|
|
34094
|
+
if (nextChar !== void 0 && /[A-Za-z0-9]/.test(nextChar))
|
|
34095
|
+
continue;
|
|
34096
|
+
const weekResetsAt = parseResetDateTime(resetStr, now);
|
|
34097
|
+
if (!weekResetsAt)
|
|
34098
|
+
continue;
|
|
34099
|
+
if (match.index >= bestIndex) {
|
|
34100
|
+
bestIndex = match.index;
|
|
34101
|
+
best = { pct, weekResetsAt };
|
|
34102
|
+
}
|
|
34103
|
+
}
|
|
34104
|
+
}
|
|
34105
|
+
return best;
|
|
34106
|
+
}
|
|
34107
|
+
var MONTHS = [
|
|
34108
|
+
"jan",
|
|
34109
|
+
"feb",
|
|
34110
|
+
"mar",
|
|
34111
|
+
"apr",
|
|
34112
|
+
"may",
|
|
34113
|
+
"jun",
|
|
34114
|
+
"jul",
|
|
34115
|
+
"aug",
|
|
34116
|
+
"sep",
|
|
34117
|
+
"oct",
|
|
34118
|
+
"nov",
|
|
34119
|
+
"dec"
|
|
34120
|
+
];
|
|
34121
|
+
var TIME_TAIL = /,\s*(\d{1,2})(?::(\d{2}))?\s*(am|pm)(?:\s*\(?UTC\)?)?\s*$/i;
|
|
34122
|
+
var TIME_ONLY = /^(\d{1,2})(?::(\d{2}))?\s*(am|pm)(?:\s*\(?UTC\)?)?$/i;
|
|
34039
34123
|
var MS_PER_DAY = 24 * 60 * 60 * 1e3;
|
|
34124
|
+
function parseAmPm(hourStr, minStr, ampm) {
|
|
34125
|
+
const rawHour = Number.parseInt(hourStr, 10);
|
|
34126
|
+
if (!Number.isFinite(rawHour) || rawHour < 1 || rawHour > 12)
|
|
34127
|
+
return null;
|
|
34128
|
+
let minute = 0;
|
|
34129
|
+
if (minStr) {
|
|
34130
|
+
minute = Number.parseInt(minStr, 10);
|
|
34131
|
+
if (!Number.isFinite(minute) || minute < 0 || minute > 59)
|
|
34132
|
+
return null;
|
|
34133
|
+
}
|
|
34134
|
+
const isPm = ampm.toLowerCase() === "pm";
|
|
34135
|
+
return { hour: rawHour % 12 + (isPm ? 12 : 0), minute };
|
|
34136
|
+
}
|
|
34137
|
+
function parseResetDateTime(humanDate, now) {
|
|
34138
|
+
const trimmed = humanDate.trim();
|
|
34139
|
+
const timeOnly = trimmed.match(TIME_ONLY);
|
|
34140
|
+
if (timeOnly) {
|
|
34141
|
+
const hm = parseAmPm(timeOnly[1], timeOnly[2], timeOnly[3]);
|
|
34142
|
+
if (!hm)
|
|
34143
|
+
return null;
|
|
34144
|
+
const todayAt = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), hm.hour, hm.minute);
|
|
34145
|
+
return new Date(todayAt <= now.getTime() ? todayAt + MS_PER_DAY : todayAt);
|
|
34146
|
+
}
|
|
34147
|
+
const timeMatch = trimmed.match(TIME_TAIL);
|
|
34148
|
+
const dateOnly = timeMatch ? trimmed.slice(0, timeMatch.index).trim() : trimmed;
|
|
34149
|
+
const parts = dateOnly.split(/\s+/);
|
|
34150
|
+
if (parts.length !== 2)
|
|
34151
|
+
return null;
|
|
34152
|
+
const month = MONTHS.indexOf(parts[0].slice(0, 3).toLowerCase());
|
|
34153
|
+
if (month < 0)
|
|
34154
|
+
return null;
|
|
34155
|
+
const day = Number.parseInt(parts[1], 10);
|
|
34156
|
+
if (!Number.isFinite(day) || day < 1 || day > 31)
|
|
34157
|
+
return null;
|
|
34158
|
+
let hour = 0;
|
|
34159
|
+
let minute = 0;
|
|
34160
|
+
if (timeMatch) {
|
|
34161
|
+
const hm = parseAmPm(timeMatch[1], timeMatch[2], timeMatch[3]);
|
|
34162
|
+
if (!hm)
|
|
34163
|
+
return null;
|
|
34164
|
+
hour = hm.hour;
|
|
34165
|
+
minute = hm.minute;
|
|
34166
|
+
}
|
|
34167
|
+
const baseYear = now.getUTCFullYear();
|
|
34168
|
+
let resolved = null;
|
|
34169
|
+
let bestDelta = Number.POSITIVE_INFINITY;
|
|
34170
|
+
for (const y of [baseYear - 1, baseYear, baseYear + 1]) {
|
|
34171
|
+
const candidate = new Date(Date.UTC(y, month, day, hour, minute));
|
|
34172
|
+
const delta = Math.abs(candidate.getTime() - now.getTime());
|
|
34173
|
+
if (delta < bestDelta) {
|
|
34174
|
+
bestDelta = delta;
|
|
34175
|
+
resolved = candidate;
|
|
34176
|
+
}
|
|
34177
|
+
}
|
|
34178
|
+
return resolved;
|
|
34179
|
+
}
|
|
34040
34180
|
|
|
34041
34181
|
// ../core/dist/claude-code-usage/usage-limit-marker.js
|
|
34042
34182
|
var USAGE_LIMIT_MARKER_FILENAME = "claude-usage-limit.json";
|
|
@@ -34081,6 +34221,101 @@ var UNKNOWN_RATE_LIMIT = Object.freeze({
|
|
|
34081
34221
|
resetsAt: null,
|
|
34082
34222
|
text: null
|
|
34083
34223
|
});
|
|
34224
|
+
function contentText(record2) {
|
|
34225
|
+
const candidates = [record2.content];
|
|
34226
|
+
const message = record2.message;
|
|
34227
|
+
if (typeof message === "object" && message !== null) {
|
|
34228
|
+
candidates.push(message.content);
|
|
34229
|
+
}
|
|
34230
|
+
const parts = [];
|
|
34231
|
+
for (const candidate of candidates) {
|
|
34232
|
+
if (typeof candidate === "string") {
|
|
34233
|
+
if (candidate)
|
|
34234
|
+
parts.push(candidate);
|
|
34235
|
+
continue;
|
|
34236
|
+
}
|
|
34237
|
+
if (!Array.isArray(candidate))
|
|
34238
|
+
continue;
|
|
34239
|
+
for (const block of candidate) {
|
|
34240
|
+
if (typeof block === "string") {
|
|
34241
|
+
if (block)
|
|
34242
|
+
parts.push(block);
|
|
34243
|
+
continue;
|
|
34244
|
+
}
|
|
34245
|
+
if (typeof block !== "object" || block === null)
|
|
34246
|
+
continue;
|
|
34247
|
+
const text = block.text;
|
|
34248
|
+
if (typeof text === "string" && text)
|
|
34249
|
+
parts.push(text);
|
|
34250
|
+
}
|
|
34251
|
+
}
|
|
34252
|
+
const joined = parts.join("\n").trim();
|
|
34253
|
+
return joined ? joined : null;
|
|
34254
|
+
}
|
|
34255
|
+
function classifyTranscriptLine(line, startMs, endMs, now) {
|
|
34256
|
+
const trimmed = line.trim();
|
|
34257
|
+
if (!trimmed)
|
|
34258
|
+
return null;
|
|
34259
|
+
let obj;
|
|
34260
|
+
try {
|
|
34261
|
+
obj = JSON.parse(trimmed);
|
|
34262
|
+
} catch {
|
|
34263
|
+
return null;
|
|
34264
|
+
}
|
|
34265
|
+
if (typeof obj !== "object" || obj === null)
|
|
34266
|
+
return null;
|
|
34267
|
+
const record2 = obj;
|
|
34268
|
+
if (record2.type !== "assistant")
|
|
34269
|
+
return null;
|
|
34270
|
+
const ts = record2.timestamp;
|
|
34271
|
+
if (typeof ts !== "string" || !ts)
|
|
34272
|
+
return null;
|
|
34273
|
+
const tsMs = new Date(ts).getTime();
|
|
34274
|
+
if (!Number.isFinite(tsMs) || tsMs < startMs || tsMs > endMs)
|
|
34275
|
+
return null;
|
|
34276
|
+
if (record2.error === "rate_limit" || record2.apiErrorStatus === 429) {
|
|
34277
|
+
const text = contentText(record2);
|
|
34278
|
+
const observation = text ? parseUsageBanner(text, now ?? new Date(endMs)) : null;
|
|
34279
|
+
return { verdict: "capped", atMs: tsMs, resetsAt: observation?.weekResetsAt ?? null, text };
|
|
34280
|
+
}
|
|
34281
|
+
if (record2.isApiErrorMessage === true)
|
|
34282
|
+
return null;
|
|
34283
|
+
const message = record2.message;
|
|
34284
|
+
if (typeof message !== "object" || message === null)
|
|
34285
|
+
return null;
|
|
34286
|
+
const msg = message;
|
|
34287
|
+
if (msg.model === "<synthetic>")
|
|
34288
|
+
return null;
|
|
34289
|
+
const usage = msg.usage;
|
|
34290
|
+
if (typeof usage !== "object" || usage === null)
|
|
34291
|
+
return null;
|
|
34292
|
+
const u = usage;
|
|
34293
|
+
const spent = Number(u.input_tokens ?? 0) + Number(u.output_tokens ?? 0) + Number(u.cache_creation_input_tokens ?? 0) + Number(u.cache_read_input_tokens ?? 0);
|
|
34294
|
+
if (!Number.isFinite(spent) || spent <= 0)
|
|
34295
|
+
return null;
|
|
34296
|
+
return { verdict: "serving", atMs: tsMs, resetsAt: null, text: null };
|
|
34297
|
+
}
|
|
34298
|
+
function pickNewerClassification(current, next) {
|
|
34299
|
+
if (next.verdict === "unknown")
|
|
34300
|
+
return current;
|
|
34301
|
+
if (current.verdict === "unknown")
|
|
34302
|
+
return next;
|
|
34303
|
+
return next.atMs >= current.atMs ? next : current;
|
|
34304
|
+
}
|
|
34305
|
+
function classifyTranscriptRateLimit(jsonl, startMs, endMs, now) {
|
|
34306
|
+
let newest = UNKNOWN_RATE_LIMIT;
|
|
34307
|
+
for (const line of jsonl.split("\n")) {
|
|
34308
|
+
const classified = classifyTranscriptLine(line, startMs, endMs, now);
|
|
34309
|
+
if (classified)
|
|
34310
|
+
newest = pickNewerClassification(newest, classified);
|
|
34311
|
+
}
|
|
34312
|
+
return newest;
|
|
34313
|
+
}
|
|
34314
|
+
|
|
34315
|
+
// ../core/dist/claude-code-usage/transcript-location.js
|
|
34316
|
+
function encodeClaudeProjectPath(projectDir) {
|
|
34317
|
+
return "-" + projectDir.replace(/^\//, "").replace(/[/.]/g, "-");
|
|
34318
|
+
}
|
|
34084
34319
|
|
|
34085
34320
|
// ../core/dist/account-enforcement/marker.js
|
|
34086
34321
|
var ACCOUNT_ENFORCEMENT_MARKER_FILENAME = "account-enforcement.json";
|
|
@@ -37099,11 +37334,102 @@ function emitToolCallMarkupRedactionTelemetry(channel) {
|
|
|
37099
37334
|
}
|
|
37100
37335
|
}
|
|
37101
37336
|
|
|
37337
|
+
// src/rate-limit-watch.ts
|
|
37338
|
+
import { readFileSync as readFileSync11, readdirSync, statSync } from "fs";
|
|
37339
|
+
import { homedir as homedir5 } from "os";
|
|
37340
|
+
import { join as join9 } from "path";
|
|
37341
|
+
var DEFAULT_WATCH_MS = 5e3;
|
|
37342
|
+
var DEFAULT_POLL_MS = 400;
|
|
37343
|
+
function agentTranscriptDir(opts) {
|
|
37344
|
+
const cwd = opts?.cwd ?? process.cwd();
|
|
37345
|
+
const home = opts?.home ?? homedir5();
|
|
37346
|
+
return join9(home, ".claude", "projects", encodeClaudeProjectPath(cwd));
|
|
37347
|
+
}
|
|
37348
|
+
function classifyTranscriptSince(opts) {
|
|
37349
|
+
const dir = opts.transcriptDir ?? agentTranscriptDir({ cwd: opts.cwd, home: opts.home });
|
|
37350
|
+
let entries;
|
|
37351
|
+
try {
|
|
37352
|
+
entries = readdirSync(dir);
|
|
37353
|
+
} catch {
|
|
37354
|
+
return UNKNOWN_RATE_LIMIT;
|
|
37355
|
+
}
|
|
37356
|
+
let newest = UNKNOWN_RATE_LIMIT;
|
|
37357
|
+
for (const name of entries) {
|
|
37358
|
+
if (!name.endsWith(".jsonl")) continue;
|
|
37359
|
+
const path = join9(dir, name);
|
|
37360
|
+
try {
|
|
37361
|
+
const st = statSync(path);
|
|
37362
|
+
if (!st.isFile() || st.mtimeMs < opts.sinceMs) continue;
|
|
37363
|
+
} catch {
|
|
37364
|
+
continue;
|
|
37365
|
+
}
|
|
37366
|
+
let content;
|
|
37367
|
+
try {
|
|
37368
|
+
content = readFileSync11(path, "utf-8");
|
|
37369
|
+
} catch {
|
|
37370
|
+
continue;
|
|
37371
|
+
}
|
|
37372
|
+
newest = pickNewerClassification(
|
|
37373
|
+
newest,
|
|
37374
|
+
classifyTranscriptRateLimit(content, opts.sinceMs, opts.nowMs, new Date(opts.nowMs))
|
|
37375
|
+
);
|
|
37376
|
+
}
|
|
37377
|
+
return newest;
|
|
37378
|
+
}
|
|
37379
|
+
var sleep = (ms) => new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
37380
|
+
async function watchForRateLimitRefusal(opts) {
|
|
37381
|
+
const now = opts.now ?? (() => Date.now());
|
|
37382
|
+
const wait = opts.wait ?? sleep;
|
|
37383
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_WATCH_MS;
|
|
37384
|
+
const pollMs = opts.pollMs ?? DEFAULT_POLL_MS;
|
|
37385
|
+
const deadline = now() + timeoutMs;
|
|
37386
|
+
for (; ; ) {
|
|
37387
|
+
let result;
|
|
37388
|
+
try {
|
|
37389
|
+
result = classifyTranscriptSince({
|
|
37390
|
+
sinceMs: opts.sinceMs,
|
|
37391
|
+
nowMs: now(),
|
|
37392
|
+
transcriptDir: opts.transcriptDir,
|
|
37393
|
+
cwd: opts.cwd,
|
|
37394
|
+
home: opts.home
|
|
37395
|
+
});
|
|
37396
|
+
} catch {
|
|
37397
|
+
return null;
|
|
37398
|
+
}
|
|
37399
|
+
if (result.verdict === "capped") return result;
|
|
37400
|
+
if (result.verdict === "serving") return null;
|
|
37401
|
+
if (now() >= deadline) return null;
|
|
37402
|
+
await wait(pollMs);
|
|
37403
|
+
}
|
|
37404
|
+
}
|
|
37405
|
+
|
|
37406
|
+
// src/usage-limit-reactive-decision.ts
|
|
37407
|
+
import { createHash } from "crypto";
|
|
37408
|
+
function shouldReadPredictiveMarker(mode) {
|
|
37409
|
+
return mode !== "enforce";
|
|
37410
|
+
}
|
|
37411
|
+
function armedWatchMode(opts) {
|
|
37412
|
+
if (opts.mode === "off") return null;
|
|
37413
|
+
if (opts.isBot || !opts.replyOwed) return null;
|
|
37414
|
+
return opts.mode;
|
|
37415
|
+
}
|
|
37416
|
+
function decideRefusalAction(opts) {
|
|
37417
|
+
const { refusal } = opts;
|
|
37418
|
+
if (!refusal || refusal.verdict !== "capped") return "none";
|
|
37419
|
+
if (!refusal.resetsAt) return "missing-reset";
|
|
37420
|
+
return opts.mode === "shadow" ? "shadow-log" : "notify";
|
|
37421
|
+
}
|
|
37422
|
+
function describeUnparsedRefusal(text) {
|
|
37423
|
+
if (!text) return "refusal=absent";
|
|
37424
|
+
const hash = createHash("sha256").update(text).digest("hex").slice(0, 12);
|
|
37425
|
+
return `refusal_hash=${hash} refusal_len=${text.length}`;
|
|
37426
|
+
}
|
|
37427
|
+
|
|
37102
37428
|
// src/reply-intent-runtime.ts
|
|
37103
37429
|
import { execFile as execFile2 } from "child_process";
|
|
37104
37430
|
import { existsSync as existsSync5, mkdirSync as mkdirSync6, writeFileSync as writeFileSync7 } from "fs";
|
|
37105
|
-
import { homedir as
|
|
37106
|
-
import { join as
|
|
37431
|
+
import { homedir as homedir6 } from "os";
|
|
37432
|
+
import { join as join10 } from "path";
|
|
37107
37433
|
var DEFAULT_CLAUDE_EVAL_MODEL = "claude-haiku-4-5-20251001";
|
|
37108
37434
|
var DEFAULT_ANTHROPIC_MESSAGES_URL = "https://api.anthropic.com/v1/messages";
|
|
37109
37435
|
var ANTHROPIC_API_VERSION = "2023-06-01";
|
|
@@ -37202,12 +37528,12 @@ async function runAnthropicMessages(prompt, opts) {
|
|
|
37202
37528
|
var emptyMcpConfigPath = null;
|
|
37203
37529
|
function ensureEmptyMcpConfig() {
|
|
37204
37530
|
if (emptyMcpConfigPath && existsSync5(emptyMcpConfigPath)) return emptyMcpConfigPath;
|
|
37205
|
-
const dir =
|
|
37531
|
+
const dir = join10(homedir6(), ".augmented");
|
|
37206
37532
|
try {
|
|
37207
37533
|
mkdirSync6(dir, { recursive: true });
|
|
37208
37534
|
} catch {
|
|
37209
37535
|
}
|
|
37210
|
-
const p2 =
|
|
37536
|
+
const p2 = join10(dir, ".reply-intent-empty-mcp.json");
|
|
37211
37537
|
writeFileSync7(p2, JSON.stringify({ mcpServers: {} }));
|
|
37212
37538
|
emptyMcpConfigPath = p2;
|
|
37213
37539
|
return p2;
|
|
@@ -37232,7 +37558,7 @@ function runClaudeP(prompt, model) {
|
|
|
37232
37558
|
execFile2(
|
|
37233
37559
|
"claude",
|
|
37234
37560
|
args,
|
|
37235
|
-
{ cwd:
|
|
37561
|
+
{ cwd: homedir6(), timeout: CLASSIFY_TIMEOUT_MS, maxBuffer: 1 << 20 },
|
|
37236
37562
|
(err, stdout) => {
|
|
37237
37563
|
if (err) {
|
|
37238
37564
|
reject(err);
|
|
@@ -37354,17 +37680,17 @@ function emitTransientApiErrorTelemetry(channel, match, original) {
|
|
|
37354
37680
|
}
|
|
37355
37681
|
|
|
37356
37682
|
// src/telegram-pending-inbound-cleanup.ts
|
|
37357
|
-
import { readdirSync, readFileSync as
|
|
37358
|
-
import { join as
|
|
37683
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync12, statSync as statSync2 } from "fs";
|
|
37684
|
+
import { join as join11 } from "path";
|
|
37359
37685
|
function markerArrivalMs(fullPath) {
|
|
37360
37686
|
try {
|
|
37361
|
-
const received = JSON.parse(
|
|
37687
|
+
const received = JSON.parse(readFileSync12(fullPath, "utf-8")).received_at;
|
|
37362
37688
|
const parsed = received ? Date.parse(received) : Number.NaN;
|
|
37363
37689
|
if (Number.isFinite(parsed)) return parsed;
|
|
37364
37690
|
} catch {
|
|
37365
37691
|
}
|
|
37366
37692
|
try {
|
|
37367
|
-
return
|
|
37693
|
+
return statSync2(fullPath).mtimeMs;
|
|
37368
37694
|
} catch {
|
|
37369
37695
|
return Number.POSITIVE_INFINITY;
|
|
37370
37696
|
}
|
|
@@ -37380,7 +37706,7 @@ function applyToChatMarkers(pendingDir, chatId, op, cutoffMs) {
|
|
|
37380
37706
|
const bounded = Number.isFinite(cutoffMs);
|
|
37381
37707
|
let filenames;
|
|
37382
37708
|
try {
|
|
37383
|
-
filenames =
|
|
37709
|
+
filenames = readdirSync2(pendingDir);
|
|
37384
37710
|
} catch {
|
|
37385
37711
|
return 0;
|
|
37386
37712
|
}
|
|
@@ -37388,7 +37714,7 @@ function applyToChatMarkers(pendingDir, chatId, op, cutoffMs) {
|
|
|
37388
37714
|
for (const filename of filenames) {
|
|
37389
37715
|
if (!filename.startsWith(prefix)) continue;
|
|
37390
37716
|
if (!filename.endsWith(".json")) continue;
|
|
37391
|
-
const fullPath =
|
|
37717
|
+
const fullPath = join11(pendingDir, filename);
|
|
37392
37718
|
if (bounded && markerArrivalMs(fullPath) > cutoffMs) continue;
|
|
37393
37719
|
op(fullPath);
|
|
37394
37720
|
applied++;
|
|
@@ -37398,12 +37724,12 @@ function applyToChatMarkers(pendingDir, chatId, op, cutoffMs) {
|
|
|
37398
37724
|
|
|
37399
37725
|
// src/recovery-ledger.ts
|
|
37400
37726
|
import { existsSync as existsSync6, unlinkSync as unlinkSync6 } from "fs";
|
|
37401
|
-
import { join as
|
|
37727
|
+
import { join as join12 } from "path";
|
|
37402
37728
|
function recoveryLedgerEntryExists(ledgerDir, markerName, exists = (p2) => existsSync6(p2)) {
|
|
37403
37729
|
if (!ledgerDir || !markerName) return false;
|
|
37404
37730
|
if (markerName.includes("/") || markerName.includes("\\") || markerName.includes("..")) return false;
|
|
37405
37731
|
try {
|
|
37406
|
-
return exists(
|
|
37732
|
+
return exists(join12(ledgerDir, markerName));
|
|
37407
37733
|
} catch {
|
|
37408
37734
|
return false;
|
|
37409
37735
|
}
|
|
@@ -37414,14 +37740,14 @@ function removeRecoveryLedgerEntry(ledgerDir, markerName, unlink = (p2) => {
|
|
|
37414
37740
|
if (!ledgerDir || !markerName) return;
|
|
37415
37741
|
if (markerName.includes("/") || markerName.includes("\\") || markerName.includes("..")) return;
|
|
37416
37742
|
try {
|
|
37417
|
-
unlink(
|
|
37743
|
+
unlink(join12(ledgerDir, markerName));
|
|
37418
37744
|
} catch {
|
|
37419
37745
|
}
|
|
37420
37746
|
}
|
|
37421
37747
|
|
|
37422
37748
|
// src/inbound-delivery-ledger.ts
|
|
37423
|
-
import { existsSync as existsSync7, mkdirSync as mkdirSync7, readdirSync as
|
|
37424
|
-
import { join as
|
|
37749
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync7, readdirSync as readdirSync3, readFileSync as readFileSync13, renameSync as renameSync5, writeFileSync as writeFileSync8 } from "fs";
|
|
37750
|
+
import { join as join13 } from "path";
|
|
37425
37751
|
function safeInboundId(inboundId) {
|
|
37426
37752
|
return inboundId.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
37427
37753
|
}
|
|
@@ -37429,8 +37755,8 @@ var defaultDeps = {
|
|
|
37429
37755
|
mkdir: (dir) => mkdirSync7(dir, { recursive: true }),
|
|
37430
37756
|
writeFile: (path, data) => writeFileSync8(path, data, "utf8"),
|
|
37431
37757
|
rename: (from, to) => renameSync5(from, to),
|
|
37432
|
-
readdir: (dir) =>
|
|
37433
|
-
readFile: (path) =>
|
|
37758
|
+
readdir: (dir) => readdirSync3(dir),
|
|
37759
|
+
readFile: (path) => readFileSync13(path, "utf8"),
|
|
37434
37760
|
exists: (path) => existsSync7(path)
|
|
37435
37761
|
};
|
|
37436
37762
|
function writeInboundDeliveryLedgerEntry(dir, record2, deps = defaultDeps) {
|
|
@@ -37439,7 +37765,7 @@ function writeInboundDeliveryLedgerEntry(dir, record2, deps = defaultDeps) {
|
|
|
37439
37765
|
if (!safe || safe.includes("/") || safe.includes("\\") || safe.includes("..")) return;
|
|
37440
37766
|
try {
|
|
37441
37767
|
deps.mkdir(dir);
|
|
37442
|
-
const final =
|
|
37768
|
+
const final = join13(dir, `${safe}.json`);
|
|
37443
37769
|
const tmp = `${final}.tmp`;
|
|
37444
37770
|
deps.writeFile(tmp, JSON.stringify(record2));
|
|
37445
37771
|
deps.rename(tmp, final);
|
|
@@ -37448,10 +37774,10 @@ function writeInboundDeliveryLedgerEntry(dir, record2, deps = defaultDeps) {
|
|
|
37448
37774
|
}
|
|
37449
37775
|
|
|
37450
37776
|
// src/channel-inbound-id.ts
|
|
37451
|
-
import { createHash } from "crypto";
|
|
37777
|
+
import { createHash as createHash2 } from "crypto";
|
|
37452
37778
|
var INBOUND_ID_HEX_LEN = 12;
|
|
37453
37779
|
function hashInboundId(payload) {
|
|
37454
|
-
const digest =
|
|
37780
|
+
const digest = createHash2("sha256").update(payload).digest("hex").slice(0, INBOUND_ID_HEX_LEN);
|
|
37455
37781
|
return `ib_${digest}`;
|
|
37456
37782
|
}
|
|
37457
37783
|
function telegramInboundId(chatId, messageId) {
|
|
@@ -37644,14 +37970,14 @@ function createKanbanCardActiveClient(args) {
|
|
|
37644
37970
|
import {
|
|
37645
37971
|
existsSync as existsSync8,
|
|
37646
37972
|
mkdirSync as mkdirSync8,
|
|
37647
|
-
readFileSync as
|
|
37973
|
+
readFileSync as readFileSync14,
|
|
37648
37974
|
renameSync as renameSync6,
|
|
37649
|
-
statSync as
|
|
37975
|
+
statSync as statSync3,
|
|
37650
37976
|
unlinkSync as unlinkSync7,
|
|
37651
37977
|
utimesSync,
|
|
37652
37978
|
writeFileSync as writeFileSync9
|
|
37653
37979
|
} from "fs";
|
|
37654
|
-
import { join as
|
|
37980
|
+
import { join as join14 } from "path";
|
|
37655
37981
|
var STALE_LOCK_MS = 9e4;
|
|
37656
37982
|
var HEARTBEAT_INTERVAL_MS = 3e4;
|
|
37657
37983
|
function defaultIsPidAlive(pid) {
|
|
@@ -37674,7 +38000,7 @@ function acquireMcpSpawnLock(args) {
|
|
|
37674
38000
|
const nowMs = options.nowMs ?? (() => Date.now());
|
|
37675
38001
|
const lockMtimeMs = options.lockMtimeMs ?? defaultLockMtimeMs;
|
|
37676
38002
|
const staleMs = options.staleMs ?? STALE_LOCK_MS;
|
|
37677
|
-
const path =
|
|
38003
|
+
const path = join14(agentDir, basename2);
|
|
37678
38004
|
const existing = readLockHolder(path);
|
|
37679
38005
|
if (existing) {
|
|
37680
38006
|
if (existing.pid === selfPid) {
|
|
@@ -37733,7 +38059,7 @@ function startMcpSpawnLockHeartbeat(lockPath, opts = {}) {
|
|
|
37733
38059
|
}
|
|
37734
38060
|
function defaultLockMtimeMs(path) {
|
|
37735
38061
|
try {
|
|
37736
|
-
return
|
|
38062
|
+
return statSync3(path).mtimeMs;
|
|
37737
38063
|
} catch {
|
|
37738
38064
|
return null;
|
|
37739
38065
|
}
|
|
@@ -37741,7 +38067,7 @@ function defaultLockMtimeMs(path) {
|
|
|
37741
38067
|
function readLockHolder(path) {
|
|
37742
38068
|
if (!existsSync8(path)) return null;
|
|
37743
38069
|
try {
|
|
37744
|
-
const raw =
|
|
38070
|
+
const raw = readFileSync14(path, "utf8");
|
|
37745
38071
|
const parsed = JSON.parse(raw);
|
|
37746
38072
|
const pid = typeof parsed.pid === "number" ? parsed.pid : Number(parsed.pid);
|
|
37747
38073
|
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
@@ -37753,8 +38079,8 @@ function readLockHolder(path) {
|
|
|
37753
38079
|
}
|
|
37754
38080
|
|
|
37755
38081
|
// src/ack-reaction.ts
|
|
37756
|
-
import { readdirSync as
|
|
37757
|
-
import { join as
|
|
38082
|
+
import { readdirSync as readdirSync4, readFileSync as readFileSync15, writeFileSync as writeFileSync10 } from "fs";
|
|
38083
|
+
import { join as join15 } from "path";
|
|
37758
38084
|
var REPLY_WEDGED_THRESHOLD_MS = 5 * 60 * 1e3;
|
|
37759
38085
|
var ACK_STARTUP_GRACE_MS = 6e4;
|
|
37760
38086
|
var ACK_PANE_FRESH_THRESHOLD_MS = 6e4;
|
|
@@ -37827,7 +38153,7 @@ var GIVE_UP_SIGNAL_MAX_AGE_MS = 30 * 60 * 1e3;
|
|
|
37827
38153
|
function readGiveUpSignal(path, now = Date.now()) {
|
|
37828
38154
|
if (!path) return null;
|
|
37829
38155
|
try {
|
|
37830
|
-
const raw = JSON.parse(
|
|
38156
|
+
const raw = JSON.parse(readFileSync15(path, "utf8"));
|
|
37831
38157
|
if (typeof raw.gave_up_at !== "string") return null;
|
|
37832
38158
|
const t = Date.parse(raw.gave_up_at);
|
|
37833
38159
|
if (!Number.isFinite(t) || t > now) return null;
|
|
@@ -37853,7 +38179,7 @@ function oldestPendingMarkerAgeMs(dir, now = Date.now(), opts) {
|
|
|
37853
38179
|
if (!dir) return null;
|
|
37854
38180
|
let names;
|
|
37855
38181
|
try {
|
|
37856
|
-
names =
|
|
38182
|
+
names = readdirSync4(dir);
|
|
37857
38183
|
} catch {
|
|
37858
38184
|
return null;
|
|
37859
38185
|
}
|
|
@@ -37862,7 +38188,7 @@ function oldestPendingMarkerAgeMs(dir, now = Date.now(), opts) {
|
|
|
37862
38188
|
if (!name.endsWith(".json")) continue;
|
|
37863
38189
|
let receivedAt;
|
|
37864
38190
|
try {
|
|
37865
|
-
const raw = JSON.parse(
|
|
38191
|
+
const raw = JSON.parse(readFileSync15(join15(dir, name), "utf-8"));
|
|
37866
38192
|
if (raw.discretionary === true) continue;
|
|
37867
38193
|
if (!opts?.includeSeen && typeof raw.seen_at === "string" && raw.seen_at) continue;
|
|
37868
38194
|
receivedAt = raw.received_at;
|
|
@@ -37939,14 +38265,14 @@ function isMarkerGenuinelyAged(receivedAt, nowMs, thresholdMs) {
|
|
|
37939
38265
|
}
|
|
37940
38266
|
var DEFLECTION_COUNTER_SUFFIX = "-deflections.json";
|
|
37941
38267
|
function deflectionCounterPath(agentDir, channel) {
|
|
37942
|
-
return
|
|
38268
|
+
return join15(agentDir, `${channel}${DEFLECTION_COUNTER_SUFFIX}`);
|
|
37943
38269
|
}
|
|
37944
38270
|
function recordChannelDeflection(agentDir, channel, cause) {
|
|
37945
38271
|
if (!agentDir) return;
|
|
37946
38272
|
const path = deflectionCounterPath(agentDir, channel);
|
|
37947
38273
|
let counts = {};
|
|
37948
38274
|
try {
|
|
37949
|
-
const parsed = JSON.parse(
|
|
38275
|
+
const parsed = JSON.parse(readFileSync15(path, "utf-8"));
|
|
37950
38276
|
if (parsed && typeof parsed === "object") counts = parsed;
|
|
37951
38277
|
} catch {
|
|
37952
38278
|
}
|
|
@@ -38023,11 +38349,11 @@ async function actuateHostRestart(opts) {
|
|
|
38023
38349
|
|
|
38024
38350
|
// src/telegram-channel.ts
|
|
38025
38351
|
function redactId(id) {
|
|
38026
|
-
return
|
|
38352
|
+
return createHash3("sha256").update(String(id)).digest("hex").slice(0, 8);
|
|
38027
38353
|
}
|
|
38028
38354
|
var BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN;
|
|
38029
38355
|
var AGENT_CODE_NAME = process.env.AGT_AGENT_CODE_NAME ?? "unknown";
|
|
38030
|
-
var TELEGRAM_AGENT_DIR = AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown" ?
|
|
38356
|
+
var TELEGRAM_AGENT_DIR = AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown" ? join16(homedir7(), ".augmented", AGENT_CODE_NAME) : null;
|
|
38031
38357
|
var AGT_HOST = process.env.AGT_HOST ?? null;
|
|
38032
38358
|
var AGT_API_KEY = process.env.AGT_API_KEY ?? null;
|
|
38033
38359
|
var AGT_AGENT_ID = process.env.AGT_AGENT_ID ?? null;
|
|
@@ -38130,11 +38456,11 @@ var peerRateLimiter = peerRateApiClient && parsePeerAgentModeEnv(process.env.TEL
|
|
|
38130
38456
|
log: (line) => process.stderr.write(`telegram-channel(${AGENT_CODE_NAME}): ${line}
|
|
38131
38457
|
`)
|
|
38132
38458
|
}) : createPeerRateLimiter();
|
|
38133
|
-
var PEER_PRESENCE_STATE_FILE = TELEGRAM_AGENT_DIR ?
|
|
38459
|
+
var PEER_PRESENCE_STATE_FILE = TELEGRAM_AGENT_DIR ? join16(TELEGRAM_AGENT_DIR, "telegram-peer-presence.json") : null;
|
|
38134
38460
|
function readPeerPresenceState() {
|
|
38135
38461
|
if (!PEER_PRESENCE_STATE_FILE) return null;
|
|
38136
38462
|
try {
|
|
38137
|
-
const parsed = JSON.parse(
|
|
38463
|
+
const parsed = JSON.parse(readFileSync16(PEER_PRESENCE_STATE_FILE, "utf-8"));
|
|
38138
38464
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
38139
38465
|
return parsed;
|
|
38140
38466
|
} catch {
|
|
@@ -38169,9 +38495,9 @@ if (!BOT_TOKEN) {
|
|
|
38169
38495
|
var stderrLogStream = null;
|
|
38170
38496
|
if (AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown") {
|
|
38171
38497
|
try {
|
|
38172
|
-
const logDir =
|
|
38498
|
+
const logDir = join16(homedir7(), ".augmented", AGENT_CODE_NAME);
|
|
38173
38499
|
mkdirSync9(logDir, { recursive: true });
|
|
38174
|
-
stderrLogStream = createWriteStream(
|
|
38500
|
+
stderrLogStream = createWriteStream(join16(logDir, "telegram-channel-stderr.log"), {
|
|
38175
38501
|
flags: "a",
|
|
38176
38502
|
mode: 384
|
|
38177
38503
|
});
|
|
@@ -38356,6 +38682,47 @@ async function maybeSendTelegramUsageLimitNotice(args) {
|
|
|
38356
38682
|
);
|
|
38357
38683
|
}
|
|
38358
38684
|
}
|
|
38685
|
+
function armTelegramUsageLimitWatch(args) {
|
|
38686
|
+
void (async () => {
|
|
38687
|
+
try {
|
|
38688
|
+
const refusal = await watchForRateLimitRefusal({ sinceMs: args.sinceMs });
|
|
38689
|
+
const action = decideRefusalAction({ mode: args.mode, refusal });
|
|
38690
|
+
if (action === "none") return;
|
|
38691
|
+
if (action === "missing-reset") {
|
|
38692
|
+
process.stderr.write(
|
|
38693
|
+
`telegram-channel(${AGENT_CODE_NAME}): [usage-limit-reactive] mode=${args.mode} refusal detected for chat=${redactId(args.chatId)} but no reset time in it (${describeUnparsedRefusal(refusal?.text)}) - no notice
|
|
38694
|
+
`
|
|
38695
|
+
);
|
|
38696
|
+
return;
|
|
38697
|
+
}
|
|
38698
|
+
const resetsAt = refusal?.resetsAt;
|
|
38699
|
+
if (!resetsAt) return;
|
|
38700
|
+
if (action === "shadow-log") {
|
|
38701
|
+
process.stderr.write(
|
|
38702
|
+
`telegram-channel(${AGENT_CODE_NAME}): [usage-limit-reactive] mode=shadow WOULD notify chat=${redactId(args.chatId)} resets=${resetsAt.toISOString()}
|
|
38703
|
+
`
|
|
38704
|
+
);
|
|
38705
|
+
return;
|
|
38706
|
+
}
|
|
38707
|
+
await maybeSendTelegramUsageLimitNotice({
|
|
38708
|
+
chatId: args.chatId,
|
|
38709
|
+
senderId: args.senderId,
|
|
38710
|
+
...args.messageThreadId != null ? { messageThreadId: args.messageThreadId } : {},
|
|
38711
|
+
limitedUntil: resetsAt
|
|
38712
|
+
});
|
|
38713
|
+
clearPendingMessage(args.chatId, args.sinceMs);
|
|
38714
|
+
process.stderr.write(
|
|
38715
|
+
`telegram-channel(${AGENT_CODE_NAME}): [usage-limit-reactive] reported refusal for chat=${redactId(args.chatId)} resets=${resetsAt.toISOString()}
|
|
38716
|
+
`
|
|
38717
|
+
);
|
|
38718
|
+
} catch (err) {
|
|
38719
|
+
process.stderr.write(
|
|
38720
|
+
`telegram-channel(${AGENT_CODE_NAME}): [usage-limit-reactive] watch failed for chat=${redactId(args.chatId)}: ${err.message}
|
|
38721
|
+
`
|
|
38722
|
+
);
|
|
38723
|
+
}
|
|
38724
|
+
})();
|
|
38725
|
+
}
|
|
38359
38726
|
var TELEGRAM_ACCOUNT_MUTE_NOTICE_CACHE = /* @__PURE__ */ new Map();
|
|
38360
38727
|
async function maybeSendTelegramAccountMuteNotice(args) {
|
|
38361
38728
|
if (args.senderId === void 0) return;
|
|
@@ -38567,7 +38934,7 @@ function scheduleBusyAck(chatId, messageId, arrivedWhileBusy) {
|
|
|
38567
38934
|
let paneLogFreshAgeMs = null;
|
|
38568
38935
|
if (AGENT_DIR) {
|
|
38569
38936
|
try {
|
|
38570
|
-
const paneMtimeMs =
|
|
38937
|
+
const paneMtimeMs = statSync4(join16(AGENT_DIR, "pane.log")).mtimeMs;
|
|
38571
38938
|
paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
|
|
38572
38939
|
} catch {
|
|
38573
38940
|
}
|
|
@@ -38597,7 +38964,7 @@ function scheduleBusyAck(chatId, messageId, arrivedWhileBusy) {
|
|
|
38597
38964
|
function __resetBusyAckNoticeThrottle() {
|
|
38598
38965
|
lastBusyAckNoticeAt.clear();
|
|
38599
38966
|
}
|
|
38600
|
-
var RESTART_FLAGS_DIR =
|
|
38967
|
+
var RESTART_FLAGS_DIR = join16(homedir7(), ".augmented", "restart-flags");
|
|
38601
38968
|
function actuateHostRestartTelegram() {
|
|
38602
38969
|
return actuateHostRestart({
|
|
38603
38970
|
agtHost: AGT_HOST,
|
|
@@ -38982,7 +39349,7 @@ async function handleRestartCommand(opts) {
|
|
|
38982
39349
|
if (!existsSync9(RESTART_FLAGS_DIR)) {
|
|
38983
39350
|
mkdirSync9(RESTART_FLAGS_DIR, { recursive: true });
|
|
38984
39351
|
}
|
|
38985
|
-
const flagPath =
|
|
39352
|
+
const flagPath = join16(RESTART_FLAGS_DIR, `${AGENT_CODE_NAME}.flag`);
|
|
38986
39353
|
const flag = {
|
|
38987
39354
|
codeName: AGENT_CODE_NAME,
|
|
38988
39355
|
source: "telegram",
|
|
@@ -39388,16 +39755,16 @@ async function classifyRestartCommand(text) {
|
|
|
39388
39755
|
if (!ours) return "verification_failed";
|
|
39389
39756
|
return target === ours ? "act" : "ignore";
|
|
39390
39757
|
}
|
|
39391
|
-
var AGENT_DIR = AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown" ?
|
|
39392
|
-
var PENDING_INBOUND_DIR = AGENT_DIR ?
|
|
39393
|
-
var RECOVERY_OUTBOX_DIR = AGENT_DIR ?
|
|
39394
|
-
var RECOVERY_LEDGER_DIR = AGENT_DIR ?
|
|
39395
|
-
var DELIVERY_LEDGER_DIR = AGENT_DIR ?
|
|
39396
|
-
var RESTART_CONFIRM_FILE = AGENT_DIR ?
|
|
39758
|
+
var AGENT_DIR = AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown" ? join16(homedir7(), ".augmented", AGENT_CODE_NAME) : null;
|
|
39759
|
+
var PENDING_INBOUND_DIR = AGENT_DIR ? join16(AGENT_DIR, "telegram-pending-inbound") : null;
|
|
39760
|
+
var RECOVERY_OUTBOX_DIR = AGENT_DIR ? join16(AGENT_DIR, "telegram-recovery-outbox") : null;
|
|
39761
|
+
var RECOVERY_LEDGER_DIR = AGENT_DIR ? join16(AGENT_DIR, ".agt-telegram-recovery-ledger") : null;
|
|
39762
|
+
var DELIVERY_LEDGER_DIR = AGENT_DIR ? join16(AGENT_DIR, ".agt-inbound-delivery-ledger") : null;
|
|
39763
|
+
var RESTART_CONFIRM_FILE = AGENT_DIR ? join16(AGENT_DIR, "telegram-restart-confirm.json") : null;
|
|
39397
39764
|
var TELEGRAM_PROCESS_BOOT_MS = Date.now();
|
|
39398
|
-
var TELEGRAM_RECENT_DMS_FILE = AGENT_DIR ?
|
|
39399
|
-
var TELEGRAM_CHANNEL_ADD_RESTART_FILE = AGENT_DIR ?
|
|
39400
|
-
var TELEGRAM_OFFSET_FILE = AGENT_DIR ?
|
|
39765
|
+
var TELEGRAM_RECENT_DMS_FILE = AGENT_DIR ? join16(AGENT_DIR, "telegram-recent-dms.json") : null;
|
|
39766
|
+
var TELEGRAM_CHANNEL_ADD_RESTART_FILE = AGENT_DIR ? join16(AGENT_DIR, "telegram-channel-add-restart.json") : null;
|
|
39767
|
+
var TELEGRAM_OFFSET_FILE = AGENT_DIR ? join16(AGENT_DIR, "telegram-getupdates-offset.json") : null;
|
|
39401
39768
|
var recentDms = /* @__PURE__ */ new Map();
|
|
39402
39769
|
var recentDmPersister = TELEGRAM_RECENT_DMS_FILE ? createRecentDmPersister({
|
|
39403
39770
|
filePath: TELEGRAM_RECENT_DMS_FILE,
|
|
@@ -39452,7 +39819,7 @@ function safeMarkerName(chatId, messageId) {
|
|
|
39452
39819
|
}
|
|
39453
39820
|
function pendingInboundPath(chatId, messageId) {
|
|
39454
39821
|
if (!PENDING_INBOUND_DIR) return null;
|
|
39455
|
-
return
|
|
39822
|
+
return join16(PENDING_INBOUND_DIR, safeMarkerName(chatId, messageId));
|
|
39456
39823
|
}
|
|
39457
39824
|
function writePendingInboundMarker(chatId, messageId, chatType, undeliverable = false, payload) {
|
|
39458
39825
|
const path = pendingInboundPath(chatId, messageId);
|
|
@@ -39500,7 +39867,7 @@ function rewriteTelegramMarkerInPlace(path, marker) {
|
|
|
39500
39867
|
function clearTelegramMarkerFileWithHeal(fullPath) {
|
|
39501
39868
|
let marker = null;
|
|
39502
39869
|
try {
|
|
39503
|
-
marker = JSON.parse(
|
|
39870
|
+
marker = JSON.parse(readFileSync16(fullPath, "utf-8"));
|
|
39504
39871
|
} catch {
|
|
39505
39872
|
}
|
|
39506
39873
|
if (marker && decideRecoveryHeal({
|
|
@@ -39517,7 +39884,7 @@ function clearTelegramMarkerFileWithHeal(fullPath) {
|
|
|
39517
39884
|
function markTelegramMarkerSeenInPlace(fullPath) {
|
|
39518
39885
|
let marker;
|
|
39519
39886
|
try {
|
|
39520
|
-
marker = JSON.parse(
|
|
39887
|
+
marker = JSON.parse(readFileSync16(fullPath, "utf-8"));
|
|
39521
39888
|
} catch {
|
|
39522
39889
|
return;
|
|
39523
39890
|
}
|
|
@@ -39529,7 +39896,7 @@ function markTelegramMarkerSeenInPlace(fullPath) {
|
|
|
39529
39896
|
function markTelegramMarkerSeenWithHeal(fullPath) {
|
|
39530
39897
|
let marker = null;
|
|
39531
39898
|
try {
|
|
39532
|
-
marker = JSON.parse(
|
|
39899
|
+
marker = JSON.parse(readFileSync16(fullPath, "utf-8"));
|
|
39533
39900
|
} catch {
|
|
39534
39901
|
return;
|
|
39535
39902
|
}
|
|
@@ -39545,7 +39912,7 @@ function readPendingInboundMarker(chatId, messageId) {
|
|
|
39545
39912
|
const path = pendingInboundPath(chatId, messageId);
|
|
39546
39913
|
if (!path || !existsSync9(path)) return null;
|
|
39547
39914
|
try {
|
|
39548
|
-
return JSON.parse(
|
|
39915
|
+
return JSON.parse(readFileSync16(path, "utf-8"));
|
|
39549
39916
|
} catch {
|
|
39550
39917
|
return null;
|
|
39551
39918
|
}
|
|
@@ -39565,10 +39932,10 @@ function nextRetryName(filename) {
|
|
|
39565
39932
|
async function processRecoveryOutboxFile(filename) {
|
|
39566
39933
|
if (!RECOVERY_OUTBOX_DIR) return;
|
|
39567
39934
|
if (filename.endsWith(".poison.json") || filename.endsWith(".tmp")) return;
|
|
39568
|
-
const fullPath =
|
|
39935
|
+
const fullPath = join16(RECOVERY_OUTBOX_DIR, filename);
|
|
39569
39936
|
let payload;
|
|
39570
39937
|
try {
|
|
39571
|
-
const raw =
|
|
39938
|
+
const raw = readFileSync16(fullPath, "utf-8");
|
|
39572
39939
|
payload = JSON.parse(raw);
|
|
39573
39940
|
} catch (err) {
|
|
39574
39941
|
process.stderr.write(
|
|
@@ -39662,7 +40029,7 @@ async function processRecoveryOutboxFile(filename) {
|
|
|
39662
40029
|
const next = nextRetryName(filename);
|
|
39663
40030
|
if (next) {
|
|
39664
40031
|
try {
|
|
39665
|
-
renameSync7(fullPath,
|
|
40032
|
+
renameSync7(fullPath, join16(RECOVERY_OUTBOX_DIR, next.next));
|
|
39666
40033
|
if (next.attempt >= MAX_RECOVERY_ATTEMPTS) {
|
|
39667
40034
|
process.stderr.write(
|
|
39668
40035
|
`telegram-channel(${AGENT_CODE_NAME}): ghost-reply recovery exhausted retries \u2014 moved to ${next.next}
|
|
@@ -39694,7 +40061,7 @@ function scanRecoveryRetries() {
|
|
|
39694
40061
|
if (!RECOVERY_OUTBOX_DIR) return;
|
|
39695
40062
|
let entries;
|
|
39696
40063
|
try {
|
|
39697
|
-
entries =
|
|
40064
|
+
entries = readdirSync5(RECOVERY_OUTBOX_DIR);
|
|
39698
40065
|
} catch {
|
|
39699
40066
|
return;
|
|
39700
40067
|
}
|
|
@@ -39703,7 +40070,7 @@ function scanRecoveryRetries() {
|
|
|
39703
40070
|
if (!f.includes(".retry-") || f.endsWith(".poison.json")) continue;
|
|
39704
40071
|
let mtimeMs;
|
|
39705
40072
|
try {
|
|
39706
|
-
mtimeMs =
|
|
40073
|
+
mtimeMs = statSync4(join16(RECOVERY_OUTBOX_DIR, f)).mtimeMs;
|
|
39707
40074
|
} catch {
|
|
39708
40075
|
continue;
|
|
39709
40076
|
}
|
|
@@ -39724,7 +40091,7 @@ function startRecoveryOutboxWatcher() {
|
|
|
39724
40091
|
return;
|
|
39725
40092
|
}
|
|
39726
40093
|
try {
|
|
39727
|
-
for (const f of
|
|
40094
|
+
for (const f of readdirSync5(RECOVERY_OUTBOX_DIR)) {
|
|
39728
40095
|
if (isFirstAttemptOutboxFile(f)) void processRecoveryOutboxFile(f);
|
|
39729
40096
|
}
|
|
39730
40097
|
} catch {
|
|
@@ -39733,7 +40100,7 @@ function startRecoveryOutboxWatcher() {
|
|
|
39733
40100
|
const watcher = watch(RECOVERY_OUTBOX_DIR, (event, filename) => {
|
|
39734
40101
|
if (event !== "rename" || !filename) return;
|
|
39735
40102
|
if (!isFirstAttemptOutboxFile(filename)) return;
|
|
39736
|
-
if (existsSync9(
|
|
40103
|
+
if (existsSync9(join16(RECOVERY_OUTBOX_DIR, filename))) {
|
|
39737
40104
|
void processRecoveryOutboxFile(filename);
|
|
39738
40105
|
}
|
|
39739
40106
|
});
|
|
@@ -39748,7 +40115,7 @@ function startRecoveryOutboxWatcher() {
|
|
|
39748
40115
|
retryTimer.unref?.();
|
|
39749
40116
|
}
|
|
39750
40117
|
startRecoveryOutboxWatcher();
|
|
39751
|
-
var NOTICE_OUTBOX_DIR = AGENT_DIR ?
|
|
40118
|
+
var NOTICE_OUTBOX_DIR = AGENT_DIR ? join16(AGENT_DIR, "telegram-notice-outbox") : null;
|
|
39752
40119
|
var NOTICE_MAX_AGE_MS = 9e4;
|
|
39753
40120
|
var NOTICE_INFLIGHT = /* @__PURE__ */ new Set();
|
|
39754
40121
|
async function processNoticeOutboxFile(filename) {
|
|
@@ -39756,11 +40123,11 @@ async function processNoticeOutboxFile(filename) {
|
|
|
39756
40123
|
if (filename.startsWith(".") || filename.endsWith(".tmp") || !filename.endsWith(".json")) return;
|
|
39757
40124
|
if (NOTICE_INFLIGHT.has(filename)) return;
|
|
39758
40125
|
NOTICE_INFLIGHT.add(filename);
|
|
39759
|
-
const fullPath =
|
|
40126
|
+
const fullPath = join16(NOTICE_OUTBOX_DIR, filename);
|
|
39760
40127
|
try {
|
|
39761
40128
|
let mtimeMs;
|
|
39762
40129
|
try {
|
|
39763
|
-
mtimeMs =
|
|
40130
|
+
mtimeMs = statSync4(fullPath).mtimeMs;
|
|
39764
40131
|
} catch {
|
|
39765
40132
|
return;
|
|
39766
40133
|
}
|
|
@@ -39773,7 +40140,7 @@ async function processNoticeOutboxFile(filename) {
|
|
|
39773
40140
|
}
|
|
39774
40141
|
let payload;
|
|
39775
40142
|
try {
|
|
39776
|
-
const parsed = JSON.parse(
|
|
40143
|
+
const parsed = JSON.parse(readFileSync16(fullPath, "utf-8"));
|
|
39777
40144
|
if (!parsed || typeof parsed !== "object") throw new Error("not an object");
|
|
39778
40145
|
payload = parsed;
|
|
39779
40146
|
} catch {
|
|
@@ -39844,13 +40211,13 @@ function startNoticeOutboxWatcher() {
|
|
|
39844
40211
|
return;
|
|
39845
40212
|
}
|
|
39846
40213
|
try {
|
|
39847
|
-
for (const f of
|
|
40214
|
+
for (const f of readdirSync5(NOTICE_OUTBOX_DIR)) void processNoticeOutboxFile(f);
|
|
39848
40215
|
} catch {
|
|
39849
40216
|
}
|
|
39850
40217
|
try {
|
|
39851
40218
|
const watcher = watch(NOTICE_OUTBOX_DIR, (event, filename) => {
|
|
39852
40219
|
if (event !== "rename" || !filename) return;
|
|
39853
|
-
if (existsSync9(
|
|
40220
|
+
if (existsSync9(join16(NOTICE_OUTBOX_DIR, filename))) void processNoticeOutboxFile(filename);
|
|
39854
40221
|
});
|
|
39855
40222
|
watcher.unref?.();
|
|
39856
40223
|
} catch (err) {
|
|
@@ -39870,7 +40237,7 @@ function sweepTelegramStaleMarkers(thresholdMs) {
|
|
|
39870
40237
|
if (!existsSync9(PENDING_INBOUND_DIR)) return;
|
|
39871
40238
|
let filenames;
|
|
39872
40239
|
try {
|
|
39873
|
-
filenames =
|
|
40240
|
+
filenames = readdirSync5(PENDING_INBOUND_DIR);
|
|
39874
40241
|
} catch (err) {
|
|
39875
40242
|
process.stderr.write(
|
|
39876
40243
|
`telegram-channel(${AGENT_CODE_NAME}): stale-marker readdir failed: ${err.message}
|
|
@@ -39884,10 +40251,10 @@ function sweepTelegramStaleMarkers(thresholdMs) {
|
|
|
39884
40251
|
for (const filename of filenames) {
|
|
39885
40252
|
if (!filename.endsWith(".json")) continue;
|
|
39886
40253
|
if (filename.endsWith(".tmp")) continue;
|
|
39887
|
-
const fullPath =
|
|
40254
|
+
const fullPath = join16(PENDING_INBOUND_DIR, filename);
|
|
39888
40255
|
let marker;
|
|
39889
40256
|
try {
|
|
39890
|
-
marker = JSON.parse(
|
|
40257
|
+
marker = JSON.parse(readFileSync16(fullPath, "utf-8"));
|
|
39891
40258
|
} catch (err) {
|
|
39892
40259
|
process.stderr.write(
|
|
39893
40260
|
`telegram-channel(${AGENT_CODE_NAME}): stale-marker parse failed for ${redactId(filename)}: ${err.message}
|
|
@@ -39940,13 +40307,13 @@ var orphanSweepTimer = setInterval(() => {
|
|
|
39940
40307
|
checkWatchdogGiveUpNotice();
|
|
39941
40308
|
}, orphanSweepIntervalMs());
|
|
39942
40309
|
orphanSweepTimer.unref?.();
|
|
39943
|
-
var TELEGRAM_PROGRESS_HEARTBEAT_PATH = AGENT_DIR ?
|
|
40310
|
+
var TELEGRAM_PROGRESS_HEARTBEAT_PATH = AGENT_DIR ? join16(AGENT_DIR, "channel-progress-heartbeat.json") : null;
|
|
39944
40311
|
var telegramTrackedProgress = null;
|
|
39945
40312
|
var telegramProgressTickRunning = false;
|
|
39946
40313
|
function readTelegramProgressHeartbeat() {
|
|
39947
40314
|
if (!TELEGRAM_PROGRESS_HEARTBEAT_PATH || !existsSync9(TELEGRAM_PROGRESS_HEARTBEAT_PATH)) return null;
|
|
39948
40315
|
try {
|
|
39949
|
-
return parseProgressHeartbeat(
|
|
40316
|
+
return parseProgressHeartbeat(readFileSync16(TELEGRAM_PROGRESS_HEARTBEAT_PATH, "utf-8"));
|
|
39950
40317
|
} catch {
|
|
39951
40318
|
return null;
|
|
39952
40319
|
}
|
|
@@ -39969,11 +40336,11 @@ function findTelegramProgressTarget() {
|
|
|
39969
40336
|
let best = null;
|
|
39970
40337
|
let bestMs = Infinity;
|
|
39971
40338
|
try {
|
|
39972
|
-
for (const name of
|
|
40339
|
+
for (const name of readdirSync5(PENDING_INBOUND_DIR)) {
|
|
39973
40340
|
if (!name.endsWith(".json")) continue;
|
|
39974
40341
|
let m;
|
|
39975
40342
|
try {
|
|
39976
|
-
m = JSON.parse(
|
|
40343
|
+
m = JSON.parse(readFileSync16(join16(PENDING_INBOUND_DIR, name), "utf-8"));
|
|
39977
40344
|
} catch {
|
|
39978
40345
|
continue;
|
|
39979
40346
|
}
|
|
@@ -40100,11 +40467,11 @@ function listPendingInboundChatIds() {
|
|
|
40100
40467
|
if (!PENDING_INBOUND_DIR || !existsSync9(PENDING_INBOUND_DIR)) return [];
|
|
40101
40468
|
const chats = /* @__PURE__ */ new Set();
|
|
40102
40469
|
try {
|
|
40103
|
-
for (const name of
|
|
40470
|
+
for (const name of readdirSync5(PENDING_INBOUND_DIR)) {
|
|
40104
40471
|
if (!name.endsWith(".json")) continue;
|
|
40105
40472
|
try {
|
|
40106
40473
|
const marker = JSON.parse(
|
|
40107
|
-
|
|
40474
|
+
readFileSync16(join16(PENDING_INBOUND_DIR, name), "utf8")
|
|
40108
40475
|
);
|
|
40109
40476
|
if (typeof marker.seen_at === "string" && marker.seen_at) continue;
|
|
40110
40477
|
if (typeof marker.chat_id === "string" && marker.chat_id) chats.add(marker.chat_id);
|
|
@@ -40146,7 +40513,7 @@ async function notifyWatchdogGiveUp(chatId, reason) {
|
|
|
40146
40513
|
}
|
|
40147
40514
|
function checkWatchdogGiveUpNotice() {
|
|
40148
40515
|
if (!AGENT_DIR) return;
|
|
40149
|
-
const signal = readGiveUpSignal(
|
|
40516
|
+
const signal = readGiveUpSignal(join16(AGENT_DIR, GIVE_UP_SIGNAL_FILENAME));
|
|
40150
40517
|
const signalAtMs = signal?.atMs ?? null;
|
|
40151
40518
|
const act = decideGiveUpNotice({
|
|
40152
40519
|
signalAtMs,
|
|
@@ -40425,7 +40792,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
40425
40792
|
isError: true
|
|
40426
40793
|
};
|
|
40427
40794
|
}
|
|
40428
|
-
const allowedRoot = resolve2(
|
|
40795
|
+
const allowedRoot = resolve2(homedir7(), ".augmented", AGENT_CODE_NAME, "project") + "/";
|
|
40429
40796
|
const resolvedPath = resolve2(path);
|
|
40430
40797
|
if (!resolvedPath.startsWith(allowedRoot)) {
|
|
40431
40798
|
return {
|
|
@@ -40473,7 +40840,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
40473
40840
|
}
|
|
40474
40841
|
let realRoot = allowedRoot;
|
|
40475
40842
|
try {
|
|
40476
|
-
realRoot = realpathSync(resolve2(
|
|
40843
|
+
realRoot = realpathSync(resolve2(homedir7(), ".augmented", AGENT_CODE_NAME, "project")) + "/";
|
|
40477
40844
|
} catch {
|
|
40478
40845
|
}
|
|
40479
40846
|
if (!realPath.startsWith(realRoot)) {
|
|
@@ -40488,7 +40855,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
40488
40855
|
let bytes;
|
|
40489
40856
|
let size;
|
|
40490
40857
|
try {
|
|
40491
|
-
const st =
|
|
40858
|
+
const st = statSync4(realPath);
|
|
40492
40859
|
if (!st.isFile()) {
|
|
40493
40860
|
return { content: [{ type: "text", text: `Upload refused: ${resolvedPath} is not a regular file.` }], isError: true };
|
|
40494
40861
|
}
|
|
@@ -40502,7 +40869,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
40502
40869
|
isError: true
|
|
40503
40870
|
};
|
|
40504
40871
|
}
|
|
40505
|
-
bytes =
|
|
40872
|
+
bytes = readFileSync16(realPath);
|
|
40506
40873
|
} catch (err) {
|
|
40507
40874
|
return { content: [{ type: "text", text: `Failed to read file: ${err.message}` }], isError: true };
|
|
40508
40875
|
}
|
|
@@ -41056,7 +41423,7 @@ async function replayPendingTelegramMarkers() {
|
|
|
41056
41423
|
if (!sessionAlive) return;
|
|
41057
41424
|
let filenames;
|
|
41058
41425
|
try {
|
|
41059
|
-
filenames =
|
|
41426
|
+
filenames = readdirSync5(PENDING_INBOUND_DIR);
|
|
41060
41427
|
} catch {
|
|
41061
41428
|
return;
|
|
41062
41429
|
}
|
|
@@ -41064,7 +41431,7 @@ async function replayPendingTelegramMarkers() {
|
|
|
41064
41431
|
let paneFreshAgeMs = null;
|
|
41065
41432
|
if (AGENT_DIR) {
|
|
41066
41433
|
try {
|
|
41067
|
-
paneFreshAgeMs = Math.max(0, now -
|
|
41434
|
+
paneFreshAgeMs = Math.max(0, now - statSync4(join16(AGENT_DIR, "pane.log")).mtimeMs);
|
|
41068
41435
|
} catch {
|
|
41069
41436
|
}
|
|
41070
41437
|
}
|
|
@@ -41072,10 +41439,10 @@ async function replayPendingTelegramMarkers() {
|
|
|
41072
41439
|
const entries = [];
|
|
41073
41440
|
for (const name of filenames) {
|
|
41074
41441
|
if (!name.endsWith(".json") || name.endsWith(".tmp")) continue;
|
|
41075
|
-
const fullPath =
|
|
41442
|
+
const fullPath = join16(PENDING_INBOUND_DIR, name);
|
|
41076
41443
|
let marker;
|
|
41077
41444
|
try {
|
|
41078
|
-
marker = JSON.parse(
|
|
41445
|
+
marker = JSON.parse(readFileSync16(fullPath, "utf-8"));
|
|
41079
41446
|
} catch {
|
|
41080
41447
|
continue;
|
|
41081
41448
|
}
|
|
@@ -41243,7 +41610,7 @@ async function pollLoop() {
|
|
|
41243
41610
|
`telegram-channel(${AGENT_CODE_NAME}): getUpdates failed: ${resp.description ?? "unknown"}
|
|
41244
41611
|
`
|
|
41245
41612
|
);
|
|
41246
|
-
await
|
|
41613
|
+
await sleep3(5e3);
|
|
41247
41614
|
continue;
|
|
41248
41615
|
}
|
|
41249
41616
|
const offsetBeforeBatch = nextOffset;
|
|
@@ -41561,7 +41928,8 @@ async function pollLoop() {
|
|
|
41561
41928
|
});
|
|
41562
41929
|
continue;
|
|
41563
41930
|
}
|
|
41564
|
-
const
|
|
41931
|
+
const reactiveMode = resolveUsageLimitReactiveMode();
|
|
41932
|
+
const telegramUsageLimitUntil = !isFromBot && shouldReadPredictiveMarker(reactiveMode) ? readUsageLimitUntil({ codeName: AGENT_CODE_NAME }) : null;
|
|
41565
41933
|
if (telegramUsageLimitUntil) {
|
|
41566
41934
|
process.stderr.write(
|
|
41567
41935
|
`telegram-channel(${AGENT_CODE_NAME}): usage-limit active until ${telegramUsageLimitUntil.toISOString()} \u2014 notice, no dispatch (chat=${redactId(chatId)})
|
|
@@ -41625,7 +41993,7 @@ async function pollLoop() {
|
|
|
41625
41993
|
let paneLogFreshAgeMs = null;
|
|
41626
41994
|
if (AGENT_DIR) {
|
|
41627
41995
|
try {
|
|
41628
|
-
const paneMtimeMs =
|
|
41996
|
+
const paneMtimeMs = statSync4(join16(AGENT_DIR, "pane.log")).mtimeMs;
|
|
41629
41997
|
paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
|
|
41630
41998
|
} catch {
|
|
41631
41999
|
}
|
|
@@ -41724,10 +42092,27 @@ async function pollLoop() {
|
|
|
41724
42092
|
if (!isFromBot && !peerAgentMeta && userId && userId !== "unknown" && chatId) {
|
|
41725
42093
|
clearScheduledTurnMarker(TELEGRAM_AGENT_DIR);
|
|
41726
42094
|
}
|
|
42095
|
+
const dispatchedAtMs = Date.now();
|
|
41727
42096
|
await mcp.notification({
|
|
41728
42097
|
method: "notifications/claude/channel",
|
|
41729
42098
|
params: channelPayload
|
|
41730
42099
|
});
|
|
42100
|
+
const watchMode = armedWatchMode({
|
|
42101
|
+
mode: reactiveMode,
|
|
42102
|
+
isBot: isFromBot || !!peerAgentMeta,
|
|
42103
|
+
// Every Telegram inbound that reaches here owes a reply — there is no
|
|
42104
|
+
// discretionary auto-follow variant as there is on Slack.
|
|
42105
|
+
replyOwed: true
|
|
42106
|
+
});
|
|
42107
|
+
if (watchMode) {
|
|
42108
|
+
armTelegramUsageLimitWatch({
|
|
42109
|
+
mode: watchMode,
|
|
42110
|
+
chatId,
|
|
42111
|
+
senderId: userId,
|
|
42112
|
+
...msg.message_thread_id != null ? { messageThreadId: msg.message_thread_id } : {},
|
|
42113
|
+
sinceMs: dispatchedAtMs
|
|
42114
|
+
});
|
|
42115
|
+
}
|
|
41731
42116
|
seedTelegramProgressHeartbeat();
|
|
41732
42117
|
conversationIngestClient?.ingest({
|
|
41733
42118
|
channel: "telegram",
|
|
@@ -41773,11 +42158,11 @@ async function pollLoop() {
|
|
|
41773
42158
|
`telegram-channel(${AGENT_CODE_NAME}): poll error: ${err.message}
|
|
41774
42159
|
`
|
|
41775
42160
|
);
|
|
41776
|
-
await
|
|
42161
|
+
await sleep3(5e3);
|
|
41777
42162
|
}
|
|
41778
42163
|
}
|
|
41779
42164
|
}
|
|
41780
|
-
function
|
|
42165
|
+
function sleep3(ms) {
|
|
41781
42166
|
return new Promise((resolve3) => setTimeout(resolve3, ms).unref());
|
|
41782
42167
|
}
|
|
41783
42168
|
function shutdown(reason) {
|