Skip to content

Commit 72e4e9a

Browse files
VibeSWEclaude
andcommitted
Merge branch 'feat/agents-native-harness-fields' into feat/agents-harness-conversation-logs
Bring in the review fixes from #33. Harness detection now returns a list; conversation logs stay joined for a single detected harness until the page handles mixed datasets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 parents 64925c2 + 3ace7e5 commit 72e4e9a

7 files changed

Lines changed: 569 additions & 92 deletions

File tree

‎frontend/e2e/agents.spec.ts‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -891,3 +891,52 @@ test('Codex conversation logs fill run details from the paired logs dataset', as
891891
await expect(page).toHaveURL(/logs=none/);
892892
await expect(page.getByRole('heading', { name: 'No matching runs' })).toBeVisible();
893893
});
894+
895+
test('discloses the record limit from the queried rows when Codex mapping drops some', async ({
896+
page,
897+
}) => {
898+
const trace = 'f6'.repeat(16);
899+
const codex = (span: Omit<SpanFixture, 'trace' | 'status'>) =>
900+
spanRows({
901+
...span,
902+
trace,
903+
attributes: { 'service.name': 'codex-app-server', ...span.attributes },
904+
});
905+
const rows = [
906+
codex({
907+
id: 'f600000000000001',
908+
name: 'session_task.turn',
909+
start: base + 1000,
910+
duration: 4000,
911+
attributes: { model: 'gpt-6-luna', 'codex.turn.token_usage.input_tokens': '10' },
912+
}),
913+
codex({
914+
id: 'f600000000000002',
915+
parent: 'f600000000000001',
916+
name: 'try_run_sampling_request',
917+
start: base + 1100,
918+
duration: 3000,
919+
attributes: { model: 'gpt-6-luna' },
920+
}),
921+
// Stream spans count toward the record limit but are not shown as run spans.
922+
...Array.from({ length: 998 }, (_, index) =>
923+
codex({
924+
id: (index + 1).toString(16).padStart(16, '0'),
925+
parent: 'f600000000000002',
926+
name: 'receiving_stream',
927+
start: base + 1200,
928+
duration: 10,
929+
}),
930+
),
931+
].flat();
932+
await serveAgents(page, {
933+
rows,
934+
datasets: ['codex-traces'],
935+
fields: [...new Set(rows.flatMap((row) => Object.keys(row)))],
936+
});
937+
await page.goto(`/agents/codex-traces?${range}`);
938+
await expect(cell(runRow(page, 'Codex'), 'Spans')).toHaveText('2');
939+
await expect(page.getByRole('status').filter({ hasText: 'record limit' })).toContainText(
940+
'narrow the time range',
941+
);
942+
});

‎frontend/src/features/agents/AgentsPage.tsx‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import {
2424
buildAgentRunQuery,
2525
discoverAgentDatasets,
2626
} from '../../lib/agents';
27-
import { AGENT_HARNESSES, detectAgentHarness, mapHarnessRows } from '../../lib/agentHarnesses';
27+
import { AGENT_HARNESSES, detectAgentHarnesses, mapHarnessRows } from '../../lib/agentHarnesses';
2828
import {
2929
attachHarnessConversation,
3030
buildHarnessLogQuery,
@@ -123,9 +123,11 @@ export function AgentsPage() {
123123
buildAgentRunQuery(dataset, fields, bounds, timeColumn),
124124
signal,
125125
);
126-
const harness = detectAgentHarness(fields);
126+
const harnesses = detectAgentHarnesses(fields);
127+
// Conversation logs are joined for one harness; a mixed dataset has none yet.
128+
const harness = harnesses.length === 1 ? harnesses[0] : undefined;
127129
return {
128-
rows: mapHarnessRows(harness, rows),
130+
rows: mapHarnessRows(harnesses, rows),
129131
limitReached: rows.length >= AGENT_RECORD_LIMIT,
130132
timeColumn,
131133
traces: info.logSourceFormats.includes('otel-traces'),
@@ -469,7 +471,7 @@ export function AgentsPage() {
469471
the time range to explore them.
470472
</p>
471473
)}
472-
{result.data.rows.length >= AGENT_RECORD_LIMIT && (
474+
{result.data.limitReached && (
473475
<p role="status" className="agents-warnings">
474476
The record limit was reached. Runs may have additional spans or events; narrow
475477
the time range to improve coverage.

‎frontend/src/lib/agentHarnessLogs.test.ts‎

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,20 @@ const conversations = (run: AgentRun) =>
4444
const codexTrace = '1b1ef19838e4d610208a394b9af94384';
4545
const codexRuns = () =>
4646
buildAgentRuns(
47-
mapHarnessRows('codex', [
48-
span(codexTrace, 'fe5417199aa59ebf', '57d7ac8056fe8b6d', 'session_task.turn', 15.8, 4, {
49-
'service.name': 'codex_exec',
50-
model: 'gpt-6-luna',
51-
}),
52-
span(codexTrace, '67c205c2bacb4518', 'e0d1c4f0b19c5a7e', 'exec', 18, 0.2, {
53-
'service.name': 'codex_exec',
54-
tool_name: 'exec',
55-
call_id: 'call_7b616c08bc894640a843cff3e0f7b38a',
56-
}),
57-
]),
47+
mapHarnessRows(
48+
['codex'],
49+
[
50+
span(codexTrace, 'fe5417199aa59ebf', '57d7ac8056fe8b6d', 'session_task.turn', 15.8, 4, {
51+
'service.name': 'codex_exec',
52+
model: 'gpt-6-luna',
53+
}),
54+
span(codexTrace, '67c205c2bacb4518', 'e0d1c4f0b19c5a7e', 'exec', 18, 0.2, {
55+
'service.name': 'codex_exec',
56+
tool_name: 'exec',
57+
call_id: 'call_7b616c08bc894640a843cff3e0f7b38a',
58+
}),
59+
],
60+
),
5861
);
5962
const codexLog = (fields: LogRecord): LogRecord => ({
6063
'service.name': 'codex_exec',
@@ -121,15 +124,18 @@ const claudeToolOutput = {
121124
};
122125
const claudeRuns = () =>
123126
buildAgentRuns(
124-
mapHarnessRows('claude-code', [
125-
claudeSpan('671ed833b6b2a759', '', 'claude_code.interaction', 9.5, 6),
126-
claudeRequest('first', 9.6),
127-
claudeToolSpan,
128-
// Flattened span events repeat; the output is shown once.
129-
claudeToolOutput,
130-
{ ...claudeToolOutput },
131-
claudeRequest('second', 12.5),
132-
]),
127+
mapHarnessRows(
128+
['claude-code'],
129+
[
130+
claudeSpan('671ed833b6b2a759', '', 'claude_code.interaction', 9.5, 6),
131+
claudeRequest('first', 9.6),
132+
claudeToolSpan,
133+
// Flattened span events repeat; the output is shown once.
134+
claudeToolOutput,
135+
{ ...claudeToolOutput },
136+
claudeRequest('second', 12.5),
137+
],
138+
),
133139
);
134140
const claudeLog = (sequence: number, seconds: number, fields: LogRecord): LogRecord => ({
135141
'service.name': 'claude-code',

0 commit comments

Comments
 (0)