Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/harnesses/codex/rollout-activity-summary.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,39 @@ test("summarizes structured local shell and web-search calls", () => {
assert.equal(web.external, true);
});

test("summarizes current Codex code-mode web tools and their batched arguments", () => {
for (const toolName of ["web__run", "web_run", "web.run"]) {
const summary = summarizeCodexRolloutActivity(
rollout({
codeModeTools: [toolName],
callPayload: {
input: `const r = await tools.${toolName}({search_query:[{q:"Codex rollout activity"},{q:"Codex code mode"}],response_length:"long"}); text(r);`,
},
}),
);

assert.equal(summary.kind, "web");
assert.equal(summary.subject, "Codex rollout activity +1");
assert.equal(summary.external, true);
}
});

test("summarizes non-search web run operations", () => {
const summary = summarizeCodexRolloutActivity(
rollout({
codeModeTools: ["web__run"],
callPayload: {
input:
'tools.web__run({open:[{ref_id:"https://sandpi.ai/llms.txt"}]});',
},
}),
);

assert.equal(summary.kind, "web");
assert.equal(summary.subject, "https://sandpi.ai/llms.txt");
assert.equal(summary.external, true);
});

declare global {
// Test sentinel proving arbitrary code-mode input is never evaluated.
var __sandpiActivityParserExecuted: boolean | undefined;
Expand Down
44 changes: 41 additions & 3 deletions src/harnesses/codex/rollout-activity-summary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -519,16 +519,24 @@ function safeSubject(args: Record<string, unknown> | null) {
return null;
}

function isWebToolName(name: string) {
return (
name === "web_run" ||
name === "web__run" ||
name.startsWith("web.") ||
name.includes("web_search")
);
}

function externalTool(names: string[], activity: CodexRolloutToolActivity) {
return (
names.some(
(name) =>
name.startsWith("mcp__") ||
name.startsWith("web.") ||
isWebToolName(name) ||
name.startsWith("browser.") ||
name.startsWith("image_gen.") ||
name.startsWith("image_gen__") ||
name.includes("web_search") ||
name.includes("imagegen") ||
name.includes("image_generation"),
) ||
Expand All @@ -551,7 +559,7 @@ function toolKind(
return "agent";
}
if (
names.some((item) => item.startsWith("web.") || item.includes("web_search")) ||
names.some(isWebToolName) ||
activity.callType === "web_search_call"
) {
return "web";
Expand Down Expand Up @@ -670,6 +678,35 @@ function webActionSubject(activity: CodexRolloutToolActivity) {
return null;
}

function webRunSubject(args: Record<string, unknown> | null) {
const candidates: Array<[string, string]> = [
["search_query", "q"],
["image_query", "q"],
["open", "ref_id"],
["find", "pattern"],
["weather", "location"],
["finance", "ticker"],
["time", "utc_offset"],
["sports", "league"],
];
for (const [collection, property] of candidates) {
const items = args?.[collection];
if (!Array.isArray(items)) continue;
const values = items
.map((item) => objectRecord(item)?.[property])
.filter(
(value): value is string =>
typeof value === "string" && value.trim().length > 0,
);
if (values.length > 0) {
return values.length === 1
? values[0]!
: `${values[0]} +${values.length - 1}`;
}
}
return null;
}

export function summarizeCodexRolloutActivity(
activity: CodexRolloutToolActivity,
): CodexRolloutActivitySummary {
Expand Down Expand Up @@ -725,6 +762,7 @@ export function summarizeCodexRolloutActivity(
(cellId ? `#${cellId}` : null) ??
(sessionId ? `#${sessionId}` : null) ??
webActionSubject(activity) ??
(kind === "web" ? webRunSubject(args) : null) ??
safeSubject(args) ??
(names.length > 1 ? names.join(" · ") : toolName);
const detail =
Expand Down
7 changes: 4 additions & 3 deletions src/harnesses/codex/session-activity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ test("restores the real 30-call rollout shape alongside its modeled file change"
test("categorizes namespaced Codex code-mode tools without cross-harness normalization", () => {
const activity = rolloutFeed([
rolloutTool(1, { codeModeTools: ["web.run"] }),
rolloutTool(6, { codeModeTools: ["web__run"] }),
rolloutTool(2, { codeModeTools: ["image_gen.imagegen"] }),
rolloutTool(3, { codeModeTools: ["collaboration.spawn_agent"] }),
rolloutTool(4, { codeModeTools: ["functions.exec_command"] }),
Expand All @@ -508,10 +509,10 @@ test("categorizes namespaced Codex code-mode tools without cross-harness normali
for (const record of activity.records) record.turnId = turnId;

assert.deepEqual(summarizeCodexSessionActivity(emptyProjection, activity), {
total: 5,
records: 5,
total: 6,
records: 6,
issues: 0,
external: 3,
external: 4,
commands: 2,
files: 0,
agents: 1,
Expand Down
21 changes: 4 additions & 17 deletions src/harnesses/codex/session-activity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,30 +117,17 @@ function codexRolloutActivityIsVisible(entry: CodexRolloutToolActivity) {
function rolloutToolCategories(
entry: CodexRolloutToolActivity,
): CodexSessionActivityCategory[] {
const summary = summarizeCodexRolloutActivity(entry);
const names =
entry.codeModeTools.length > 0 ? entry.codeModeTools : [entry.name];
const nameVariants = names.flatMap((name) => [
name,
name.split(".").at(-1) ?? name,
]);
const categories: CodexSessionActivityCategory[] = [];
const external =
names.some(
(name) =>
name.startsWith("mcp__") ||
name.startsWith("web.") ||
name.startsWith("image_gen.") ||
name.startsWith("image_gen__") ||
name.startsWith("browser.") ||
name.includes("web_search") ||
name.includes("imagegen") ||
name.includes("image_generation") ||
name.includes("browser"),
) ||
entry.callType === "tool_search_call" ||
entry.callType === "web_search_call" ||
entry.callType === "image_generation_call";
if (external) categories.push("external");
if (summary.external || entry.callType === "tool_search_call") {
categories.push("external");
}
if (nameVariants.some((name) => CODEX_ROLLOUT_AGENT_TOOLS.has(name))) {
categories.push("agents");
}
Expand Down