refactor(commands): unify repeated ACP and routing flows

This commit is contained in:
Peter Steinberger
2026-03-02 05:19:47 +00:00
parent 2d31126e6a
commit 6b78544f82
12 changed files with 333 additions and 442 deletions

View File

@@ -179,24 +179,26 @@ function runAgentAttempt(params: {
});
if (isCliProvider(params.providerOverride, params.cfg)) {
const cliSessionId = getCliSessionId(params.sessionEntry, params.providerOverride);
return runCliAgent({
sessionId: params.sessionId,
sessionKey: params.sessionKey,
agentId: params.sessionAgentId,
sessionFile: params.sessionFile,
workspaceDir: params.workspaceDir,
config: params.cfg,
prompt: effectivePrompt,
provider: params.providerOverride,
model: params.modelOverride,
thinkLevel: params.resolvedThinkLevel,
timeoutMs: params.timeoutMs,
runId: params.runId,
extraSystemPrompt: params.opts.extraSystemPrompt,
cliSessionId,
images: params.isFallbackRetry ? undefined : params.opts.images,
streamParams: params.opts.streamParams,
}).catch(async (err) => {
const runCliWithSession = (nextCliSessionId: string | undefined) =>
runCliAgent({
sessionId: params.sessionId,
sessionKey: params.sessionKey,
agentId: params.sessionAgentId,
sessionFile: params.sessionFile,
workspaceDir: params.workspaceDir,
config: params.cfg,
prompt: effectivePrompt,
provider: params.providerOverride,
model: params.modelOverride,
thinkLevel: params.resolvedThinkLevel,
timeoutMs: params.timeoutMs,
runId: params.runId,
extraSystemPrompt: params.opts.extraSystemPrompt,
cliSessionId: nextCliSessionId,
images: params.isFallbackRetry ? undefined : params.opts.images,
streamParams: params.opts.streamParams,
});
return runCliWithSession(cliSessionId).catch(async (err) => {
// Handle CLI session expired error
if (
err instanceof FailoverError &&
@@ -237,24 +239,7 @@ function runAgentAttempt(params: {
}
// Retry with no session ID (will create a new session)
return runCliAgent({
sessionId: params.sessionId,
sessionKey: params.sessionKey,
agentId: params.sessionAgentId,
sessionFile: params.sessionFile,
workspaceDir: params.workspaceDir,
config: params.cfg,
prompt: effectivePrompt,
provider: params.providerOverride,
model: params.modelOverride,
thinkLevel: params.resolvedThinkLevel,
timeoutMs: params.timeoutMs,
runId: params.runId,
extraSystemPrompt: params.opts.extraSystemPrompt,
cliSessionId: undefined, // No session ID to force new session
images: params.isFallbackRetry ? undefined : params.opts.images,
streamParams: params.opts.streamParams,
}).then(async (result) => {
return runCliWithSession(undefined).then(async (result) => {
// Update session store with new CLI session ID if available
if (
result.meta.agentMeta?.sessionId &&

View File

@@ -60,6 +60,35 @@ function formatBindingOwnerLine(binding: AgentBinding): string {
return `${normalizeAgentId(binding.agentId)} <- ${describeBinding(binding)}`;
}
function resolveTargetAgentIdOrExit(params: {
cfg: Awaited<ReturnType<typeof requireValidConfig>>;
runtime: RuntimeEnv;
agentInput: string | undefined;
}): string | null {
const agentId = resolveAgentId(params.cfg, params.agentInput?.trim(), {
fallbackToDefault: true,
});
if (!agentId) {
params.runtime.error("Unable to resolve agent id.");
params.runtime.exit(1);
return null;
}
if (!hasAgent(params.cfg, agentId)) {
params.runtime.error(`Agent "${agentId}" not found.`);
params.runtime.exit(1);
return null;
}
return agentId;
}
function formatBindingConflicts(
conflicts: Array<{ binding: AgentBinding; existingAgentId: string }>,
): string[] {
return conflicts.map(
(conflict) => `${describeBinding(conflict.binding)} (agent=${conflict.existingAgentId})`,
);
}
export async function agentsBindingsCommand(
opts: AgentsBindingsListOptions,
runtime: RuntimeEnv = defaultRuntime,
@@ -123,15 +152,8 @@ export async function agentsBindCommand(
return;
}
const agentId = resolveAgentId(cfg, opts.agent?.trim(), { fallbackToDefault: true });
const agentId = resolveTargetAgentIdOrExit({ cfg, runtime, agentInput: opts.agent });
if (!agentId) {
runtime.error("Unable to resolve agent id.");
runtime.exit(1);
return;
}
if (!hasAgent(cfg, agentId)) {
runtime.error(`Agent "${agentId}" not found.`);
runtime.exit(1);
return;
}
@@ -162,9 +184,7 @@ export async function agentsBindCommand(
added: result.added.map(describeBinding),
updated: result.updated.map(describeBinding),
skipped: result.skipped.map(describeBinding),
conflicts: result.conflicts.map(
(conflict) => `${describeBinding(conflict.binding)} (agent=${conflict.existingAgentId})`,
),
conflicts: formatBindingConflicts(result.conflicts),
};
if (opts.json) {
runtime.log(JSON.stringify(payload, null, 2));
@@ -215,15 +235,8 @@ export async function agentsUnbindCommand(
return;
}
const agentId = resolveAgentId(cfg, opts.agent?.trim(), { fallbackToDefault: true });
const agentId = resolveTargetAgentIdOrExit({ cfg, runtime, agentInput: opts.agent });
if (!agentId) {
runtime.error("Unable to resolve agent id.");
runtime.exit(1);
return;
}
if (!hasAgent(cfg, agentId)) {
runtime.error(`Agent "${agentId}" not found.`);
runtime.exit(1);
return;
}
if (opts.all && (opts.bind?.length ?? 0) > 0) {
@@ -288,9 +301,7 @@ export async function agentsUnbindCommand(
agentId,
removed: result.removed.map(describeBinding),
missing: result.missing.map(describeBinding),
conflicts: result.conflicts.map(
(conflict) => `${describeBinding(conflict.binding)} (agent=${conflict.existingAgentId})`,
),
conflicts: formatBindingConflicts(result.conflicts),
};
if (opts.json) {
runtime.log(JSON.stringify(payload, null, 2));

View File

@@ -289,25 +289,7 @@ export async function scanStatus(
progress.setLabel("Checking memory…");
const memoryPlugin = resolveMemoryPluginStatus(cfg);
const memory = await (async (): Promise<MemoryStatusSnapshot | null> => {
if (!memoryPlugin.enabled) {
return null;
}
if (memoryPlugin.slot !== "memory-core") {
return null;
}
const agentId = agentStatus.defaultId ?? "main";
const { manager } = await getMemorySearchManager({ cfg, agentId, purpose: "status" });
if (!manager) {
return null;
}
try {
await manager.probeVectorAvailability();
} catch {}
const status = manager.status();
await manager.close?.().catch(() => {});
return { agentId, ...status };
})();
const memory = await resolveMemoryStatusSnapshot({ cfg, agentStatus, memoryPlugin });
progress.tick();
progress.setLabel("Reading sessions…");