@integrity-labs/agt-cli 0.28.458 → 0.28.459
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 +4 -4
- package/dist/{chunk-KAIH24HZ.js → chunk-BWH5XTDU.js} +25 -4
- package/dist/chunk-BWH5XTDU.js.map +1 -0
- package/dist/{chunk-QIQQ46NH.js → chunk-PKZMFA2U.js} +3 -3
- package/dist/{claude-pair-runtime-CVCPBJOZ.js → claude-pair-runtime-YNOY2ATX.js} +2 -2
- package/dist/lib/manager-worker.js +16 -10
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/direct-chat-channel.js +1134 -788
- package/dist/mcp/origami.js +11 -1
- package/dist/mcp/slack-channel.js +539 -139
- package/dist/mcp/telegram-channel.js +482 -94
- package/dist/{persistent-session-EVLWDI3I.js → persistent-session-KGRCIIS5.js} +2 -2
- package/dist/{responsiveness-probe-EGP2F3WD.js → responsiveness-probe-4FVGB6NY.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-KAIH24HZ.js.map +0 -1
- /package/dist/{chunk-QIQQ46NH.js.map → chunk-PKZMFA2U.js.map} +0 -0
- /package/dist/{claude-pair-runtime-CVCPBJOZ.js.map → claude-pair-runtime-YNOY2ATX.js.map} +0 -0
- /package/dist/{persistent-session-EVLWDI3I.js.map → persistent-session-KGRCIIS5.js.map} +0 -0
- /package/dist/{responsiveness-probe-EGP2F3WD.js.map → responsiveness-probe-4FVGB6NY.js.map} +0 -0
|
@@ -18906,7 +18906,7 @@ var require_filters = __commonJS({
|
|
|
18906
18906
|
return r.copySafeness(str, res);
|
|
18907
18907
|
}
|
|
18908
18908
|
_exports.indent = indent;
|
|
18909
|
-
function
|
|
18909
|
+
function join18(arr, del, attr) {
|
|
18910
18910
|
del = del || "";
|
|
18911
18911
|
if (attr) {
|
|
18912
18912
|
arr = lib.map(arr, function(v) {
|
|
@@ -18915,7 +18915,7 @@ var require_filters = __commonJS({
|
|
|
18915
18915
|
}
|
|
18916
18916
|
return arr.join(del);
|
|
18917
18917
|
}
|
|
18918
|
-
_exports.join =
|
|
18918
|
+
_exports.join = join18;
|
|
18919
18919
|
function last(arr) {
|
|
18920
18920
|
return arr[arr.length - 1];
|
|
18921
18921
|
}
|
|
@@ -22516,11 +22516,11 @@ async function waitForResolution(cfg, callbackId, opts) {
|
|
|
22516
22516
|
}
|
|
22517
22517
|
} catch {
|
|
22518
22518
|
}
|
|
22519
|
-
await
|
|
22519
|
+
await sleep3(interval);
|
|
22520
22520
|
}
|
|
22521
22521
|
return { kind: "timeout" };
|
|
22522
22522
|
}
|
|
22523
|
-
function
|
|
22523
|
+
function sleep3(ms) {
|
|
22524
22524
|
return new Promise((r) => setTimeout(r, ms));
|
|
22525
22525
|
}
|
|
22526
22526
|
function generateOptionToken() {
|
|
@@ -30132,18 +30132,18 @@ import {
|
|
|
30132
30132
|
ftruncateSync,
|
|
30133
30133
|
mkdirSync as mkdirSync9,
|
|
30134
30134
|
openSync,
|
|
30135
|
-
readFileSync as
|
|
30136
|
-
readdirSync as
|
|
30135
|
+
readFileSync as readFileSync17,
|
|
30136
|
+
readdirSync as readdirSync6,
|
|
30137
30137
|
realpathSync,
|
|
30138
30138
|
renameSync as renameSync7,
|
|
30139
|
-
statSync as
|
|
30139
|
+
statSync as statSync5,
|
|
30140
30140
|
unlinkSync as unlinkSync8,
|
|
30141
30141
|
watch,
|
|
30142
30142
|
writeFileSync as writeFileSync11,
|
|
30143
30143
|
writeSync
|
|
30144
30144
|
} from "fs";
|
|
30145
30145
|
import { homedir as homedir7 } from "os";
|
|
30146
|
-
import { basename, extname, join as
|
|
30146
|
+
import { basename, extname, join as join17, resolve as resolve2 } from "path";
|
|
30147
30147
|
|
|
30148
30148
|
// src/channel-attachments.ts
|
|
30149
30149
|
import { homedir } from "os";
|
|
@@ -34354,6 +34354,160 @@ function classifyTranscriptRateLimit(jsonl, startMs, endMs, now) {
|
|
|
34354
34354
|
return newest;
|
|
34355
34355
|
}
|
|
34356
34356
|
|
|
34357
|
+
// ../core/dist/claude-code-usage/turn-failure-classifier.js
|
|
34358
|
+
var UNKNOWN_TURN_FAILURE = Object.freeze({
|
|
34359
|
+
outcome: "unknown",
|
|
34360
|
+
atMs: null,
|
|
34361
|
+
failureClass: null,
|
|
34362
|
+
httpStatus: null,
|
|
34363
|
+
attempt: null,
|
|
34364
|
+
maxAttempts: null
|
|
34365
|
+
});
|
|
34366
|
+
var EXCLUDED_STATUSES = /* @__PURE__ */ new Set([429]);
|
|
34367
|
+
function classifyTransientStatus(status) {
|
|
34368
|
+
if (!Number.isFinite(status))
|
|
34369
|
+
return null;
|
|
34370
|
+
if (EXCLUDED_STATUSES.has(status))
|
|
34371
|
+
return null;
|
|
34372
|
+
if (status === 529)
|
|
34373
|
+
return "overloaded";
|
|
34374
|
+
if (status >= 500 && status <= 599)
|
|
34375
|
+
return "server_error";
|
|
34376
|
+
return null;
|
|
34377
|
+
}
|
|
34378
|
+
function numberOrNull(value) {
|
|
34379
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
34380
|
+
}
|
|
34381
|
+
function isErrorShaped(record2) {
|
|
34382
|
+
if (record2.isApiErrorMessage === true)
|
|
34383
|
+
return true;
|
|
34384
|
+
if (record2.type === "system" && record2.level === "error")
|
|
34385
|
+
return true;
|
|
34386
|
+
if (record2.type === "assistant" && typeof record2.error === "string" && record2.error)
|
|
34387
|
+
return true;
|
|
34388
|
+
return false;
|
|
34389
|
+
}
|
|
34390
|
+
function classifyRecord(record2, tsMs) {
|
|
34391
|
+
if (record2.isSidechain === true)
|
|
34392
|
+
return null;
|
|
34393
|
+
if (record2.type === "system" && record2.subtype === "api_error") {
|
|
34394
|
+
const error2 = record2.error;
|
|
34395
|
+
const status = typeof error2 === "object" && error2 !== null ? numberOrNull(error2.status) : null;
|
|
34396
|
+
if (status === null)
|
|
34397
|
+
return null;
|
|
34398
|
+
const failureClass = classifyTransientStatus(status);
|
|
34399
|
+
if (!failureClass)
|
|
34400
|
+
return null;
|
|
34401
|
+
return {
|
|
34402
|
+
outcome: "retrying",
|
|
34403
|
+
atMs: tsMs,
|
|
34404
|
+
failureClass,
|
|
34405
|
+
httpStatus: status,
|
|
34406
|
+
attempt: numberOrNull(record2.retryAttempt),
|
|
34407
|
+
maxAttempts: numberOrNull(record2.maxRetries)
|
|
34408
|
+
};
|
|
34409
|
+
}
|
|
34410
|
+
if (record2.type !== "assistant")
|
|
34411
|
+
return null;
|
|
34412
|
+
if (record2.isApiErrorMessage === true) {
|
|
34413
|
+
const status = numberOrNull(record2.apiErrorStatus);
|
|
34414
|
+
const failureClass = status === null ? null : classifyTransientStatus(status);
|
|
34415
|
+
if (!failureClass)
|
|
34416
|
+
return null;
|
|
34417
|
+
return {
|
|
34418
|
+
outcome: "failed",
|
|
34419
|
+
atMs: tsMs,
|
|
34420
|
+
failureClass,
|
|
34421
|
+
httpStatus: status,
|
|
34422
|
+
attempt: null,
|
|
34423
|
+
maxAttempts: null
|
|
34424
|
+
};
|
|
34425
|
+
}
|
|
34426
|
+
const message = record2.message;
|
|
34427
|
+
if (typeof message !== "object" || message === null)
|
|
34428
|
+
return null;
|
|
34429
|
+
const msg = message;
|
|
34430
|
+
if (msg.model === "<synthetic>")
|
|
34431
|
+
return null;
|
|
34432
|
+
const usage = msg.usage;
|
|
34433
|
+
if (typeof usage !== "object" || usage === null)
|
|
34434
|
+
return null;
|
|
34435
|
+
const u = usage;
|
|
34436
|
+
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);
|
|
34437
|
+
if (!Number.isFinite(spent) || spent <= 0)
|
|
34438
|
+
return null;
|
|
34439
|
+
return {
|
|
34440
|
+
outcome: "served",
|
|
34441
|
+
atMs: tsMs,
|
|
34442
|
+
failureClass: null,
|
|
34443
|
+
httpStatus: null,
|
|
34444
|
+
attempt: null,
|
|
34445
|
+
maxAttempts: null
|
|
34446
|
+
};
|
|
34447
|
+
}
|
|
34448
|
+
function pickNewerTurnFailure(current, next) {
|
|
34449
|
+
if (next.outcome === "unknown")
|
|
34450
|
+
return current;
|
|
34451
|
+
if (current.outcome === "unknown")
|
|
34452
|
+
return next;
|
|
34453
|
+
return (next.atMs ?? 0) >= (current.atMs ?? 0) ? next : current;
|
|
34454
|
+
}
|
|
34455
|
+
function isShapeRecognised(record2) {
|
|
34456
|
+
if (record2.type === "system" && record2.subtype === "api_error") {
|
|
34457
|
+
const error2 = record2.error;
|
|
34458
|
+
return typeof error2 === "object" && error2 !== null && numberOrNull(error2.status) !== null;
|
|
34459
|
+
}
|
|
34460
|
+
if (record2.type === "assistant" && record2.isApiErrorMessage === true) {
|
|
34461
|
+
return numberOrNull(record2.apiErrorStatus) !== null;
|
|
34462
|
+
}
|
|
34463
|
+
return false;
|
|
34464
|
+
}
|
|
34465
|
+
function analyzeTranscriptTurnFailure(jsonl, startMs, endMs, opts = {}) {
|
|
34466
|
+
const maxKeys = opts.maxKeys ?? 40;
|
|
34467
|
+
let newest = UNKNOWN_TURN_FAILURE;
|
|
34468
|
+
let coarse = 0;
|
|
34469
|
+
let fine = 0;
|
|
34470
|
+
const keys = /* @__PURE__ */ new Set();
|
|
34471
|
+
for (const line of jsonl.split("\n")) {
|
|
34472
|
+
const trimmed = line.trim();
|
|
34473
|
+
if (!trimmed)
|
|
34474
|
+
continue;
|
|
34475
|
+
let obj;
|
|
34476
|
+
try {
|
|
34477
|
+
obj = JSON.parse(trimmed);
|
|
34478
|
+
} catch {
|
|
34479
|
+
continue;
|
|
34480
|
+
}
|
|
34481
|
+
if (typeof obj !== "object" || obj === null)
|
|
34482
|
+
continue;
|
|
34483
|
+
const record2 = obj;
|
|
34484
|
+
const ts = record2.timestamp;
|
|
34485
|
+
if (typeof ts !== "string" || !ts)
|
|
34486
|
+
continue;
|
|
34487
|
+
const tsMs = new Date(ts).getTime();
|
|
34488
|
+
if (!Number.isFinite(tsMs) || tsMs < startMs || tsMs > endMs)
|
|
34489
|
+
continue;
|
|
34490
|
+
const classified = classifyRecord(record2, tsMs);
|
|
34491
|
+
if (classified)
|
|
34492
|
+
newest = pickNewerTurnFailure(newest, classified);
|
|
34493
|
+
if (!isErrorShaped(record2) || record2.isSidechain === true)
|
|
34494
|
+
continue;
|
|
34495
|
+
coarse++;
|
|
34496
|
+
if (isShapeRecognised(record2)) {
|
|
34497
|
+
fine++;
|
|
34498
|
+
continue;
|
|
34499
|
+
}
|
|
34500
|
+
if (keys.size < maxKeys) {
|
|
34501
|
+
for (const key2 of Object.keys(record2)) {
|
|
34502
|
+
if (keys.size >= maxKeys)
|
|
34503
|
+
break;
|
|
34504
|
+
keys.add(key2);
|
|
34505
|
+
}
|
|
34506
|
+
}
|
|
34507
|
+
}
|
|
34508
|
+
return { result: newest, coarse, fine, unrecognisedKeys: [...keys].sort() };
|
|
34509
|
+
}
|
|
34510
|
+
|
|
34357
34511
|
// ../core/dist/claude-code-usage/transcript-location.js
|
|
34358
34512
|
function encodeClaudeProjectPath(projectDir) {
|
|
34359
34513
|
return "-" + projectDir.replace(/^\//, "").replace(/[/.]/g, "-");
|
|
@@ -35210,7 +35364,7 @@ var FLAG_REGISTRY = [
|
|
|
35210
35364
|
},
|
|
35211
35365
|
{
|
|
35212
35366
|
key: "wedge-transient-notice",
|
|
35213
|
-
description:
|
|
35367
|
+
description: `Tell the person waiting when their turn dies on a transient LLM-API failure (529 overloaded / 5xx). TWO consumers now share this gate. (1) ENG-7360: a wedge-respawn preceded by such an error writes the ENG-6058 give-up signal tagged reason=transient_overload so the channel sweeps post a "please resend" notice. (2) ENG-8269: the channel MCPs watch the dispatched turn in Claude Code's own transcript and notify the conversation that was actually waiting \u2014 Slack, Telegram AND direct chat \u2014 plus a "still working on this" notice after ~3min on Slack/Telegram only (direct chat already shows a client-side one at 90s). NOTE: (2) fires on a MUCH larger population than (1) \u2014 any dispatched turn that dies, not only one that also wedged the session \u2014 and (1) has never actually been able to fire, because its pane.log detector cannot match the banner Claude Code renders today. So flipping this on is in practice enabling (2) for the first time. Boolean gate; ships dark \u2014 channel-visible copy soaks per host before going wide. Materialized into the channel-MCP spawn env: a Docker-isolated agent never mounts the host flags-cache, so a central flip reaches it only that way.`,
|
|
35214
35368
|
flagType: "boolean",
|
|
35215
35369
|
defaultValue: false,
|
|
35216
35370
|
envVar: "AGT_WEDGE_TRANSIENT_NOTICE_ENABLED"
|
|
@@ -37496,6 +37650,149 @@ async function watchForRateLimitRefusal(opts) {
|
|
|
37496
37650
|
}
|
|
37497
37651
|
}
|
|
37498
37652
|
|
|
37653
|
+
// src/turn-failure-watch.ts
|
|
37654
|
+
import { readFileSync as readFileSync12, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
|
|
37655
|
+
import { join as join10 } from "path";
|
|
37656
|
+
function turnFailureNoticeEnabled(env2) {
|
|
37657
|
+
return resolveHostBooleanFlag({
|
|
37658
|
+
key: "wedge-transient-notice",
|
|
37659
|
+
envVar: "AGT_WEDGE_TRANSIENT_NOTICE_ENABLED",
|
|
37660
|
+
defaultValue: false,
|
|
37661
|
+
...env2 ? { env: env2 } : {}
|
|
37662
|
+
});
|
|
37663
|
+
}
|
|
37664
|
+
var DEFAULT_FAILURE_WATCH_MS = 5 * 6e4;
|
|
37665
|
+
var FAST_POLL_MS = 500;
|
|
37666
|
+
var SLOW_POLL_MS = 3e3;
|
|
37667
|
+
var FAST_PHASE_MS = 1e4;
|
|
37668
|
+
var RETRYING_NOTICE_AFTER_MS = 3 * 6e4;
|
|
37669
|
+
var sleep2 = (ms) => new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
37670
|
+
function classifyTurnFailureSince(opts) {
|
|
37671
|
+
const dir = opts.transcriptDir ?? agentTranscriptDir({ cwd: opts.cwd, home: opts.home });
|
|
37672
|
+
let entries;
|
|
37673
|
+
try {
|
|
37674
|
+
entries = readdirSync2(dir);
|
|
37675
|
+
} catch {
|
|
37676
|
+
return { result: UNKNOWN_TURN_FAILURE, coarse: 0, fine: 0, unrecognisedKeys: [] };
|
|
37677
|
+
}
|
|
37678
|
+
let newest = UNKNOWN_TURN_FAILURE;
|
|
37679
|
+
let coarse = 0;
|
|
37680
|
+
let fine = 0;
|
|
37681
|
+
const unrecognised = /* @__PURE__ */ new Set();
|
|
37682
|
+
for (const name of entries) {
|
|
37683
|
+
if (!name.endsWith(".jsonl")) continue;
|
|
37684
|
+
const path = join10(dir, name);
|
|
37685
|
+
let fingerprint;
|
|
37686
|
+
try {
|
|
37687
|
+
const st = statSync2(path);
|
|
37688
|
+
if (!st.isFile() || st.mtimeMs < opts.sinceMs) continue;
|
|
37689
|
+
fingerprint = `${st.mtimeMs}:${st.size}`;
|
|
37690
|
+
} catch {
|
|
37691
|
+
continue;
|
|
37692
|
+
}
|
|
37693
|
+
const cached2 = opts.cache?.get(path);
|
|
37694
|
+
let scan;
|
|
37695
|
+
if (cached2 && cached2.fingerprint === fingerprint) {
|
|
37696
|
+
scan = cached2.scan;
|
|
37697
|
+
} else {
|
|
37698
|
+
let content;
|
|
37699
|
+
try {
|
|
37700
|
+
content = readFileSync12(path, "utf-8");
|
|
37701
|
+
} catch {
|
|
37702
|
+
continue;
|
|
37703
|
+
}
|
|
37704
|
+
const analysis = analyzeTranscriptTurnFailure(content, opts.sinceMs, opts.nowMs);
|
|
37705
|
+
scan = {
|
|
37706
|
+
result: analysis.result,
|
|
37707
|
+
coarse: analysis.coarse,
|
|
37708
|
+
fine: analysis.fine,
|
|
37709
|
+
unrecognisedKeys: analysis.unrecognisedKeys
|
|
37710
|
+
};
|
|
37711
|
+
opts.cache?.set(path, { fingerprint, scan });
|
|
37712
|
+
}
|
|
37713
|
+
newest = pickNewerTurnFailure(newest, scan.result);
|
|
37714
|
+
coarse += scan.coarse;
|
|
37715
|
+
fine += scan.fine;
|
|
37716
|
+
for (const key2 of scan.unrecognisedKeys) unrecognised.add(key2);
|
|
37717
|
+
}
|
|
37718
|
+
return { result: newest, coarse, fine, unrecognisedKeys: [...unrecognised].sort() };
|
|
37719
|
+
}
|
|
37720
|
+
function emitDriftTelemetryIfBlind(args) {
|
|
37721
|
+
if (args.coarse <= 0 || args.fine > 0) return;
|
|
37722
|
+
try {
|
|
37723
|
+
process.stderr.write(
|
|
37724
|
+
`agt.transcript.api_error.unclassified ${JSON.stringify({
|
|
37725
|
+
channel: args.channel,
|
|
37726
|
+
agent_code: process.env.AGT_AGENT_CODE_NAME ?? "unknown",
|
|
37727
|
+
coarse: args.coarse,
|
|
37728
|
+
keys: args.unrecognisedKeys.slice(0, 20)
|
|
37729
|
+
})}
|
|
37730
|
+
`
|
|
37731
|
+
);
|
|
37732
|
+
} catch {
|
|
37733
|
+
}
|
|
37734
|
+
}
|
|
37735
|
+
async function watchForTurnFailure(opts) {
|
|
37736
|
+
const now = opts.now ?? (() => Date.now());
|
|
37737
|
+
const wait = opts.wait ?? sleep2;
|
|
37738
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_FAILURE_WATCH_MS;
|
|
37739
|
+
const fastPollMs = opts.fastPollMs ?? FAST_POLL_MS;
|
|
37740
|
+
const slowPollMs = opts.slowPollMs ?? SLOW_POLL_MS;
|
|
37741
|
+
const fastPhaseMs = opts.fastPhaseMs ?? FAST_PHASE_MS;
|
|
37742
|
+
const retryingAfterMs = opts.retryingNoticeAfterMs ?? RETRYING_NOTICE_AFTER_MS;
|
|
37743
|
+
const startedAt = now();
|
|
37744
|
+
const deadline = startedAt + timeoutMs;
|
|
37745
|
+
let longRetryFired = false;
|
|
37746
|
+
let driftEmitted = false;
|
|
37747
|
+
const cache = /* @__PURE__ */ new Map();
|
|
37748
|
+
for (; ; ) {
|
|
37749
|
+
let scan;
|
|
37750
|
+
try {
|
|
37751
|
+
scan = classifyTurnFailureSince({
|
|
37752
|
+
sinceMs: opts.sinceMs,
|
|
37753
|
+
// No upper bound, deliberately. Two reasons, and the second is a
|
|
37754
|
+
// correctness requirement of the cache above:
|
|
37755
|
+
// 1. For a post-dispatch watch the question is "has anything since the
|
|
37756
|
+
// dispatch killed this turn?" — a future-dated entry is still an
|
|
37757
|
+
// answer, and rejecting it on clock skew would drop the notice.
|
|
37758
|
+
// 2. A window that widens each poll makes a cached scan unsound: an
|
|
37759
|
+
// entry stamped a hair ahead of our clock would be parsed as
|
|
37760
|
+
// out-of-window, cached as "not seen", and — because a DEAD turn
|
|
37761
|
+
// produces no further appends to invalidate the entry — never looked
|
|
37762
|
+
// at again. That is exactly the silence this feature exists to end.
|
|
37763
|
+
nowMs: Number.POSITIVE_INFINITY,
|
|
37764
|
+
transcriptDir: opts.transcriptDir,
|
|
37765
|
+
cwd: opts.cwd,
|
|
37766
|
+
home: opts.home,
|
|
37767
|
+
cache
|
|
37768
|
+
});
|
|
37769
|
+
} catch {
|
|
37770
|
+
return null;
|
|
37771
|
+
}
|
|
37772
|
+
if (!driftEmitted && scan.coarse > 0 && scan.fine === 0) {
|
|
37773
|
+
driftEmitted = true;
|
|
37774
|
+
emitDriftTelemetryIfBlind({
|
|
37775
|
+
channel: opts.channel ?? "unknown",
|
|
37776
|
+
coarse: scan.coarse,
|
|
37777
|
+
fine: scan.fine,
|
|
37778
|
+
unrecognisedKeys: scan.unrecognisedKeys
|
|
37779
|
+
});
|
|
37780
|
+
}
|
|
37781
|
+
const { result } = scan;
|
|
37782
|
+
if (result.outcome === "failed") return result;
|
|
37783
|
+
if (result.outcome === "served") return null;
|
|
37784
|
+
if (result.outcome === "retrying" && !longRetryFired && opts.onLongRetry && now() - startedAt >= retryingAfterMs) {
|
|
37785
|
+
longRetryFired = true;
|
|
37786
|
+
try {
|
|
37787
|
+
await opts.onLongRetry(result);
|
|
37788
|
+
} catch {
|
|
37789
|
+
}
|
|
37790
|
+
}
|
|
37791
|
+
if (now() >= deadline) return null;
|
|
37792
|
+
await wait(now() - startedAt < fastPhaseMs ? fastPollMs : slowPollMs);
|
|
37793
|
+
}
|
|
37794
|
+
}
|
|
37795
|
+
|
|
37499
37796
|
// src/usage-limit-reactive-decision.ts
|
|
37500
37797
|
import { createHash } from "crypto";
|
|
37501
37798
|
function shouldReadPredictiveMarker(mode) {
|
|
@@ -37522,7 +37819,7 @@ function describeUnparsedRefusal(text) {
|
|
|
37522
37819
|
import { execFile as execFile2 } from "child_process";
|
|
37523
37820
|
import { existsSync as existsSync5, mkdirSync as mkdirSync6, writeFileSync as writeFileSync7 } from "fs";
|
|
37524
37821
|
import { homedir as homedir6 } from "os";
|
|
37525
|
-
import { join as
|
|
37822
|
+
import { join as join11 } from "path";
|
|
37526
37823
|
var DEFAULT_CLAUDE_EVAL_MODEL = "claude-haiku-4-5-20251001";
|
|
37527
37824
|
var DEFAULT_ANTHROPIC_MESSAGES_URL = "https://api.anthropic.com/v1/messages";
|
|
37528
37825
|
var ANTHROPIC_API_VERSION = "2023-06-01";
|
|
@@ -37621,12 +37918,12 @@ async function runAnthropicMessages(prompt, opts) {
|
|
|
37621
37918
|
var emptyMcpConfigPath = null;
|
|
37622
37919
|
function ensureEmptyMcpConfig() {
|
|
37623
37920
|
if (emptyMcpConfigPath && existsSync5(emptyMcpConfigPath)) return emptyMcpConfigPath;
|
|
37624
|
-
const dir =
|
|
37921
|
+
const dir = join11(homedir6(), ".augmented");
|
|
37625
37922
|
try {
|
|
37626
37923
|
mkdirSync6(dir, { recursive: true });
|
|
37627
37924
|
} catch {
|
|
37628
37925
|
}
|
|
37629
|
-
const p2 =
|
|
37926
|
+
const p2 = join11(dir, ".reply-intent-empty-mcp.json");
|
|
37630
37927
|
writeFileSync7(p2, JSON.stringify({ mcpServers: {} }));
|
|
37631
37928
|
emptyMcpConfigPath = p2;
|
|
37632
37929
|
return p2;
|
|
@@ -37773,17 +38070,17 @@ function emitTransientApiErrorTelemetry(channel, match, original) {
|
|
|
37773
38070
|
}
|
|
37774
38071
|
|
|
37775
38072
|
// src/telegram-pending-inbound-cleanup.ts
|
|
37776
|
-
import { readdirSync as
|
|
37777
|
-
import { join as
|
|
38073
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync13, statSync as statSync3 } from "fs";
|
|
38074
|
+
import { join as join12 } from "path";
|
|
37778
38075
|
function markerArrivalMs(fullPath) {
|
|
37779
38076
|
try {
|
|
37780
|
-
const received = JSON.parse(
|
|
38077
|
+
const received = JSON.parse(readFileSync13(fullPath, "utf-8")).received_at;
|
|
37781
38078
|
const parsed = received ? Date.parse(received) : Number.NaN;
|
|
37782
38079
|
if (Number.isFinite(parsed)) return parsed;
|
|
37783
38080
|
} catch {
|
|
37784
38081
|
}
|
|
37785
38082
|
try {
|
|
37786
|
-
return
|
|
38083
|
+
return statSync3(fullPath).mtimeMs;
|
|
37787
38084
|
} catch {
|
|
37788
38085
|
return Number.POSITIVE_INFINITY;
|
|
37789
38086
|
}
|
|
@@ -37799,7 +38096,7 @@ function applyToChatMarkers(pendingDir, chatId, op, cutoffMs) {
|
|
|
37799
38096
|
const bounded = Number.isFinite(cutoffMs);
|
|
37800
38097
|
let filenames;
|
|
37801
38098
|
try {
|
|
37802
|
-
filenames =
|
|
38099
|
+
filenames = readdirSync3(pendingDir);
|
|
37803
38100
|
} catch {
|
|
37804
38101
|
return 0;
|
|
37805
38102
|
}
|
|
@@ -37807,7 +38104,7 @@ function applyToChatMarkers(pendingDir, chatId, op, cutoffMs) {
|
|
|
37807
38104
|
for (const filename of filenames) {
|
|
37808
38105
|
if (!filename.startsWith(prefix)) continue;
|
|
37809
38106
|
if (!filename.endsWith(".json")) continue;
|
|
37810
|
-
const fullPath =
|
|
38107
|
+
const fullPath = join12(pendingDir, filename);
|
|
37811
38108
|
if (bounded && markerArrivalMs(fullPath) > cutoffMs) continue;
|
|
37812
38109
|
op(fullPath);
|
|
37813
38110
|
applied++;
|
|
@@ -37817,12 +38114,12 @@ function applyToChatMarkers(pendingDir, chatId, op, cutoffMs) {
|
|
|
37817
38114
|
|
|
37818
38115
|
// src/recovery-ledger.ts
|
|
37819
38116
|
import { existsSync as existsSync6, unlinkSync as unlinkSync6 } from "fs";
|
|
37820
|
-
import { join as
|
|
38117
|
+
import { join as join13 } from "path";
|
|
37821
38118
|
function recoveryLedgerEntryExists(ledgerDir, markerName, exists = (p2) => existsSync6(p2)) {
|
|
37822
38119
|
if (!ledgerDir || !markerName) return false;
|
|
37823
38120
|
if (markerName.includes("/") || markerName.includes("\\") || markerName.includes("..")) return false;
|
|
37824
38121
|
try {
|
|
37825
|
-
return exists(
|
|
38122
|
+
return exists(join13(ledgerDir, markerName));
|
|
37826
38123
|
} catch {
|
|
37827
38124
|
return false;
|
|
37828
38125
|
}
|
|
@@ -37833,14 +38130,14 @@ function removeRecoveryLedgerEntry(ledgerDir, markerName, unlink = (p2) => {
|
|
|
37833
38130
|
if (!ledgerDir || !markerName) return;
|
|
37834
38131
|
if (markerName.includes("/") || markerName.includes("\\") || markerName.includes("..")) return;
|
|
37835
38132
|
try {
|
|
37836
|
-
unlink(
|
|
38133
|
+
unlink(join13(ledgerDir, markerName));
|
|
37837
38134
|
} catch {
|
|
37838
38135
|
}
|
|
37839
38136
|
}
|
|
37840
38137
|
|
|
37841
38138
|
// src/inbound-delivery-ledger.ts
|
|
37842
|
-
import { existsSync as existsSync7, mkdirSync as mkdirSync7, readdirSync as
|
|
37843
|
-
import { join as
|
|
38139
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync7, readdirSync as readdirSync4, readFileSync as readFileSync14, renameSync as renameSync5, writeFileSync as writeFileSync8 } from "fs";
|
|
38140
|
+
import { join as join14 } from "path";
|
|
37844
38141
|
function safeInboundId(inboundId) {
|
|
37845
38142
|
return inboundId.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
37846
38143
|
}
|
|
@@ -37848,8 +38145,8 @@ var defaultDeps = {
|
|
|
37848
38145
|
mkdir: (dir) => mkdirSync7(dir, { recursive: true }),
|
|
37849
38146
|
writeFile: (path, data) => writeFileSync8(path, data, "utf8"),
|
|
37850
38147
|
rename: (from, to) => renameSync5(from, to),
|
|
37851
|
-
readdir: (dir) =>
|
|
37852
|
-
readFile: (path) =>
|
|
38148
|
+
readdir: (dir) => readdirSync4(dir),
|
|
38149
|
+
readFile: (path) => readFileSync14(path, "utf8"),
|
|
37853
38150
|
exists: (path) => existsSync7(path)
|
|
37854
38151
|
};
|
|
37855
38152
|
function writeInboundDeliveryLedgerEntry(dir, record2, deps = defaultDeps) {
|
|
@@ -37858,7 +38155,7 @@ function writeInboundDeliveryLedgerEntry(dir, record2, deps = defaultDeps) {
|
|
|
37858
38155
|
if (!safe || safe.includes("/") || safe.includes("\\") || safe.includes("..")) return;
|
|
37859
38156
|
try {
|
|
37860
38157
|
deps.mkdir(dir);
|
|
37861
|
-
const final =
|
|
38158
|
+
const final = join14(dir, `${safe}.json`);
|
|
37862
38159
|
const tmp = `${final}.tmp`;
|
|
37863
38160
|
deps.writeFile(tmp, JSON.stringify(record2));
|
|
37864
38161
|
deps.rename(tmp, final);
|
|
@@ -38063,14 +38360,14 @@ function createKanbanCardActiveClient(args) {
|
|
|
38063
38360
|
import {
|
|
38064
38361
|
existsSync as existsSync8,
|
|
38065
38362
|
mkdirSync as mkdirSync8,
|
|
38066
|
-
readFileSync as
|
|
38363
|
+
readFileSync as readFileSync15,
|
|
38067
38364
|
renameSync as renameSync6,
|
|
38068
|
-
statSync as
|
|
38365
|
+
statSync as statSync4,
|
|
38069
38366
|
unlinkSync as unlinkSync7,
|
|
38070
38367
|
utimesSync,
|
|
38071
38368
|
writeFileSync as writeFileSync9
|
|
38072
38369
|
} from "fs";
|
|
38073
|
-
import { join as
|
|
38370
|
+
import { join as join15 } from "path";
|
|
38074
38371
|
var STALE_LOCK_MS = 9e4;
|
|
38075
38372
|
var HEARTBEAT_INTERVAL_MS = 3e4;
|
|
38076
38373
|
function defaultIsPidAlive(pid) {
|
|
@@ -38093,7 +38390,7 @@ function acquireMcpSpawnLock(args) {
|
|
|
38093
38390
|
const nowMs = options.nowMs ?? (() => Date.now());
|
|
38094
38391
|
const lockMtimeMs = options.lockMtimeMs ?? defaultLockMtimeMs;
|
|
38095
38392
|
const staleMs = options.staleMs ?? STALE_LOCK_MS;
|
|
38096
|
-
const path =
|
|
38393
|
+
const path = join15(agentDir, basename2);
|
|
38097
38394
|
const existing = readLockHolder(path);
|
|
38098
38395
|
if (existing) {
|
|
38099
38396
|
if (existing.pid === selfPid) {
|
|
@@ -38152,7 +38449,7 @@ function startMcpSpawnLockHeartbeat(lockPath, opts = {}) {
|
|
|
38152
38449
|
}
|
|
38153
38450
|
function defaultLockMtimeMs(path) {
|
|
38154
38451
|
try {
|
|
38155
|
-
return
|
|
38452
|
+
return statSync4(path).mtimeMs;
|
|
38156
38453
|
} catch {
|
|
38157
38454
|
return null;
|
|
38158
38455
|
}
|
|
@@ -38160,7 +38457,7 @@ function defaultLockMtimeMs(path) {
|
|
|
38160
38457
|
function readLockHolder(path) {
|
|
38161
38458
|
if (!existsSync8(path)) return null;
|
|
38162
38459
|
try {
|
|
38163
|
-
const raw =
|
|
38460
|
+
const raw = readFileSync15(path, "utf8");
|
|
38164
38461
|
const parsed = JSON.parse(raw);
|
|
38165
38462
|
const pid = typeof parsed.pid === "number" ? parsed.pid : Number(parsed.pid);
|
|
38166
38463
|
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
@@ -38172,8 +38469,8 @@ function readLockHolder(path) {
|
|
|
38172
38469
|
}
|
|
38173
38470
|
|
|
38174
38471
|
// src/ack-reaction.ts
|
|
38175
|
-
import { readdirSync as
|
|
38176
|
-
import { join as
|
|
38472
|
+
import { readdirSync as readdirSync5, readFileSync as readFileSync16, writeFileSync as writeFileSync10 } from "fs";
|
|
38473
|
+
import { join as join16 } from "path";
|
|
38177
38474
|
var REPLY_WEDGED_THRESHOLD_MS = 5 * 60 * 1e3;
|
|
38178
38475
|
var ACK_STARTUP_GRACE_MS = 6e4;
|
|
38179
38476
|
var ACK_PANE_FRESH_THRESHOLD_MS = 6e4;
|
|
@@ -38246,7 +38543,7 @@ var GIVE_UP_SIGNAL_MAX_AGE_MS = 30 * 60 * 1e3;
|
|
|
38246
38543
|
function readGiveUpSignal(path, now = Date.now()) {
|
|
38247
38544
|
if (!path) return null;
|
|
38248
38545
|
try {
|
|
38249
|
-
const raw = JSON.parse(
|
|
38546
|
+
const raw = JSON.parse(readFileSync16(path, "utf8"));
|
|
38250
38547
|
if (typeof raw.gave_up_at !== "string") return null;
|
|
38251
38548
|
const t = Date.parse(raw.gave_up_at);
|
|
38252
38549
|
if (!Number.isFinite(t) || t > now) return null;
|
|
@@ -38268,11 +38565,17 @@ function giveUpNoticeText(reason = null) {
|
|
|
38268
38565
|
}
|
|
38269
38566
|
return "\u26A0\uFE0F I couldn't read your last message \u2014 please resend it.";
|
|
38270
38567
|
}
|
|
38568
|
+
function turnFailedNoticeText() {
|
|
38569
|
+
return "\u26A0\uFE0F Something went wrong on my side and I couldn\u2019t finish that. Sorry \u2014 send it again when you get a chance and I\u2019ll pick it straight up.";
|
|
38570
|
+
}
|
|
38571
|
+
function turnRetryingNoticeText() {
|
|
38572
|
+
return "\u23F3 Still working on this \u2014 things are running slower than usual on my side. I\u2019ll reply as soon as I have it.";
|
|
38573
|
+
}
|
|
38271
38574
|
function oldestPendingMarkerAgeMs(dir, now = Date.now(), opts) {
|
|
38272
38575
|
if (!dir) return null;
|
|
38273
38576
|
let names;
|
|
38274
38577
|
try {
|
|
38275
|
-
names =
|
|
38578
|
+
names = readdirSync5(dir);
|
|
38276
38579
|
} catch {
|
|
38277
38580
|
return null;
|
|
38278
38581
|
}
|
|
@@ -38281,7 +38584,7 @@ function oldestPendingMarkerAgeMs(dir, now = Date.now(), opts) {
|
|
|
38281
38584
|
if (!name.endsWith(".json")) continue;
|
|
38282
38585
|
let receivedAt;
|
|
38283
38586
|
try {
|
|
38284
|
-
const raw = JSON.parse(
|
|
38587
|
+
const raw = JSON.parse(readFileSync16(join16(dir, name), "utf-8"));
|
|
38285
38588
|
if (raw.discretionary === true) continue;
|
|
38286
38589
|
if (!opts?.includeSeen && typeof raw.seen_at === "string" && raw.seen_at) continue;
|
|
38287
38590
|
receivedAt = raw.received_at;
|
|
@@ -38358,14 +38661,14 @@ function isMarkerGenuinelyAged(receivedAt, nowMs, thresholdMs) {
|
|
|
38358
38661
|
}
|
|
38359
38662
|
var DEFLECTION_COUNTER_SUFFIX = "-deflections.json";
|
|
38360
38663
|
function deflectionCounterPath(agentDir, channel) {
|
|
38361
|
-
return
|
|
38664
|
+
return join16(agentDir, `${channel}${DEFLECTION_COUNTER_SUFFIX}`);
|
|
38362
38665
|
}
|
|
38363
38666
|
function recordChannelDeflection(agentDir, channel, cause) {
|
|
38364
38667
|
if (!agentDir) return;
|
|
38365
38668
|
const path = deflectionCounterPath(agentDir, channel);
|
|
38366
38669
|
let counts = {};
|
|
38367
38670
|
try {
|
|
38368
|
-
const parsed = JSON.parse(
|
|
38671
|
+
const parsed = JSON.parse(readFileSync16(path, "utf-8"));
|
|
38369
38672
|
if (parsed && typeof parsed === "object") counts = parsed;
|
|
38370
38673
|
} catch {
|
|
38371
38674
|
}
|
|
@@ -38446,7 +38749,7 @@ function redactId(id) {
|
|
|
38446
38749
|
}
|
|
38447
38750
|
var BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN;
|
|
38448
38751
|
var AGENT_CODE_NAME = process.env.AGT_AGENT_CODE_NAME ?? "unknown";
|
|
38449
|
-
var TELEGRAM_AGENT_DIR = AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown" ?
|
|
38752
|
+
var TELEGRAM_AGENT_DIR = AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown" ? join17(homedir7(), ".augmented", AGENT_CODE_NAME) : null;
|
|
38450
38753
|
var AGT_HOST = process.env.AGT_HOST ?? null;
|
|
38451
38754
|
var AGT_API_KEY = process.env.AGT_API_KEY ?? null;
|
|
38452
38755
|
var AGT_AGENT_ID = process.env.AGT_AGENT_ID ?? null;
|
|
@@ -38549,11 +38852,11 @@ var peerRateLimiter = peerRateApiClient && parsePeerAgentModeEnv(process.env.TEL
|
|
|
38549
38852
|
log: (line) => process.stderr.write(`telegram-channel(${AGENT_CODE_NAME}): ${line}
|
|
38550
38853
|
`)
|
|
38551
38854
|
}) : createPeerRateLimiter();
|
|
38552
|
-
var PEER_PRESENCE_STATE_FILE = TELEGRAM_AGENT_DIR ?
|
|
38855
|
+
var PEER_PRESENCE_STATE_FILE = TELEGRAM_AGENT_DIR ? join17(TELEGRAM_AGENT_DIR, "telegram-peer-presence.json") : null;
|
|
38553
38856
|
function readPeerPresenceState() {
|
|
38554
38857
|
if (!PEER_PRESENCE_STATE_FILE) return null;
|
|
38555
38858
|
try {
|
|
38556
|
-
const parsed = JSON.parse(
|
|
38859
|
+
const parsed = JSON.parse(readFileSync17(PEER_PRESENCE_STATE_FILE, "utf-8"));
|
|
38557
38860
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
38558
38861
|
return parsed;
|
|
38559
38862
|
} catch {
|
|
@@ -38588,9 +38891,9 @@ if (!BOT_TOKEN) {
|
|
|
38588
38891
|
var stderrLogStream = null;
|
|
38589
38892
|
if (AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown") {
|
|
38590
38893
|
try {
|
|
38591
|
-
const logDir =
|
|
38894
|
+
const logDir = join17(homedir7(), ".augmented", AGENT_CODE_NAME);
|
|
38592
38895
|
mkdirSync9(logDir, { recursive: true });
|
|
38593
|
-
stderrLogStream = createWriteStream(
|
|
38896
|
+
stderrLogStream = createWriteStream(join17(logDir, "telegram-channel-stderr.log"), {
|
|
38594
38897
|
flags: "a",
|
|
38595
38898
|
mode: 384
|
|
38596
38899
|
});
|
|
@@ -39027,7 +39330,7 @@ function scheduleBusyAck(chatId, messageId, arrivedWhileBusy) {
|
|
|
39027
39330
|
let paneLogFreshAgeMs = null;
|
|
39028
39331
|
if (AGENT_DIR) {
|
|
39029
39332
|
try {
|
|
39030
|
-
const paneMtimeMs =
|
|
39333
|
+
const paneMtimeMs = statSync5(join17(AGENT_DIR, "pane.log")).mtimeMs;
|
|
39031
39334
|
paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
|
|
39032
39335
|
} catch {
|
|
39033
39336
|
}
|
|
@@ -39057,7 +39360,7 @@ function scheduleBusyAck(chatId, messageId, arrivedWhileBusy) {
|
|
|
39057
39360
|
function __resetBusyAckNoticeThrottle() {
|
|
39058
39361
|
lastBusyAckNoticeAt.clear();
|
|
39059
39362
|
}
|
|
39060
|
-
var RESTART_FLAGS_DIR =
|
|
39363
|
+
var RESTART_FLAGS_DIR = join17(homedir7(), ".augmented", "restart-flags");
|
|
39061
39364
|
function actuateHostRestartTelegram() {
|
|
39062
39365
|
return actuateHostRestart({
|
|
39063
39366
|
agtHost: AGT_HOST,
|
|
@@ -39442,7 +39745,7 @@ async function handleRestartCommand(opts) {
|
|
|
39442
39745
|
if (!existsSync9(RESTART_FLAGS_DIR)) {
|
|
39443
39746
|
mkdirSync9(RESTART_FLAGS_DIR, { recursive: true });
|
|
39444
39747
|
}
|
|
39445
|
-
const flagPath =
|
|
39748
|
+
const flagPath = join17(RESTART_FLAGS_DIR, `${AGENT_CODE_NAME}.flag`);
|
|
39446
39749
|
const flag = {
|
|
39447
39750
|
codeName: AGENT_CODE_NAME,
|
|
39448
39751
|
source: "telegram",
|
|
@@ -39848,16 +40151,16 @@ async function classifyRestartCommand(text) {
|
|
|
39848
40151
|
if (!ours) return "verification_failed";
|
|
39849
40152
|
return target === ours ? "act" : "ignore";
|
|
39850
40153
|
}
|
|
39851
|
-
var AGENT_DIR = AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown" ?
|
|
39852
|
-
var PENDING_INBOUND_DIR = AGENT_DIR ?
|
|
39853
|
-
var RECOVERY_OUTBOX_DIR = AGENT_DIR ?
|
|
39854
|
-
var RECOVERY_LEDGER_DIR = AGENT_DIR ?
|
|
39855
|
-
var DELIVERY_LEDGER_DIR = AGENT_DIR ?
|
|
39856
|
-
var RESTART_CONFIRM_FILE = AGENT_DIR ?
|
|
40154
|
+
var AGENT_DIR = AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown" ? join17(homedir7(), ".augmented", AGENT_CODE_NAME) : null;
|
|
40155
|
+
var PENDING_INBOUND_DIR = AGENT_DIR ? join17(AGENT_DIR, "telegram-pending-inbound") : null;
|
|
40156
|
+
var RECOVERY_OUTBOX_DIR = AGENT_DIR ? join17(AGENT_DIR, "telegram-recovery-outbox") : null;
|
|
40157
|
+
var RECOVERY_LEDGER_DIR = AGENT_DIR ? join17(AGENT_DIR, ".agt-telegram-recovery-ledger") : null;
|
|
40158
|
+
var DELIVERY_LEDGER_DIR = AGENT_DIR ? join17(AGENT_DIR, ".agt-inbound-delivery-ledger") : null;
|
|
40159
|
+
var RESTART_CONFIRM_FILE = AGENT_DIR ? join17(AGENT_DIR, "telegram-restart-confirm.json") : null;
|
|
39857
40160
|
var TELEGRAM_PROCESS_BOOT_MS = Date.now();
|
|
39858
|
-
var TELEGRAM_RECENT_DMS_FILE = AGENT_DIR ?
|
|
39859
|
-
var TELEGRAM_CHANNEL_ADD_RESTART_FILE = AGENT_DIR ?
|
|
39860
|
-
var TELEGRAM_OFFSET_FILE = AGENT_DIR ?
|
|
40161
|
+
var TELEGRAM_RECENT_DMS_FILE = AGENT_DIR ? join17(AGENT_DIR, "telegram-recent-dms.json") : null;
|
|
40162
|
+
var TELEGRAM_CHANNEL_ADD_RESTART_FILE = AGENT_DIR ? join17(AGENT_DIR, "telegram-channel-add-restart.json") : null;
|
|
40163
|
+
var TELEGRAM_OFFSET_FILE = AGENT_DIR ? join17(AGENT_DIR, "telegram-getupdates-offset.json") : null;
|
|
39861
40164
|
var recentDms = /* @__PURE__ */ new Map();
|
|
39862
40165
|
var recentDmPersister = TELEGRAM_RECENT_DMS_FILE ? createRecentDmPersister({
|
|
39863
40166
|
filePath: TELEGRAM_RECENT_DMS_FILE,
|
|
@@ -39912,7 +40215,7 @@ function safeMarkerName(chatId, messageId) {
|
|
|
39912
40215
|
}
|
|
39913
40216
|
function pendingInboundPath(chatId, messageId) {
|
|
39914
40217
|
if (!PENDING_INBOUND_DIR) return null;
|
|
39915
|
-
return
|
|
40218
|
+
return join17(PENDING_INBOUND_DIR, safeMarkerName(chatId, messageId));
|
|
39916
40219
|
}
|
|
39917
40220
|
function writePendingInboundMarker(chatId, messageId, chatType, undeliverable = false, payload) {
|
|
39918
40221
|
const path = pendingInboundPath(chatId, messageId);
|
|
@@ -39960,7 +40263,7 @@ function rewriteTelegramMarkerInPlace(path, marker) {
|
|
|
39960
40263
|
function clearTelegramMarkerFileWithHeal(fullPath) {
|
|
39961
40264
|
let marker = null;
|
|
39962
40265
|
try {
|
|
39963
|
-
marker = JSON.parse(
|
|
40266
|
+
marker = JSON.parse(readFileSync17(fullPath, "utf-8"));
|
|
39964
40267
|
} catch {
|
|
39965
40268
|
}
|
|
39966
40269
|
if (marker && decideRecoveryHeal({
|
|
@@ -39977,7 +40280,7 @@ function clearTelegramMarkerFileWithHeal(fullPath) {
|
|
|
39977
40280
|
function markTelegramMarkerSeenInPlace(fullPath) {
|
|
39978
40281
|
let marker;
|
|
39979
40282
|
try {
|
|
39980
|
-
marker = JSON.parse(
|
|
40283
|
+
marker = JSON.parse(readFileSync17(fullPath, "utf-8"));
|
|
39981
40284
|
} catch {
|
|
39982
40285
|
return;
|
|
39983
40286
|
}
|
|
@@ -39989,7 +40292,7 @@ function markTelegramMarkerSeenInPlace(fullPath) {
|
|
|
39989
40292
|
function markTelegramMarkerSeenWithHeal(fullPath) {
|
|
39990
40293
|
let marker = null;
|
|
39991
40294
|
try {
|
|
39992
|
-
marker = JSON.parse(
|
|
40295
|
+
marker = JSON.parse(readFileSync17(fullPath, "utf-8"));
|
|
39993
40296
|
} catch {
|
|
39994
40297
|
return;
|
|
39995
40298
|
}
|
|
@@ -40005,7 +40308,7 @@ function readPendingInboundMarker(chatId, messageId) {
|
|
|
40005
40308
|
const path = pendingInboundPath(chatId, messageId);
|
|
40006
40309
|
if (!path || !existsSync9(path)) return null;
|
|
40007
40310
|
try {
|
|
40008
|
-
return JSON.parse(
|
|
40311
|
+
return JSON.parse(readFileSync17(path, "utf-8"));
|
|
40009
40312
|
} catch {
|
|
40010
40313
|
return null;
|
|
40011
40314
|
}
|
|
@@ -40025,10 +40328,10 @@ function nextRetryName(filename) {
|
|
|
40025
40328
|
async function processRecoveryOutboxFile(filename) {
|
|
40026
40329
|
if (!RECOVERY_OUTBOX_DIR) return;
|
|
40027
40330
|
if (filename.endsWith(".poison.json") || filename.endsWith(".tmp")) return;
|
|
40028
|
-
const fullPath =
|
|
40331
|
+
const fullPath = join17(RECOVERY_OUTBOX_DIR, filename);
|
|
40029
40332
|
let payload;
|
|
40030
40333
|
try {
|
|
40031
|
-
const raw =
|
|
40334
|
+
const raw = readFileSync17(fullPath, "utf-8");
|
|
40032
40335
|
payload = JSON.parse(raw);
|
|
40033
40336
|
} catch (err) {
|
|
40034
40337
|
process.stderr.write(
|
|
@@ -40122,7 +40425,7 @@ async function processRecoveryOutboxFile(filename) {
|
|
|
40122
40425
|
const next = nextRetryName(filename);
|
|
40123
40426
|
if (next) {
|
|
40124
40427
|
try {
|
|
40125
|
-
renameSync7(fullPath,
|
|
40428
|
+
renameSync7(fullPath, join17(RECOVERY_OUTBOX_DIR, next.next));
|
|
40126
40429
|
if (next.attempt >= MAX_RECOVERY_ATTEMPTS) {
|
|
40127
40430
|
process.stderr.write(
|
|
40128
40431
|
`telegram-channel(${AGENT_CODE_NAME}): ghost-reply recovery exhausted retries \u2014 moved to ${next.next}
|
|
@@ -40154,7 +40457,7 @@ function scanRecoveryRetries() {
|
|
|
40154
40457
|
if (!RECOVERY_OUTBOX_DIR) return;
|
|
40155
40458
|
let entries;
|
|
40156
40459
|
try {
|
|
40157
|
-
entries =
|
|
40460
|
+
entries = readdirSync6(RECOVERY_OUTBOX_DIR);
|
|
40158
40461
|
} catch {
|
|
40159
40462
|
return;
|
|
40160
40463
|
}
|
|
@@ -40163,7 +40466,7 @@ function scanRecoveryRetries() {
|
|
|
40163
40466
|
if (!f.includes(".retry-") || f.endsWith(".poison.json")) continue;
|
|
40164
40467
|
let mtimeMs;
|
|
40165
40468
|
try {
|
|
40166
|
-
mtimeMs =
|
|
40469
|
+
mtimeMs = statSync5(join17(RECOVERY_OUTBOX_DIR, f)).mtimeMs;
|
|
40167
40470
|
} catch {
|
|
40168
40471
|
continue;
|
|
40169
40472
|
}
|
|
@@ -40184,7 +40487,7 @@ function startRecoveryOutboxWatcher() {
|
|
|
40184
40487
|
return;
|
|
40185
40488
|
}
|
|
40186
40489
|
try {
|
|
40187
|
-
for (const f of
|
|
40490
|
+
for (const f of readdirSync6(RECOVERY_OUTBOX_DIR)) {
|
|
40188
40491
|
if (isFirstAttemptOutboxFile(f)) void processRecoveryOutboxFile(f);
|
|
40189
40492
|
}
|
|
40190
40493
|
} catch {
|
|
@@ -40193,7 +40496,7 @@ function startRecoveryOutboxWatcher() {
|
|
|
40193
40496
|
const watcher = watch(RECOVERY_OUTBOX_DIR, (event, filename) => {
|
|
40194
40497
|
if (event !== "rename" || !filename) return;
|
|
40195
40498
|
if (!isFirstAttemptOutboxFile(filename)) return;
|
|
40196
|
-
if (existsSync9(
|
|
40499
|
+
if (existsSync9(join17(RECOVERY_OUTBOX_DIR, filename))) {
|
|
40197
40500
|
void processRecoveryOutboxFile(filename);
|
|
40198
40501
|
}
|
|
40199
40502
|
});
|
|
@@ -40208,7 +40511,7 @@ function startRecoveryOutboxWatcher() {
|
|
|
40208
40511
|
retryTimer.unref?.();
|
|
40209
40512
|
}
|
|
40210
40513
|
startRecoveryOutboxWatcher();
|
|
40211
|
-
var NOTICE_OUTBOX_DIR = AGENT_DIR ?
|
|
40514
|
+
var NOTICE_OUTBOX_DIR = AGENT_DIR ? join17(AGENT_DIR, "telegram-notice-outbox") : null;
|
|
40212
40515
|
var NOTICE_MAX_AGE_MS = 9e4;
|
|
40213
40516
|
var NOTICE_INFLIGHT = /* @__PURE__ */ new Set();
|
|
40214
40517
|
async function processNoticeOutboxFile(filename) {
|
|
@@ -40216,11 +40519,11 @@ async function processNoticeOutboxFile(filename) {
|
|
|
40216
40519
|
if (filename.startsWith(".") || filename.endsWith(".tmp") || !filename.endsWith(".json")) return;
|
|
40217
40520
|
if (NOTICE_INFLIGHT.has(filename)) return;
|
|
40218
40521
|
NOTICE_INFLIGHT.add(filename);
|
|
40219
|
-
const fullPath =
|
|
40522
|
+
const fullPath = join17(NOTICE_OUTBOX_DIR, filename);
|
|
40220
40523
|
try {
|
|
40221
40524
|
let mtimeMs;
|
|
40222
40525
|
try {
|
|
40223
|
-
mtimeMs =
|
|
40526
|
+
mtimeMs = statSync5(fullPath).mtimeMs;
|
|
40224
40527
|
} catch {
|
|
40225
40528
|
return;
|
|
40226
40529
|
}
|
|
@@ -40233,7 +40536,7 @@ async function processNoticeOutboxFile(filename) {
|
|
|
40233
40536
|
}
|
|
40234
40537
|
let payload;
|
|
40235
40538
|
try {
|
|
40236
|
-
const parsed = JSON.parse(
|
|
40539
|
+
const parsed = JSON.parse(readFileSync17(fullPath, "utf-8"));
|
|
40237
40540
|
if (!parsed || typeof parsed !== "object") throw new Error("not an object");
|
|
40238
40541
|
payload = parsed;
|
|
40239
40542
|
} catch {
|
|
@@ -40304,13 +40607,13 @@ function startNoticeOutboxWatcher() {
|
|
|
40304
40607
|
return;
|
|
40305
40608
|
}
|
|
40306
40609
|
try {
|
|
40307
|
-
for (const f of
|
|
40610
|
+
for (const f of readdirSync6(NOTICE_OUTBOX_DIR)) void processNoticeOutboxFile(f);
|
|
40308
40611
|
} catch {
|
|
40309
40612
|
}
|
|
40310
40613
|
try {
|
|
40311
40614
|
const watcher = watch(NOTICE_OUTBOX_DIR, (event, filename) => {
|
|
40312
40615
|
if (event !== "rename" || !filename) return;
|
|
40313
|
-
if (existsSync9(
|
|
40616
|
+
if (existsSync9(join17(NOTICE_OUTBOX_DIR, filename))) void processNoticeOutboxFile(filename);
|
|
40314
40617
|
});
|
|
40315
40618
|
watcher.unref?.();
|
|
40316
40619
|
} catch (err) {
|
|
@@ -40330,7 +40633,7 @@ function sweepTelegramStaleMarkers(thresholdMs) {
|
|
|
40330
40633
|
if (!existsSync9(PENDING_INBOUND_DIR)) return;
|
|
40331
40634
|
let filenames;
|
|
40332
40635
|
try {
|
|
40333
|
-
filenames =
|
|
40636
|
+
filenames = readdirSync6(PENDING_INBOUND_DIR);
|
|
40334
40637
|
} catch (err) {
|
|
40335
40638
|
process.stderr.write(
|
|
40336
40639
|
`telegram-channel(${AGENT_CODE_NAME}): stale-marker readdir failed: ${err.message}
|
|
@@ -40344,10 +40647,10 @@ function sweepTelegramStaleMarkers(thresholdMs) {
|
|
|
40344
40647
|
for (const filename of filenames) {
|
|
40345
40648
|
if (!filename.endsWith(".json")) continue;
|
|
40346
40649
|
if (filename.endsWith(".tmp")) continue;
|
|
40347
|
-
const fullPath =
|
|
40650
|
+
const fullPath = join17(PENDING_INBOUND_DIR, filename);
|
|
40348
40651
|
let marker;
|
|
40349
40652
|
try {
|
|
40350
|
-
marker = JSON.parse(
|
|
40653
|
+
marker = JSON.parse(readFileSync17(fullPath, "utf-8"));
|
|
40351
40654
|
} catch (err) {
|
|
40352
40655
|
process.stderr.write(
|
|
40353
40656
|
`telegram-channel(${AGENT_CODE_NAME}): stale-marker parse failed for ${redactId(filename)}: ${err.message}
|
|
@@ -40400,13 +40703,13 @@ var orphanSweepTimer = setInterval(() => {
|
|
|
40400
40703
|
checkWatchdogGiveUpNotice();
|
|
40401
40704
|
}, orphanSweepIntervalMs());
|
|
40402
40705
|
orphanSweepTimer.unref?.();
|
|
40403
|
-
var TELEGRAM_PROGRESS_HEARTBEAT_PATH = AGENT_DIR ?
|
|
40706
|
+
var TELEGRAM_PROGRESS_HEARTBEAT_PATH = AGENT_DIR ? join17(AGENT_DIR, "channel-progress-heartbeat.json") : null;
|
|
40404
40707
|
var telegramTrackedProgress = null;
|
|
40405
40708
|
var telegramProgressTickRunning = false;
|
|
40406
40709
|
function readTelegramProgressHeartbeat() {
|
|
40407
40710
|
if (!TELEGRAM_PROGRESS_HEARTBEAT_PATH || !existsSync9(TELEGRAM_PROGRESS_HEARTBEAT_PATH)) return null;
|
|
40408
40711
|
try {
|
|
40409
|
-
return parseProgressHeartbeat(
|
|
40712
|
+
return parseProgressHeartbeat(readFileSync17(TELEGRAM_PROGRESS_HEARTBEAT_PATH, "utf-8"));
|
|
40410
40713
|
} catch {
|
|
40411
40714
|
return null;
|
|
40412
40715
|
}
|
|
@@ -40429,11 +40732,11 @@ function findTelegramProgressTarget() {
|
|
|
40429
40732
|
let best = null;
|
|
40430
40733
|
let bestMs = Infinity;
|
|
40431
40734
|
try {
|
|
40432
|
-
for (const name of
|
|
40735
|
+
for (const name of readdirSync6(PENDING_INBOUND_DIR)) {
|
|
40433
40736
|
if (!name.endsWith(".json")) continue;
|
|
40434
40737
|
let m;
|
|
40435
40738
|
try {
|
|
40436
|
-
m = JSON.parse(
|
|
40739
|
+
m = JSON.parse(readFileSync17(join17(PENDING_INBOUND_DIR, name), "utf-8"));
|
|
40437
40740
|
} catch {
|
|
40438
40741
|
continue;
|
|
40439
40742
|
}
|
|
@@ -40560,11 +40863,11 @@ function listPendingInboundChatIds() {
|
|
|
40560
40863
|
if (!PENDING_INBOUND_DIR || !existsSync9(PENDING_INBOUND_DIR)) return [];
|
|
40561
40864
|
const chats = /* @__PURE__ */ new Set();
|
|
40562
40865
|
try {
|
|
40563
|
-
for (const name of
|
|
40866
|
+
for (const name of readdirSync6(PENDING_INBOUND_DIR)) {
|
|
40564
40867
|
if (!name.endsWith(".json")) continue;
|
|
40565
40868
|
try {
|
|
40566
40869
|
const marker = JSON.parse(
|
|
40567
|
-
|
|
40870
|
+
readFileSync17(join17(PENDING_INBOUND_DIR, name), "utf8")
|
|
40568
40871
|
);
|
|
40569
40872
|
if (typeof marker.seen_at === "string" && marker.seen_at) continue;
|
|
40570
40873
|
if (typeof marker.chat_id === "string" && marker.chat_id) chats.add(marker.chat_id);
|
|
@@ -40576,6 +40879,84 @@ function listPendingInboundChatIds() {
|
|
|
40576
40879
|
}
|
|
40577
40880
|
return [...chats];
|
|
40578
40881
|
}
|
|
40882
|
+
var lastTurnFailedNoticeAt = /* @__PURE__ */ new Map();
|
|
40883
|
+
var lastTurnRetryingNoticeAt = /* @__PURE__ */ new Map();
|
|
40884
|
+
async function postTelegramTurnNotice(args) {
|
|
40885
|
+
try {
|
|
40886
|
+
const resp = await telegramApiCall(
|
|
40887
|
+
"sendMessage",
|
|
40888
|
+
{
|
|
40889
|
+
chat_id: args.chatId,
|
|
40890
|
+
text: args.text,
|
|
40891
|
+
...args.messageThreadId != null ? { message_thread_id: args.messageThreadId } : {}
|
|
40892
|
+
},
|
|
40893
|
+
1e4
|
|
40894
|
+
);
|
|
40895
|
+
return resp.ok === true;
|
|
40896
|
+
} catch {
|
|
40897
|
+
return false;
|
|
40898
|
+
}
|
|
40899
|
+
}
|
|
40900
|
+
function armTelegramTurnFailureWatch(args) {
|
|
40901
|
+
const conversationKey = args.messageThreadId != null ? `${args.chatId}:${args.messageThreadId}` : args.chatId;
|
|
40902
|
+
void (async () => {
|
|
40903
|
+
try {
|
|
40904
|
+
const failure = await watchForTurnFailure({
|
|
40905
|
+
sinceMs: args.sinceMs,
|
|
40906
|
+
channel: "telegram",
|
|
40907
|
+
onLongRetry: async () => {
|
|
40908
|
+
const now2 = Date.now();
|
|
40909
|
+
if (!shouldPostUndeliverableNotice(lastTurnRetryingNoticeAt.get(conversationKey), now2)) {
|
|
40910
|
+
return;
|
|
40911
|
+
}
|
|
40912
|
+
lastTurnRetryingNoticeAt.set(conversationKey, now2);
|
|
40913
|
+
const posted2 = await postTelegramTurnNotice({
|
|
40914
|
+
chatId: args.chatId,
|
|
40915
|
+
...args.messageThreadId != null ? { messageThreadId: args.messageThreadId } : {},
|
|
40916
|
+
text: turnRetryingNoticeText()
|
|
40917
|
+
});
|
|
40918
|
+
if (!posted2) lastTurnRetryingNoticeAt.delete(conversationKey);
|
|
40919
|
+
process.stderr.write(
|
|
40920
|
+
`telegram-channel(${AGENT_CODE_NAME}): [turn-failure] retrying notice ${posted2 ? "posted" : "FAILED"} chat=${redactId(args.chatId)}
|
|
40921
|
+
`
|
|
40922
|
+
);
|
|
40923
|
+
}
|
|
40924
|
+
});
|
|
40925
|
+
if (!failure) return;
|
|
40926
|
+
const now = Date.now();
|
|
40927
|
+
if (!shouldPostUndeliverableNotice(lastTurnFailedNoticeAt.get(conversationKey), now)) {
|
|
40928
|
+
process.stderr.write(
|
|
40929
|
+
`telegram-channel(${AGENT_CODE_NAME}): [turn-failure] suppressed (throttled) chat=${redactId(args.chatId)} class=${failure.failureClass}
|
|
40930
|
+
`
|
|
40931
|
+
);
|
|
40932
|
+
return;
|
|
40933
|
+
}
|
|
40934
|
+
lastTurnFailedNoticeAt.set(conversationKey, now);
|
|
40935
|
+
const posted = await postTelegramTurnNotice({
|
|
40936
|
+
chatId: args.chatId,
|
|
40937
|
+
...args.messageThreadId != null ? { messageThreadId: args.messageThreadId } : {},
|
|
40938
|
+
text: turnFailedNoticeText()
|
|
40939
|
+
});
|
|
40940
|
+
if (!posted) {
|
|
40941
|
+
lastTurnFailedNoticeAt.delete(conversationKey);
|
|
40942
|
+
process.stderr.write(
|
|
40943
|
+
`telegram-channel(${AGENT_CODE_NAME}): [turn-failure] NOTICE POST FAILED chat=${redactId(args.chatId)} - the user is still waiting on a dead turn
|
|
40944
|
+
`
|
|
40945
|
+
);
|
|
40946
|
+
return;
|
|
40947
|
+
}
|
|
40948
|
+
process.stderr.write(
|
|
40949
|
+
`telegram-channel(${AGENT_CODE_NAME}): [turn-failure] notified chat=${redactId(args.chatId)} class=${failure.failureClass} status=${failure.httpStatus}
|
|
40950
|
+
`
|
|
40951
|
+
);
|
|
40952
|
+
} catch (err) {
|
|
40953
|
+
process.stderr.write(
|
|
40954
|
+
`telegram-channel(${AGENT_CODE_NAME}): [turn-failure] watch error: ${err.message}
|
|
40955
|
+
`
|
|
40956
|
+
);
|
|
40957
|
+
}
|
|
40958
|
+
})();
|
|
40959
|
+
}
|
|
40579
40960
|
async function notifyWatchdogGiveUp(chatId, reason) {
|
|
40580
40961
|
const now = Date.now();
|
|
40581
40962
|
if (!shouldPostUndeliverableNotice(lastUndeliverableNoticeAt.get(chatId), now)) return;
|
|
@@ -40606,7 +40987,7 @@ async function notifyWatchdogGiveUp(chatId, reason) {
|
|
|
40606
40987
|
}
|
|
40607
40988
|
function checkWatchdogGiveUpNotice() {
|
|
40608
40989
|
if (!AGENT_DIR) return;
|
|
40609
|
-
const signal = readGiveUpSignal(
|
|
40990
|
+
const signal = readGiveUpSignal(join17(AGENT_DIR, GIVE_UP_SIGNAL_FILENAME));
|
|
40610
40991
|
const signalAtMs = signal?.atMs ?? null;
|
|
40611
40992
|
const act = decideGiveUpNotice({
|
|
40612
40993
|
signalAtMs,
|
|
@@ -40948,7 +41329,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
40948
41329
|
let bytes;
|
|
40949
41330
|
let size;
|
|
40950
41331
|
try {
|
|
40951
|
-
const st =
|
|
41332
|
+
const st = statSync5(realPath);
|
|
40952
41333
|
if (!st.isFile()) {
|
|
40953
41334
|
return { content: [{ type: "text", text: `Upload refused: ${resolvedPath} is not a regular file.` }], isError: true };
|
|
40954
41335
|
}
|
|
@@ -40962,7 +41343,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
40962
41343
|
isError: true
|
|
40963
41344
|
};
|
|
40964
41345
|
}
|
|
40965
|
-
bytes =
|
|
41346
|
+
bytes = readFileSync17(realPath);
|
|
40966
41347
|
} catch (err) {
|
|
40967
41348
|
return { content: [{ type: "text", text: `Failed to read file: ${err.message}` }], isError: true };
|
|
40968
41349
|
}
|
|
@@ -41516,7 +41897,7 @@ async function replayPendingTelegramMarkers() {
|
|
|
41516
41897
|
if (!sessionAlive) return;
|
|
41517
41898
|
let filenames;
|
|
41518
41899
|
try {
|
|
41519
|
-
filenames =
|
|
41900
|
+
filenames = readdirSync6(PENDING_INBOUND_DIR);
|
|
41520
41901
|
} catch {
|
|
41521
41902
|
return;
|
|
41522
41903
|
}
|
|
@@ -41524,7 +41905,7 @@ async function replayPendingTelegramMarkers() {
|
|
|
41524
41905
|
let paneFreshAgeMs = null;
|
|
41525
41906
|
if (AGENT_DIR) {
|
|
41526
41907
|
try {
|
|
41527
|
-
paneFreshAgeMs = Math.max(0, now -
|
|
41908
|
+
paneFreshAgeMs = Math.max(0, now - statSync5(join17(AGENT_DIR, "pane.log")).mtimeMs);
|
|
41528
41909
|
} catch {
|
|
41529
41910
|
}
|
|
41530
41911
|
}
|
|
@@ -41532,10 +41913,10 @@ async function replayPendingTelegramMarkers() {
|
|
|
41532
41913
|
const entries = [];
|
|
41533
41914
|
for (const name of filenames) {
|
|
41534
41915
|
if (!name.endsWith(".json") || name.endsWith(".tmp")) continue;
|
|
41535
|
-
const fullPath =
|
|
41916
|
+
const fullPath = join17(PENDING_INBOUND_DIR, name);
|
|
41536
41917
|
let marker;
|
|
41537
41918
|
try {
|
|
41538
|
-
marker = JSON.parse(
|
|
41919
|
+
marker = JSON.parse(readFileSync17(fullPath, "utf-8"));
|
|
41539
41920
|
} catch {
|
|
41540
41921
|
continue;
|
|
41541
41922
|
}
|
|
@@ -41703,7 +42084,7 @@ async function pollLoop() {
|
|
|
41703
42084
|
`telegram-channel(${AGENT_CODE_NAME}): getUpdates failed: ${resp.description ?? "unknown"}
|
|
41704
42085
|
`
|
|
41705
42086
|
);
|
|
41706
|
-
await
|
|
42087
|
+
await sleep4(5e3);
|
|
41707
42088
|
continue;
|
|
41708
42089
|
}
|
|
41709
42090
|
const offsetBeforeBatch = nextOffset;
|
|
@@ -42086,7 +42467,7 @@ async function pollLoop() {
|
|
|
42086
42467
|
let paneLogFreshAgeMs = null;
|
|
42087
42468
|
if (AGENT_DIR) {
|
|
42088
42469
|
try {
|
|
42089
|
-
const paneMtimeMs =
|
|
42470
|
+
const paneMtimeMs = statSync5(join17(AGENT_DIR, "pane.log")).mtimeMs;
|
|
42090
42471
|
paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
|
|
42091
42472
|
} catch {
|
|
42092
42473
|
}
|
|
@@ -42206,6 +42587,13 @@ async function pollLoop() {
|
|
|
42206
42587
|
sinceMs: dispatchedAtMs
|
|
42207
42588
|
});
|
|
42208
42589
|
}
|
|
42590
|
+
if (!isFromBot && !peerAgentMeta && turnFailureNoticeEnabled()) {
|
|
42591
|
+
armTelegramTurnFailureWatch({
|
|
42592
|
+
chatId,
|
|
42593
|
+
...msg.message_thread_id != null ? { messageThreadId: msg.message_thread_id } : {},
|
|
42594
|
+
sinceMs: dispatchedAtMs
|
|
42595
|
+
});
|
|
42596
|
+
}
|
|
42209
42597
|
seedTelegramProgressHeartbeat();
|
|
42210
42598
|
conversationIngestClient?.ingest({
|
|
42211
42599
|
channel: "telegram",
|
|
@@ -42251,11 +42639,11 @@ async function pollLoop() {
|
|
|
42251
42639
|
`telegram-channel(${AGENT_CODE_NAME}): poll error: ${err.message}
|
|
42252
42640
|
`
|
|
42253
42641
|
);
|
|
42254
|
-
await
|
|
42642
|
+
await sleep4(5e3);
|
|
42255
42643
|
}
|
|
42256
42644
|
}
|
|
42257
42645
|
}
|
|
42258
|
-
function
|
|
42646
|
+
function sleep4(ms) {
|
|
42259
42647
|
return new Promise((resolve3) => setTimeout(resolve3, ms).unref());
|
|
42260
42648
|
}
|
|
42261
42649
|
function shutdown(reason) {
|