@alook/daemon 0.1.19 → 0.1.21
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/cli/index.js +172 -13
- package/dist/index.js +2301 -72
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -17679,7 +17679,7 @@ var AuditLogWakeTriggerPayloadSchema = exports_external.object({
|
|
|
17679
17679
|
reason: exports_external.enum(["unread", "mention"])
|
|
17680
17680
|
});
|
|
17681
17681
|
var AuditLogSessionResetPayloadSchema = exports_external.object({
|
|
17682
|
-
trigger: exports_external.enum(["single", "reset_all"])
|
|
17682
|
+
trigger: exports_external.enum(["single", "reset_all", "idle_timeout"])
|
|
17683
17683
|
});
|
|
17684
17684
|
var AuditLogNapPayloadSchema = exports_external.object({
|
|
17685
17685
|
trigger: exports_external.literal("nap")
|
|
@@ -17722,10 +17722,33 @@ var BotAuditEventKindSchema = exports_external.enum([
|
|
|
17722
17722
|
]);
|
|
17723
17723
|
var HostBotAuditEventFrameSchema = exports_external.object({
|
|
17724
17724
|
type: exports_external.literal("bot_audit_event"),
|
|
17725
|
+
eventId: exports_external.string().min(1).max(128).optional(),
|
|
17726
|
+
occurredAt: exports_external.string().datetime({ offset: true }).optional(),
|
|
17725
17727
|
agentId: exports_external.string().min(1),
|
|
17726
17728
|
sessionId: exports_external.string().nullable().optional(),
|
|
17727
17729
|
launchId: exports_external.string().nullable().optional(),
|
|
17728
17730
|
event: BotAuditEventSchema
|
|
17731
|
+
}).superRefine((frame, ctx) => {
|
|
17732
|
+
if (frame.event.kind === "session_reset" && frame.event.payload.trigger === "idle_timeout" && (!frame.eventId || !frame.occurredAt)) {
|
|
17733
|
+
if (!frame.eventId) {
|
|
17734
|
+
ctx.addIssue({
|
|
17735
|
+
code: "custom",
|
|
17736
|
+
path: ["eventId"],
|
|
17737
|
+
message: "eventId is required for idle_timeout session_reset"
|
|
17738
|
+
});
|
|
17739
|
+
}
|
|
17740
|
+
if (!frame.occurredAt) {
|
|
17741
|
+
ctx.addIssue({
|
|
17742
|
+
code: "custom",
|
|
17743
|
+
path: ["occurredAt"],
|
|
17744
|
+
message: "occurredAt is required for idle_timeout session_reset"
|
|
17745
|
+
});
|
|
17746
|
+
}
|
|
17747
|
+
}
|
|
17748
|
+
});
|
|
17749
|
+
var BotAuditEventAckFrameSchema = exports_external.strictObject({
|
|
17750
|
+
type: exports_external.literal("bot_audit_event_ack"),
|
|
17751
|
+
eventId: exports_external.string().min(1).max(128)
|
|
17729
17752
|
});
|
|
17730
17753
|
// ../shared/src/db/community-schema.ts
|
|
17731
17754
|
var exports_community_schema = {};
|
|
@@ -25708,6 +25731,7 @@ var DEFAULT_PING_INTERVAL_MS = 15000;
|
|
|
25708
25731
|
var DEFAULT_PONG_TIMEOUT_MS = 30000;
|
|
25709
25732
|
var DEFAULT_RECONNECT_BASE_MS = 500;
|
|
25710
25733
|
var DEFAULT_RECONNECT_MAX_MS = 30000;
|
|
25734
|
+
var DEFAULT_AUDIT_ACK_RETRY_MS = 5000;
|
|
25711
25735
|
function describeErr(err) {
|
|
25712
25736
|
return err instanceof Error ? err.message : String(err);
|
|
25713
25737
|
}
|
|
@@ -25723,8 +25747,10 @@ class WsControlChannel {
|
|
|
25723
25747
|
closedByUser = false;
|
|
25724
25748
|
authRejected = false;
|
|
25725
25749
|
pingTimer = null;
|
|
25750
|
+
auditRetryTimer = null;
|
|
25726
25751
|
pongDeadline = 0;
|
|
25727
25752
|
resyncProvider = null;
|
|
25753
|
+
pendingBotAuditEvents = new Map;
|
|
25728
25754
|
log;
|
|
25729
25755
|
wakeCoordinator = new WakeCoordinator;
|
|
25730
25756
|
constructor(opts) {
|
|
@@ -25742,6 +25768,7 @@ class WsControlChannel {
|
|
|
25742
25768
|
close() {
|
|
25743
25769
|
this.closedByUser = true;
|
|
25744
25770
|
this.clearHeartbeat();
|
|
25771
|
+
this.clearAuditRetry();
|
|
25745
25772
|
this.ws?.close();
|
|
25746
25773
|
this.ws = null;
|
|
25747
25774
|
this.statusValue = "closed";
|
|
@@ -25799,8 +25826,27 @@ class WsControlChannel {
|
|
|
25799
25826
|
this.sendFrame({ type: "agent_typing_stop", ...info });
|
|
25800
25827
|
}
|
|
25801
25828
|
async reportBotAuditEvent(frame) {
|
|
25829
|
+
if (frame.event.kind === "session_reset" && frame.event.payload.trigger === "idle_timeout") {
|
|
25830
|
+
if (!frame.eventId || !frame.occurredAt) {
|
|
25831
|
+
this.log.error("durable idle-reset audit missing local receipt", {
|
|
25832
|
+
agentId: frame.agentId
|
|
25833
|
+
});
|
|
25834
|
+
return;
|
|
25835
|
+
}
|
|
25836
|
+
this.pendingBotAuditEvents.set(frame.eventId, frame);
|
|
25837
|
+
this.sendFrame(frame);
|
|
25838
|
+
this.scheduleAuditRetry();
|
|
25839
|
+
return;
|
|
25840
|
+
}
|
|
25802
25841
|
this.sendFrame(frame);
|
|
25803
25842
|
}
|
|
25843
|
+
restorePendingBotAuditEvent(frame) {
|
|
25844
|
+
if (!frame.eventId || !frame.occurredAt)
|
|
25845
|
+
return;
|
|
25846
|
+
this.pendingBotAuditEvents.set(frame.eventId, frame);
|
|
25847
|
+
this.sendFrame(frame);
|
|
25848
|
+
this.scheduleAuditRetry();
|
|
25849
|
+
}
|
|
25804
25850
|
async reportWakeAck(info) {
|
|
25805
25851
|
this.wakeCoordinator.recordDeliveryAck(info.agentId, info.launchId, info.status);
|
|
25806
25852
|
this.sendFrame({ type: "agent_wake_ack", ...info });
|
|
@@ -25827,10 +25873,14 @@ class WsControlChannel {
|
|
|
25827
25873
|
const liveActivities = activities ?? [];
|
|
25828
25874
|
for (const a of liveActivities)
|
|
25829
25875
|
this.sendFrame({ type: "agent_activity", ...a });
|
|
25876
|
+
for (const frame of this.pendingBotAuditEvents.values())
|
|
25877
|
+
this.sendFrame(frame);
|
|
25878
|
+
this.scheduleAuditRetry();
|
|
25830
25879
|
this.log.info("resync sent", {
|
|
25831
25880
|
ready: ready.runtimeReport.length,
|
|
25832
25881
|
sessions: sessions.length,
|
|
25833
|
-
activities: liveActivities.length
|
|
25882
|
+
activities: liveActivities.length,
|
|
25883
|
+
pendingAuditEvents: this.pendingBotAuditEvents.size
|
|
25834
25884
|
});
|
|
25835
25885
|
}
|
|
25836
25886
|
for (const hook of this.resyncHooks) {
|
|
@@ -25873,6 +25923,34 @@ class WsControlChannel {
|
|
|
25873
25923
|
this.opts.onAuthRejected?.();
|
|
25874
25924
|
return;
|
|
25875
25925
|
}
|
|
25926
|
+
const auditAck = BotAuditEventAckFrameSchema.safeParse(frame);
|
|
25927
|
+
if (auditAck.success) {
|
|
25928
|
+
this.attempt = 0;
|
|
25929
|
+
const pending = this.pendingBotAuditEvents.get(auditAck.data.eventId);
|
|
25930
|
+
if (!pending)
|
|
25931
|
+
return;
|
|
25932
|
+
let durableCleared = this.opts.onBotAuditEventAck === undefined;
|
|
25933
|
+
try {
|
|
25934
|
+
durableCleared = this.opts.onBotAuditEventAck?.({
|
|
25935
|
+
agentId: pending.agentId,
|
|
25936
|
+
eventId: auditAck.data.eventId
|
|
25937
|
+
}) ?? true;
|
|
25938
|
+
} catch (err) {
|
|
25939
|
+
this.log.warn("bot audit ack local clear threw", {
|
|
25940
|
+
eventId: auditAck.data.eventId,
|
|
25941
|
+
err: describeErr(err)
|
|
25942
|
+
});
|
|
25943
|
+
}
|
|
25944
|
+
if (durableCleared)
|
|
25945
|
+
this.pendingBotAuditEvents.delete(auditAck.data.eventId);
|
|
25946
|
+
else
|
|
25947
|
+
this.log.warn("bot audit ack local clear deferred", { eventId: auditAck.data.eventId });
|
|
25948
|
+
if (this.pendingBotAuditEvents.size === 0)
|
|
25949
|
+
this.clearAuditRetry();
|
|
25950
|
+
else
|
|
25951
|
+
this.scheduleAuditRetry();
|
|
25952
|
+
return;
|
|
25953
|
+
}
|
|
25876
25954
|
this.attempt = 0;
|
|
25877
25955
|
this.ingestCommand(frame).catch((err) => {
|
|
25878
25956
|
this.log.warn("command ingress failed", { type: frame.type, err: describeErr(err) });
|
|
@@ -25947,6 +26025,7 @@ class WsControlChannel {
|
|
|
25947
26025
|
onSocketClosed(code, reason) {
|
|
25948
26026
|
this.log.warn("control channel closed", { code, reason: reason ? String(reason) : "" });
|
|
25949
26027
|
this.clearHeartbeat();
|
|
26028
|
+
this.clearAuditRetry();
|
|
25950
26029
|
this.ws = null;
|
|
25951
26030
|
if (this.closedByUser)
|
|
25952
26031
|
return;
|
|
@@ -25994,6 +26073,26 @@ class WsControlChannel {
|
|
|
25994
26073
|
this.pingTimer = null;
|
|
25995
26074
|
}
|
|
25996
26075
|
}
|
|
26076
|
+
scheduleAuditRetry() {
|
|
26077
|
+
if (this.auditRetryTimer || this.pendingBotAuditEvents.size === 0)
|
|
26078
|
+
return;
|
|
26079
|
+
const delayMs = this.opts.auditAckRetryMs ?? DEFAULT_AUDIT_ACK_RETRY_MS;
|
|
26080
|
+
this.auditRetryTimer = setTimeout(() => {
|
|
26081
|
+
this.auditRetryTimer = null;
|
|
26082
|
+
if (this.statusValue === "open") {
|
|
26083
|
+
for (const frame of this.pendingBotAuditEvents.values())
|
|
26084
|
+
this.sendFrame(frame);
|
|
26085
|
+
}
|
|
26086
|
+
this.scheduleAuditRetry();
|
|
26087
|
+
}, delayMs);
|
|
26088
|
+
this.auditRetryTimer.unref?.();
|
|
26089
|
+
}
|
|
26090
|
+
clearAuditRetry() {
|
|
26091
|
+
if (!this.auditRetryTimer)
|
|
26092
|
+
return;
|
|
26093
|
+
clearTimeout(this.auditRetryTimer);
|
|
26094
|
+
this.auditRetryTimer = null;
|
|
26095
|
+
}
|
|
25997
26096
|
now() {
|
|
25998
26097
|
return this.opts.now ? this.opts.now() : Date.now();
|
|
25999
26098
|
}
|
|
@@ -27697,14 +27796,14 @@ class AgentProcessManager {
|
|
|
27697
27796
|
const effects = this.dispatch({ type: "wake", agentId, message: normalized, nowMs: this.now() });
|
|
27698
27797
|
return effects.length > 0;
|
|
27699
27798
|
}
|
|
27700
|
-
forgetSession(agentId, barrierType = "reset_session", forgottenSessionId) {
|
|
27701
|
-
if (!this.forgetSessionSources(agentId, barrierType, forgottenSessionId))
|
|
27799
|
+
forgetSession(agentId, barrierType = "reset_session", forgottenSessionId, pendingIdleResetEvent) {
|
|
27800
|
+
if (!this.forgetSessionSources(agentId, barrierType, forgottenSessionId, pendingIdleResetEvent))
|
|
27702
27801
|
return false;
|
|
27703
27802
|
this.dispatch({ type: "reset_session", agentId });
|
|
27704
27803
|
return true;
|
|
27705
27804
|
}
|
|
27706
|
-
forgetSessionSources(agentId, barrierType, forgottenSessionId) {
|
|
27707
|
-
const persisted = this.opts.timeline?.forgetSession(agentId, barrierType, forgottenSessionId);
|
|
27805
|
+
forgetSessionSources(agentId, barrierType, forgottenSessionId, pendingIdleResetEvent) {
|
|
27806
|
+
const persisted = pendingIdleResetEvent ? this.opts.timeline?.forgetSession(agentId, barrierType, forgottenSessionId, pendingIdleResetEvent) : this.opts.timeline?.forgetSession(agentId, barrierType, forgottenSessionId);
|
|
27708
27807
|
if (persisted === false)
|
|
27709
27808
|
return false;
|
|
27710
27809
|
this.resumeSessions.delete(agentId);
|
|
@@ -28283,7 +28382,11 @@ ${this.opts.wakePromptFooter}` : text2;
|
|
|
28283
28382
|
break;
|
|
28284
28383
|
case "reset_idle_session": {
|
|
28285
28384
|
const spawnState = this.activeSpawnState.get(effect.agentId);
|
|
28286
|
-
const
|
|
28385
|
+
const completion = {
|
|
28386
|
+
eventId: `bae_${randomUUID5()}`,
|
|
28387
|
+
occurredAt: new Date(this.now()).toISOString()
|
|
28388
|
+
};
|
|
28389
|
+
const persisted = this.forgetSession(effect.agentId, "reset_session", effect.sessionId, completion);
|
|
28287
28390
|
if (!persisted) {
|
|
28288
28391
|
this.log.error("idle session reset barrier was not persisted; reset deferred", {
|
|
28289
28392
|
agentId: effect.agentId,
|
|
@@ -28295,6 +28398,23 @@ ${this.opts.wakePromptFooter}` : text2;
|
|
|
28295
28398
|
if (spawnState)
|
|
28296
28399
|
spawnState.discardEvents = true;
|
|
28297
28400
|
this.dispatch({ type: "idle_reset_committed", agentId: effect.agentId, nowMs: this.now() });
|
|
28401
|
+
if (this.opts.onBotAuditEvent) {
|
|
28402
|
+
try {
|
|
28403
|
+
this.opts.onBotAuditEvent(effect.agentId, {
|
|
28404
|
+
kind: "session_reset",
|
|
28405
|
+
payload: { trigger: "idle_timeout" }
|
|
28406
|
+
}, {
|
|
28407
|
+
sessionId: null,
|
|
28408
|
+
launchId: null,
|
|
28409
|
+
...completion
|
|
28410
|
+
});
|
|
28411
|
+
} catch (err) {
|
|
28412
|
+
this.log.debug("audit emit failed (idle session reset)", {
|
|
28413
|
+
agentId: effect.agentId,
|
|
28414
|
+
err: String(err)
|
|
28415
|
+
});
|
|
28416
|
+
}
|
|
28417
|
+
}
|
|
28298
28418
|
this.log.info("idle agent session reset", {
|
|
28299
28419
|
agentId: effect.agentId,
|
|
28300
28420
|
sessionId: effect.sessionId
|
|
@@ -29317,11 +29437,13 @@ var TIMELINE_READ_CHUNK_BYTES = 65536;
|
|
|
29317
29437
|
var DATE_FILENAME_PATTERN = /^\d{4}-\d{2}-\d{2}\.jsonl$/;
|
|
29318
29438
|
var RESUME_CONTROL_FILENAME = ".resume-control.json";
|
|
29319
29439
|
var RESUME_CONTROL_MAX_BYTES = 4096;
|
|
29440
|
+
var MAX_PENDING_IDLE_RESET_EVENTS = 32;
|
|
29320
29441
|
var EMPTY_RESUME_CONTROL = {
|
|
29321
29442
|
version: 1,
|
|
29322
29443
|
attemptedSessionId: null,
|
|
29323
29444
|
fencedSessionId: null,
|
|
29324
|
-
fullBarrier: null
|
|
29445
|
+
fullBarrier: null,
|
|
29446
|
+
pendingIdleResetEvents: []
|
|
29325
29447
|
};
|
|
29326
29448
|
function isBarrier(entry) {
|
|
29327
29449
|
return entry.system !== undefined;
|
|
@@ -29711,7 +29833,8 @@ function readResumeControlState(timelineDir) {
|
|
|
29711
29833
|
const raw = bounded.subarray(0, bytesRead).toString("utf8");
|
|
29712
29834
|
const value = JSON.parse(raw);
|
|
29713
29835
|
const validSessionId = (candidate) => candidate === null || typeof candidate === "string" && candidate.length > 0 && candidate.length <= 512;
|
|
29714
|
-
|
|
29836
|
+
const pendingIdleResetEvents = value.pendingIdleResetEvents === undefined ? [] : value.pendingIdleResetEvents;
|
|
29837
|
+
if (value.version !== 1 || !validSessionId(value.attemptedSessionId) || !validSessionId(value.fencedSessionId) || !Array.isArray(pendingIdleResetEvents) || pendingIdleResetEvents.length > MAX_PENDING_IDLE_RESET_EVENTS || pendingIdleResetEvents.some((event) => !event || typeof event !== "object" || typeof event.eventId !== "string" || event.eventId.length < 1 || event.eventId.length > 128 || typeof event.occurredAt !== "string" || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(event.occurredAt) || !Number.isFinite(Date.parse(event.occurredAt))) || new Set(pendingIdleResetEvents.map((event) => event.eventId)).size !== pendingIdleResetEvents.length || value.fullBarrier !== null && value.fullBarrier !== "reset_session" && value.fullBarrier !== "nap")
|
|
29715
29838
|
return { kind: "invalid" };
|
|
29716
29839
|
return {
|
|
29717
29840
|
kind: "state",
|
|
@@ -29719,7 +29842,8 @@ function readResumeControlState(timelineDir) {
|
|
|
29719
29842
|
version: 1,
|
|
29720
29843
|
attemptedSessionId: value.attemptedSessionId,
|
|
29721
29844
|
fencedSessionId: value.fencedSessionId,
|
|
29722
|
-
fullBarrier: value.fullBarrier
|
|
29845
|
+
fullBarrier: value.fullBarrier,
|
|
29846
|
+
pendingIdleResetEvents
|
|
29723
29847
|
}
|
|
29724
29848
|
};
|
|
29725
29849
|
} catch {
|
|
@@ -29742,11 +29866,14 @@ function updateResumeControlState(timelineDir, update) {
|
|
|
29742
29866
|
const current = readResumeControlState(timelineDir);
|
|
29743
29867
|
const base = current.kind === "state" ? current.state : EMPTY_RESUME_CONTROL;
|
|
29744
29868
|
const next = update({ ...base });
|
|
29869
|
+
if (!Array.isArray(next.pendingIdleResetEvents) || next.pendingIdleResetEvents.length > MAX_PENDING_IDLE_RESET_EVENTS || next.pendingIdleResetEvents.some((event) => !event || typeof event !== "object" || typeof event.eventId !== "string" || event.eventId.length < 1 || event.eventId.length > 128 || typeof event.occurredAt !== "string" || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(event.occurredAt) || !Number.isFinite(Date.parse(event.occurredAt))) || new Set(next.pendingIdleResetEvents.map((event) => event.eventId)).size !== next.pendingIdleResetEvents.length)
|
|
29870
|
+
return false;
|
|
29745
29871
|
const canonical = {
|
|
29746
29872
|
version: 1,
|
|
29747
29873
|
attemptedSessionId: next.attemptedSessionId,
|
|
29748
29874
|
fencedSessionId: next.fencedSessionId,
|
|
29749
|
-
fullBarrier: next.fullBarrier
|
|
29875
|
+
fullBarrier: next.fullBarrier,
|
|
29876
|
+
pendingIdleResetEvents: next.pendingIdleResetEvents
|
|
29750
29877
|
};
|
|
29751
29878
|
const body = JSON.stringify(canonical) + `
|
|
29752
29879
|
`;
|
|
@@ -30410,7 +30537,7 @@ function createTimelineRecorder(opts) {
|
|
|
30410
30537
|
clearSessionStall(agentId, sessionId) {
|
|
30411
30538
|
return appendStallMarker(agentId, "stall_recovery_clear", sessionId);
|
|
30412
30539
|
},
|
|
30413
|
-
forgetSession(agentId, barrierType = "reset_session", forgottenSessionId) {
|
|
30540
|
+
forgetSession(agentId, barrierType = "reset_session", forgottenSessionId, pendingIdleResetEvent) {
|
|
30414
30541
|
retryPending(agentId);
|
|
30415
30542
|
const dir = dirFor(agentId);
|
|
30416
30543
|
if (!prepareTimelineDirectory(dir))
|
|
@@ -30422,7 +30549,8 @@ function createTimelineRecorder(opts) {
|
|
|
30422
30549
|
...state,
|
|
30423
30550
|
attemptedSessionId: null,
|
|
30424
30551
|
fencedSessionId: null,
|
|
30425
|
-
fullBarrier: barrierType
|
|
30552
|
+
fullBarrier: barrierType,
|
|
30553
|
+
pendingIdleResetEvents: pendingIdleResetEvent && !state.pendingIdleResetEvents.some(({ eventId }) => eventId === pendingIdleResetEvent.eventId) ? [...state.pendingIdleResetEvents, pendingIdleResetEvent] : state.pendingIdleResetEvents
|
|
30426
30554
|
}));
|
|
30427
30555
|
} else if (barrierType === "stall_recovery") {
|
|
30428
30556
|
persisted = updateResumeControlState(dir, (state) => ({
|
|
@@ -30453,6 +30581,19 @@ function createTimelineRecorder(opts) {
|
|
|
30453
30581
|
const result = appendTrackedEntry(dir, createSystemEntry(barrierType, stamp.toISOString(), forgottenSessionId), stamp);
|
|
30454
30582
|
handleTrackedResult(agentId, null, result);
|
|
30455
30583
|
return true;
|
|
30584
|
+
},
|
|
30585
|
+
pendingIdleResetEvents(agentId) {
|
|
30586
|
+
const state = readResumeControlState(dirFor(agentId));
|
|
30587
|
+
return state.kind === "state" ? state.state.pendingIdleResetEvents.map((event) => ({ ...event })) : [];
|
|
30588
|
+
},
|
|
30589
|
+
acknowledgeIdleResetEvent(agentId, eventId) {
|
|
30590
|
+
const dir = dirFor(agentId);
|
|
30591
|
+
if (!prepareTimelineDirectory(dir))
|
|
30592
|
+
return false;
|
|
30593
|
+
return updateResumeControlState(dir, (state) => ({
|
|
30594
|
+
...state,
|
|
30595
|
+
pendingIdleResetEvents: state.pendingIdleResetEvents.filter((event) => event.eventId !== eventId)
|
|
30596
|
+
}));
|
|
30456
30597
|
}
|
|
30457
30598
|
};
|
|
30458
30599
|
function appendStallMarker(agentId, type, sessionId) {
|
|
@@ -31007,6 +31148,8 @@ async function createDaemon(opts) {
|
|
|
31007
31148
|
const emitBotAuditEvent = (agentId, event, context) => {
|
|
31008
31149
|
channelRef?.reportBotAuditEvent?.({
|
|
31009
31150
|
type: "bot_audit_event",
|
|
31151
|
+
...context?.eventId ? { eventId: context.eventId } : {},
|
|
31152
|
+
...context?.occurredAt ? { occurredAt: context.occurredAt } : {},
|
|
31010
31153
|
agentId,
|
|
31011
31154
|
sessionId: context?.sessionId ?? null,
|
|
31012
31155
|
launchId: context?.launchId ?? null,
|
|
@@ -31106,6 +31249,7 @@ async function createDaemon(opts) {
|
|
|
31106
31249
|
ownerName: b.ownerName,
|
|
31107
31250
|
ownerDiscriminator: b.ownerDiscriminator
|
|
31108
31251
|
});
|
|
31252
|
+
restorePendingIdleResetEvents(b.id);
|
|
31109
31253
|
}
|
|
31110
31254
|
botCacheReady = true;
|
|
31111
31255
|
}
|
|
@@ -31200,9 +31344,23 @@ async function createDaemon(opts) {
|
|
|
31200
31344
|
headers: { Authorization: `Bearer ${opts.machineKey}` },
|
|
31201
31345
|
webSocketFactory: opts.webSocketFactory,
|
|
31202
31346
|
onAuthRejected: opts.onAuthRejected,
|
|
31347
|
+
onBotAuditEventAck: ({ agentId, eventId }) => timeline2.acknowledgeIdleResetEvent(agentId, eventId),
|
|
31203
31348
|
logger: log2.child("ws")
|
|
31204
31349
|
});
|
|
31205
31350
|
channelRef = channel2;
|
|
31351
|
+
function restorePendingIdleResetEvents(agentId) {
|
|
31352
|
+
for (const pending of timeline2.pendingIdleResetEvents(agentId)) {
|
|
31353
|
+
channel2.restorePendingBotAuditEvent({
|
|
31354
|
+
type: "bot_audit_event",
|
|
31355
|
+
eventId: pending.eventId,
|
|
31356
|
+
occurredAt: pending.occurredAt,
|
|
31357
|
+
agentId,
|
|
31358
|
+
sessionId: null,
|
|
31359
|
+
launchId: null,
|
|
31360
|
+
event: { kind: "session_reset", payload: { trigger: "idle_timeout" } }
|
|
31361
|
+
});
|
|
31362
|
+
}
|
|
31363
|
+
}
|
|
31206
31364
|
function handleBotFrame(cmd) {
|
|
31207
31365
|
switch (cmd.type) {
|
|
31208
31366
|
case "bot:added":
|
|
@@ -31213,6 +31371,7 @@ async function createDaemon(opts) {
|
|
|
31213
31371
|
ownerName: cmd.ownerName,
|
|
31214
31372
|
ownerDiscriminator: cmd.ownerDiscriminator
|
|
31215
31373
|
});
|
|
31374
|
+
restorePendingIdleResetEvents(cmd.botId);
|
|
31216
31375
|
log2.debug("bot:added", { botId: cmd.botId, name: cmd.name });
|
|
31217
31376
|
break;
|
|
31218
31377
|
case "bot:updated": {
|