fix: make AgentRun log tail render-only

This commit is contained in:
Codex
2026-06-11 09:06:26 +00:00
parent cb181cd21a
commit bb0f0ec497
2 changed files with 54 additions and 4 deletions
+4 -2
View File
@@ -117,8 +117,10 @@ assertCondition(
assertCondition(
agentRunSource.includes("const effectiveLimit = options.tail ?? options.limit;")
&& agentRunSource.includes("resourceLogsTailResult(config, ref.name, effectiveLimit, options.fullText)")
&& agentRunSource.includes("clientTail: {")
&& agentRunSource.includes("return renderEventLike(command, result, { ...options, limit: effectiveLimit }, \"Log\""),
"AgentRun logs must map --tail N into the low-noise page limit and preserve pagination commands",
"AgentRun logs must map --tail N into render-only client tailing for human and raw outputs",
);
assertCondition(
@@ -143,7 +145,7 @@ console.log(JSON.stringify({
"AgentRun resource parser supports apply -f -",
"AgentRun resource task dispatch and active task list visibility",
"AgentRun resource failure output is visible in human mode",
"AgentRun logs tail controls page limit",
"AgentRun logs tail is enforced by the render-only client",
"AgentRun dry-run mutations keep resource-command follow-up",
],
}));
+50 -2
View File
@@ -498,12 +498,54 @@ async function resourceLogs(config: UniDeskConfig | null, command: string, actio
const effectiveLimit = options.tail ?? options.limit;
const logArgs = ["output", ref.name, "--limit", String(effectiveLimit)];
if (options.afterSeq !== null) logArgs.push("--after-seq", String(options.afterSeq));
else logArgs.push("--tail");
if (options.fullText) logArgs.push("--full-text");
const result = await runAgentRunRestCommand(config, "sessions", logArgs);
let result: Record<string, unknown>;
if (options.afterSeq === null && options.tail !== null) {
result = await resourceLogsTailResult(config, ref.name, effectiveLimit, options.fullText);
} else {
result = await runAgentRunRestCommand(config, "sessions", logArgs);
}
return renderEventLike(command, result, { ...options, limit: effectiveLimit }, "Log", normalizeLogItems(innerData(result)), ref.name);
}
async function resourceLogsTailResult(config: UniDeskConfig | null, sessionId: string, limit: number, fullText: boolean): Promise<Record<string, unknown>> {
const session = record(innerData(await runAgentRunRestCommand(config, "sessions", ["show", sessionId])));
const lastSeq = nonNegativeIntegerOrNull(session.lastEventSeq) ?? 0;
let window = Math.max(limit * 4, 100);
let result: Record<string, unknown> | null = null;
let data: Record<string, unknown> = {};
for (let attempt = 0; attempt < 6; attempt += 1) {
const afterSeq = Math.max(0, lastSeq - window);
const queryLimit = Math.max(limit, Math.min(1000, window));
const args = ["output", sessionId, "--limit", String(queryLimit), "--after-seq", String(afterSeq)];
if (fullText) args.push("--full-text");
result = await runAgentRunRestCommand(config, "sessions", args);
data = record(innerData(result));
const items = arrayRecords(data.items);
if (items.length >= limit || afterSeq === 0) break;
window *= 2;
}
if (result === null) return await runAgentRunRestCommand(config, "sessions", ["output", sessionId, "--limit", String(limit), "--after-seq", "0"]);
const items = arrayRecords(data.items);
const tailedItems = items.slice(-limit);
const lastReturnedSeq = tailedItems.length > 0 ? nonNegativeIntegerOrNull(tailedItems[tailedItems.length - 1]?.seq) : null;
return {
...result,
data: {
...data,
items: tailedItems,
count: tailedItems.length,
cursor: lastReturnedSeq === null ? data.cursor : String(lastReturnedSeq),
clientTail: {
requested: limit,
sourceLastEventSeq: lastSeq,
scanned: items.length,
valuesPrinted: false,
},
},
};
}
async function resourceResult(config: UniDeskConfig | null, command: string, action: string | undefined, args: string[], options: AgentRunResourceOptions): Promise<RenderedCliResult> {
const ref = parseResourceRef(action, args);
if (ref.kind === "run") {
@@ -4029,6 +4071,12 @@ function stringOrNull(value: unknown): string | null {
return typeof value === "string" && value.length > 0 ? value : null;
}
function nonNegativeIntegerOrNull(value: unknown): number | null {
if (typeof value === "number" && Number.isInteger(value) && value >= 0) return value;
if (typeof value === "string" && /^\d+$/u.test(value)) return Number(value);
return null;
}
function parseArgoStatus(text: string): { revision: string | null; syncStatus: string | null; healthStatus: string | null } {
const lines = text.split(/\r?\n/u);
const index = lines.findIndex((line) => line.trim() === "argo");