child-catalog.worker.ts 4.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /** Cold catalog observations of persisted fork children with tool-heavy inherited histories. */
  2. import { performance } from 'node:perf_hooks'
  3. import { Context } from '@deepseek-ai/cordis'
  4. import SessionStore, { SESSION_FORMAT_VERSION, SessionId, SessionLogOffset, SessionSeq } from '@deepseek-ai/dsh-session'
  5. import type { SessionEvent } from '@deepseek-ai/dsh-session'
  6. import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl'
  7. import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
  8. import SessionQueryEngine from '@deepseek-ai/dsh-session-query'
  9. import SubagentRuntime, { SUBAGENT_DESCRIPTOR_VERSION } from '@deepseek-ai/dsh-subagent'
  10. import { assertBuiltBenchmarkRuntime } from '../support/built-worker.ts'
  11. import { PARENT_ID, syntheticHistory, TIME_ZERO, WORKLOAD } from './workload.ts'
  12. /** Two complete catalog reads in one fresh Host, with every child observation released. */
  13. export interface CatalogReport {
  14. readonly totalMs: number
  15. readonly firstMs: number
  16. readonly repeatMs: number
  17. readonly cpuUserMs: number
  18. readonly cpuSystemMs: number
  19. readonly children: number
  20. readonly peakRssMb: number
  21. }
  22. class CatalogQuery extends SessionQueryEngine {
  23. override searchSessions(): Promise<never> {
  24. return Promise.reject(new Error('search is outside the child-catalog benchmark'))
  25. }
  26. override searchEvents(): Promise<never> {
  27. return Promise.reject(new Error('search is outside the child-catalog benchmark'))
  28. }
  29. }
  30. async function seed(ctx: Context): Promise<void> {
  31. const inherited = syntheticHistory(WORKLOAD.childHistoryTurns)
  32. for (let child = 0; child < WORKLOAD.children; child++) {
  33. const id = SessionId('bench-child-' + String(child))
  34. const events: SessionEvent[] = [
  35. ...inherited,
  36. { type: 'session/end-seed', seq: SessionSeq(inherited.length), time: TIME_ZERO + inherited.length, data: { inherited: true } },
  37. { type: 'subagent/descriptor', seq: SessionSeq(inherited.length + 1), time: TIME_ZERO + inherited.length + 1, data: {
  38. version: SUBAGENT_DESCRIPTOR_VERSION, mode: 'continuable', provider: 'fork', label: 'Synthetic child ' + String(child),
  39. } },
  40. ]
  41. const handle = await ctx.sessionPersistence.create({
  42. version: SESSION_FORMAT_VERSION, id, createdAt: TIME_ZERO + child, cwd: '/bench',
  43. parentSession: PARENT_ID, isSeeded: true, origin: 'subagent', delegationDepth: 1,
  44. }, { inheritedEventCount: SessionLogOffset(inherited.length) })
  45. try {
  46. await handle.append(events)
  47. await handle.flush()
  48. } finally { await handle.close() }
  49. }
  50. }
  51. async function run(root: string, mode: string): Promise<CatalogReport | { seeded: true }> {
  52. const ctx = new Context()
  53. try {
  54. await ctx.plugin(SessionStore)
  55. await ctx.plugin(SessionProjectionRegistry)
  56. await ctx.plugin(JsonlSessionPersistence, { root, compression: 'zstd' })
  57. await ctx.plugin(CatalogQuery)
  58. await ctx.plugin(SubagentRuntime)
  59. if (mode === 'seed') {
  60. await seed(ctx)
  61. return { seeded: true }
  62. }
  63. const cpuStart = process.cpuUsage()
  64. const start = performance.now()
  65. const first = await ctx.subagents.listChildren(PARENT_ID)
  66. const firstDone = performance.now()
  67. const repeated = await ctx.subagents.listChildren(PARENT_ID)
  68. const end = performance.now()
  69. const cpu = process.cpuUsage(cpuStart)
  70. if (first.length !== WORKLOAD.children || repeated.length !== WORKLOAD.children
  71. || [...first, ...repeated].some(row => row.kind !== 'child')) {
  72. throw new Error('child-catalog benchmark did not reach the complete healthy catalog')
  73. }
  74. return {
  75. totalMs: end - start, firstMs: firstDone - start, repeatMs: end - firstDone,
  76. cpuUserMs: cpu.user / 1_000, cpuSystemMs: cpu.system / 1_000,
  77. children: first.length, peakRssMb: process.resourceUsage().maxRSS / 1_024,
  78. }
  79. } finally { await ctx.fiber.dispose() }
  80. }
  81. assertBuiltBenchmarkRuntime(import.meta.url, Object.fromEntries([
  82. '@deepseek-ai/dsh-subagent', '@deepseek-ai/dsh-session-query',
  83. '@deepseek-ai/dsh-session-persistence-jsonl',
  84. ].map(name => [name, import.meta.resolve(name)])))
  85. const [root, mode] = process.argv.slice(2)
  86. if (root === undefined || (mode !== 'seed' && mode !== 'catalog')) {
  87. throw new Error('usage: child-catalog.worker.js <root> <seed|catalog>')
  88. }
  89. process.stdout.write(JSON.stringify(await run(root, mode)) + '\n')