@autohq/cli 0.1.583 → 0.1.584
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 +37635 -27103
- package/dist/index.js +699 -122
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -16681,13 +16681,13 @@ function parseClaudeCodeStreamRecord(parsed) {
|
|
|
16681
16681
|
}
|
|
16682
16682
|
const isError = record2.is_error === true || record2.subtype === "error";
|
|
16683
16683
|
const sdkErrorMessage = record2.errors?.map((error51) => error51.trim()).filter(Boolean).join("\n");
|
|
16684
|
-
const
|
|
16684
|
+
const errorMessage7 = isError ? record2.error ?? record2.result ?? (sdkErrorMessage || void 0) ?? "claude-code reported an error" : void 0;
|
|
16685
16685
|
const usage = claudeCodeUsageFromRecord(record2);
|
|
16686
16686
|
return {
|
|
16687
16687
|
projections: [],
|
|
16688
16688
|
result: {
|
|
16689
16689
|
isError,
|
|
16690
|
-
errorMessage:
|
|
16690
|
+
errorMessage: errorMessage7,
|
|
16691
16691
|
...usage ? { usage } : {}
|
|
16692
16692
|
}
|
|
16693
16693
|
};
|
|
@@ -16705,11 +16705,11 @@ function isClaudeCodeInterruptMarker(record2) {
|
|
|
16705
16705
|
(block) => block !== null && block.type === "text" && block.text.startsWith(CLAUDE_CODE_INTERRUPT_MARKER_PREFIX)
|
|
16706
16706
|
);
|
|
16707
16707
|
}
|
|
16708
|
-
function isClaudeCodeEdeDiagnosticOnlyError(
|
|
16709
|
-
if (!
|
|
16708
|
+
function isClaudeCodeEdeDiagnosticOnlyError(errorMessage7) {
|
|
16709
|
+
if (!errorMessage7) {
|
|
16710
16710
|
return false;
|
|
16711
16711
|
}
|
|
16712
|
-
const lines =
|
|
16712
|
+
const lines = errorMessage7.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
|
|
16713
16713
|
return lines.length > 0 && lines.every((line) => line.startsWith(CLAUDE_CODE_EDE_DIAGNOSTIC_PREFIX));
|
|
16714
16714
|
}
|
|
16715
16715
|
function isClaudeCodePermissionDenialText(text) {
|
|
@@ -88606,7 +88606,7 @@ var init_package = __esm({
|
|
|
88606
88606
|
"package.json"() {
|
|
88607
88607
|
package_default = {
|
|
88608
88608
|
name: "@autohq/cli",
|
|
88609
|
-
version: "0.1.
|
|
88609
|
+
version: "0.1.584",
|
|
88610
88610
|
license: "SEE LICENSE IN README.md",
|
|
88611
88611
|
publishConfig: {
|
|
88612
88612
|
access: "public"
|
|
@@ -92337,9 +92337,9 @@ var init_actions = __esm({
|
|
|
92337
92337
|
});
|
|
92338
92338
|
|
|
92339
92339
|
// src/commands/auth/pkce.ts
|
|
92340
|
-
import { createHash as createHash6, randomBytes as
|
|
92340
|
+
import { createHash as createHash6, randomBytes as randomBytes4 } from "crypto";
|
|
92341
92341
|
function pkceVerifier() {
|
|
92342
|
-
return
|
|
92342
|
+
return randomBytes4(32).toString("base64url");
|
|
92343
92343
|
}
|
|
92344
92344
|
function pkceChallenge(verifier) {
|
|
92345
92345
|
return createHash6("sha256").update(verifier).digest("base64url");
|
|
@@ -95904,7 +95904,7 @@ function SessionsView({
|
|
|
95904
95904
|
visibleSessions.map((session, vi) => {
|
|
95905
95905
|
const i = scrollOffset + vi;
|
|
95906
95906
|
const title = sessionDisplayTitle(session);
|
|
95907
|
-
const err = session.status === "failed" ?
|
|
95907
|
+
const err = session.status === "failed" ? errorMessage5(session) : null;
|
|
95908
95908
|
const isSelected = i === safeIndex;
|
|
95909
95909
|
const isMarked = selectedSessionIds.has(session.id);
|
|
95910
95910
|
return /* @__PURE__ */ jsxs10(Box11, { flexDirection: "column", children: [
|
|
@@ -96042,7 +96042,7 @@ function truncateToWidth(value, width) {
|
|
|
96042
96042
|
function agentNameForRun(session) {
|
|
96043
96043
|
return session.snapshot.metadata.name;
|
|
96044
96044
|
}
|
|
96045
|
-
function
|
|
96045
|
+
function errorMessage5(session) {
|
|
96046
96046
|
if (session.error == null) return null;
|
|
96047
96047
|
if (typeof session.error === "string") return session.error;
|
|
96048
96048
|
const msg = readField(session.error, "message");
|
|
@@ -97477,7 +97477,7 @@ function HomeView({
|
|
|
97477
97477
|
if (inspectedResource) {
|
|
97478
97478
|
sectionTitle = `Inspect ${inspectedResource.kind}/${inspectedResource.name}`;
|
|
97479
97479
|
}
|
|
97480
|
-
const runError =
|
|
97480
|
+
const runError = errorMessage6(triggerSession.error) ?? errorMessage6(archiveSessions.error) ?? errorMessage6(unarchiveSessions.error) ?? errorMessage6(stopSessions.error);
|
|
97481
97481
|
const isRunMutationPending = triggerSession.isPending || archiveSessions.isPending || unarchiveSessions.isPending || stopSessions.isPending;
|
|
97482
97482
|
const isConnectionMutationPending = startConnection.isPending || allowConnection.isPending || removeConnection.isPending || createGithubSyncBinding.isPending;
|
|
97483
97483
|
const serviceAccountStatus = createServiceAccount2.error instanceof Error ? createServiceAccount2.error.message : rotateServiceAccount2.error instanceof Error ? rotateServiceAccount2.error.message : removeServiceAccount2.error instanceof Error ? removeServiceAccount2.error.message : serviceAccountNotice;
|
|
@@ -97890,7 +97890,7 @@ function runActionTargetLabel(sessionIds, markedRunCount) {
|
|
|
97890
97890
|
function pluralizeRunCount(count) {
|
|
97891
97891
|
return `${count} ${count === 1 ? "session" : "sessions"}`;
|
|
97892
97892
|
}
|
|
97893
|
-
function
|
|
97893
|
+
function errorMessage6(error51) {
|
|
97894
97894
|
if (error51 instanceof Error) return error51.message;
|
|
97895
97895
|
return error51 ? String(error51) : null;
|
|
97896
97896
|
}
|
|
@@ -100733,7 +100733,7 @@ function jsonRecordString(value, key) {
|
|
|
100733
100733
|
init_src();
|
|
100734
100734
|
|
|
100735
100735
|
// src/commands/agent-bridge/harness/agent-facing-auto-mcp.ts
|
|
100736
|
-
import { randomBytes as randomBytes2
|
|
100736
|
+
import { randomBytes as randomBytes2 } from "crypto";
|
|
100737
100737
|
import { lstatSync, readFileSync as readFileSync3, realpathSync, statSync } from "fs";
|
|
100738
100738
|
import {
|
|
100739
100739
|
createServer as createServer3
|
|
@@ -100751,7 +100751,17 @@ import {
|
|
|
100751
100751
|
import { parseAllDocuments as parseAllDocuments2 } from "yaml";
|
|
100752
100752
|
|
|
100753
100753
|
// src/commands/agent-bridge/harness/turn-bound-mcp.ts
|
|
100754
|
+
import { timingSafeEqual } from "crypto";
|
|
100754
100755
|
var AGENT_BRIDGE_MCP_CAPABILITY_HEADER = "x-auto-agent-bridge-mcp-capability";
|
|
100756
|
+
function requestHasMcpCapability(headers, expected) {
|
|
100757
|
+
const received = headers[AGENT_BRIDGE_MCP_CAPABILITY_HEADER];
|
|
100758
|
+
if (typeof received !== "string") {
|
|
100759
|
+
return false;
|
|
100760
|
+
}
|
|
100761
|
+
const expectedBytes = Buffer.from(expected);
|
|
100762
|
+
const receivedBytes = Buffer.from(received);
|
|
100763
|
+
return expectedBytes.length === receivedBytes.length && timingSafeEqual(expectedBytes, receivedBytes);
|
|
100764
|
+
}
|
|
100755
100765
|
|
|
100756
100766
|
// src/commands/agent-bridge/harness/agent-facing-auto-mcp.ts
|
|
100757
100767
|
var MAX_DRY_RUN_PATH_FILES = 100;
|
|
@@ -101221,7 +101231,7 @@ async function startAutoMcpProxy(input) {
|
|
|
101221
101231
|
let pathsCompatible = false;
|
|
101222
101232
|
const server = createServer3(async (request, response) => {
|
|
101223
101233
|
try {
|
|
101224
|
-
if (!
|
|
101234
|
+
if (!requestHasMcpCapability(request.headers, input.capability)) {
|
|
101225
101235
|
writeResponse(
|
|
101226
101236
|
response,
|
|
101227
101237
|
401,
|
|
@@ -101427,15 +101437,6 @@ function exactActiveCommandId(activeTurnCommandIds) {
|
|
|
101427
101437
|
const commandIds = activeTurnCommandIds();
|
|
101428
101438
|
return commandIds.length === 1 ? commandIds[0] ?? null : null;
|
|
101429
101439
|
}
|
|
101430
|
-
function requestHasCapability(headers, expected) {
|
|
101431
|
-
const received = headers[AGENT_BRIDGE_MCP_CAPABILITY_HEADER];
|
|
101432
|
-
if (typeof received !== "string") {
|
|
101433
|
-
return false;
|
|
101434
|
-
}
|
|
101435
|
-
const expectedBytes = Buffer.from(expected);
|
|
101436
|
-
const receivedBytes = Buffer.from(received);
|
|
101437
|
-
return expectedBytes.length === receivedBytes.length && timingSafeEqual(expectedBytes, receivedBytes);
|
|
101438
|
-
}
|
|
101439
101440
|
function readRequestBody(request) {
|
|
101440
101441
|
return new Promise((resolveBody, reject) => {
|
|
101441
101442
|
const chunks = [];
|
|
@@ -101468,6 +101469,384 @@ function isRecord2(value) {
|
|
|
101468
101469
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
101469
101470
|
}
|
|
101470
101471
|
|
|
101472
|
+
// src/commands/agent-bridge/harness/ask-user-projection.ts
|
|
101473
|
+
init_src();
|
|
101474
|
+
var ASK_USER_MCP_SERVER_NAME = "user";
|
|
101475
|
+
var ASK_USER_MCP_TOOL_NAME = "ask_question";
|
|
101476
|
+
var ASK_USER_TOOL_NAME = `${ASK_USER_MCP_SERVER_NAME}.${ASK_USER_MCP_TOOL_NAME}`;
|
|
101477
|
+
var CLAUDE_ASK_USER_TOOL_NAME = `mcp__${ASK_USER_MCP_SERVER_NAME}__${ASK_USER_MCP_TOOL_NAME}`;
|
|
101478
|
+
function isAskUserMcpTool(server, tool) {
|
|
101479
|
+
return server === ASK_USER_MCP_SERVER_NAME && tool === ASK_USER_MCP_TOOL_NAME;
|
|
101480
|
+
}
|
|
101481
|
+
function projectAskUserQuestion(input) {
|
|
101482
|
+
return [
|
|
101483
|
+
{
|
|
101484
|
+
type: "entry",
|
|
101485
|
+
entry: {
|
|
101486
|
+
role: "assistant",
|
|
101487
|
+
kind: "question",
|
|
101488
|
+
turnStatus: "waiting_for_input",
|
|
101489
|
+
content: {
|
|
101490
|
+
parts: [
|
|
101491
|
+
{
|
|
101492
|
+
type: "question",
|
|
101493
|
+
toolCallId: input.id,
|
|
101494
|
+
questions: input.questions
|
|
101495
|
+
}
|
|
101496
|
+
]
|
|
101497
|
+
}
|
|
101498
|
+
}
|
|
101499
|
+
},
|
|
101500
|
+
{
|
|
101501
|
+
type: "ui_message_chunk",
|
|
101502
|
+
chunk: {
|
|
101503
|
+
type: "tool-input-available",
|
|
101504
|
+
toolCallId: input.id,
|
|
101505
|
+
toolName: ASK_USER_TOOL_NAME,
|
|
101506
|
+
input: { questions: input.questions }
|
|
101507
|
+
},
|
|
101508
|
+
turnStatus: "waiting_for_input"
|
|
101509
|
+
}
|
|
101510
|
+
];
|
|
101511
|
+
}
|
|
101512
|
+
function projectAskUserAnswer(answer) {
|
|
101513
|
+
return {
|
|
101514
|
+
type: "ui_message_chunk",
|
|
101515
|
+
chunk: {
|
|
101516
|
+
type: "tool-output-available",
|
|
101517
|
+
toolCallId: answer.toolCallId || UNKNOWN_MESSAGE_ID,
|
|
101518
|
+
output: toJsonValue({
|
|
101519
|
+
answers: answer.answers,
|
|
101520
|
+
...answer.response ? { response: answer.response } : {}
|
|
101521
|
+
})
|
|
101522
|
+
}
|
|
101523
|
+
};
|
|
101524
|
+
}
|
|
101525
|
+
|
|
101526
|
+
// src/commands/agent-bridge/harness/ask-user-server.ts
|
|
101527
|
+
init_src();
|
|
101528
|
+
init_zod();
|
|
101529
|
+
import { randomBytes as randomBytes3, randomUUID } from "crypto";
|
|
101530
|
+
import {
|
|
101531
|
+
createServer as createServer4
|
|
101532
|
+
} from "http";
|
|
101533
|
+
import { Server as McpProtocolServer } from "@modelcontextprotocol/sdk/server/index.js";
|
|
101534
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
101535
|
+
import {
|
|
101536
|
+
CallToolRequestSchema as CallToolRequestSchema2,
|
|
101537
|
+
ListToolsRequestSchema as ListToolsRequestSchema2
|
|
101538
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
101539
|
+
var ASK_USER_PROGRESS_INTERVAL_MS = 3e4;
|
|
101540
|
+
var ASK_USER_CALL_DEADLINE_MS = 84e4;
|
|
101541
|
+
var ASK_USER_FALLBACK_MESSAGE = "The question remains pending for the user. Continue this turn; the answer will arrive as a user message.";
|
|
101542
|
+
var AuthoredQuestionSchema = ConversationQuestionSchema.extend({
|
|
101543
|
+
question: external_exports.string().trim().min(1).max(1024),
|
|
101544
|
+
header: external_exports.string().trim().min(1).max(64),
|
|
101545
|
+
options: external_exports.array(
|
|
101546
|
+
external_exports.object({
|
|
101547
|
+
label: external_exports.string().trim().min(1).max(128),
|
|
101548
|
+
description: external_exports.string().trim().max(512)
|
|
101549
|
+
}).strict()
|
|
101550
|
+
).min(2).max(6)
|
|
101551
|
+
}).strict();
|
|
101552
|
+
var AskUserQuestionInputSchema2 = external_exports.object({
|
|
101553
|
+
questions: external_exports.array(AuthoredQuestionSchema).min(1).max(4)
|
|
101554
|
+
}).strict();
|
|
101555
|
+
var AskUserQuestionRegistry = class {
|
|
101556
|
+
pending = /* @__PURE__ */ new Map();
|
|
101557
|
+
deadlineMs;
|
|
101558
|
+
progressIntervalMs;
|
|
101559
|
+
constructor(options = {}) {
|
|
101560
|
+
this.deadlineMs = positiveDuration(
|
|
101561
|
+
options.deadlineMs ?? ASK_USER_CALL_DEADLINE_MS,
|
|
101562
|
+
"ask-user deadline"
|
|
101563
|
+
);
|
|
101564
|
+
this.progressIntervalMs = positiveDuration(
|
|
101565
|
+
options.progressIntervalMs ?? ASK_USER_PROGRESS_INTERVAL_MS,
|
|
101566
|
+
"ask-user progress interval"
|
|
101567
|
+
);
|
|
101568
|
+
}
|
|
101569
|
+
get size() {
|
|
101570
|
+
return this.pending.size;
|
|
101571
|
+
}
|
|
101572
|
+
has(id) {
|
|
101573
|
+
return this.pending.has(id);
|
|
101574
|
+
}
|
|
101575
|
+
park(input) {
|
|
101576
|
+
const { questions } = AskUserQuestionInputSchema2.parse({
|
|
101577
|
+
questions: input.questions
|
|
101578
|
+
});
|
|
101579
|
+
const id = `q_${randomUUID()}`;
|
|
101580
|
+
let resolveWait = () => {
|
|
101581
|
+
};
|
|
101582
|
+
const wait = new Promise((resolve6) => {
|
|
101583
|
+
resolveWait = resolve6;
|
|
101584
|
+
});
|
|
101585
|
+
const progress = setInterval(() => {
|
|
101586
|
+
try {
|
|
101587
|
+
void Promise.resolve(input.onProgress?.()).catch(() => {
|
|
101588
|
+
});
|
|
101589
|
+
} catch {
|
|
101590
|
+
}
|
|
101591
|
+
}, this.progressIntervalMs);
|
|
101592
|
+
const deadline = setTimeout(() => {
|
|
101593
|
+
this.settle(id, {
|
|
101594
|
+
kind: "fallback",
|
|
101595
|
+
message: ASK_USER_FALLBACK_MESSAGE,
|
|
101596
|
+
reason: "deadline"
|
|
101597
|
+
});
|
|
101598
|
+
}, this.deadlineMs);
|
|
101599
|
+
this.pending.set(id, {
|
|
101600
|
+
id,
|
|
101601
|
+
questions,
|
|
101602
|
+
deadline,
|
|
101603
|
+
progress,
|
|
101604
|
+
resolve: resolveWait,
|
|
101605
|
+
onSettled: input.onSettled
|
|
101606
|
+
});
|
|
101607
|
+
return { id, wait };
|
|
101608
|
+
}
|
|
101609
|
+
answer(id, answer) {
|
|
101610
|
+
if (answer.toolCallId !== id) {
|
|
101611
|
+
return false;
|
|
101612
|
+
}
|
|
101613
|
+
return this.settle(id, { kind: "answered", answer });
|
|
101614
|
+
}
|
|
101615
|
+
quarantine(id, reason) {
|
|
101616
|
+
return this.settle(id, {
|
|
101617
|
+
kind: "fallback",
|
|
101618
|
+
message: ASK_USER_FALLBACK_MESSAGE,
|
|
101619
|
+
reason
|
|
101620
|
+
});
|
|
101621
|
+
}
|
|
101622
|
+
quarantineAll(reason) {
|
|
101623
|
+
let settled = 0;
|
|
101624
|
+
for (const id of [...this.pending.keys()]) {
|
|
101625
|
+
if (this.quarantine(id, reason)) {
|
|
101626
|
+
settled += 1;
|
|
101627
|
+
}
|
|
101628
|
+
}
|
|
101629
|
+
return settled;
|
|
101630
|
+
}
|
|
101631
|
+
settle(id, settlement) {
|
|
101632
|
+
const pending = this.pending.get(id);
|
|
101633
|
+
if (!pending || !this.pending.delete(id)) {
|
|
101634
|
+
return false;
|
|
101635
|
+
}
|
|
101636
|
+
clearTimeout(pending.deadline);
|
|
101637
|
+
clearInterval(pending.progress);
|
|
101638
|
+
pending.resolve(settlement);
|
|
101639
|
+
try {
|
|
101640
|
+
pending.onSettled?.(settlement);
|
|
101641
|
+
} catch {
|
|
101642
|
+
}
|
|
101643
|
+
return true;
|
|
101644
|
+
}
|
|
101645
|
+
};
|
|
101646
|
+
var AskUserServer = class {
|
|
101647
|
+
constructor(options) {
|
|
101648
|
+
this.options = options;
|
|
101649
|
+
this.registry = new AskUserQuestionRegistry(options);
|
|
101650
|
+
}
|
|
101651
|
+
options;
|
|
101652
|
+
registry;
|
|
101653
|
+
path = `/mcp/${randomBytes3(24).toString("base64url")}`;
|
|
101654
|
+
capability = randomBytes3(32).toString("base64url");
|
|
101655
|
+
server = null;
|
|
101656
|
+
prepared = null;
|
|
101657
|
+
prepare() {
|
|
101658
|
+
this.prepared ??= this.prepareOnce();
|
|
101659
|
+
return this.prepared;
|
|
101660
|
+
}
|
|
101661
|
+
answer(answer) {
|
|
101662
|
+
return this.registry.answer(answer.toolCallId, answer);
|
|
101663
|
+
}
|
|
101664
|
+
quarantineAll(reason) {
|
|
101665
|
+
return this.registry.quarantineAll(reason);
|
|
101666
|
+
}
|
|
101667
|
+
close() {
|
|
101668
|
+
this.quarantineAll("harness shutdown");
|
|
101669
|
+
this.server?.close();
|
|
101670
|
+
this.server = null;
|
|
101671
|
+
}
|
|
101672
|
+
async prepareOnce() {
|
|
101673
|
+
const server = createServer4((request, response) => {
|
|
101674
|
+
void this.handleRequest(request, response);
|
|
101675
|
+
});
|
|
101676
|
+
this.server = server;
|
|
101677
|
+
await new Promise((resolve6, reject) => {
|
|
101678
|
+
server.once("error", reject);
|
|
101679
|
+
server.listen(0, "127.0.0.1", () => {
|
|
101680
|
+
server.off("error", reject);
|
|
101681
|
+
resolve6();
|
|
101682
|
+
});
|
|
101683
|
+
});
|
|
101684
|
+
const address = server.address();
|
|
101685
|
+
if (!address || typeof address === "string") {
|
|
101686
|
+
server.close();
|
|
101687
|
+
throw new Error("ask-user MCP server did not receive a TCP address");
|
|
101688
|
+
}
|
|
101689
|
+
server.unref();
|
|
101690
|
+
return {
|
|
101691
|
+
url: `http://127.0.0.1:${address.port}${this.path}`,
|
|
101692
|
+
headers: {
|
|
101693
|
+
[AGENT_BRIDGE_MCP_CAPABILITY_HEADER]: this.capability
|
|
101694
|
+
}
|
|
101695
|
+
};
|
|
101696
|
+
}
|
|
101697
|
+
async handleRequest(request, response) {
|
|
101698
|
+
if (request.url !== this.path || request.method !== "POST") {
|
|
101699
|
+
response.writeHead(request.url === this.path ? 405 : 404).end();
|
|
101700
|
+
return;
|
|
101701
|
+
}
|
|
101702
|
+
if (!requestHasMcpCapability(request.headers, this.capability)) {
|
|
101703
|
+
response.writeHead(401, { "content-type": "application/json" }).end(JSON.stringify({ error: "Invalid ask-user MCP capability" }));
|
|
101704
|
+
return;
|
|
101705
|
+
}
|
|
101706
|
+
try {
|
|
101707
|
+
await this.handleMcpRequest(request, response);
|
|
101708
|
+
} catch (error51) {
|
|
101709
|
+
this.options.writeOutput?.(
|
|
101710
|
+
`agent_bridge_ask_user_http_error error=${errorMessage2(error51)}`
|
|
101711
|
+
);
|
|
101712
|
+
if (!response.headersSent) {
|
|
101713
|
+
response.writeHead(500, { "content-type": "application/json" });
|
|
101714
|
+
response.end(
|
|
101715
|
+
JSON.stringify({
|
|
101716
|
+
jsonrpc: "2.0",
|
|
101717
|
+
id: null,
|
|
101718
|
+
error: { code: -32603, message: "Ask-user server failed" }
|
|
101719
|
+
})
|
|
101720
|
+
);
|
|
101721
|
+
}
|
|
101722
|
+
}
|
|
101723
|
+
}
|
|
101724
|
+
async handleMcpRequest(request, response) {
|
|
101725
|
+
const body = await readJsonRequest(request);
|
|
101726
|
+
this.options.writeOutput?.(
|
|
101727
|
+
`agent_bridge_ask_user_mcp_request method=${typeof body.method === "string" ? body.method : "unknown"}`
|
|
101728
|
+
);
|
|
101729
|
+
const server = this.createMcpServer();
|
|
101730
|
+
const transport = new StreamableHTTPServerTransport({
|
|
101731
|
+
sessionIdGenerator: void 0,
|
|
101732
|
+
// Codex 0.145.0 requires ordinary initialize/list responses as JSON. A
|
|
101733
|
+
// parked tool call keeps SSE enabled so progress notifications can flow
|
|
101734
|
+
// over the held response without extending the hard client deadline.
|
|
101735
|
+
enableJsonResponse: body.method !== "tools/call"
|
|
101736
|
+
});
|
|
101737
|
+
response.once("close", () => {
|
|
101738
|
+
void transport.close();
|
|
101739
|
+
void server.close();
|
|
101740
|
+
});
|
|
101741
|
+
await server.connect(transport);
|
|
101742
|
+
await transport.handleRequest(request, response, body);
|
|
101743
|
+
}
|
|
101744
|
+
createMcpServer() {
|
|
101745
|
+
const server = new McpProtocolServer(
|
|
101746
|
+
{ name: "auto-ask-user", version: "1.0.0" },
|
|
101747
|
+
{ capabilities: { tools: {} } }
|
|
101748
|
+
);
|
|
101749
|
+
server.setRequestHandler(ListToolsRequestSchema2, () => ({
|
|
101750
|
+
tools: [
|
|
101751
|
+
{
|
|
101752
|
+
name: ASK_USER_MCP_TOOL_NAME,
|
|
101753
|
+
title: ASK_USER_TOOL_NAME,
|
|
101754
|
+
description: "Ask the user one to four blocking questions and wait for their answer.",
|
|
101755
|
+
inputSchema: external_exports.toJSONSchema(AskUserQuestionInputSchema2)
|
|
101756
|
+
}
|
|
101757
|
+
]
|
|
101758
|
+
}));
|
|
101759
|
+
server.setRequestHandler(
|
|
101760
|
+
CallToolRequestSchema2,
|
|
101761
|
+
async (request, extra) => {
|
|
101762
|
+
if (request.params.name !== ASK_USER_MCP_TOOL_NAME) {
|
|
101763
|
+
throw new Error(`Unknown ask-user tool: ${request.params.name}`);
|
|
101764
|
+
}
|
|
101765
|
+
const { questions } = AskUserQuestionInputSchema2.parse(
|
|
101766
|
+
request.params.arguments
|
|
101767
|
+
);
|
|
101768
|
+
let questionId = "";
|
|
101769
|
+
const parked = this.registry.park({
|
|
101770
|
+
questions,
|
|
101771
|
+
onProgress: async () => {
|
|
101772
|
+
const progressToken = extra._meta?.progressToken;
|
|
101773
|
+
if (progressToken === void 0) {
|
|
101774
|
+
return;
|
|
101775
|
+
}
|
|
101776
|
+
await extra.sendNotification({
|
|
101777
|
+
method: "notifications/progress",
|
|
101778
|
+
params: {
|
|
101779
|
+
progressToken,
|
|
101780
|
+
progress: Date.now(),
|
|
101781
|
+
message: "Waiting for the user to answer"
|
|
101782
|
+
}
|
|
101783
|
+
});
|
|
101784
|
+
},
|
|
101785
|
+
onSettled: (settlement2) => {
|
|
101786
|
+
this.options.onQuestionSettled?.({ id: questionId, settlement: settlement2 });
|
|
101787
|
+
}
|
|
101788
|
+
});
|
|
101789
|
+
questionId = parked.id;
|
|
101790
|
+
try {
|
|
101791
|
+
await this.options.onQuestionPending({
|
|
101792
|
+
id: parked.id,
|
|
101793
|
+
questions
|
|
101794
|
+
});
|
|
101795
|
+
} catch (error51) {
|
|
101796
|
+
this.registry.quarantine(parked.id, "question projection failed");
|
|
101797
|
+
throw error51;
|
|
101798
|
+
}
|
|
101799
|
+
const settlement = await parked.wait;
|
|
101800
|
+
return settlementResult(settlement);
|
|
101801
|
+
}
|
|
101802
|
+
);
|
|
101803
|
+
return server;
|
|
101804
|
+
}
|
|
101805
|
+
};
|
|
101806
|
+
function settlementResult(settlement) {
|
|
101807
|
+
if (settlement.kind === "fallback") {
|
|
101808
|
+
return {
|
|
101809
|
+
content: [{ type: "text", text: settlement.message }]
|
|
101810
|
+
};
|
|
101811
|
+
}
|
|
101812
|
+
const answer = settlement.answer;
|
|
101813
|
+
const lines = Object.entries(answer.answers).map(
|
|
101814
|
+
([question, value]) => `- ${question}: ${value}`
|
|
101815
|
+
);
|
|
101816
|
+
return {
|
|
101817
|
+
content: [
|
|
101818
|
+
{
|
|
101819
|
+
type: "text",
|
|
101820
|
+
text: [
|
|
101821
|
+
"The user answered your questions:",
|
|
101822
|
+
...lines,
|
|
101823
|
+
...answer.response ? [`The user also responded: ${answer.response}`] : []
|
|
101824
|
+
].join("\n")
|
|
101825
|
+
}
|
|
101826
|
+
]
|
|
101827
|
+
};
|
|
101828
|
+
}
|
|
101829
|
+
function positiveDuration(value, label) {
|
|
101830
|
+
if (!Number.isSafeInteger(value) || value < 1) {
|
|
101831
|
+
throw new Error(`${label} must be a positive safe integer`);
|
|
101832
|
+
}
|
|
101833
|
+
return value;
|
|
101834
|
+
}
|
|
101835
|
+
function errorMessage2(error51) {
|
|
101836
|
+
return error51 instanceof Error ? error51.message : String(error51);
|
|
101837
|
+
}
|
|
101838
|
+
async function readJsonRequest(request) {
|
|
101839
|
+
const chunks = [];
|
|
101840
|
+
for await (const chunk of request) {
|
|
101841
|
+
chunks.push(Buffer.from(chunk));
|
|
101842
|
+
}
|
|
101843
|
+
const parsed = JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
101844
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
101845
|
+
throw new Error("ask-user MCP request body must be a JSON object");
|
|
101846
|
+
}
|
|
101847
|
+
return parsed;
|
|
101848
|
+
}
|
|
101849
|
+
|
|
101471
101850
|
// src/commands/agent-bridge/harness/liveness-ticker.ts
|
|
101472
101851
|
var RUNTIME_LIVENESS_INTERVAL_MS = 2e4;
|
|
101473
101852
|
function startRuntimeLivenessTicker(input) {
|
|
@@ -102597,7 +102976,7 @@ function isTerminalUiMessageChunk(chunk) {
|
|
|
102597
102976
|
function legacyToolEntries(chunk) {
|
|
102598
102977
|
switch (chunk.type) {
|
|
102599
102978
|
case "tool-input-available":
|
|
102600
|
-
if (chunk.toolName === ASK_USER_QUESTION_TOOL_NAME) {
|
|
102979
|
+
if (chunk.toolName === ASK_USER_QUESTION_TOOL_NAME || chunk.toolName === ASK_USER_TOOL_NAME) {
|
|
102601
102980
|
return [];
|
|
102602
102981
|
}
|
|
102603
102982
|
return [
|
|
@@ -102921,6 +103300,111 @@ function jsonRecordString2(value, key) {
|
|
|
102921
103300
|
return typeof field === "string" ? field : void 0;
|
|
102922
103301
|
}
|
|
102923
103302
|
|
|
103303
|
+
// src/commands/agent-bridge/harness/mcp-timeout.ts
|
|
103304
|
+
var HARNESS_MCP_TOOL_TIMEOUT_SECONDS = 900;
|
|
103305
|
+
var MAX_HARNESS_MCP_TOOL_TIMEOUT_SECONDS = 3600;
|
|
103306
|
+
function validatedMcpToolTimeoutSeconds(value) {
|
|
103307
|
+
if (!Number.isSafeInteger(value) || value < 1 || value > MAX_HARNESS_MCP_TOOL_TIMEOUT_SECONDS) {
|
|
103308
|
+
throw new Error(
|
|
103309
|
+
`MCP tool timeout must be a safe integer from 1 to ${MAX_HARNESS_MCP_TOOL_TIMEOUT_SECONDS} seconds`
|
|
103310
|
+
);
|
|
103311
|
+
}
|
|
103312
|
+
return value;
|
|
103313
|
+
}
|
|
103314
|
+
function validatedMcpToolTimeoutMilliseconds(value) {
|
|
103315
|
+
return validatedMcpToolTimeoutSeconds(value) * 1e3;
|
|
103316
|
+
}
|
|
103317
|
+
|
|
103318
|
+
// src/commands/agent-bridge/harness/claude-code/options.ts
|
|
103319
|
+
var CLAUDE_AGENT_SDK_CLIENT_APP = "auto-agent-bridge";
|
|
103320
|
+
var CLAUDE_RUNTIME_PROCESS_ENV_KEYS = ["PATH", "HOME"];
|
|
103321
|
+
var CLAUDE_CODE_EXECUTABLE_PATH = "/usr/local/bin/claude";
|
|
103322
|
+
var CLAUDE_CODE_SHELL_PATH = "/bin/bash";
|
|
103323
|
+
var CLAUDE_CODE_DEFAULT_MODEL = "claude-opus-4-8";
|
|
103324
|
+
function claudeAgentOptions(config2, input = {}) {
|
|
103325
|
+
return {
|
|
103326
|
+
...config2.cwd ? { cwd: config2.cwd } : {},
|
|
103327
|
+
...input.resume ? { resume: input.resume } : {},
|
|
103328
|
+
env: claudeProcessEnv(
|
|
103329
|
+
config2.env,
|
|
103330
|
+
input.clientApp ?? CLAUDE_AGENT_SDK_CLIENT_APP
|
|
103331
|
+
),
|
|
103332
|
+
includePartialMessages: true,
|
|
103333
|
+
thinking: { type: "adaptive", display: "summarized" },
|
|
103334
|
+
settings: { showThinkingSummaries: true },
|
|
103335
|
+
model: config2.model?.id ?? CLAUDE_CODE_DEFAULT_MODEL,
|
|
103336
|
+
...config2.reasoningEffort ? { effort: config2.reasoningEffort } : {},
|
|
103337
|
+
permissionMode: "bypassPermissions",
|
|
103338
|
+
allowDangerouslySkipPermissions: true,
|
|
103339
|
+
pathToClaudeCodeExecutable: claudeCodeExecutablePath(),
|
|
103340
|
+
...input.mcpServers ?? config2.mcpServers ? {
|
|
103341
|
+
mcpServers: input.mcpServers ?? config2.mcpServers,
|
|
103342
|
+
strictMcpConfig: true
|
|
103343
|
+
} : {},
|
|
103344
|
+
systemPrompt: {
|
|
103345
|
+
type: "preset",
|
|
103346
|
+
preset: "claude_code",
|
|
103347
|
+
...config2.systemPromptAppend ? { append: config2.systemPromptAppend } : {}
|
|
103348
|
+
},
|
|
103349
|
+
settingSources: [],
|
|
103350
|
+
tools: {
|
|
103351
|
+
type: "preset",
|
|
103352
|
+
preset: "claude_code"
|
|
103353
|
+
},
|
|
103354
|
+
stderr: input.onStderrChunk ?? (() => {
|
|
103355
|
+
})
|
|
103356
|
+
};
|
|
103357
|
+
}
|
|
103358
|
+
function withClaudeAskUserMcpServer(mcpServers, url2, headers) {
|
|
103359
|
+
if (mcpServers?.[ASK_USER_MCP_SERVER_NAME]) {
|
|
103360
|
+
throw new Error(
|
|
103361
|
+
`MCP server name ${ASK_USER_MCP_SERVER_NAME} is reserved by the harness`
|
|
103362
|
+
);
|
|
103363
|
+
}
|
|
103364
|
+
return {
|
|
103365
|
+
...mcpServers,
|
|
103366
|
+
[ASK_USER_MCP_SERVER_NAME]: {
|
|
103367
|
+
type: "http",
|
|
103368
|
+
url: url2,
|
|
103369
|
+
headers,
|
|
103370
|
+
timeout: validatedMcpToolTimeoutMilliseconds(
|
|
103371
|
+
HARNESS_MCP_TOOL_TIMEOUT_SECONDS
|
|
103372
|
+
)
|
|
103373
|
+
}
|
|
103374
|
+
};
|
|
103375
|
+
}
|
|
103376
|
+
function claudeProcessEnv(env, clientApp) {
|
|
103377
|
+
const runtimeEnv = runtimeProcessEnv();
|
|
103378
|
+
return {
|
|
103379
|
+
// Claude Code only needs ambient shell basics from the bridge process.
|
|
103380
|
+
// Dynamic Claude/MCP/session secrets arrive through encrypted bootstrap env.
|
|
103381
|
+
...runtimeEnv,
|
|
103382
|
+
...env,
|
|
103383
|
+
// Claude Code auto-detects a shell when this is absent. Hosted sandboxes run
|
|
103384
|
+
// Bash tool commands, so pin the shell snapshot source to bash instead of
|
|
103385
|
+
// letting zsh profile functions leak into bash snapshots and inherit user
|
|
103386
|
+
// strict-mode options such as `set -u`.
|
|
103387
|
+
CLAUDE_CODE_SHELL: CLAUDE_CODE_SHELL_PATH,
|
|
103388
|
+
CLAUDE_AGENT_SDK_CLIENT_APP: clientApp
|
|
103389
|
+
};
|
|
103390
|
+
}
|
|
103391
|
+
function runtimeProcessEnv() {
|
|
103392
|
+
const selected = {};
|
|
103393
|
+
for (const key of CLAUDE_RUNTIME_PROCESS_ENV_KEYS) {
|
|
103394
|
+
const value = process.env[key];
|
|
103395
|
+
if (value !== void 0) {
|
|
103396
|
+
selected[key] = value;
|
|
103397
|
+
}
|
|
103398
|
+
}
|
|
103399
|
+
return selected;
|
|
103400
|
+
}
|
|
103401
|
+
function claudeCodeExecutablePath() {
|
|
103402
|
+
if (process.env.AUTO_AGENT_BRIDGE_TEST_CLAUDE_COMMAND === "1" && process.env.AUTO_CLAUDE_CODE_COMMAND?.trim()) {
|
|
103403
|
+
return process.env.AUTO_CLAUDE_CODE_COMMAND.trim();
|
|
103404
|
+
}
|
|
103405
|
+
return CLAUDE_CODE_EXECUTABLE_PATH;
|
|
103406
|
+
}
|
|
103407
|
+
|
|
102924
103408
|
// src/commands/agent-bridge/harness/claude-code/projector.ts
|
|
102925
103409
|
init_src();
|
|
102926
103410
|
var ClaudeCodeProjector = class {
|
|
@@ -102939,6 +103423,7 @@ var ClaudeCodeProjector = class {
|
|
|
102939
103423
|
activeResponseMessageId = null;
|
|
102940
103424
|
activeParts = /* @__PURE__ */ new Map();
|
|
102941
103425
|
activeToolInputs = /* @__PURE__ */ new Map();
|
|
103426
|
+
suppressedAskUserToolCallIds = /* @__PURE__ */ new Set();
|
|
102942
103427
|
streamedMessageIds = /* @__PURE__ */ new Set();
|
|
102943
103428
|
// The SDK's "[Request interrupted by user]" transcript marker was seen since
|
|
102944
103429
|
// the last terminal result: the very next diagnostic-only
|
|
@@ -102958,6 +103443,7 @@ var ClaudeCodeProjector = class {
|
|
|
102958
103443
|
bridge: context.bridgeInterruptSettling === true
|
|
102959
103444
|
};
|
|
102960
103445
|
const parsed = parseClaudeCodeStreamRecord(message);
|
|
103446
|
+
parsed.projections = this.suppressAskUserProjections(parsed.projections);
|
|
102961
103447
|
const snapshotMessageId = assistantSnapshotMessageId(message);
|
|
102962
103448
|
const suppressStreamed = snapshotMessageId !== null && this.streamedMessageIds.has(snapshotMessageId);
|
|
102963
103449
|
if (message.type === "assistant" && !suppressStreamed) {
|
|
@@ -102990,6 +103476,7 @@ var ClaudeCodeProjector = class {
|
|
|
102990
103476
|
);
|
|
102991
103477
|
}
|
|
102992
103478
|
outputs.push(projectClaudeCodeResult(parsed.result, { interrupted }));
|
|
103479
|
+
this.suppressedAskUserToolCallIds.clear();
|
|
102993
103480
|
this.interruptMarkerSeen = false;
|
|
102994
103481
|
}
|
|
102995
103482
|
return outputs;
|
|
@@ -103074,6 +103561,11 @@ var ClaudeCodeProjector = class {
|
|
|
103074
103561
|
return [uiChunk({ type: `${type}-end`, id })];
|
|
103075
103562
|
}
|
|
103076
103563
|
startToolInput(message) {
|
|
103564
|
+
const askUserToolCallId = askUserMcpToolCallId(message);
|
|
103565
|
+
if (askUserToolCallId) {
|
|
103566
|
+
this.suppressedAskUserToolCallIds.add(askUserToolCallId);
|
|
103567
|
+
return [];
|
|
103568
|
+
}
|
|
103077
103569
|
const started = toolInputStartFromEvent(message);
|
|
103078
103570
|
if (!started) {
|
|
103079
103571
|
return [];
|
|
@@ -103092,6 +103584,32 @@ var ClaudeCodeProjector = class {
|
|
|
103092
103584
|
})
|
|
103093
103585
|
];
|
|
103094
103586
|
}
|
|
103587
|
+
suppressAskUserProjections(projections) {
|
|
103588
|
+
return projections.flatMap((projection) => {
|
|
103589
|
+
if (projection.kind === "tool_call") {
|
|
103590
|
+
const askUserParts = projection.content.parts.filter(
|
|
103591
|
+
(part) => part.type === "tool_call" && (part.name === ASK_USER_TOOL_NAME || part.name === CLAUDE_ASK_USER_TOOL_NAME)
|
|
103592
|
+
);
|
|
103593
|
+
for (const part of askUserParts) {
|
|
103594
|
+
if (part.type === "tool_call" && part.toolCallId) {
|
|
103595
|
+
this.suppressedAskUserToolCallIds.add(part.toolCallId);
|
|
103596
|
+
}
|
|
103597
|
+
}
|
|
103598
|
+
if (askUserParts.length > 0) {
|
|
103599
|
+
return [];
|
|
103600
|
+
}
|
|
103601
|
+
}
|
|
103602
|
+
if (projection.kind === "tool_result") {
|
|
103603
|
+
const suppressed = projection.content.parts.some(
|
|
103604
|
+
(part) => part.type === "tool_result" && part.toolUseId !== null && this.suppressedAskUserToolCallIds.has(part.toolUseId)
|
|
103605
|
+
);
|
|
103606
|
+
if (suppressed) {
|
|
103607
|
+
return [];
|
|
103608
|
+
}
|
|
103609
|
+
}
|
|
103610
|
+
return [projection];
|
|
103611
|
+
});
|
|
103612
|
+
}
|
|
103095
103613
|
finishActiveToolInput(index) {
|
|
103096
103614
|
const active = this.activeToolInputs.get(index);
|
|
103097
103615
|
if (!active) {
|
|
@@ -103288,6 +103806,17 @@ function toolInputStartFromEvent(message) {
|
|
|
103288
103806
|
input: contentBlock.input
|
|
103289
103807
|
};
|
|
103290
103808
|
}
|
|
103809
|
+
function askUserMcpToolCallId(message) {
|
|
103810
|
+
const event = message.event;
|
|
103811
|
+
if (event.type !== "content_block_start") {
|
|
103812
|
+
return null;
|
|
103813
|
+
}
|
|
103814
|
+
const block = event.content_block;
|
|
103815
|
+
if (block.type !== "mcp_tool_use" || typeof block.id !== "string" || typeof block.server_name !== "string" || typeof block.name !== "string" || !isAskUserMcpTool(block.server_name, block.name)) {
|
|
103816
|
+
return null;
|
|
103817
|
+
}
|
|
103818
|
+
return block.id;
|
|
103819
|
+
}
|
|
103291
103820
|
function toolInputDeltaFromDelta(delta) {
|
|
103292
103821
|
if (delta.type !== "input_json_delta") {
|
|
103293
103822
|
return null;
|
|
@@ -103808,78 +104337,6 @@ function serverStatusList(servers, context) {
|
|
|
103808
104337
|
return reported.map((server) => `${server.name}:${server.status}`).join(",");
|
|
103809
104338
|
}
|
|
103810
104339
|
|
|
103811
|
-
// src/commands/agent-bridge/harness/claude-code/options.ts
|
|
103812
|
-
var CLAUDE_AGENT_SDK_CLIENT_APP = "auto-agent-bridge";
|
|
103813
|
-
var CLAUDE_RUNTIME_PROCESS_ENV_KEYS = ["PATH", "HOME"];
|
|
103814
|
-
var CLAUDE_CODE_EXECUTABLE_PATH = "/usr/local/bin/claude";
|
|
103815
|
-
var CLAUDE_CODE_SHELL_PATH = "/bin/bash";
|
|
103816
|
-
var CLAUDE_CODE_DEFAULT_MODEL = "claude-opus-4-8";
|
|
103817
|
-
function claudeAgentOptions(config2, input = {}) {
|
|
103818
|
-
return {
|
|
103819
|
-
...config2.cwd ? { cwd: config2.cwd } : {},
|
|
103820
|
-
...input.resume ? { resume: input.resume } : {},
|
|
103821
|
-
env: claudeProcessEnv(
|
|
103822
|
-
config2.env,
|
|
103823
|
-
input.clientApp ?? CLAUDE_AGENT_SDK_CLIENT_APP
|
|
103824
|
-
),
|
|
103825
|
-
includePartialMessages: true,
|
|
103826
|
-
thinking: { type: "adaptive", display: "summarized" },
|
|
103827
|
-
settings: { showThinkingSummaries: true },
|
|
103828
|
-
model: config2.model?.id ?? CLAUDE_CODE_DEFAULT_MODEL,
|
|
103829
|
-
...config2.reasoningEffort ? { effort: config2.reasoningEffort } : {},
|
|
103830
|
-
permissionMode: "bypassPermissions",
|
|
103831
|
-
allowDangerouslySkipPermissions: true,
|
|
103832
|
-
pathToClaudeCodeExecutable: claudeCodeExecutablePath(),
|
|
103833
|
-
...input.mcpServers ?? config2.mcpServers ? {
|
|
103834
|
-
mcpServers: input.mcpServers ?? config2.mcpServers,
|
|
103835
|
-
strictMcpConfig: true
|
|
103836
|
-
} : {},
|
|
103837
|
-
systemPrompt: {
|
|
103838
|
-
type: "preset",
|
|
103839
|
-
preset: "claude_code",
|
|
103840
|
-
...config2.systemPromptAppend ? { append: config2.systemPromptAppend } : {}
|
|
103841
|
-
},
|
|
103842
|
-
settingSources: [],
|
|
103843
|
-
tools: {
|
|
103844
|
-
type: "preset",
|
|
103845
|
-
preset: "claude_code"
|
|
103846
|
-
},
|
|
103847
|
-
stderr: input.onStderrChunk ?? (() => {
|
|
103848
|
-
})
|
|
103849
|
-
};
|
|
103850
|
-
}
|
|
103851
|
-
function claudeProcessEnv(env, clientApp) {
|
|
103852
|
-
const runtimeEnv = runtimeProcessEnv();
|
|
103853
|
-
return {
|
|
103854
|
-
// Claude Code only needs ambient shell basics from the bridge process.
|
|
103855
|
-
// Dynamic Claude/MCP/session secrets arrive through encrypted bootstrap env.
|
|
103856
|
-
...runtimeEnv,
|
|
103857
|
-
...env,
|
|
103858
|
-
// Claude Code auto-detects a shell when this is absent. Hosted sandboxes run
|
|
103859
|
-
// Bash tool commands, so pin the shell snapshot source to bash instead of
|
|
103860
|
-
// letting zsh profile functions leak into bash snapshots and inherit user
|
|
103861
|
-
// strict-mode options such as `set -u`.
|
|
103862
|
-
CLAUDE_CODE_SHELL: CLAUDE_CODE_SHELL_PATH,
|
|
103863
|
-
CLAUDE_AGENT_SDK_CLIENT_APP: clientApp
|
|
103864
|
-
};
|
|
103865
|
-
}
|
|
103866
|
-
function runtimeProcessEnv() {
|
|
103867
|
-
const selected = {};
|
|
103868
|
-
for (const key of CLAUDE_RUNTIME_PROCESS_ENV_KEYS) {
|
|
103869
|
-
const value = process.env[key];
|
|
103870
|
-
if (value !== void 0) {
|
|
103871
|
-
selected[key] = value;
|
|
103872
|
-
}
|
|
103873
|
-
}
|
|
103874
|
-
return selected;
|
|
103875
|
-
}
|
|
103876
|
-
function claudeCodeExecutablePath() {
|
|
103877
|
-
if (process.env.AUTO_AGENT_BRIDGE_TEST_CLAUDE_COMMAND === "1" && process.env.AUTO_CLAUDE_CODE_COMMAND?.trim()) {
|
|
103878
|
-
return process.env.AUTO_CLAUDE_CODE_COMMAND.trim();
|
|
103879
|
-
}
|
|
103880
|
-
return CLAUDE_CODE_EXECUTABLE_PATH;
|
|
103881
|
-
}
|
|
103882
|
-
|
|
103883
104340
|
// src/commands/agent-bridge/harness/claude-code/stderr.ts
|
|
103884
104341
|
var STDERR_LINE_MAX_CHARS = 400;
|
|
103885
104342
|
var STDERR_FORWARD_MAX_LINES = 200;
|
|
@@ -105055,6 +105512,10 @@ var ClaudeCodeCommandHandler = class {
|
|
|
105055
105512
|
mcpServers: input.claude.mcpServers,
|
|
105056
105513
|
writeOutput: input.writeOutput
|
|
105057
105514
|
});
|
|
105515
|
+
this.askUserServer = new AskUserServer({
|
|
105516
|
+
onQuestionPending: (question) => this.handleAskUserQuestion(question),
|
|
105517
|
+
writeOutput: input.writeOutput
|
|
105518
|
+
});
|
|
105058
105519
|
this.outputBuffer = new AgentBridgeOutputBuffer(input);
|
|
105059
105520
|
this.projector = new ClaudeCodeProjector({
|
|
105060
105521
|
writeOutput: input.writeOutput
|
|
@@ -105067,6 +105528,7 @@ var ClaudeCodeCommandHandler = class {
|
|
|
105067
105528
|
claudeConfig;
|
|
105068
105529
|
claudeMcpServers;
|
|
105069
105530
|
autoMcpShim;
|
|
105531
|
+
askUserServer;
|
|
105070
105532
|
// Selection-change restarts happen in-process, so prefer the live SDK id even
|
|
105071
105533
|
// when the file resume store is stale or temporarily unreadable.
|
|
105072
105534
|
lastObservedAgentId = null;
|
|
@@ -105102,7 +105564,13 @@ var ClaudeCodeCommandHandler = class {
|
|
|
105102
105564
|
return this.outputBuffer.pendingOutputStats();
|
|
105103
105565
|
}
|
|
105104
105566
|
async prepare() {
|
|
105105
|
-
|
|
105567
|
+
const mcpServers = await this.autoMcpShim.prepareClaude();
|
|
105568
|
+
const askUserEndpoint = await this.askUserServer.prepare();
|
|
105569
|
+
this.claudeMcpServers = withClaudeAskUserMcpServer(
|
|
105570
|
+
mcpServers,
|
|
105571
|
+
askUserEndpoint.url,
|
|
105572
|
+
askUserEndpoint.headers
|
|
105573
|
+
);
|
|
105106
105574
|
await this.ensureAgentSession().prepare();
|
|
105107
105575
|
}
|
|
105108
105576
|
shutdown() {
|
|
@@ -105111,6 +105579,7 @@ var ClaudeCodeCommandHandler = class {
|
|
|
105111
105579
|
this.agentSession?.close();
|
|
105112
105580
|
this.agentSession = null;
|
|
105113
105581
|
this.autoMcpShim.close();
|
|
105582
|
+
this.askUserServer.close();
|
|
105114
105583
|
this.settlePendingQuestions("Runtime is shutting down");
|
|
105115
105584
|
}
|
|
105116
105585
|
async handleCommand(rawDelivery) {
|
|
@@ -105170,6 +105639,7 @@ var ClaudeCodeCommandHandler = class {
|
|
|
105170
105639
|
}
|
|
105171
105640
|
if (delivery.kind === "interrupt") {
|
|
105172
105641
|
this.injectedCommands.add(delivery.commandId);
|
|
105642
|
+
this.askUserServer.quarantineAll("turn interrupted");
|
|
105173
105643
|
await this.agentSession?.interruptActiveTurn();
|
|
105174
105644
|
this.input.runtimeLogger?.info(
|
|
105175
105645
|
"agent_bridge_claude_command_interrupt_ready",
|
|
@@ -105378,6 +105848,17 @@ var ClaudeCodeCommandHandler = class {
|
|
|
105378
105848
|
);
|
|
105379
105849
|
return;
|
|
105380
105850
|
}
|
|
105851
|
+
if (this.askUserServer.answer(answer)) {
|
|
105852
|
+
this.agentSession?.noteActiveTurnCommand(delivery.commandId);
|
|
105853
|
+
await this.emitRequiredBridgeOutput(
|
|
105854
|
+
activeContext,
|
|
105855
|
+
projectAskUserAnswer(answer)
|
|
105856
|
+
);
|
|
105857
|
+
this.input.writeOutput?.(
|
|
105858
|
+
`agent_bridge_question_answered tool_use_id=${answer.toolCallId}`
|
|
105859
|
+
);
|
|
105860
|
+
return;
|
|
105861
|
+
}
|
|
105381
105862
|
const message = answerFallbackMessage(answer);
|
|
105382
105863
|
await this.emitRequiredBridgeOutput(activeContext, {
|
|
105383
105864
|
type: "entry",
|
|
@@ -105408,11 +105889,28 @@ var ClaudeCodeCommandHandler = class {
|
|
|
105408
105889
|
}
|
|
105409
105890
|
this.pendingQuestions.clear();
|
|
105410
105891
|
}
|
|
105892
|
+
async handleAskUserQuestion(input) {
|
|
105893
|
+
const activeContext = this.context;
|
|
105894
|
+
if (!activeContext) {
|
|
105895
|
+
throw new Error(
|
|
105896
|
+
"Cannot publish an ask-user question without bridge context"
|
|
105897
|
+
);
|
|
105898
|
+
}
|
|
105899
|
+
this.input.writeOutput?.(
|
|
105900
|
+
`agent_bridge_question_pending tool_use_id=${input.id}`
|
|
105901
|
+
);
|
|
105902
|
+
for (const projection of projectAskUserQuestion(input)) {
|
|
105903
|
+
await this.emitRequiredBridgeOutput(activeContext, projection);
|
|
105904
|
+
}
|
|
105905
|
+
}
|
|
105411
105906
|
// Permission callback for the Claude Agent SDK session. The sessions with
|
|
105412
105907
|
// bypassPermissions, so regular tools are auto-approved and only the
|
|
105413
105908
|
// AskUserQuestion tool reaches this callback for a real decision: it parks
|
|
105414
105909
|
// the SDK on a promise that an `answer` bridge command later resolves.
|
|
105415
105910
|
canUseTool = (toolName, toolInput, options) => {
|
|
105911
|
+
if (toolName === CLAUDE_ASK_USER_TOOL_NAME) {
|
|
105912
|
+
return Promise.resolve({ behavior: "allow", updatedInput: toolInput });
|
|
105913
|
+
}
|
|
105416
105914
|
if (toolName !== ASK_USER_QUESTION_TOOL_NAME) {
|
|
105417
105915
|
return Promise.resolve({ behavior: "allow", updatedInput: toolInput });
|
|
105418
105916
|
}
|
|
@@ -105491,6 +105989,9 @@ var ClaudeCodeCommandHandler = class {
|
|
|
105491
105989
|
}
|
|
105492
105990
|
this.persistAgentId(activeContext, message);
|
|
105493
105991
|
this.trackReadState(activeContext, message);
|
|
105992
|
+
if (message.type === "result") {
|
|
105993
|
+
this.askUserServer.quarantineAll("turn ended");
|
|
105994
|
+
}
|
|
105494
105995
|
let projections;
|
|
105495
105996
|
try {
|
|
105496
105997
|
projections = this.projector.project(message, {
|
|
@@ -105510,6 +106011,7 @@ var ClaudeCodeCommandHandler = class {
|
|
|
105510
106011
|
}
|
|
105511
106012
|
}
|
|
105512
106013
|
async handleAgentError(error51) {
|
|
106014
|
+
this.askUserServer.quarantineAll("harness session failed");
|
|
105513
106015
|
this.input.writeOutput?.(
|
|
105514
106016
|
`agent_bridge_claude_sdk_failed error=${error51 instanceof Error ? error51.message : String(error51)}`
|
|
105515
106017
|
);
|
|
@@ -105629,6 +106131,7 @@ var ClaudeCodeCommandHandler = class {
|
|
|
105629
106131
|
onMessage: (message, meta3) => this.handleAgentMessage(message, meta3),
|
|
105630
106132
|
onError: (error51) => this.handleAgentError(error51),
|
|
105631
106133
|
onExit: () => {
|
|
106134
|
+
this.askUserServer.quarantineAll("harness child exited");
|
|
105632
106135
|
if (this.agentSession === session) {
|
|
105633
106136
|
this.agentSession = null;
|
|
105634
106137
|
}
|
|
@@ -105657,6 +106160,7 @@ var ClaudeCodeCommandHandler = class {
|
|
|
105657
106160
|
this.requireResumeForNextAgentSession = this.lastObservedAgentId !== null;
|
|
105658
106161
|
this.agentSession?.close();
|
|
105659
106162
|
this.agentSession = null;
|
|
106163
|
+
this.askUserServer.quarantineAll("harness session restarted");
|
|
105660
106164
|
this.settlePendingQuestions("The runtime restarted to change model");
|
|
105661
106165
|
this.input.writeOutput?.(
|
|
105662
106166
|
`agent_bridge_claude_model_selection_changed provider=${next.model?.provider ?? ""} model=${next.model?.id ?? ""} reasoning_effort=${next.reasoningEffort ?? ""}`
|
|
@@ -105850,6 +106354,9 @@ var CodexProjector = class {
|
|
|
105850
106354
|
toolMetadata: statusMetadata(item.status)
|
|
105851
106355
|
});
|
|
105852
106356
|
case "mcpToolCall":
|
|
106357
|
+
if (isAskUserMcpTool(item.server, item.tool)) {
|
|
106358
|
+
return [];
|
|
106359
|
+
}
|
|
105853
106360
|
return this.projectToolItem({
|
|
105854
106361
|
phase,
|
|
105855
106362
|
itemId: item.id,
|
|
@@ -106193,6 +106700,9 @@ function renderCodexConfigToml(config2) {
|
|
|
106193
106700
|
lines.push("");
|
|
106194
106701
|
lines.push(`[mcp_servers.${tomlKey(name)}]`);
|
|
106195
106702
|
lines.push(`url = ${tomlString(server.url)}`);
|
|
106703
|
+
lines.push(
|
|
106704
|
+
`tool_timeout_sec = ${validatedMcpToolTimeoutSeconds(HARNESS_MCP_TOOL_TIMEOUT_SECONDS)}`
|
|
106705
|
+
);
|
|
106196
106706
|
const persistedHeaders = Object.fromEntries(
|
|
106197
106707
|
Object.entries(server.headers ?? {}).filter(
|
|
106198
106708
|
([name2]) => name2 !== AGENT_BRIDGE_MCP_CAPABILITY_HEADER
|
|
@@ -106206,20 +106716,30 @@ function renderCodexConfigToml(config2) {
|
|
|
106206
106716
|
`;
|
|
106207
106717
|
}
|
|
106208
106718
|
function turnOnlyMcpConfig(mcpServers) {
|
|
106719
|
+
const hasTurnOnlyCapability = Object.values(mcpServers ?? {}).some(
|
|
106720
|
+
(server) => server.headers?.[AGENT_BRIDGE_MCP_CAPABILITY_HEADER] !== void 0
|
|
106721
|
+
);
|
|
106722
|
+
if (!hasTurnOnlyCapability) {
|
|
106723
|
+
return void 0;
|
|
106724
|
+
}
|
|
106209
106725
|
const servers = Object.fromEntries(
|
|
106210
|
-
Object.entries(mcpServers ?? {}).
|
|
106726
|
+
Object.entries(mcpServers ?? {}).map(([name, server]) => {
|
|
106211
106727
|
const capability = server.headers?.[AGENT_BRIDGE_MCP_CAPABILITY_HEADER];
|
|
106212
|
-
return
|
|
106213
|
-
|
|
106214
|
-
|
|
106215
|
-
|
|
106216
|
-
|
|
106728
|
+
return [
|
|
106729
|
+
name,
|
|
106730
|
+
{
|
|
106731
|
+
url: server.url,
|
|
106732
|
+
tool_timeout_sec: validatedMcpToolTimeoutSeconds(
|
|
106733
|
+
HARNESS_MCP_TOOL_TIMEOUT_SECONDS
|
|
106734
|
+
),
|
|
106735
|
+
...server.headers ? {
|
|
106217
106736
|
http_headers: {
|
|
106218
|
-
|
|
106737
|
+
...server.headers,
|
|
106738
|
+
...capability ? { [AGENT_BRIDGE_MCP_CAPABILITY_HEADER]: capability } : {}
|
|
106219
106739
|
}
|
|
106220
|
-
}
|
|
106221
|
-
|
|
106222
|
-
]
|
|
106740
|
+
} : {}
|
|
106741
|
+
}
|
|
106742
|
+
];
|
|
106223
106743
|
})
|
|
106224
106744
|
);
|
|
106225
106745
|
return Object.keys(servers).length > 0 ? { mcp_servers: servers } : void 0;
|
|
@@ -106813,7 +107333,7 @@ var CodexAgentBridgeSessionImpl = class {
|
|
|
106813
107333
|
return;
|
|
106814
107334
|
} catch (error51) {
|
|
106815
107335
|
this.input.writeOutput?.(
|
|
106816
|
-
`agent_bridge_codex_resume_fallback thread_id=${this.input.resumeThreadId} error=${
|
|
107336
|
+
`agent_bridge_codex_resume_fallback thread_id=${this.input.resumeThreadId} error=${errorMessage3(error51)}`
|
|
106817
107337
|
);
|
|
106818
107338
|
}
|
|
106819
107339
|
}
|
|
@@ -106891,7 +107411,7 @@ var CodexAgentBridgeSessionImpl = class {
|
|
|
106891
107411
|
this.activeCommandIds = previousCommandIds;
|
|
106892
107412
|
this.publishActiveTurnCommandIds();
|
|
106893
107413
|
this.input.writeOutput?.(
|
|
106894
|
-
`agent_bridge_codex_steer_failed error=${
|
|
107414
|
+
`agent_bridge_codex_steer_failed error=${errorMessage3(error51)}`
|
|
106895
107415
|
);
|
|
106896
107416
|
}
|
|
106897
107417
|
if (this.activeTurnId) {
|
|
@@ -106905,7 +107425,7 @@ var CodexAgentBridgeSessionImpl = class {
|
|
|
106905
107425
|
this.input.writeOutput?.("agent_bridge_codex_interrupted");
|
|
106906
107426
|
} catch (error51) {
|
|
106907
107427
|
this.input.writeOutput?.(
|
|
106908
|
-
`agent_bridge_codex_interrupt_failed error=${
|
|
107428
|
+
`agent_bridge_codex_interrupt_failed error=${errorMessage3(error51)}`
|
|
106909
107429
|
);
|
|
106910
107430
|
}
|
|
106911
107431
|
}
|
|
@@ -106980,7 +107500,7 @@ var CodexAgentBridgeSessionImpl = class {
|
|
|
106980
107500
|
message = parseCodexServerFrame(JSON.parse(line));
|
|
106981
107501
|
} catch (error51) {
|
|
106982
107502
|
this.input.writeOutput?.(
|
|
106983
|
-
`agent_bridge_codex_parse_failed error=${
|
|
107503
|
+
`agent_bridge_codex_parse_failed error=${errorMessage3(error51)}`
|
|
106984
107504
|
);
|
|
106985
107505
|
return;
|
|
106986
107506
|
}
|
|
@@ -107175,7 +107695,7 @@ var CodexAgentBridgeSessionImpl = class {
|
|
|
107175
107695
|
);
|
|
107176
107696
|
} catch (error51) {
|
|
107177
107697
|
this.input.writeOutput?.(
|
|
107178
|
-
`agent_bridge_codex_turn_retry_failed attempt=${input.attempt} error=${
|
|
107698
|
+
`agent_bridge_codex_turn_retry_failed attempt=${input.attempt} error=${errorMessage3(error51)}`
|
|
107179
107699
|
);
|
|
107180
107700
|
this.turnRetry = null;
|
|
107181
107701
|
this.clearPendingRetryableError();
|
|
@@ -107390,7 +107910,7 @@ function threadIdFromResult(result) {
|
|
|
107390
107910
|
const id = thread.id;
|
|
107391
107911
|
return typeof id === "string" && id.length > 0 ? id : null;
|
|
107392
107912
|
}
|
|
107393
|
-
function
|
|
107913
|
+
function errorMessage3(error51) {
|
|
107394
107914
|
return error51 instanceof Error ? error51.message : String(error51);
|
|
107395
107915
|
}
|
|
107396
107916
|
function toErrnoException(error51) {
|
|
@@ -107416,6 +107936,11 @@ var CodexCommandHandler = class {
|
|
|
107416
107936
|
mcpServers: input.codex.mcpServers,
|
|
107417
107937
|
writeOutput: input.writeOutput
|
|
107418
107938
|
});
|
|
107939
|
+
this.askUserServer = new AskUserServer({
|
|
107940
|
+
onQuestionPending: (question) => this.handleAskUserQuestion(question),
|
|
107941
|
+
onQuestionSettled: ({ id }) => this.pendingQuestions.delete(id),
|
|
107942
|
+
writeOutput: input.writeOutput
|
|
107943
|
+
});
|
|
107419
107944
|
this.outputBuffer = new AgentBridgeOutputBuffer(input);
|
|
107420
107945
|
}
|
|
107421
107946
|
input;
|
|
@@ -107423,10 +107948,12 @@ var CodexCommandHandler = class {
|
|
|
107423
107948
|
session = null;
|
|
107424
107949
|
codexConfig;
|
|
107425
107950
|
autoMcpShim;
|
|
107951
|
+
askUserServer;
|
|
107426
107952
|
injectedCommands = /* @__PURE__ */ new Set();
|
|
107427
107953
|
// itemId -> JSON-RPC request id of the parked approval request, so an `answer`
|
|
107428
107954
|
// command keyed by toolCallId (= itemId) can resolve the right server request.
|
|
107429
107955
|
pendingApprovals = /* @__PURE__ */ new Map();
|
|
107956
|
+
pendingQuestions = /* @__PURE__ */ new Set();
|
|
107430
107957
|
outputBuffer;
|
|
107431
107958
|
projector = new CodexProjector();
|
|
107432
107959
|
livenessTicker = null;
|
|
@@ -107448,9 +107975,23 @@ var CodexCommandHandler = class {
|
|
|
107448
107975
|
return this.outputBuffer.pendingOutputStats();
|
|
107449
107976
|
}
|
|
107450
107977
|
async prepare() {
|
|
107978
|
+
const mcpServers = await this.autoMcpShim.prepare();
|
|
107979
|
+
if (mcpServers?.[ASK_USER_MCP_SERVER_NAME]) {
|
|
107980
|
+
throw new Error(
|
|
107981
|
+
`MCP server name ${ASK_USER_MCP_SERVER_NAME} is reserved by the harness`
|
|
107982
|
+
);
|
|
107983
|
+
}
|
|
107984
|
+
const askUserEndpoint = await this.askUserServer.prepare();
|
|
107451
107985
|
this.codexConfig = {
|
|
107452
107986
|
...this.codexConfig,
|
|
107453
|
-
mcpServers:
|
|
107987
|
+
mcpServers: {
|
|
107988
|
+
...mcpServers,
|
|
107989
|
+
[ASK_USER_MCP_SERVER_NAME]: {
|
|
107990
|
+
type: "http",
|
|
107991
|
+
url: askUserEndpoint.url,
|
|
107992
|
+
headers: askUserEndpoint.headers
|
|
107993
|
+
}
|
|
107994
|
+
}
|
|
107454
107995
|
};
|
|
107455
107996
|
await this.ensureSession().prepare();
|
|
107456
107997
|
}
|
|
@@ -107460,7 +108001,9 @@ var CodexCommandHandler = class {
|
|
|
107460
108001
|
this.session?.close();
|
|
107461
108002
|
this.session = null;
|
|
107462
108003
|
this.autoMcpShim.close();
|
|
108004
|
+
this.askUserServer.close();
|
|
107463
108005
|
this.pendingApprovals.clear();
|
|
108006
|
+
this.pendingQuestions.clear();
|
|
107464
108007
|
}
|
|
107465
108008
|
async handleCommand(rawDelivery) {
|
|
107466
108009
|
const delivery = RuntimeBridgeCommandDeliverySchema.parse(rawDelivery);
|
|
@@ -107477,6 +108020,7 @@ var CodexCommandHandler = class {
|
|
|
107477
108020
|
}
|
|
107478
108021
|
if (delivery.kind === "interrupt") {
|
|
107479
108022
|
this.injectedCommands.add(delivery.commandId);
|
|
108023
|
+
this.askUserServer.quarantineAll("turn interrupted");
|
|
107480
108024
|
await this.session?.interruptActiveTurn();
|
|
107481
108025
|
return commandAck({ delivery, socketId, status: "injected" });
|
|
107482
108026
|
}
|
|
@@ -107520,7 +108064,7 @@ var CodexCommandHandler = class {
|
|
|
107520
108064
|
delivery,
|
|
107521
108065
|
socketId,
|
|
107522
108066
|
status: "failed",
|
|
107523
|
-
error:
|
|
108067
|
+
error: errorMessage4(error51)
|
|
107524
108068
|
});
|
|
107525
108069
|
}
|
|
107526
108070
|
return commandAck({ delivery, socketId, status: "injected" });
|
|
@@ -107553,6 +108097,11 @@ var CodexCommandHandler = class {
|
|
|
107553
108097
|
this.input.writeOutput?.(
|
|
107554
108098
|
`agent_bridge_codex_question_answered tool_use_id=${payload.data.toolCallId} decision=${decision}`
|
|
107555
108099
|
);
|
|
108100
|
+
} else if (this.pendingQuestions.has(payload.data.toolCallId) && this.askUserServer.answer(payload.data)) {
|
|
108101
|
+
await this.emit(activeContext, projectAskUserAnswer(payload.data));
|
|
108102
|
+
this.input.writeOutput?.(
|
|
108103
|
+
`agent_bridge_codex_question_answered tool_use_id=${payload.data.toolCallId} decision=answered`
|
|
108104
|
+
);
|
|
107556
108105
|
} else {
|
|
107557
108106
|
const message = answerFallbackMessage2(payload.data);
|
|
107558
108107
|
await this.emitUserMessageEntry(
|
|
@@ -107570,7 +108119,7 @@ var CodexCommandHandler = class {
|
|
|
107570
108119
|
delivery,
|
|
107571
108120
|
socketId,
|
|
107572
108121
|
status: "failed",
|
|
107573
|
-
error:
|
|
108122
|
+
error: errorMessage4(error51)
|
|
107574
108123
|
});
|
|
107575
108124
|
}
|
|
107576
108125
|
return commandAck({ delivery, socketId, status: "injected" });
|
|
@@ -107598,6 +108147,9 @@ var CodexCommandHandler = class {
|
|
|
107598
108147
|
if (notification.type === "tokenUsage") {
|
|
107599
108148
|
return;
|
|
107600
108149
|
}
|
|
108150
|
+
if (notification.type === "turnCompleted") {
|
|
108151
|
+
this.askUserServer.quarantineAll("turn ended");
|
|
108152
|
+
}
|
|
107601
108153
|
for (const projection of this.projector.project(notification)) {
|
|
107602
108154
|
await this.emit(activeContext, projection);
|
|
107603
108155
|
}
|
|
@@ -107615,9 +108167,25 @@ var CodexCommandHandler = class {
|
|
|
107615
108167
|
await this.emit(activeContext, projection);
|
|
107616
108168
|
}
|
|
107617
108169
|
}
|
|
108170
|
+
async handleAskUserQuestion(input) {
|
|
108171
|
+
const activeContext = this.context;
|
|
108172
|
+
if (!activeContext) {
|
|
108173
|
+
throw new Error(
|
|
108174
|
+
"Cannot publish an ask-user question without bridge context"
|
|
108175
|
+
);
|
|
108176
|
+
}
|
|
108177
|
+
this.pendingQuestions.add(input.id);
|
|
108178
|
+
this.input.writeOutput?.(
|
|
108179
|
+
`agent_bridge_codex_question_pending tool_use_id=${input.id}`
|
|
108180
|
+
);
|
|
108181
|
+
for (const projection of projectAskUserQuestion(input)) {
|
|
108182
|
+
await this.emitRequired(activeContext, projection);
|
|
108183
|
+
}
|
|
108184
|
+
}
|
|
107618
108185
|
async handleSessionError(error51) {
|
|
108186
|
+
this.askUserServer.quarantineAll("harness session failed");
|
|
107619
108187
|
this.input.writeOutput?.(
|
|
107620
|
-
`agent_bridge_codex_session_failed error=${
|
|
108188
|
+
`agent_bridge_codex_session_failed error=${errorMessage4(error51)}`
|
|
107621
108189
|
);
|
|
107622
108190
|
const activeContext = this.context;
|
|
107623
108191
|
if (!activeContext) {
|
|
@@ -107625,7 +108193,7 @@ var CodexCommandHandler = class {
|
|
|
107625
108193
|
}
|
|
107626
108194
|
await this.emit(
|
|
107627
108195
|
activeContext,
|
|
107628
|
-
this.projector.projectSessionFailure(
|
|
108196
|
+
this.projector.projectSessionFailure(errorMessage4(error51))
|
|
107629
108197
|
);
|
|
107630
108198
|
}
|
|
107631
108199
|
async emitLivenessBeat() {
|
|
@@ -107650,10 +108218,16 @@ var CodexCommandHandler = class {
|
|
|
107650
108218
|
await this.outputBuffer.emitProjection(activeContext, projection);
|
|
107651
108219
|
} catch (error51) {
|
|
107652
108220
|
this.input.writeOutput?.(
|
|
107653
|
-
`agent_bridge_output_emit_failed error=${
|
|
108221
|
+
`agent_bridge_output_emit_failed error=${errorMessage4(error51)}`
|
|
107654
108222
|
);
|
|
107655
108223
|
}
|
|
107656
108224
|
}
|
|
108225
|
+
async emitRequired(activeContext, projection) {
|
|
108226
|
+
await this.outputBuffer.emitProjection(activeContext, projection, {
|
|
108227
|
+
discardOnFailure: true,
|
|
108228
|
+
requireDrain: true
|
|
108229
|
+
});
|
|
108230
|
+
}
|
|
107657
108231
|
ensureSession() {
|
|
107658
108232
|
if (this.session) {
|
|
107659
108233
|
return this.session;
|
|
@@ -107670,6 +108244,7 @@ var CodexCommandHandler = class {
|
|
|
107670
108244
|
onUsageTurnChanged: (turnId) => this.emitUsageTurn(turnId),
|
|
107671
108245
|
onError: (error51) => this.handleSessionError(error51),
|
|
107672
108246
|
onExit: () => {
|
|
108247
|
+
this.askUserServer.quarantineAll("harness child exited");
|
|
107673
108248
|
if (this.session === session) {
|
|
107674
108249
|
this.session = null;
|
|
107675
108250
|
}
|
|
@@ -107697,7 +108272,9 @@ var CodexCommandHandler = class {
|
|
|
107697
108272
|
this.skipResumeForNextSession = true;
|
|
107698
108273
|
this.session?.close();
|
|
107699
108274
|
this.session = null;
|
|
108275
|
+
this.askUserServer.quarantineAll("harness session restarted");
|
|
107700
108276
|
this.pendingApprovals.clear();
|
|
108277
|
+
this.pendingQuestions.clear();
|
|
107701
108278
|
this.input.writeOutput?.(
|
|
107702
108279
|
`agent_bridge_codex_model_selection_changed provider=${next.model?.provider ?? ""} model=${next.model?.id ?? ""} reasoning_effort=${next.reasoningEffort ?? ""}`
|
|
107703
108280
|
);
|
|
@@ -107712,7 +108289,7 @@ var CodexCommandHandler = class {
|
|
|
107712
108289
|
return store.read(activeContext.sessionId) ?? void 0;
|
|
107713
108290
|
} catch (error51) {
|
|
107714
108291
|
this.input.writeOutput?.(
|
|
107715
|
-
`agent_bridge_codex_thread_read_failed error=${
|
|
108292
|
+
`agent_bridge_codex_thread_read_failed error=${errorMessage4(error51)}`
|
|
107716
108293
|
);
|
|
107717
108294
|
return void 0;
|
|
107718
108295
|
}
|
|
@@ -107727,7 +108304,7 @@ var CodexCommandHandler = class {
|
|
|
107727
108304
|
store.write({ sessionId: activeContext.sessionId, threadId });
|
|
107728
108305
|
} catch (error51) {
|
|
107729
108306
|
this.input.writeOutput?.(
|
|
107730
|
-
`agent_bridge_codex_thread_persist_failed error=${
|
|
108307
|
+
`agent_bridge_codex_thread_persist_failed error=${errorMessage4(error51)}`
|
|
107731
108308
|
);
|
|
107732
108309
|
}
|
|
107733
108310
|
}
|
|
@@ -107769,7 +108346,7 @@ function deliveryMode2(delivery) {
|
|
|
107769
108346
|
}
|
|
107770
108347
|
return "interrupt";
|
|
107771
108348
|
}
|
|
107772
|
-
function
|
|
108349
|
+
function errorMessage4(error51) {
|
|
107773
108350
|
return error51 instanceof Error ? error51.message : String(error51);
|
|
107774
108351
|
}
|
|
107775
108352
|
|