verify-timeline.ts 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #!/usr/bin/env npx tsx
  2. /**
  3. * Verify timeline builder correctly captures tools from a real session
  4. */
  5. import { createOpencodeClient } from '@opencode-ai/sdk';
  6. import { SessionReader } from './src/collector/session-reader.js';
  7. import { TimelineBuilder } from './src/collector/timeline-builder.js';
  8. const sessionId = process.argv[2];
  9. const baseUrl = process.argv[3] || 'http://127.0.0.1:3000';
  10. async function verify() {
  11. console.log(`Connecting to ${baseUrl}...`);
  12. const client = createOpencodeClient({ baseUrl });
  13. // Create reader with SDK client
  14. const reader = new SessionReader(client);
  15. const builder = new TimelineBuilder(reader);
  16. // Get session to test
  17. let targetSessionId = sessionId;
  18. if (!targetSessionId) {
  19. const sessions = await client.session.list();
  20. // Find a session with tools (our current conversation)
  21. targetSessionId = sessions.data?.find(s => s.title?.includes('Testing eval system'))?.id || sessions.data?.[0]?.id;
  22. }
  23. if (!targetSessionId) {
  24. console.log('No session found');
  25. return;
  26. }
  27. console.log(`\nTesting session: ${targetSessionId}`);
  28. // Get raw messages with parts
  29. console.log('\n=== Raw Data ===');
  30. const messagesWithParts = await reader.getMessagesWithParts(targetSessionId);
  31. console.log(`Messages: ${messagesWithParts.length}`);
  32. let rawToolCount = 0;
  33. const rawToolNames: string[] = [];
  34. for (const msg of messagesWithParts) {
  35. for (const part of msg.parts || []) {
  36. if (part.type === 'tool') {
  37. rawToolCount++;
  38. rawToolNames.push(part.tool);
  39. }
  40. }
  41. }
  42. console.log(`Tool parts in raw data: ${rawToolCount}`);
  43. if (rawToolNames.length > 0) {
  44. console.log(`Tools: ${[...new Set(rawToolNames)].join(', ')}`);
  45. }
  46. // Build timeline
  47. console.log('\n=== Timeline ===');
  48. const timeline = await builder.buildTimeline(targetSessionId);
  49. const toolCalls = timeline.filter(e => e.type === 'tool_call');
  50. console.log(`Total timeline events: ${timeline.length}`);
  51. console.log(`Tool call events: ${toolCalls.length}`);
  52. if (toolCalls.length > 0) {
  53. console.log('\nTool calls found:');
  54. toolCalls.slice(0, 10).forEach((tc, i) => {
  55. console.log(` ${i + 1}. ${tc.data?.tool}: ${JSON.stringify(tc.data?.state?.input || tc.data?.input || {}).substring(0, 100)}`);
  56. });
  57. }
  58. // Verify
  59. console.log('\n=== Verification ===');
  60. if (rawToolCount === toolCalls.length) {
  61. console.log(`✅ SUCCESS: Raw data has ${rawToolCount} tools, timeline has ${toolCalls.length} tool_call events`);
  62. } else {
  63. console.log(`❌ MISMATCH: Raw data has ${rawToolCount} tools, timeline has ${toolCalls.length} tool_call events`);
  64. }
  65. }
  66. verify().catch(console.error);