@buildautomaton/cli 0.1.75 → 0.1.77
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.js +196 -166
- package/dist/cli.js.map +4 -4
- package/dist/index.js +196 -166
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -31064,7 +31064,7 @@ var {
|
|
|
31064
31064
|
} = import_index.default;
|
|
31065
31065
|
|
|
31066
31066
|
// src/cli-version.ts
|
|
31067
|
-
var CLI_VERSION = "0.1.
|
|
31067
|
+
var CLI_VERSION = "0.1.77".length > 0 ? "0.1.77" : "0.0.0-dev";
|
|
31068
31068
|
|
|
31069
31069
|
// src/cli/defaults.ts
|
|
31070
31070
|
var DEFAULT_API_URL = process.env.BUILDAUTOMATON_API_URL ?? "https://api.buildautomaton.com";
|
|
@@ -36205,9 +36205,12 @@ function cancelPendingCursorPermissionRequests(pendingRequests2, respond) {
|
|
|
36205
36205
|
// src/agents/acp/clients/cursor/create-cursor-acp-handle.ts
|
|
36206
36206
|
function createCursorAcpHandle(options) {
|
|
36207
36207
|
let teardownStarted = false;
|
|
36208
|
+
let cancelFallback = null;
|
|
36208
36209
|
async function disconnectGracefully() {
|
|
36209
36210
|
if (teardownStarted) return;
|
|
36210
36211
|
teardownStarted = true;
|
|
36212
|
+
if (cancelFallback) clearTimeout(cancelFallback);
|
|
36213
|
+
cancelFallback = null;
|
|
36211
36214
|
cancelPendingCursorPermissionRequests(options.pendingRequests, options.wire.respond);
|
|
36212
36215
|
try {
|
|
36213
36216
|
await options.transport.cancelSession(options.sessionId);
|
|
@@ -36233,7 +36236,17 @@ function createCursorAcpHandle(options) {
|
|
|
36233
36236
|
},
|
|
36234
36237
|
async cancel() {
|
|
36235
36238
|
cancelPendingCursorPermissionRequests(options.pendingRequests, options.wire.respond);
|
|
36236
|
-
|
|
36239
|
+
try {
|
|
36240
|
+
await options.transport.cancelSession(options.sessionId);
|
|
36241
|
+
} catch {
|
|
36242
|
+
}
|
|
36243
|
+
if (cancelFallback) return;
|
|
36244
|
+
cancelFallback = setTimeout(() => {
|
|
36245
|
+
if (options.child.exitCode == null && options.child.signalCode == null) {
|
|
36246
|
+
void disconnectGracefully();
|
|
36247
|
+
}
|
|
36248
|
+
}, 5e3);
|
|
36249
|
+
cancelFallback.unref?.();
|
|
36237
36250
|
},
|
|
36238
36251
|
resolveRequest(requestId, result) {
|
|
36239
36252
|
if (options.pendingRequests.has(requestId)) {
|
|
@@ -37989,6 +38002,66 @@ function augmentPromptResultAuthFields(agentType, errorText) {
|
|
|
37989
38002
|
return { agentAuthRequired: true, agentType };
|
|
37990
38003
|
}
|
|
37991
38004
|
|
|
38005
|
+
// src/agents/planning/submit-planning-todos-for-turn.ts
|
|
38006
|
+
async function submitPlanningTodosForTurn(params) {
|
|
38007
|
+
const token = params.getCloudAccessToken();
|
|
38008
|
+
if (!token.trim()) return { ok: false, error: "Missing cloud access token" };
|
|
38009
|
+
const base = params.cloudApiBaseUrl.replace(/\/$/, "");
|
|
38010
|
+
const url2 = `${base}/internal/sessions/todos/submit`;
|
|
38011
|
+
const res = await fetch(url2, {
|
|
38012
|
+
method: "POST",
|
|
38013
|
+
headers: {
|
|
38014
|
+
Authorization: `Bearer ${token}`,
|
|
38015
|
+
"Content-Type": "application/json"
|
|
38016
|
+
},
|
|
38017
|
+
body: JSON.stringify({
|
|
38018
|
+
sessionId: params.sessionId,
|
|
38019
|
+
turnId: params.turnId,
|
|
38020
|
+
items: params.items
|
|
38021
|
+
})
|
|
38022
|
+
});
|
|
38023
|
+
if (!res.ok) {
|
|
38024
|
+
const body = await res.json().catch(() => null);
|
|
38025
|
+
return { ok: false, error: body?.error ?? `Planning todo submit failed (${res.status})` };
|
|
38026
|
+
}
|
|
38027
|
+
return { ok: true };
|
|
38028
|
+
}
|
|
38029
|
+
|
|
38030
|
+
// src/agents/planning/maybe-submit-planning-todos-after-agent-success.ts
|
|
38031
|
+
async function maybeSubmitPlanningTodosAfterAgentSuccess(params) {
|
|
38032
|
+
const { sessionId, runId, resultSuccess, output, cloudApiBaseUrl, getCloudAccessToken, log: log2 } = params;
|
|
38033
|
+
const buffered = runId ? getPlanningSessionTurnOutput(runId) : "";
|
|
38034
|
+
const outputFromResult = typeof output === "string" ? output : "";
|
|
38035
|
+
const outputStr = buffered.trim() !== "" ? buffered : outputFromResult;
|
|
38036
|
+
if (!sessionId || !runId || !resultSuccess || outputStr.trim() === "") {
|
|
38037
|
+
return { submitted: false, suppressOutput: false };
|
|
38038
|
+
}
|
|
38039
|
+
if (!cloudApiBaseUrl || !getCloudAccessToken) {
|
|
38040
|
+
return { submitted: false, suppressOutput: false };
|
|
38041
|
+
}
|
|
38042
|
+
const items = parsePlanningTodoAgentJson(outputStr);
|
|
38043
|
+
if (items.length === 0) {
|
|
38044
|
+
return { submitted: false, suppressOutput: false };
|
|
38045
|
+
}
|
|
38046
|
+
const result = await submitPlanningTodosForTurn({
|
|
38047
|
+
sessionId,
|
|
38048
|
+
turnId: runId,
|
|
38049
|
+
items,
|
|
38050
|
+
cloudApiBaseUrl,
|
|
38051
|
+
getCloudAccessToken
|
|
38052
|
+
});
|
|
38053
|
+
if (!result.ok) {
|
|
38054
|
+
log2(`[Agent] Planning todo submit failed: ${result.error}`);
|
|
38055
|
+
return { submitted: false, suppressOutput: false };
|
|
38056
|
+
}
|
|
38057
|
+
if (runId) consumePlanningSessionTurnOutput(runId);
|
|
38058
|
+
log2(`[Agent] Planning session: stored ${items.length} todo(s) via internal API`);
|
|
38059
|
+
return { submitted: true, suppressOutput: true };
|
|
38060
|
+
}
|
|
38061
|
+
|
|
38062
|
+
// src/agents/acp/prompts/report-post-turn-enrichment.ts
|
|
38063
|
+
init_yield_to_event_loop();
|
|
38064
|
+
|
|
37992
38065
|
// src/git/git-runtime.ts
|
|
37993
38066
|
init_cli_process_interrupt();
|
|
37994
38067
|
var activeGitChildProcesses = /* @__PURE__ */ new Set();
|
|
@@ -38325,6 +38398,7 @@ async function loadPreTurnSnapshot(options) {
|
|
|
38325
38398
|
}
|
|
38326
38399
|
return data;
|
|
38327
38400
|
} catch (e) {
|
|
38401
|
+
if (e.code === "ENOENT") return null;
|
|
38328
38402
|
log2(
|
|
38329
38403
|
`[turn-diff] No pre-turn snapshot for run ${runId.slice(0, 8)}\u2026: ${e instanceof Error ? e.message : String(e)}`
|
|
38330
38404
|
);
|
|
@@ -38350,61 +38424,30 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
|
|
|
38350
38424
|
});
|
|
38351
38425
|
}
|
|
38352
38426
|
|
|
38353
|
-
// src/agents/
|
|
38354
|
-
|
|
38355
|
-
|
|
38356
|
-
|
|
38357
|
-
|
|
38358
|
-
|
|
38359
|
-
|
|
38360
|
-
|
|
38361
|
-
|
|
38362
|
-
|
|
38363
|
-
|
|
38364
|
-
|
|
38365
|
-
|
|
38366
|
-
|
|
38367
|
-
|
|
38368
|
-
|
|
38369
|
-
|
|
38370
|
-
|
|
38371
|
-
|
|
38372
|
-
|
|
38373
|
-
|
|
38374
|
-
}
|
|
38375
|
-
|
|
38376
|
-
}
|
|
38377
|
-
|
|
38378
|
-
// src/agents/planning/maybe-submit-planning-todos-after-agent-success.ts
|
|
38379
|
-
async function maybeSubmitPlanningTodosAfterAgentSuccess(params) {
|
|
38380
|
-
const { sessionId, runId, resultSuccess, output, cloudApiBaseUrl, getCloudAccessToken, log: log2 } = params;
|
|
38381
|
-
const buffered = runId ? getPlanningSessionTurnOutput(runId) : "";
|
|
38382
|
-
const outputFromResult = typeof output === "string" ? output : "";
|
|
38383
|
-
const outputStr = buffered.trim() !== "" ? buffered : outputFromResult;
|
|
38384
|
-
if (!sessionId || !runId || !resultSuccess || outputStr.trim() === "") {
|
|
38385
|
-
return { submitted: false, suppressOutput: false };
|
|
38386
|
-
}
|
|
38387
|
-
if (!cloudApiBaseUrl || !getCloudAccessToken) {
|
|
38388
|
-
return { submitted: false, suppressOutput: false };
|
|
38389
|
-
}
|
|
38390
|
-
const items = parsePlanningTodoAgentJson(outputStr);
|
|
38391
|
-
if (items.length === 0) {
|
|
38392
|
-
return { submitted: false, suppressOutput: false };
|
|
38393
|
-
}
|
|
38394
|
-
const result = await submitPlanningTodosForTurn({
|
|
38395
|
-
sessionId,
|
|
38396
|
-
turnId: runId,
|
|
38397
|
-
items,
|
|
38398
|
-
cloudApiBaseUrl,
|
|
38399
|
-
getCloudAccessToken
|
|
38427
|
+
// src/agents/acp/prompts/report-post-turn-enrichment.ts
|
|
38428
|
+
function reportPostTurnEnrichment(options) {
|
|
38429
|
+
void (async () => {
|
|
38430
|
+
const {
|
|
38431
|
+
sessionId,
|
|
38432
|
+
runId,
|
|
38433
|
+
agentCwd,
|
|
38434
|
+
result,
|
|
38435
|
+
sendSessionUpdate,
|
|
38436
|
+
log: log2
|
|
38437
|
+
} = options;
|
|
38438
|
+
await yieldToEventLoop();
|
|
38439
|
+
if (sessionId && runId && sendSessionUpdate && agentCwd && result.success) {
|
|
38440
|
+
await collectTurnGitDiffFromPreTurnSnapshot({
|
|
38441
|
+
sessionId,
|
|
38442
|
+
runId,
|
|
38443
|
+
agentCwd,
|
|
38444
|
+
sendSessionUpdate,
|
|
38445
|
+
log: log2
|
|
38446
|
+
});
|
|
38447
|
+
}
|
|
38448
|
+
})().catch((error40) => {
|
|
38449
|
+
options.log(`[Agent] Post-turn enrichment failed: ${error40 instanceof Error ? error40.message : String(error40)}`);
|
|
38400
38450
|
});
|
|
38401
|
-
if (!result.ok) {
|
|
38402
|
-
log2(`[Agent] Planning todo submit failed: ${result.error}`);
|
|
38403
|
-
return { submitted: false, suppressOutput: false };
|
|
38404
|
-
}
|
|
38405
|
-
if (runId) consumePlanningSessionTurnOutput(runId);
|
|
38406
|
-
log2(`[Agent] Planning session: stored ${items.length} todo(s) via internal API`);
|
|
38407
|
-
return { submitted: true, suppressOutput: true };
|
|
38408
38451
|
}
|
|
38409
38452
|
|
|
38410
38453
|
// src/agents/acp/prompts/finalize-and-send-prompt-result.ts
|
|
@@ -38424,16 +38467,7 @@ async function finalizeAndSendPromptResult(params) {
|
|
|
38424
38467
|
sendSessionUpdate,
|
|
38425
38468
|
log: log2
|
|
38426
38469
|
} = params;
|
|
38427
|
-
|
|
38428
|
-
await collectTurnGitDiffFromPreTurnSnapshot({
|
|
38429
|
-
sessionId,
|
|
38430
|
-
runId,
|
|
38431
|
-
agentCwd,
|
|
38432
|
-
sendSessionUpdate,
|
|
38433
|
-
log: log2
|
|
38434
|
-
});
|
|
38435
|
-
}
|
|
38436
|
-
const planningTodosSubmit = await maybeSubmitPlanningTodosAfterAgentSuccess({
|
|
38470
|
+
const planningTodosSubmit = isPlanningSession ? await maybeSubmitPlanningTodosAfterAgentSuccess({
|
|
38437
38471
|
sessionId,
|
|
38438
38472
|
runId,
|
|
38439
38473
|
resultSuccess: result.success === true,
|
|
@@ -38441,11 +38475,11 @@ async function finalizeAndSendPromptResult(params) {
|
|
|
38441
38475
|
cloudApiBaseUrl,
|
|
38442
38476
|
getCloudAccessToken,
|
|
38443
38477
|
log: log2
|
|
38444
|
-
});
|
|
38478
|
+
}) : { suppressOutput: false };
|
|
38479
|
+
const planningFallbackOutput = !planningTodosSubmit.suppressOutput && isPlanningSession && runId ? consumePlanningSessionTurnOutput(runId) : "";
|
|
38445
38480
|
const errStr = typeof result.error === "string" ? result.error : void 0;
|
|
38446
38481
|
const resultStop = typeof result.stopReason === "string" ? result.stopReason.trim() : "";
|
|
38447
38482
|
const cancelledByAgent = resultStop.toLowerCase() === "cancelled" || errStr != null && isUserEndedSessionTurnErrorText(errStr);
|
|
38448
|
-
const planningFallbackOutput = !planningTodosSubmit.suppressOutput && isPlanningSession && runId ? consumePlanningSessionTurnOutput(runId) : "";
|
|
38449
38483
|
sendResult({
|
|
38450
38484
|
type: "prompt_result",
|
|
38451
38485
|
id: promptId,
|
|
@@ -38466,6 +38500,14 @@ async function finalizeAndSendPromptResult(params) {
|
|
|
38466
38500
|
);
|
|
38467
38501
|
}
|
|
38468
38502
|
}
|
|
38503
|
+
void reportPostTurnEnrichment({
|
|
38504
|
+
sessionId,
|
|
38505
|
+
runId,
|
|
38506
|
+
agentCwd,
|
|
38507
|
+
result,
|
|
38508
|
+
sendSessionUpdate,
|
|
38509
|
+
log: log2
|
|
38510
|
+
});
|
|
38469
38511
|
}
|
|
38470
38512
|
|
|
38471
38513
|
// src/agents/acp/build-forked-session-agent-prompt.ts
|
|
@@ -38922,7 +38964,6 @@ async function sendPromptToAgent(options) {
|
|
|
38922
38964
|
followUpCatalogPromptId,
|
|
38923
38965
|
cloudApiBaseUrl,
|
|
38924
38966
|
getCloudAccessToken,
|
|
38925
|
-
e2ee,
|
|
38926
38967
|
sendResult,
|
|
38927
38968
|
sendSessionUpdate,
|
|
38928
38969
|
log: log2
|
|
@@ -38945,16 +38986,6 @@ async function sendPromptToAgent(options) {
|
|
|
38945
38986
|
}
|
|
38946
38987
|
}
|
|
38947
38988
|
|
|
38948
|
-
// src/agents/acp/manager/get-acp-agent-state.ts
|
|
38949
|
-
function getAcpSessionAgentState(ctx, acpSessionAgentKey) {
|
|
38950
|
-
let state = ctx.acpAgents.get(acpSessionAgentKey);
|
|
38951
|
-
if (!state) {
|
|
38952
|
-
state = createEmptyAcpClientState();
|
|
38953
|
-
ctx.acpAgents.set(acpSessionAgentKey, state);
|
|
38954
|
-
}
|
|
38955
|
-
return state;
|
|
38956
|
-
}
|
|
38957
|
-
|
|
38958
38989
|
// src/agents/acp/manager/handle-pending-prompt-cancel.ts
|
|
38959
38990
|
async function handlePendingPromptCancel(params) {
|
|
38960
38991
|
const { ctx, activeRunId, promptId, sessionId, handle, sendResult } = params;
|
|
@@ -38978,94 +39009,104 @@ async function handlePendingPromptCancel(params) {
|
|
|
38978
39009
|
return true;
|
|
38979
39010
|
}
|
|
38980
39011
|
|
|
38981
|
-
// src/agents/acp/manager/
|
|
38982
|
-
async function
|
|
38983
|
-
const {
|
|
38984
|
-
|
|
38985
|
-
|
|
38986
|
-
sessionId,
|
|
38987
|
-
mode,
|
|
38988
|
-
agentConfig,
|
|
38989
|
-
sessionParentPath,
|
|
38990
|
-
sendResult,
|
|
38991
|
-
sendSessionUpdate,
|
|
38992
|
-
followUpCatalogPromptId,
|
|
38993
|
-
cloudApiBaseUrl,
|
|
38994
|
-
getCloudAccessToken,
|
|
38995
|
-
e2ee,
|
|
38996
|
-
attachments,
|
|
38997
|
-
isNewSession
|
|
38998
|
-
} = opts;
|
|
38999
|
-
const { activeRunId, activeAcpAgentKey, activeAcpSessionAgentKey, preferredForPrompt } = runCtx;
|
|
39000
|
-
const acpAgentState = getAcpSessionAgentState(ctx, activeAcpSessionAgentKey);
|
|
39001
|
-
const handle = await ensureAcpClient({
|
|
39002
|
-
state: acpAgentState,
|
|
39003
|
-
acpAgentKey: activeAcpAgentKey,
|
|
39004
|
-
preferredAgentType: preferredForPrompt,
|
|
39005
|
-
mode,
|
|
39006
|
-
agentConfig: agentConfig ?? null,
|
|
39007
|
-
sessionParentPath,
|
|
39008
|
-
resolveRouting: () => ctx.promptRouting.resolveRouting(activeAcpSessionAgentKey),
|
|
39009
|
-
cloudSessionId: sessionId,
|
|
39010
|
-
bridgeAccessPort: ctx.getBridgeAccessPort(),
|
|
39011
|
-
sendSessionUpdate,
|
|
39012
|
-
sendRequest: sendSessionUpdate,
|
|
39013
|
-
log: ctx.log,
|
|
39014
|
-
reportAgentCapabilities: ctx.reportAgentCapabilities
|
|
39015
|
-
});
|
|
39016
|
-
if (!handle) {
|
|
39017
|
-
const errMsg = acpAgentState.lastAcpStartError || "No agent configured. Register local agents on this bridge in the app.";
|
|
39018
|
-
const evaluated = Boolean(preferredForPrompt && errMsg.trim());
|
|
39019
|
-
const suggestsAuth = evaluated ? localAgentErrorSuggestsAuth(preferredForPrompt, errMsg) : false;
|
|
39020
|
-
const auth = suggestsAuth && preferredForPrompt ? { agentAuthRequired: true, agentType: preferredForPrompt } : {};
|
|
39021
|
-
sendResult({
|
|
39012
|
+
// src/agents/acp/manager/dispatch-acp-prompt.ts
|
|
39013
|
+
async function dispatchAcpPrompt(ctx, runCtx, opts, handle) {
|
|
39014
|
+
const { activeRunId, activeAcpSessionAgentKey, preferredForPrompt } = runCtx;
|
|
39015
|
+
if (!ctx.promptRouting.isRegisteredRun(activeRunId)) {
|
|
39016
|
+
opts.sendResult({
|
|
39022
39017
|
type: "prompt_result",
|
|
39023
|
-
id: promptId,
|
|
39024
|
-
...sessionId ? { sessionId } : {},
|
|
39018
|
+
id: opts.promptId,
|
|
39019
|
+
...opts.sessionId ? { sessionId: opts.sessionId } : {},
|
|
39025
39020
|
runId: activeRunId,
|
|
39026
39021
|
success: false,
|
|
39027
|
-
error:
|
|
39028
|
-
...auth
|
|
39022
|
+
error: "Prompt dispatch was superseded before the agent started."
|
|
39029
39023
|
});
|
|
39030
39024
|
return;
|
|
39031
39025
|
}
|
|
39032
|
-
if (!ctx.promptRouting.isRegisteredRun(activeRunId)) {
|
|
39033
|
-
return;
|
|
39034
|
-
}
|
|
39035
39026
|
const cancelled = await handlePendingPromptCancel({
|
|
39036
39027
|
ctx,
|
|
39037
39028
|
activeRunId,
|
|
39038
|
-
promptId,
|
|
39039
|
-
sessionId,
|
|
39029
|
+
promptId: opts.promptId,
|
|
39030
|
+
sessionId: opts.sessionId,
|
|
39040
39031
|
handle,
|
|
39041
|
-
sendResult
|
|
39032
|
+
sendResult: opts.sendResult
|
|
39042
39033
|
});
|
|
39043
39034
|
if (cancelled) return;
|
|
39044
39035
|
ctx.promptRouting.setStreamingRunId(activeAcpSessionAgentKey, activeRunId);
|
|
39045
39036
|
try {
|
|
39046
39037
|
await sendPromptToAgent({
|
|
39047
39038
|
handle,
|
|
39048
|
-
promptText,
|
|
39049
|
-
promptId,
|
|
39050
|
-
sessionId,
|
|
39039
|
+
promptText: opts.promptText,
|
|
39040
|
+
promptId: opts.promptId,
|
|
39041
|
+
sessionId: opts.sessionId,
|
|
39051
39042
|
runId: activeRunId,
|
|
39052
39043
|
agentType: preferredForPrompt,
|
|
39053
|
-
agentCwd: resolveSessionParentPathForAgentProcess(sessionParentPath),
|
|
39054
|
-
sendResult,
|
|
39055
|
-
sendSessionUpdate,
|
|
39044
|
+
agentCwd: resolveSessionParentPathForAgentProcess(opts.sessionParentPath),
|
|
39045
|
+
sendResult: opts.sendResult,
|
|
39046
|
+
sendSessionUpdate: opts.sendSessionUpdate,
|
|
39056
39047
|
log: ctx.log,
|
|
39057
|
-
followUpCatalogPromptId,
|
|
39058
|
-
cloudApiBaseUrl,
|
|
39059
|
-
getCloudAccessToken,
|
|
39060
|
-
e2ee,
|
|
39061
|
-
attachments,
|
|
39062
|
-
isNewSession
|
|
39048
|
+
followUpCatalogPromptId: opts.followUpCatalogPromptId,
|
|
39049
|
+
cloudApiBaseUrl: opts.cloudApiBaseUrl,
|
|
39050
|
+
getCloudAccessToken: opts.getCloudAccessToken,
|
|
39051
|
+
e2ee: opts.e2ee,
|
|
39052
|
+
attachments: opts.attachments,
|
|
39053
|
+
isNewSession: opts.isNewSession
|
|
39063
39054
|
});
|
|
39064
39055
|
} finally {
|
|
39065
39056
|
ctx.promptRouting.clearStreamingRunId(activeAcpSessionAgentKey, activeRunId);
|
|
39066
39057
|
}
|
|
39067
39058
|
}
|
|
39068
39059
|
|
|
39060
|
+
// src/agents/acp/manager/get-acp-agent-state.ts
|
|
39061
|
+
function getAcpSessionAgentState(ctx, acpSessionAgentKey) {
|
|
39062
|
+
let state = ctx.acpAgents.get(acpSessionAgentKey);
|
|
39063
|
+
if (!state) {
|
|
39064
|
+
state = createEmptyAcpClientState();
|
|
39065
|
+
ctx.acpAgents.set(acpSessionAgentKey, state);
|
|
39066
|
+
}
|
|
39067
|
+
return state;
|
|
39068
|
+
}
|
|
39069
|
+
|
|
39070
|
+
// src/agents/acp/manager/ensure-acp-prompt-client.ts
|
|
39071
|
+
async function ensureAcpPromptClient(ctx, runCtx, opts) {
|
|
39072
|
+
const state = getAcpSessionAgentState(ctx, runCtx.activeAcpSessionAgentKey);
|
|
39073
|
+
const handle = await ensureAcpClient({
|
|
39074
|
+
state,
|
|
39075
|
+
acpAgentKey: runCtx.activeAcpAgentKey,
|
|
39076
|
+
preferredAgentType: runCtx.preferredForPrompt,
|
|
39077
|
+
mode: opts.mode,
|
|
39078
|
+
agentConfig: opts.agentConfig ?? null,
|
|
39079
|
+
sessionParentPath: opts.sessionParentPath,
|
|
39080
|
+
resolveRouting: () => ctx.promptRouting.resolveRouting(runCtx.activeAcpSessionAgentKey),
|
|
39081
|
+
cloudSessionId: opts.sessionId,
|
|
39082
|
+
bridgeAccessPort: ctx.getBridgeAccessPort(),
|
|
39083
|
+
sendSessionUpdate: opts.sendSessionUpdate,
|
|
39084
|
+
sendRequest: opts.sendSessionUpdate,
|
|
39085
|
+
log: ctx.log,
|
|
39086
|
+
reportAgentCapabilities: ctx.reportAgentCapabilities
|
|
39087
|
+
});
|
|
39088
|
+
if (handle) return handle;
|
|
39089
|
+
const error40 = state.lastAcpStartError || "No agent configured. Register local agents on this bridge in the app.";
|
|
39090
|
+
const agentType = runCtx.preferredForPrompt;
|
|
39091
|
+
const requiresAuth = Boolean(agentType && localAgentErrorSuggestsAuth(agentType, error40));
|
|
39092
|
+
opts.sendResult({
|
|
39093
|
+
type: "prompt_result",
|
|
39094
|
+
id: opts.promptId,
|
|
39095
|
+
...opts.sessionId ? { sessionId: opts.sessionId } : {},
|
|
39096
|
+
runId: runCtx.activeRunId,
|
|
39097
|
+
success: false,
|
|
39098
|
+
error: error40,
|
|
39099
|
+
...requiresAuth && agentType ? { agentAuthRequired: true, agentType } : {}
|
|
39100
|
+
});
|
|
39101
|
+
return null;
|
|
39102
|
+
}
|
|
39103
|
+
|
|
39104
|
+
// src/agents/acp/manager/run-acp-prompt.ts
|
|
39105
|
+
async function runAcpPrompt(ctx, runCtx, opts) {
|
|
39106
|
+
const handle = await ensureAcpPromptClient(ctx, runCtx, opts);
|
|
39107
|
+
if (handle) await dispatchAcpPrompt(ctx, runCtx, opts, handle);
|
|
39108
|
+
}
|
|
39109
|
+
|
|
39069
39110
|
// src/agents/acp/manager/handle-prompt.ts
|
|
39070
39111
|
function handlePrompt(ctx, opts) {
|
|
39071
39112
|
const { promptId, sessionId, runId, mode, agentType, agentConfig, sendResult } = opts;
|
|
@@ -51915,15 +51956,18 @@ function dispatchLocalPrompt(next, deps) {
|
|
|
51915
51956
|
|
|
51916
51957
|
// src/prompt-turn-queue/runner/run-id-queue-key-map.ts
|
|
51917
51958
|
var runIdToQueueKey = /* @__PURE__ */ new Map();
|
|
51959
|
+
var locallyDispatchedRunIds = /* @__PURE__ */ new Set();
|
|
51918
51960
|
function getRunIdQueueKey(runId) {
|
|
51919
51961
|
return runIdToQueueKey.get(runId);
|
|
51920
51962
|
}
|
|
51921
51963
|
function setRunIdQueueKey(runId, queueKey) {
|
|
51922
51964
|
runIdToQueueKey.set(runId, queueKey);
|
|
51965
|
+
locallyDispatchedRunIds.add(runId);
|
|
51923
51966
|
}
|
|
51924
51967
|
function deleteRunIdQueueKey(runId) {
|
|
51925
51968
|
const queueKey = runIdToQueueKey.get(runId);
|
|
51926
51969
|
runIdToQueueKey.delete(runId);
|
|
51970
|
+
locallyDispatchedRunIds.delete(runId);
|
|
51927
51971
|
return queueKey;
|
|
51928
51972
|
}
|
|
51929
51973
|
function syncRunningTurnQueueKeys(turns, queueKey) {
|
|
@@ -51978,7 +52022,7 @@ async function handlePromptQueueCancellations(entries, deps) {
|
|
|
51978
52022
|
for (const [queueKey] of entries) {
|
|
51979
52023
|
const file2 = await readPersistedQueue(queueKey);
|
|
51980
52024
|
const turn = file2?.turns.find((row) => row.bridgeServerState === "cancel_requested" && row.lastCliState === "running");
|
|
51981
|
-
if (!turn) {
|
|
52025
|
+
if (!turn || getRunIdQueueKey(turn.turnId) !== queueKey) {
|
|
51982
52026
|
await yieldToEventLoop();
|
|
51983
52027
|
continue;
|
|
51984
52028
|
}
|
|
@@ -51987,19 +52031,8 @@ async function handlePromptQueueCancellations(entries, deps) {
|
|
|
51987
52031
|
await yieldToEventLoop();
|
|
51988
52032
|
continue;
|
|
51989
52033
|
}
|
|
51990
|
-
deps.log(`[Queue]
|
|
52034
|
+
deps.log(`[Queue] No local ACP run remains for ${turn.turnId.slice(0, 8)}\u2026; reconciling cancelled turn.`);
|
|
51991
52035
|
await finalizePromptTurnOnBridge(deps.getWs, turn.turnId, false, { terminalCliState: "cancelled" });
|
|
51992
|
-
const ws = deps.getWs();
|
|
51993
|
-
if (ws && turn.sessionId) {
|
|
51994
|
-
sendWsMessage(ws, {
|
|
51995
|
-
type: "prompt_result",
|
|
51996
|
-
sessionId: turn.sessionId,
|
|
51997
|
-
runId: turn.turnId,
|
|
51998
|
-
success: false,
|
|
51999
|
-
error: "Stopped by user",
|
|
52000
|
-
stopReason: "cancelled"
|
|
52001
|
-
});
|
|
52002
|
-
}
|
|
52003
52036
|
await yieldToEventLoop();
|
|
52004
52037
|
}
|
|
52005
52038
|
}
|
|
@@ -52389,17 +52422,14 @@ function handleBridgePrompt(msg, deps) {
|
|
|
52389
52422
|
log2(
|
|
52390
52423
|
`[Bridge service] Prompt ignored: empty or missing prompt text (session ${typeof msg.sessionId === "string" ? msg.sessionId.slice(0, 8) : "\u2014"}\u2026, run ${typeof msg.runId === "string" ? msg.runId.slice(0, 8) : "\u2014"}\u2026).`
|
|
52391
52424
|
);
|
|
52392
|
-
senders.
|
|
52393
|
-
|
|
52394
|
-
|
|
52395
|
-
|
|
52396
|
-
|
|
52397
|
-
|
|
52398
|
-
|
|
52399
|
-
|
|
52400
|
-
},
|
|
52401
|
-
["error"]
|
|
52402
|
-
);
|
|
52425
|
+
senders.sendResult({
|
|
52426
|
+
type: "prompt_result",
|
|
52427
|
+
...promptId ? { id: promptId } : {},
|
|
52428
|
+
...sessionId ? { sessionId } : {},
|
|
52429
|
+
...runId ? { runId } : {},
|
|
52430
|
+
success: false,
|
|
52431
|
+
error: "Empty or missing prompt text from the bridge; this turn was not sent to the agent."
|
|
52432
|
+
});
|
|
52403
52433
|
return;
|
|
52404
52434
|
}
|
|
52405
52435
|
const isNewSession = msg.isNewSession === true;
|