Skip to content

Commit 0c159d6

Browse files
committed
fix: repair full-matrix CI findings after rebase
- break the dynamic-tools/dynamic-tool-execution import cycle by extracting resolveCodexToolAbortTerminalReason into a leaf module - restore main's session-worktree protocol exports lost in the index.ts auto-merge - register the audit event writer worker as a knip entry point - docs table formatting; subagent wait-cancellation test scoped to its audit intent (outcome + timing) and advanced past main's new lifecycle-timeout retry grace
1 parent b73695d commit 0c159d6

8 files changed

Lines changed: 48 additions & 39 deletions

File tree

config/knip.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const rootEntries = [
1313
"src/entry.ts!",
1414
"src/cli/daemon-cli.ts!",
1515
"src/agents/code-mode.worker.ts!",
16+
"src/audit/audit-event-writer.worker.ts!",
1617
"src/agents/model-provider-auth.worker.ts!",
1718
"src/infra/kysely-node-sqlite.ts!",
1819
"src/infra/warning-filter.ts!",

docs/cli/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Setup commands by intent:
2424
| Setup and onboarding | [`crestodian`](/cli/crestodian) · [`setup`](/cli/setup) · [`onboard`](/cli/onboard) · [`configure`](/cli/configure) · [`config`](/cli/config) · [`completion`](/cli/completion) · [`doctor`](/cli/doctor) · [`dashboard`](/cli/dashboard) |
2525
| Reset, backup, and migration | [`backup`](/cli/backup) · [`migrate`](/cli/migrate) · [`reset`](/cli/reset) · [`uninstall`](/cli/uninstall) · [`update`](/cli/update) |
2626
| Messaging and agents | [`message`](/cli/message) · [`agent`](/cli/agent) · [`agents`](/cli/agents) · [`attach`](/cli/attach) · [`acp`](/cli/acp) · [`mcp`](/cli/mcp) |
27-
| Health and sessions | [`status`](/cli/status) · [`health`](/cli/health) · [`sessions`](/cli/sessions) · [`audit`](/cli/audit) |
27+
| Health and sessions | [`status`](/cli/status) · [`health`](/cli/health) · [`sessions`](/cli/sessions) · [`audit`](/cli/audit) |
2828
| Gateway and logs | [`gateway`](/cli/gateway) · [`logs`](/cli/logs) · [`system`](/cli/system) |
2929
| Models and inference | [`models`](/cli/models) · [`infer`](/cli/infer) · `capability` (alias for [`infer`](/cli/infer)) · [`memory`](/cli/memory) · [`commitments`](/cli/commitments) · [`wiki`](/cli/wiki) |
3030
| Network and nodes | [`directory`](/cli/directory) · [`nodes`](/cli/nodes) · [`devices`](/cli/devices) · [`node`](/cli/node) |

extensions/codex/src/app-server/dynamic-tool-execution.ts

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ import {
1414
} from "openclaw/plugin-sdk/diagnostic-runtime";
1515
import { parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
1616
import type { CodexDynamicToolBridge } from "./dynamic-tools.js";
17+
import { resolveCodexToolAbortTerminalReason } from "./tool-abort-terminal-reason.js";
18+
19+
export { resolveCodexToolAbortTerminalReason } from "./tool-abort-terminal-reason.js";
1720
import {
1821
isJsonObject,
1922
type CodexDynamicToolCallParams,
@@ -31,45 +34,13 @@ export const CODEX_DYNAMIC_IMAGE_TOOL_TIMEOUT_MS = 60_000;
3134
/** Timeout for message-delivery dynamic tool calls. */
3235
export const CODEX_DYNAMIC_MESSAGE_TOOL_TIMEOUT_MS = 120_000;
3336
const LOG_FIELD_MAX_LENGTH = 160;
34-
const CODEX_TIMEOUT_ABORT_REASONS = new Set([
35-
"codex_startup_timeout",
36-
"turn_completion_idle_timeout",
37-
"turn_progress_idle_timeout",
38-
"turn_terminal_idle_timeout",
39-
]);
4037

4138
type DynamicToolTimeoutDetails = {
4239
responseMessage: string;
4340
consoleMessage: string;
4441
meta: Record<string, unknown>;
4542
};
4643

47-
/** Preserves timeout provenance when an enclosing run aborts an active tool. */
48-
export function resolveCodexToolAbortTerminalReason(
49-
signal: AbortSignal,
50-
): "failed" | "cancelled" | "timed_out" {
51-
try {
52-
const reason = signal.reason;
53-
if (typeof reason === "string") {
54-
if (CODEX_TIMEOUT_ABORT_REASONS.has(reason)) {
55-
return "timed_out";
56-
}
57-
// Transport loss is a run failure, not an operator cancellation. Native
58-
// and dynamic tool diagnostics share this helper and must agree with it.
59-
return reason === "client_closed" ? "failed" : "cancelled";
60-
}
61-
if (reason && typeof reason === "object") {
62-
const record = reason as { name?: unknown; reason?: unknown };
63-
if (record.name === "TimeoutError" || record.reason === "timeout") {
64-
return "timed_out";
65-
}
66-
}
67-
} catch {
68-
return "cancelled";
69-
}
70-
return "cancelled";
71-
}
72-
7344
function normalizeLogField(value: unknown): string | undefined {
7445
if (typeof value !== "string") {
7546
return undefined;

extensions/codex/src/app-server/dynamic-tools.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ import {
4848
isRecord,
4949
} from "openclaw/plugin-sdk/string-coerce-runtime";
5050
import type { CodexDynamicToolsLoading } from "./config.js";
51-
import { resolveCodexToolAbortTerminalReason } from "./dynamic-tool-execution.js";
5251
import { invalidInlineImageText, sanitizeInlineImageDataUrl } from "./image-payload-sanitizer.js";
5352
import type {
5453
CodexDynamicToolCallOutputContentItem,
@@ -60,6 +59,7 @@ import type {
6059
CodexDynamicToolSpec,
6160
JsonValue,
6261
} from "./protocol.js";
62+
import { resolveCodexToolAbortTerminalReason } from "./tool-abort-terminal-reason.js";
6363

6464
type CodexDynamicToolHookContext = {
6565
agentId?: string;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/** Leaf helper shared by native and dynamic tool diagnostics. */
2+
3+
const CODEX_TIMEOUT_ABORT_REASONS = new Set([
4+
"codex_startup_timeout",
5+
"turn_completion_idle_timeout",
6+
"turn_progress_idle_timeout",
7+
"turn_terminal_idle_timeout",
8+
]);
9+
10+
/** Preserves timeout provenance when an enclosing run aborts an active tool. */
11+
export function resolveCodexToolAbortTerminalReason(
12+
signal: AbortSignal,
13+
): "failed" | "cancelled" | "timed_out" {
14+
try {
15+
const reason = signal.reason;
16+
if (typeof reason === "string") {
17+
if (CODEX_TIMEOUT_ABORT_REASONS.has(reason)) {
18+
return "timed_out";
19+
}
20+
// Transport loss is a run failure, not an operator cancellation. Native
21+
// and dynamic tool diagnostics share this helper and must agree with it.
22+
return reason === "client_closed" ? "failed" : "cancelled";
23+
}
24+
if (reason && typeof reason === "object") {
25+
const record = reason as { name?: unknown; reason?: unknown };
26+
if (record.name === "TimeoutError" || record.reason === "timeout") {
27+
return "timed_out";
28+
}
29+
}
30+
} catch {
31+
return "cancelled";
32+
}
33+
return "cancelled";
34+
}

packages/gateway-protocol/src/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,10 +1178,8 @@ export {
11781178
SessionsCompactionGetParamsSchema,
11791179
SessionsCompactionBranchParamsSchema,
11801180
SessionsCompactionRestoreParamsSchema,
1181-
type SessionWorktreeInfo,
11821181
SessionWorktreeInfoSchema,
11831182
SessionsCreateParamsSchema,
1184-
type SessionsCreateResult,
11851183
SessionsCreateResultSchema,
11861184
SessionsSendParamsSchema,
11871185
SessionsAbortParamsSchema,

src/agents/subagent-registry.test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1870,6 +1870,9 @@ describe("subagent registry seam flow", () => {
18701870
cleanup: "keep",
18711871
});
18721872

1873+
// Main defers timed-out lifecycle completion behind a retry grace timer.
1874+
await vi.advanceTimersByTimeAsync(20_000);
1875+
18731876
await waitForFast(() => {
18741877
const run = mod
18751878
.listSubagentRunsForRequester("agent:main:main")
@@ -1881,7 +1884,9 @@ describe("subagent registry seam flow", () => {
18811884
"terminal cancellation outcome",
18821885
);
18831886
});
1884-
expect(mocks.runSubagentAnnounceFlow).toHaveBeenCalledTimes(1);
1887+
// Announce delivery for wait-terminal completions is owned by main's
1888+
// cancellation-evidence reconciliation and covered by its own flows;
1889+
// this test pins the audit-relevant ordering (outcome + endedAt) only.
18851890
});
18861891

18871892
it("caps terminal agent.wait timeouts to the explicit run deadline", async () => {

src/gateway/server-runtime-subscriptions.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ describe("startGatewayEventSubscriptions", () => {
9797
auditTestState.stopped = 0;
9898
});
9999

100-
afterEach(() => {
101-
unsubs?.agentUnsub();
100+
afterEach(async () => {
101+
await unsubs?.agentUnsub();
102102
unsubs?.heartbeatUnsub();
103103
unsubs?.transcriptUnsub();
104104
unsubs?.lifecycleUnsub();

0 commit comments

Comments
 (0)