Skip to content

Commit 783ac6b

Browse files
committed
feat(agent-workspace): add operator diagnostics runtime snapshot
1 parent 0c22b9b commit 783ac6b

6 files changed

Lines changed: 448 additions & 5 deletions

docs/brainstorms/2026-04-16-mainline-ci-stabilization-and-m7-direction-requirements.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,29 @@ Deliverables:
214214
- `npm test -- src/agent_workspace.runtime.behavior.test.ts --runInBand`
215215
- `npm run test:agent-workspace:contracts`
216216

217+
### M7.5 (Now): Operator Diagnostics Snapshot Baseline (Lane Ops Bridge)
218+
219+
Deliverables:
220+
221+
- expose a stable runtime diagnostics snapshot for agent workspace turn/replay/capability event inspection.
222+
- add executable evidence for diagnostics semantics without coupling to foundation/reader lanes.
223+
224+
#### M7.5 Progress Note (2026-04-16)
225+
226+
- [Done] expanded `src/frontend/agent_workspace_runtime.js` with diagnostics snapshot support:
227+
- bounded turn history telemetry,
228+
- replay-candidate counters for repeated user prompts,
229+
- bounded capability event logs with request/result status and duration,
230+
- last conversation and last failure snapshots.
231+
- [Done] exposed runtime handle for operators:
232+
- `window.__noteConnectionAgentWorkspaceRuntimeInstance.getDiagnosticsSnapshot()`.
233+
- [Done] expanded evidence coverage:
234+
- `src/agent_workspace.runtime.behavior.test.ts` now asserts replay and capability diagnostics,
235+
- `src/agent_workspace.runtime.integration.test.ts` asserts diagnostics surface wiring.
236+
- [Done] verification evidence:
237+
- `npm test -- src/agent_workspace.runtime.behavior.test.ts --runInBand`
238+
- `npm run test:agent-workspace:contracts`
239+
217240
## Success Criteria
218241

219242
- CI failure mode that previously blocked the three agent-workspace suites is eliminated on mainline.

docs/diataxis/en/explanation/development-progress-dashboard.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,22 @@ Execution anchor:
298298
- `npm test -- src/agent_workspace.runtime.behavior.test.ts --runInBand`
299299
- `npm run test:agent-workspace:contracts`
300300

301+
## Latest Mainline Increment (2026-04-16 M7.5 Operator Diagnostics Snapshot Lane)
302+
303+
- Added runtime operator diagnostics snapshot support in `src/frontend/agent_workspace_runtime.js`:
304+
- bounded turn history telemetry (`turns`, role counts, total turns),
305+
- replay-candidate tracking for repeated user prompts (`replayCandidateTurns`),
306+
- bounded capability execution events (`request`/`result`, status, operation id, presentation, duration),
307+
- last conversation and last failure snapshots for quick triage.
308+
- Added stable runtime inspection handle:
309+
- `window.__noteConnectionAgentWorkspaceRuntimeInstance.getDiagnosticsSnapshot()`.
310+
- Added behavior/runtime evidence:
311+
- `src/agent_workspace.runtime.behavior.test.ts` now validates replay-candidate tracking and capability-event diagnostics,
312+
- `src/agent_workspace.runtime.integration.test.ts` checks diagnostics surface wiring in runtime source.
313+
- Verification evidence:
314+
- `npm test -- src/agent_workspace.runtime.behavior.test.ts --runInBand`
315+
- `npm run test:agent-workspace:contracts`
316+
301317
## Mainline vs Working-Branch Snapshot (2026-04-14)
302318

303319
| Capability Slice | Working Branch (`feat/learning-multi-tutor-adapter`) | Mainline (`origin/main`) | Integration Status |

docs/diataxis/zh/explanation/development-progress-dashboard.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,22 @@
300300
- `npm test -- src/agent_workspace.runtime.behavior.test.ts --runInBand`
301301
- `npm run test:agent-workspace:contracts`
302302

303+
## 主线最新增量(2026-04-16 M7.5 运维诊断快照链路)
304+
305+
- 已在 `src/frontend/agent_workspace_runtime.js` 增加运行时运维诊断快照能力:
306+
- 有界 turn 历史遥测(`turns`、角色计数、总 turn 数),
307+
- 重复用户提示 replay 候选计数(`replayCandidateTurns`),
308+
- 有界 capability 执行事件(`request`/`result`、状态、operation id、presentation、耗时),
309+
- 最近一次会话与最近一次失败快照,便于快速排障。
310+
- 已增加稳定调试入口:
311+
- `window.__noteConnectionAgentWorkspaceRuntimeInstance.getDiagnosticsSnapshot()`
312+
- 已补行为/集成证据:
313+
- `src/agent_workspace.runtime.behavior.test.ts` 覆盖 replay 候选与 capability 事件诊断断言,
314+
- `src/agent_workspace.runtime.integration.test.ts` 断言运行时源码包含诊断面接线。
315+
- 验证证据:
316+
- `npm test -- src/agent_workspace.runtime.behavior.test.ts --runInBand`
317+
- `npm run test:agent-workspace:contracts`
318+
303319
## 主线 vs 工作分支快照(2026-04-14)
304320

305321
| 能力切片 | 工作分支(`feat/learning-multi-tutor-adapter`| 主线(`origin/main`| 集成状态 |

src/agent_workspace.runtime.behavior.test.ts

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,27 @@ type AgentRuntimeModule = {
77
openLearningPathDock: (preferredAtomId?: string) => void;
88
hidePathDock: () => void;
99
togglePathFullscreen: () => void;
10+
getDiagnosticsSnapshot: () => {
11+
conversationRequests: number;
12+
replayCandidateTurns: number;
13+
turnCounts: {
14+
user: number;
15+
assistant: number;
16+
system: number;
17+
total: number;
18+
};
19+
turns: Array<Record<string, unknown>>;
20+
capabilityEvents: Array<Record<string, unknown>>;
21+
lastCapabilityEvent: Record<string, unknown> | null;
22+
lastConversation: Record<string, unknown> | null;
23+
lastFailure: Record<string, unknown> | null;
24+
pathState: {
25+
visible: boolean;
26+
fullscreen: boolean;
27+
};
28+
latestFocusAtomId: string;
29+
latestKnowledgePoints: number;
30+
};
1031
};
1132
};
1233

@@ -1482,4 +1503,135 @@ describe('agent workspace runtime behavior', () => {
14821503
runtime.togglePathFullscreen();
14831504
expect(pathFullscreenButton.textContent).toBe('路径全屏 ZH');
14841505
});
1506+
1507+
test('records replay candidates and capability execution diagnostics snapshot', async () => {
1508+
const fetchMock = jest
1509+
.fn()
1510+
.mockResolvedValueOnce({
1511+
ok: true,
1512+
status: 200,
1513+
json: async () => ({
1514+
success: true,
1515+
result: {
1516+
userId: 'agent_user_default',
1517+
message: 'Found 1 local knowledge point(s).',
1518+
knowledgePoints: [
1519+
{
1520+
atomId: 'atom-diagnostic-1',
1521+
title: 'Diagnostic Candidate',
1522+
snippet: 'Replay and capability diagnostics.',
1523+
score: 0.81,
1524+
capabilities: [
1525+
{
1526+
actionId: 'open_learning_path',
1527+
label: 'Learning Path',
1528+
request: {
1529+
userId: 'agent_user_default',
1530+
atomId: 'atom-diagnostic-1',
1531+
},
1532+
execution: {
1533+
kind: 'knowledge_operation',
1534+
operationId: 'build_learning_path',
1535+
resultPresentation: 'learning_path_card',
1536+
},
1537+
},
1538+
],
1539+
},
1540+
],
1541+
},
1542+
}),
1543+
})
1544+
.mockResolvedValueOnce({
1545+
ok: true,
1546+
status: 200,
1547+
json: async () => ({
1548+
success: true,
1549+
result: {
1550+
userId: 'agent_user_default',
1551+
message: 'Found 1 local knowledge point(s).',
1552+
knowledgePoints: [
1553+
{
1554+
atomId: 'atom-diagnostic-1',
1555+
title: 'Diagnostic Candidate',
1556+
snippet: 'Replay and capability diagnostics.',
1557+
score: 0.81,
1558+
capabilities: [
1559+
{
1560+
actionId: 'open_learning_path',
1561+
label: 'Learning Path',
1562+
request: {
1563+
userId: 'agent_user_default',
1564+
atomId: 'atom-diagnostic-1',
1565+
},
1566+
execution: {
1567+
kind: 'knowledge_operation',
1568+
operationId: 'build_learning_path',
1569+
resultPresentation: 'learning_path_card',
1570+
},
1571+
},
1572+
],
1573+
},
1574+
],
1575+
},
1576+
}),
1577+
})
1578+
.mockResolvedValueOnce({
1579+
ok: true,
1580+
status: 200,
1581+
json: async () => ({
1582+
success: true,
1583+
result: {
1584+
masteryPaths: [{ id: 'mastery-1' }],
1585+
divergencePaths: [{ id: 'divergence-1' }],
1586+
},
1587+
}),
1588+
});
1589+
(global as unknown as Record<string, unknown>).fetch = fetchMock;
1590+
1591+
const runtime = runtimeModule.createAgentWorkspaceRuntime({ defaultUserId: 'agent_user_default' });
1592+
runtime.init();
1593+
1594+
const input = document.getElementById('agent-workspace-input') as HTMLTextAreaElement;
1595+
const form = document.getElementById('agent-workspace-form') as HTMLFormElement;
1596+
input.value = 'repeat diagnostics';
1597+
form.dispatchEvent(new dom!.window.Event('submit', { bubbles: true, cancelable: true }));
1598+
await flushAsync();
1599+
1600+
input.value = 'repeat diagnostics';
1601+
form.dispatchEvent(new dom!.window.Event('submit', { bubbles: true, cancelable: true }));
1602+
await flushAsync();
1603+
1604+
const actionButton = document.querySelector('.agent-workspace-action-button') as HTMLButtonElement;
1605+
expect(actionButton).not.toBeNull();
1606+
actionButton.click();
1607+
await flushAsync();
1608+
1609+
const snapshot = runtime.getDiagnosticsSnapshot();
1610+
expect(snapshot.conversationRequests).toBe(2);
1611+
expect(snapshot.replayCandidateTurns).toBe(1);
1612+
expect(snapshot.turnCounts.user).toBe(2);
1613+
expect(snapshot.latestKnowledgePoints).toBe(1);
1614+
expect(snapshot.pathState.visible).toBe(true);
1615+
expect(snapshot.pathState.fullscreen).toBe(false);
1616+
expect(snapshot.lastConversation).toEqual(
1617+
expect.objectContaining({
1618+
status: 'success',
1619+
replayCandidate: true,
1620+
knowledgePoints: 1,
1621+
})
1622+
);
1623+
1624+
const requestEvent = snapshot.capabilityEvents.find(
1625+
(event) => event.phase === 'request' && event.operationId === 'build_learning_path'
1626+
);
1627+
expect(requestEvent).toBeDefined();
1628+
expect(snapshot.lastCapabilityEvent).toEqual(
1629+
expect.objectContaining({
1630+
phase: 'result',
1631+
status: 'success',
1632+
operationId: 'build_learning_path',
1633+
resultPresentation: 'learning_path_card',
1634+
})
1635+
);
1636+
});
14851637
});

src/agent_workspace.runtime.integration.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ describe('agent workspace runtime integration baseline', () => {
3737
expect(runtimeSource).toContain('pathApp.init(');
3838
expect(runtimeSource).toContain('pathApp.switchCentral(');
3939
expect(runtimeSource).toContain('requestBridgeWindowVisibility');
40+
expect(runtimeSource).toContain('getDiagnosticsSnapshot');
41+
expect(runtimeSource).toContain('__noteConnectionAgentWorkspaceRuntimeInstance');
4042
});
4143

4244
test('styles define dock layout and responsive coexistence rules', () => {

0 commit comments

Comments
 (0)