@autohq/cli 0.1.342 → 0.1.344
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/agent-bridge.js +116 -2
- package/dist/index.js +117 -3
- package/package.json +1 -1
package/dist/agent-bridge.js
CHANGED
|
@@ -19833,12 +19833,24 @@ var RuntimeBridgeOutputUiMessageCompletedEnvelopeSchema = external_exports.objec
|
|
|
19833
19833
|
createdAt: external_exports.string().datetime(),
|
|
19834
19834
|
completedAt: external_exports.string().datetime().nullable()
|
|
19835
19835
|
});
|
|
19836
|
+
var RuntimeBridgeOutputLivenessEnvelopeSchema = external_exports.object({
|
|
19837
|
+
type: external_exports.literal("runtime.liveness"),
|
|
19838
|
+
sessionId: SessionIdSchema,
|
|
19839
|
+
runtimeId: RuntimeIdSchema,
|
|
19840
|
+
bridgeLeaseId: RuntimeBridgeLeaseIdSchema,
|
|
19841
|
+
outputSeq: external_exports.number().int().positive(),
|
|
19842
|
+
// The emitter's beat cadence, so watchdog thresholds stay interpretable
|
|
19843
|
+
// against the runtime that produced them.
|
|
19844
|
+
intervalMs: external_exports.number().int().positive(),
|
|
19845
|
+
createdAt: external_exports.string().datetime()
|
|
19846
|
+
});
|
|
19836
19847
|
var RuntimeBridgeOutputEnvelopeSchema = external_exports.union([
|
|
19837
19848
|
RuntimeBridgeOutputEntryEnvelopeSchema,
|
|
19838
19849
|
RuntimeBridgeOutputDeltaEnvelopeSchema,
|
|
19839
19850
|
RuntimeBridgeOutputUiMessageChunkEnvelopeSchema,
|
|
19840
19851
|
RuntimeBridgeOutputUiMessagePartEnvelopeSchema,
|
|
19841
|
-
RuntimeBridgeOutputUiMessageCompletedEnvelopeSchema
|
|
19852
|
+
RuntimeBridgeOutputUiMessageCompletedEnvelopeSchema,
|
|
19853
|
+
RuntimeBridgeOutputLivenessEnvelopeSchema
|
|
19842
19854
|
]);
|
|
19843
19855
|
function isLiveOnlyRuntimeOutputEnvelope(envelope) {
|
|
19844
19856
|
return envelope.type === "ui.message.chunk" || envelope.type === "conversation.delta";
|
|
@@ -23480,7 +23492,7 @@ Object.assign(lookup, {
|
|
|
23480
23492
|
// package.json
|
|
23481
23493
|
var package_default = {
|
|
23482
23494
|
name: "@autohq/cli",
|
|
23483
|
-
version: "0.1.
|
|
23495
|
+
version: "0.1.344",
|
|
23484
23496
|
license: "SEE LICENSE IN README.md",
|
|
23485
23497
|
publishConfig: {
|
|
23486
23498
|
access: "public"
|
|
@@ -27224,6 +27236,15 @@ var ChatEventRequesterPayloadSchema = external_exports.object({
|
|
|
27224
27236
|
})
|
|
27225
27237
|
})
|
|
27226
27238
|
});
|
|
27239
|
+
var LinearEventRequesterPayloadSchema = external_exports.object({
|
|
27240
|
+
linear: external_exports.object({
|
|
27241
|
+
actor: external_exports.object({
|
|
27242
|
+
id: external_exports.string().trim().min(1),
|
|
27243
|
+
type: external_exports.string().trim().min(1),
|
|
27244
|
+
name: external_exports.string().optional()
|
|
27245
|
+
}).optional()
|
|
27246
|
+
})
|
|
27247
|
+
});
|
|
27227
27248
|
|
|
27228
27249
|
// ../../packages/schemas/src/pool-replace.ts
|
|
27229
27250
|
var POOL_REPLACE_REASONS = ["refresh", "failure"];
|
|
@@ -28506,6 +28527,10 @@ var SessionTurnRecordSchema = external_exports.object({
|
|
|
28506
28527
|
acceptedAt: external_exports.string().datetime().nullable(),
|
|
28507
28528
|
startedAt: external_exports.string().datetime().nullable(),
|
|
28508
28529
|
lastProgressAt: external_exports.string().datetime().nullable(),
|
|
28530
|
+
// Last runtime liveness beat that vouched for this open turn (null before
|
|
28531
|
+
// the first beat, and always null on runtimes that predate liveness).
|
|
28532
|
+
// Distinct from lastProgressAt: pipeline liveness, not durable progress.
|
|
28533
|
+
livenessAt: external_exports.string().datetime().nullable().default(null),
|
|
28509
28534
|
completedAt: external_exports.string().datetime().nullable(),
|
|
28510
28535
|
failedAt: external_exports.string().datetime().nullable(),
|
|
28511
28536
|
staleAt: external_exports.string().datetime().nullable(),
|
|
@@ -35863,6 +35888,23 @@ var ProjectUsageResponseSchema = external_exports.object({
|
|
|
35863
35888
|
daily: external_exports.array(ProjectUsageDayPointSchema)
|
|
35864
35889
|
});
|
|
35865
35890
|
|
|
35891
|
+
// src/commands/agent-bridge/harness/liveness-ticker.ts
|
|
35892
|
+
var RUNTIME_LIVENESS_INTERVAL_MS = 2e4;
|
|
35893
|
+
function startRuntimeLivenessTicker(input) {
|
|
35894
|
+
const intervalMs = input.intervalMs ?? RUNTIME_LIVENESS_INTERVAL_MS;
|
|
35895
|
+
const timer = setInterval(() => {
|
|
35896
|
+
void input.emitBeat().catch((error51) => {
|
|
35897
|
+
input.writeOutput?.(
|
|
35898
|
+
`agent_bridge_liveness_beat_failed error=${error51 instanceof Error ? error51.message : String(error51)}`
|
|
35899
|
+
);
|
|
35900
|
+
});
|
|
35901
|
+
}, intervalMs);
|
|
35902
|
+
timer.unref?.();
|
|
35903
|
+
return {
|
|
35904
|
+
stop: () => clearInterval(timer)
|
|
35905
|
+
};
|
|
35906
|
+
}
|
|
35907
|
+
|
|
35866
35908
|
// src/commands/agent-bridge/harness/output-buffer.ts
|
|
35867
35909
|
import { setTimeout as sleep } from "timers/promises";
|
|
35868
35910
|
|
|
@@ -44514,6 +44556,9 @@ var AgentBridgeOutputBuffer = class {
|
|
|
44514
44556
|
uiMessagePartTracker = new UiMessagePartTracker();
|
|
44515
44557
|
drainBlocked = false;
|
|
44516
44558
|
drainPromise = null;
|
|
44559
|
+
// Sequence of the most recent liveness beat, for the skip-while-pending
|
|
44560
|
+
// gate in emitLivenessBeat.
|
|
44561
|
+
pendingLivenessSeq = null;
|
|
44517
44562
|
// Ack-retry-ladder exhausts per pending output sequence, for the poison
|
|
44518
44563
|
// quarantine; entries clear when the sequence finally acks.
|
|
44519
44564
|
ackExhaustsBySeq = /* @__PURE__ */ new Map();
|
|
@@ -44544,6 +44589,29 @@ var AgentBridgeOutputBuffer = class {
|
|
|
44544
44589
|
await this.flushPendingDelta({ force: true });
|
|
44545
44590
|
await this.drainPendingOutputs({ force: true });
|
|
44546
44591
|
}
|
|
44592
|
+
// Emits one runtime liveness beat through the same ordered, acked drain as
|
|
44593
|
+
// content envelopes — deliberately, so a beat landing at the bridge proves
|
|
44594
|
+
// the pipeline is healthy end to end. While a previous beat is still
|
|
44595
|
+
// pending (stalled drain, retry ladder, reconnect) new beats are skipped
|
|
44596
|
+
// rather than queued: an unhealthy pipeline must show up as beats
|
|
44597
|
+
// *stopping*, and a backlog of parked beats replaying after recovery would
|
|
44598
|
+
// stamp liveness for exactly the window the runtime was mute.
|
|
44599
|
+
async emitLivenessBeat(context, intervalMs) {
|
|
44600
|
+
if (this.pendingLivenessSeq !== null && this.pendingOutputs.has(this.pendingLivenessSeq)) {
|
|
44601
|
+
return;
|
|
44602
|
+
}
|
|
44603
|
+
this.outputSeq += 1;
|
|
44604
|
+
this.pendingLivenessSeq = this.outputSeq;
|
|
44605
|
+
this.enqueueOutput(
|
|
44606
|
+
buildLivenessOutputEnvelope({
|
|
44607
|
+
context,
|
|
44608
|
+
outputSeq: this.outputSeq,
|
|
44609
|
+
intervalMs,
|
|
44610
|
+
createdAt: now2()
|
|
44611
|
+
})
|
|
44612
|
+
);
|
|
44613
|
+
await this.drainPendingOutputs();
|
|
44614
|
+
}
|
|
44547
44615
|
async emitUiMessageChunk(context, projection) {
|
|
44548
44616
|
await this.flushPendingDelta();
|
|
44549
44617
|
await this.emitLiveUiMessageChunk(context, projection.chunk);
|
|
@@ -45240,6 +45308,18 @@ function buildUiMessageChunkOutputEnvelope(input) {
|
|
|
45240
45308
|
createdAt: input.createdAt
|
|
45241
45309
|
});
|
|
45242
45310
|
}
|
|
45311
|
+
function buildLivenessOutputEnvelope(input) {
|
|
45312
|
+
const { context } = input;
|
|
45313
|
+
return RuntimeBridgeOutputEnvelopeSchema.parse({
|
|
45314
|
+
type: "runtime.liveness",
|
|
45315
|
+
sessionId: context.sessionId,
|
|
45316
|
+
runtimeId: context.runtimeId,
|
|
45317
|
+
bridgeLeaseId: context.bridgeLeaseId,
|
|
45318
|
+
outputSeq: input.outputSeq,
|
|
45319
|
+
intervalMs: input.intervalMs,
|
|
45320
|
+
createdAt: input.createdAt
|
|
45321
|
+
});
|
|
45322
|
+
}
|
|
45243
45323
|
function buildUiMessagePartOutputEnvelope(input) {
|
|
45244
45324
|
const { context, snapshot } = input;
|
|
45245
45325
|
return RuntimeBridgeOutputEnvelopeSchema.parse({
|
|
@@ -66496,11 +66576,16 @@ var ClaudeCodeCommandHandler = class {
|
|
|
66496
66576
|
pendingQuestions = /* @__PURE__ */ new Map();
|
|
66497
66577
|
outputBuffer;
|
|
66498
66578
|
projector = new ClaudeCodeProjector();
|
|
66579
|
+
livenessTicker = null;
|
|
66499
66580
|
// -----------------------------------------------------------------------------
|
|
66500
66581
|
// Lifecycle (public API)
|
|
66501
66582
|
// -----------------------------------------------------------------------------
|
|
66502
66583
|
setContext(nextContext) {
|
|
66503
66584
|
this.context = RuntimeBridgeConnectedPayloadSchema.parse(nextContext);
|
|
66585
|
+
this.livenessTicker ??= startRuntimeLivenessTicker({
|
|
66586
|
+
emitBeat: () => this.emitLivenessBeat(),
|
|
66587
|
+
writeOutput: this.input.writeOutput
|
|
66588
|
+
});
|
|
66504
66589
|
}
|
|
66505
66590
|
async replayPendingOutputs() {
|
|
66506
66591
|
await this.outputBuffer.replayPendingOutputs();
|
|
@@ -66509,6 +66594,8 @@ var ClaudeCodeCommandHandler = class {
|
|
|
66509
66594
|
await this.ensureAgentSession().prepare();
|
|
66510
66595
|
}
|
|
66511
66596
|
shutdown() {
|
|
66597
|
+
this.livenessTicker?.stop();
|
|
66598
|
+
this.livenessTicker = null;
|
|
66512
66599
|
this.agentSession?.close();
|
|
66513
66600
|
this.agentSession = null;
|
|
66514
66601
|
this.settlePendingQuestions("Runtime is shutting down");
|
|
@@ -66840,6 +66927,16 @@ var ClaudeCodeCommandHandler = class {
|
|
|
66840
66927
|
// -----------------------------------------------------------------------------
|
|
66841
66928
|
// SDK callbacks
|
|
66842
66929
|
// -----------------------------------------------------------------------------
|
|
66930
|
+
async emitLivenessBeat() {
|
|
66931
|
+
const activeContext = this.context;
|
|
66932
|
+
if (!activeContext) {
|
|
66933
|
+
return;
|
|
66934
|
+
}
|
|
66935
|
+
await this.outputBuffer.emitLivenessBeat(
|
|
66936
|
+
activeContext,
|
|
66937
|
+
RUNTIME_LIVENESS_INTERVAL_MS
|
|
66938
|
+
);
|
|
66939
|
+
}
|
|
66843
66940
|
async emitBridgeOutput(activeContext, projection) {
|
|
66844
66941
|
try {
|
|
66845
66942
|
await this.outputBuffer.emitProjection(activeContext, projection);
|
|
@@ -68301,12 +68398,17 @@ var CodexCommandHandler = class {
|
|
|
68301
68398
|
pendingApprovals = /* @__PURE__ */ new Map();
|
|
68302
68399
|
outputBuffer;
|
|
68303
68400
|
projector = new CodexProjector();
|
|
68401
|
+
livenessTicker = null;
|
|
68304
68402
|
skipResumeForNextSession = false;
|
|
68305
68403
|
// ---------------------------------------------------------------------------
|
|
68306
68404
|
// Lifecycle (public API)
|
|
68307
68405
|
// ---------------------------------------------------------------------------
|
|
68308
68406
|
setContext(nextContext) {
|
|
68309
68407
|
this.context = RuntimeBridgeConnectedPayloadSchema.parse(nextContext);
|
|
68408
|
+
this.livenessTicker ??= startRuntimeLivenessTicker({
|
|
68409
|
+
emitBeat: () => this.emitLivenessBeat(),
|
|
68410
|
+
writeOutput: this.input.writeOutput
|
|
68411
|
+
});
|
|
68310
68412
|
}
|
|
68311
68413
|
async replayPendingOutputs() {
|
|
68312
68414
|
await this.outputBuffer.replayPendingOutputs();
|
|
@@ -68315,6 +68417,8 @@ var CodexCommandHandler = class {
|
|
|
68315
68417
|
await this.ensureSession().prepare();
|
|
68316
68418
|
}
|
|
68317
68419
|
shutdown() {
|
|
68420
|
+
this.livenessTicker?.stop();
|
|
68421
|
+
this.livenessTicker = null;
|
|
68318
68422
|
this.session?.close();
|
|
68319
68423
|
this.session = null;
|
|
68320
68424
|
this.pendingApprovals.clear();
|
|
@@ -68482,6 +68586,16 @@ var CodexCommandHandler = class {
|
|
|
68482
68586
|
this.projector.projectSessionFailure(errorMessage3(error51))
|
|
68483
68587
|
);
|
|
68484
68588
|
}
|
|
68589
|
+
async emitLivenessBeat() {
|
|
68590
|
+
const activeContext = this.context;
|
|
68591
|
+
if (!activeContext) {
|
|
68592
|
+
return;
|
|
68593
|
+
}
|
|
68594
|
+
await this.outputBuffer.emitLivenessBeat(
|
|
68595
|
+
activeContext,
|
|
68596
|
+
RUNTIME_LIVENESS_INTERVAL_MS
|
|
68597
|
+
);
|
|
68598
|
+
}
|
|
68485
68599
|
async emit(activeContext, projection) {
|
|
68486
68600
|
try {
|
|
68487
68601
|
await this.outputBuffer.emitProjection(activeContext, projection);
|
package/dist/index.js
CHANGED
|
@@ -18757,7 +18757,7 @@ var init_environments = __esm({
|
|
|
18757
18757
|
});
|
|
18758
18758
|
|
|
18759
18759
|
// ../../packages/schemas/src/requester.ts
|
|
18760
|
-
var RequesterOriginSchema, REQUESTER_PROVENANCES, RequesterProvenanceSchema, RequesterSchema, ChatEventRequesterPayloadSchema;
|
|
18760
|
+
var RequesterOriginSchema, REQUESTER_PROVENANCES, RequesterProvenanceSchema, RequesterSchema, ChatEventRequesterPayloadSchema, LinearEventRequesterPayloadSchema;
|
|
18761
18761
|
var init_requester = __esm({
|
|
18762
18762
|
"../../packages/schemas/src/requester.ts"() {
|
|
18763
18763
|
"use strict";
|
|
@@ -18793,6 +18793,15 @@ var init_requester = __esm({
|
|
|
18793
18793
|
})
|
|
18794
18794
|
})
|
|
18795
18795
|
});
|
|
18796
|
+
LinearEventRequesterPayloadSchema = external_exports.object({
|
|
18797
|
+
linear: external_exports.object({
|
|
18798
|
+
actor: external_exports.object({
|
|
18799
|
+
id: external_exports.string().trim().min(1),
|
|
18800
|
+
type: external_exports.string().trim().min(1),
|
|
18801
|
+
name: external_exports.string().optional()
|
|
18802
|
+
}).optional()
|
|
18803
|
+
})
|
|
18804
|
+
});
|
|
18796
18805
|
}
|
|
18797
18806
|
});
|
|
18798
18807
|
|
|
@@ -20227,6 +20236,10 @@ var init_session_turns = __esm({
|
|
|
20227
20236
|
acceptedAt: external_exports.string().datetime().nullable(),
|
|
20228
20237
|
startedAt: external_exports.string().datetime().nullable(),
|
|
20229
20238
|
lastProgressAt: external_exports.string().datetime().nullable(),
|
|
20239
|
+
// Last runtime liveness beat that vouched for this open turn (null before
|
|
20240
|
+
// the first beat, and always null on runtimes that predate liveness).
|
|
20241
|
+
// Distinct from lastProgressAt: pipeline liveness, not durable progress.
|
|
20242
|
+
livenessAt: external_exports.string().datetime().nullable().default(null),
|
|
20230
20243
|
completedAt: external_exports.string().datetime().nullable(),
|
|
20231
20244
|
failedAt: external_exports.string().datetime().nullable(),
|
|
20232
20245
|
staleAt: external_exports.string().datetime().nullable(),
|
|
@@ -30499,7 +30512,7 @@ var init_package = __esm({
|
|
|
30499
30512
|
"package.json"() {
|
|
30500
30513
|
package_default = {
|
|
30501
30514
|
name: "@autohq/cli",
|
|
30502
|
-
version: "0.1.
|
|
30515
|
+
version: "0.1.344",
|
|
30503
30516
|
license: "SEE LICENSE IN README.md",
|
|
30504
30517
|
publishConfig: {
|
|
30505
30518
|
access: "public"
|
|
@@ -40758,12 +40771,24 @@ var RuntimeBridgeOutputUiMessageCompletedEnvelopeSchema = external_exports.objec
|
|
|
40758
40771
|
createdAt: external_exports.string().datetime(),
|
|
40759
40772
|
completedAt: external_exports.string().datetime().nullable()
|
|
40760
40773
|
});
|
|
40774
|
+
var RuntimeBridgeOutputLivenessEnvelopeSchema = external_exports.object({
|
|
40775
|
+
type: external_exports.literal("runtime.liveness"),
|
|
40776
|
+
sessionId: SessionIdSchema2,
|
|
40777
|
+
runtimeId: RuntimeIdSchema2,
|
|
40778
|
+
bridgeLeaseId: RuntimeBridgeLeaseIdSchema2,
|
|
40779
|
+
outputSeq: external_exports.number().int().positive(),
|
|
40780
|
+
// The emitter's beat cadence, so watchdog thresholds stay interpretable
|
|
40781
|
+
// against the runtime that produced them.
|
|
40782
|
+
intervalMs: external_exports.number().int().positive(),
|
|
40783
|
+
createdAt: external_exports.string().datetime()
|
|
40784
|
+
});
|
|
40761
40785
|
var RuntimeBridgeOutputEnvelopeSchema = external_exports.union([
|
|
40762
40786
|
RuntimeBridgeOutputEntryEnvelopeSchema,
|
|
40763
40787
|
RuntimeBridgeOutputDeltaEnvelopeSchema,
|
|
40764
40788
|
RuntimeBridgeOutputUiMessageChunkEnvelopeSchema,
|
|
40765
40789
|
RuntimeBridgeOutputUiMessagePartEnvelopeSchema,
|
|
40766
|
-
RuntimeBridgeOutputUiMessageCompletedEnvelopeSchema
|
|
40790
|
+
RuntimeBridgeOutputUiMessageCompletedEnvelopeSchema,
|
|
40791
|
+
RuntimeBridgeOutputLivenessEnvelopeSchema
|
|
40767
40792
|
]);
|
|
40768
40793
|
function isLiveOnlyRuntimeOutputEnvelope(envelope) {
|
|
40769
40794
|
return envelope.type === "ui.message.chunk" || envelope.type === "conversation.delta";
|
|
@@ -41278,6 +41303,23 @@ function jsonRecordString(value, key) {
|
|
|
41278
41303
|
// src/commands/agent-bridge/harness/claude-code/index.ts
|
|
41279
41304
|
init_src();
|
|
41280
41305
|
|
|
41306
|
+
// src/commands/agent-bridge/harness/liveness-ticker.ts
|
|
41307
|
+
var RUNTIME_LIVENESS_INTERVAL_MS = 2e4;
|
|
41308
|
+
function startRuntimeLivenessTicker(input) {
|
|
41309
|
+
const intervalMs = input.intervalMs ?? RUNTIME_LIVENESS_INTERVAL_MS;
|
|
41310
|
+
const timer = setInterval(() => {
|
|
41311
|
+
void input.emitBeat().catch((error51) => {
|
|
41312
|
+
input.writeOutput?.(
|
|
41313
|
+
`agent_bridge_liveness_beat_failed error=${error51 instanceof Error ? error51.message : String(error51)}`
|
|
41314
|
+
);
|
|
41315
|
+
});
|
|
41316
|
+
}, intervalMs);
|
|
41317
|
+
timer.unref?.();
|
|
41318
|
+
return {
|
|
41319
|
+
stop: () => clearInterval(timer)
|
|
41320
|
+
};
|
|
41321
|
+
}
|
|
41322
|
+
|
|
41281
41323
|
// src/commands/agent-bridge/harness/output-buffer.ts
|
|
41282
41324
|
import { setTimeout as sleep2 } from "timers/promises";
|
|
41283
41325
|
init_src();
|
|
@@ -41730,6 +41772,9 @@ var AgentBridgeOutputBuffer = class {
|
|
|
41730
41772
|
uiMessagePartTracker = new UiMessagePartTracker();
|
|
41731
41773
|
drainBlocked = false;
|
|
41732
41774
|
drainPromise = null;
|
|
41775
|
+
// Sequence of the most recent liveness beat, for the skip-while-pending
|
|
41776
|
+
// gate in emitLivenessBeat.
|
|
41777
|
+
pendingLivenessSeq = null;
|
|
41733
41778
|
// Ack-retry-ladder exhausts per pending output sequence, for the poison
|
|
41734
41779
|
// quarantine; entries clear when the sequence finally acks.
|
|
41735
41780
|
ackExhaustsBySeq = /* @__PURE__ */ new Map();
|
|
@@ -41760,6 +41805,29 @@ var AgentBridgeOutputBuffer = class {
|
|
|
41760
41805
|
await this.flushPendingDelta({ force: true });
|
|
41761
41806
|
await this.drainPendingOutputs({ force: true });
|
|
41762
41807
|
}
|
|
41808
|
+
// Emits one runtime liveness beat through the same ordered, acked drain as
|
|
41809
|
+
// content envelopes — deliberately, so a beat landing at the bridge proves
|
|
41810
|
+
// the pipeline is healthy end to end. While a previous beat is still
|
|
41811
|
+
// pending (stalled drain, retry ladder, reconnect) new beats are skipped
|
|
41812
|
+
// rather than queued: an unhealthy pipeline must show up as beats
|
|
41813
|
+
// *stopping*, and a backlog of parked beats replaying after recovery would
|
|
41814
|
+
// stamp liveness for exactly the window the runtime was mute.
|
|
41815
|
+
async emitLivenessBeat(context, intervalMs) {
|
|
41816
|
+
if (this.pendingLivenessSeq !== null && this.pendingOutputs.has(this.pendingLivenessSeq)) {
|
|
41817
|
+
return;
|
|
41818
|
+
}
|
|
41819
|
+
this.outputSeq += 1;
|
|
41820
|
+
this.pendingLivenessSeq = this.outputSeq;
|
|
41821
|
+
this.enqueueOutput(
|
|
41822
|
+
buildLivenessOutputEnvelope({
|
|
41823
|
+
context,
|
|
41824
|
+
outputSeq: this.outputSeq,
|
|
41825
|
+
intervalMs,
|
|
41826
|
+
createdAt: now2()
|
|
41827
|
+
})
|
|
41828
|
+
);
|
|
41829
|
+
await this.drainPendingOutputs();
|
|
41830
|
+
}
|
|
41763
41831
|
async emitUiMessageChunk(context, projection) {
|
|
41764
41832
|
await this.flushPendingDelta();
|
|
41765
41833
|
await this.emitLiveUiMessageChunk(context, projection.chunk);
|
|
@@ -42456,6 +42524,18 @@ function buildUiMessageChunkOutputEnvelope(input) {
|
|
|
42456
42524
|
createdAt: input.createdAt
|
|
42457
42525
|
});
|
|
42458
42526
|
}
|
|
42527
|
+
function buildLivenessOutputEnvelope(input) {
|
|
42528
|
+
const { context } = input;
|
|
42529
|
+
return RuntimeBridgeOutputEnvelopeSchema.parse({
|
|
42530
|
+
type: "runtime.liveness",
|
|
42531
|
+
sessionId: context.sessionId,
|
|
42532
|
+
runtimeId: context.runtimeId,
|
|
42533
|
+
bridgeLeaseId: context.bridgeLeaseId,
|
|
42534
|
+
outputSeq: input.outputSeq,
|
|
42535
|
+
intervalMs: input.intervalMs,
|
|
42536
|
+
createdAt: input.createdAt
|
|
42537
|
+
});
|
|
42538
|
+
}
|
|
42459
42539
|
function buildUiMessagePartOutputEnvelope(input) {
|
|
42460
42540
|
const { context, snapshot } = input;
|
|
42461
42541
|
return RuntimeBridgeOutputEnvelopeSchema.parse({
|
|
@@ -44141,11 +44221,16 @@ var ClaudeCodeCommandHandler = class {
|
|
|
44141
44221
|
pendingQuestions = /* @__PURE__ */ new Map();
|
|
44142
44222
|
outputBuffer;
|
|
44143
44223
|
projector = new ClaudeCodeProjector();
|
|
44224
|
+
livenessTicker = null;
|
|
44144
44225
|
// -----------------------------------------------------------------------------
|
|
44145
44226
|
// Lifecycle (public API)
|
|
44146
44227
|
// -----------------------------------------------------------------------------
|
|
44147
44228
|
setContext(nextContext) {
|
|
44148
44229
|
this.context = RuntimeBridgeConnectedPayloadSchema.parse(nextContext);
|
|
44230
|
+
this.livenessTicker ??= startRuntimeLivenessTicker({
|
|
44231
|
+
emitBeat: () => this.emitLivenessBeat(),
|
|
44232
|
+
writeOutput: this.input.writeOutput
|
|
44233
|
+
});
|
|
44149
44234
|
}
|
|
44150
44235
|
async replayPendingOutputs() {
|
|
44151
44236
|
await this.outputBuffer.replayPendingOutputs();
|
|
@@ -44154,6 +44239,8 @@ var ClaudeCodeCommandHandler = class {
|
|
|
44154
44239
|
await this.ensureAgentSession().prepare();
|
|
44155
44240
|
}
|
|
44156
44241
|
shutdown() {
|
|
44242
|
+
this.livenessTicker?.stop();
|
|
44243
|
+
this.livenessTicker = null;
|
|
44157
44244
|
this.agentSession?.close();
|
|
44158
44245
|
this.agentSession = null;
|
|
44159
44246
|
this.settlePendingQuestions("Runtime is shutting down");
|
|
@@ -44485,6 +44572,16 @@ var ClaudeCodeCommandHandler = class {
|
|
|
44485
44572
|
// -----------------------------------------------------------------------------
|
|
44486
44573
|
// SDK callbacks
|
|
44487
44574
|
// -----------------------------------------------------------------------------
|
|
44575
|
+
async emitLivenessBeat() {
|
|
44576
|
+
const activeContext = this.context;
|
|
44577
|
+
if (!activeContext) {
|
|
44578
|
+
return;
|
|
44579
|
+
}
|
|
44580
|
+
await this.outputBuffer.emitLivenessBeat(
|
|
44581
|
+
activeContext,
|
|
44582
|
+
RUNTIME_LIVENESS_INTERVAL_MS
|
|
44583
|
+
);
|
|
44584
|
+
}
|
|
44488
44585
|
async emitBridgeOutput(activeContext, projection) {
|
|
44489
44586
|
try {
|
|
44490
44587
|
await this.outputBuffer.emitProjection(activeContext, projection);
|
|
@@ -45951,12 +46048,17 @@ var CodexCommandHandler = class {
|
|
|
45951
46048
|
pendingApprovals = /* @__PURE__ */ new Map();
|
|
45952
46049
|
outputBuffer;
|
|
45953
46050
|
projector = new CodexProjector();
|
|
46051
|
+
livenessTicker = null;
|
|
45954
46052
|
skipResumeForNextSession = false;
|
|
45955
46053
|
// ---------------------------------------------------------------------------
|
|
45956
46054
|
// Lifecycle (public API)
|
|
45957
46055
|
// ---------------------------------------------------------------------------
|
|
45958
46056
|
setContext(nextContext) {
|
|
45959
46057
|
this.context = RuntimeBridgeConnectedPayloadSchema.parse(nextContext);
|
|
46058
|
+
this.livenessTicker ??= startRuntimeLivenessTicker({
|
|
46059
|
+
emitBeat: () => this.emitLivenessBeat(),
|
|
46060
|
+
writeOutput: this.input.writeOutput
|
|
46061
|
+
});
|
|
45960
46062
|
}
|
|
45961
46063
|
async replayPendingOutputs() {
|
|
45962
46064
|
await this.outputBuffer.replayPendingOutputs();
|
|
@@ -45965,6 +46067,8 @@ var CodexCommandHandler = class {
|
|
|
45965
46067
|
await this.ensureSession().prepare();
|
|
45966
46068
|
}
|
|
45967
46069
|
shutdown() {
|
|
46070
|
+
this.livenessTicker?.stop();
|
|
46071
|
+
this.livenessTicker = null;
|
|
45968
46072
|
this.session?.close();
|
|
45969
46073
|
this.session = null;
|
|
45970
46074
|
this.pendingApprovals.clear();
|
|
@@ -46132,6 +46236,16 @@ var CodexCommandHandler = class {
|
|
|
46132
46236
|
this.projector.projectSessionFailure(errorMessage3(error51))
|
|
46133
46237
|
);
|
|
46134
46238
|
}
|
|
46239
|
+
async emitLivenessBeat() {
|
|
46240
|
+
const activeContext = this.context;
|
|
46241
|
+
if (!activeContext) {
|
|
46242
|
+
return;
|
|
46243
|
+
}
|
|
46244
|
+
await this.outputBuffer.emitLivenessBeat(
|
|
46245
|
+
activeContext,
|
|
46246
|
+
RUNTIME_LIVENESS_INTERVAL_MS
|
|
46247
|
+
);
|
|
46248
|
+
}
|
|
46135
46249
|
async emit(activeContext, projection) {
|
|
46136
46250
|
try {
|
|
46137
46251
|
await this.outputBuffer.emitProjection(activeContext, projection);
|