@getpaseo/server 0.1.63 → 0.1.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (265) hide show
  1. package/dist/server/client/daemon-client-transport-types.d.ts +2 -0
  2. package/dist/server/client/daemon-client-transport-types.d.ts.map +1 -1
  3. package/dist/server/client/daemon-client-websocket-transport.d.ts +2 -1
  4. package/dist/server/client/daemon-client-websocket-transport.d.ts.map +1 -1
  5. package/dist/server/client/daemon-client-websocket-transport.js +4 -4
  6. package/dist/server/client/daemon-client-websocket-transport.js.map +1 -1
  7. package/dist/server/client/daemon-client.d.ts +30 -20
  8. package/dist/server/client/daemon-client.d.ts.map +1 -1
  9. package/dist/server/client/daemon-client.js +206 -98
  10. package/dist/server/client/daemon-client.js.map +1 -1
  11. package/dist/server/client/terminal-stream-router.d.ts +24 -0
  12. package/dist/server/client/terminal-stream-router.d.ts.map +1 -0
  13. package/dist/server/client/terminal-stream-router.js +100 -0
  14. package/dist/server/client/terminal-stream-router.js.map +1 -0
  15. package/dist/server/server/agent/activity-curator.d.ts +6 -3
  16. package/dist/server/server/agent/activity-curator.d.ts.map +1 -1
  17. package/dist/server/server/agent/activity-curator.js +45 -138
  18. package/dist/server/server/agent/activity-curator.js.map +1 -1
  19. package/dist/server/server/agent/agent-manager.d.ts +3 -14
  20. package/dist/server/server/agent/agent-manager.d.ts.map +1 -1
  21. package/dist/server/server/agent/agent-manager.js +75 -140
  22. package/dist/server/server/agent/agent-manager.js.map +1 -1
  23. package/dist/server/server/agent/agent-metadata-generator.d.ts +0 -5
  24. package/dist/server/server/agent/agent-metadata-generator.d.ts.map +1 -1
  25. package/dist/server/server/agent/agent-metadata-generator.js +3 -93
  26. package/dist/server/server/agent/agent-metadata-generator.js.map +1 -1
  27. package/dist/server/server/agent/agent-sdk-types.d.ts +15 -1
  28. package/dist/server/server/agent/agent-sdk-types.d.ts.map +1 -1
  29. package/dist/server/server/agent/agent-stream-coalescer.d.ts +1 -1
  30. package/dist/server/server/agent/agent-stream-coalescer.d.ts.map +1 -1
  31. package/dist/server/server/agent/agent-stream-coalescer.js +1 -1
  32. package/dist/server/server/agent/agent-stream-coalescer.js.map +1 -1
  33. package/dist/server/server/agent/agent-timeline-store.d.ts.map +1 -1
  34. package/dist/server/server/agent/agent-timeline-store.js +29 -32
  35. package/dist/server/server/agent/agent-timeline-store.js.map +1 -1
  36. package/dist/server/server/agent/foreground-run-state.d.ts +50 -0
  37. package/dist/server/server/agent/foreground-run-state.d.ts.map +1 -0
  38. package/dist/server/server/agent/foreground-run-state.js +162 -0
  39. package/dist/server/server/agent/foreground-run-state.js.map +1 -0
  40. package/dist/server/server/agent/mcp-server.d.ts +5 -3
  41. package/dist/server/server/agent/mcp-server.d.ts.map +1 -1
  42. package/dist/server/server/agent/mcp-server.js +110 -99
  43. package/dist/server/server/agent/mcp-server.js.map +1 -1
  44. package/dist/server/server/agent/mcp-shared.d.ts.map +1 -1
  45. package/dist/server/server/agent/mcp-shared.js +7 -1
  46. package/dist/server/server/agent/mcp-shared.js.map +1 -1
  47. package/dist/server/server/agent/prompt-attachments.d.ts +4 -3
  48. package/dist/server/server/agent/prompt-attachments.d.ts.map +1 -1
  49. package/dist/server/server/agent/prompt-attachments.js +43 -4
  50. package/dist/server/server/agent/prompt-attachments.js.map +1 -1
  51. package/dist/server/server/agent/provider-manifest.d.ts.map +1 -1
  52. package/dist/server/server/agent/provider-manifest.js +7 -0
  53. package/dist/server/server/agent/provider-manifest.js.map +1 -1
  54. package/dist/server/server/agent/providers/acp-agent.d.ts +38 -1
  55. package/dist/server/server/agent/providers/acp-agent.d.ts.map +1 -1
  56. package/dist/server/server/agent/providers/acp-agent.js +257 -140
  57. package/dist/server/server/agent/providers/acp-agent.js.map +1 -1
  58. package/dist/server/server/agent/providers/claude/sidechain-tracker.d.ts.map +1 -1
  59. package/dist/server/server/agent/providers/claude/sidechain-tracker.js +1 -1
  60. package/dist/server/server/agent/providers/claude/sidechain-tracker.js.map +1 -1
  61. package/dist/server/server/agent/providers/claude/tool-call-mapper.d.ts.map +1 -1
  62. package/dist/server/server/agent/providers/claude/tool-call-mapper.js +68 -198
  63. package/dist/server/server/agent/providers/claude/tool-call-mapper.js.map +1 -1
  64. package/dist/server/server/agent/providers/claude-agent.d.ts.map +1 -1
  65. package/dist/server/server/agent/providers/claude-agent.js +52 -102
  66. package/dist/server/server/agent/providers/claude-agent.js.map +1 -1
  67. package/dist/server/server/agent/providers/codex/tool-call-mapper.d.ts.map +1 -1
  68. package/dist/server/server/agent/providers/codex/tool-call-mapper.js +125 -141
  69. package/dist/server/server/agent/providers/codex/tool-call-mapper.js.map +1 -1
  70. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts +36 -6
  71. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts.map +1 -1
  72. package/dist/server/server/agent/providers/codex-app-server-agent.js +374 -219
  73. package/dist/server/server/agent/providers/codex-app-server-agent.js.map +1 -1
  74. package/dist/server/server/agent/providers/mock-load-test-agent.d.ts +6 -2
  75. package/dist/server/server/agent/providers/mock-load-test-agent.d.ts.map +1 -1
  76. package/dist/server/server/agent/providers/mock-load-test-agent.js +294 -113
  77. package/dist/server/server/agent/providers/mock-load-test-agent.js.map +1 -1
  78. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.d.ts +1 -1
  79. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.d.ts.map +1 -1
  80. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.js +94 -2
  81. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.js.map +1 -1
  82. package/dist/server/server/agent/providers/opencode/tool-call-mapper.d.ts.map +1 -1
  83. package/dist/server/server/agent/providers/opencode/tool-call-mapper.js +24 -115
  84. package/dist/server/server/agent/providers/opencode/tool-call-mapper.js.map +1 -1
  85. package/dist/server/server/agent/providers/opencode-agent.d.ts +102 -1
  86. package/dist/server/server/agent/providers/opencode-agent.d.ts.map +1 -1
  87. package/dist/server/server/agent/providers/opencode-agent.js +416 -158
  88. package/dist/server/server/agent/providers/opencode-agent.js.map +1 -1
  89. package/dist/server/server/agent/providers/provider-runner.d.ts +27 -0
  90. package/dist/server/server/agent/providers/provider-runner.d.ts.map +1 -0
  91. package/dist/server/server/agent/providers/provider-runner.js +80 -0
  92. package/dist/server/server/agent/providers/provider-runner.js.map +1 -0
  93. package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts +6 -3
  94. package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts.map +1 -1
  95. package/dist/server/server/agent/providers/tool-call-mapper-utils.d.ts +2 -0
  96. package/dist/server/server/agent/providers/tool-call-mapper-utils.d.ts.map +1 -1
  97. package/dist/server/server/agent/providers/tool-call-mapper-utils.js +31 -0
  98. package/dist/server/server/agent/providers/tool-call-mapper-utils.js.map +1 -1
  99. package/dist/server/server/agent/timeline-projection.d.ts +21 -5
  100. package/dist/server/server/agent/timeline-projection.d.ts.map +1 -1
  101. package/dist/server/server/agent/timeline-projection.js +59 -9
  102. package/dist/server/server/agent/timeline-projection.js.map +1 -1
  103. package/dist/server/server/auth.d.ts +25 -0
  104. package/dist/server/server/auth.d.ts.map +1 -0
  105. package/dist/server/server/auth.js +93 -0
  106. package/dist/server/server/auth.js.map +1 -0
  107. package/dist/server/server/bootstrap.d.ts +3 -1
  108. package/dist/server/server/bootstrap.d.ts.map +1 -1
  109. package/dist/server/server/bootstrap.js +87 -30
  110. package/dist/server/server/bootstrap.js.map +1 -1
  111. package/dist/server/server/config.d.ts.map +1 -1
  112. package/dist/server/server/config.js +11 -0
  113. package/dist/server/server/config.js.map +1 -1
  114. package/dist/server/server/exports.d.ts +7 -1
  115. package/dist/server/server/exports.d.ts.map +1 -1
  116. package/dist/server/server/exports.js +6 -1
  117. package/dist/server/server/exports.js.map +1 -1
  118. package/dist/server/server/file-explorer/service.d.ts +10 -0
  119. package/dist/server/server/file-explorer/service.d.ts.map +1 -1
  120. package/dist/server/server/file-explorer/service.js +38 -4
  121. package/dist/server/server/file-explorer/service.js.map +1 -1
  122. package/dist/server/server/index.js +9 -6
  123. package/dist/server/server/index.js.map +1 -1
  124. package/dist/server/server/logger.d.ts.map +1 -1
  125. package/dist/server/server/logger.js +15 -1
  126. package/dist/server/server/logger.js.map +1 -1
  127. package/dist/server/server/pagination/cursor.d.ts +16 -0
  128. package/dist/server/server/pagination/cursor.d.ts.map +1 -0
  129. package/dist/server/server/pagination/cursor.js +62 -0
  130. package/dist/server/server/pagination/cursor.js.map +1 -0
  131. package/dist/server/server/pagination/sortable-pager.d.ts +24 -0
  132. package/dist/server/server/pagination/sortable-pager.d.ts.map +1 -0
  133. package/dist/server/server/pagination/sortable-pager.js +68 -0
  134. package/dist/server/server/pagination/sortable-pager.js.map +1 -0
  135. package/dist/server/server/paseo-worktree-archive-service.d.ts +3 -1
  136. package/dist/server/server/paseo-worktree-archive-service.d.ts.map +1 -1
  137. package/dist/server/server/paseo-worktree-archive-service.js +61 -53
  138. package/dist/server/server/paseo-worktree-archive-service.js.map +1 -1
  139. package/dist/server/server/paseo-worktree-service.d.ts +13 -0
  140. package/dist/server/server/paseo-worktree-service.d.ts.map +1 -1
  141. package/dist/server/server/paseo-worktree-service.js +72 -3
  142. package/dist/server/server/paseo-worktree-service.js.map +1 -1
  143. package/dist/server/server/persisted-config.d.ts +25 -0
  144. package/dist/server/server/persisted-config.d.ts.map +1 -1
  145. package/dist/server/server/persisted-config.js +9 -0
  146. package/dist/server/server/persisted-config.js.map +1 -1
  147. package/dist/server/server/relay-transport.d.ts.map +1 -1
  148. package/dist/server/server/relay-transport.js +16 -4
  149. package/dist/server/server/relay-transport.js.map +1 -1
  150. package/dist/server/server/resolve-worktree-creation-intent.d.ts +0 -10
  151. package/dist/server/server/resolve-worktree-creation-intent.d.ts.map +1 -1
  152. package/dist/server/server/resolve-worktree-creation-intent.js +1 -45
  153. package/dist/server/server/resolve-worktree-creation-intent.js.map +1 -1
  154. package/dist/server/server/script-status-projection.d.ts +6 -1
  155. package/dist/server/server/script-status-projection.d.ts.map +1 -1
  156. package/dist/server/server/script-status-projection.js +12 -3
  157. package/dist/server/server/script-status-projection.js.map +1 -1
  158. package/dist/server/server/session.d.ts +19 -51
  159. package/dist/server/server/session.d.ts.map +1 -1
  160. package/dist/server/server/session.js +354 -1069
  161. package/dist/server/server/session.js.map +1 -1
  162. package/dist/server/server/websocket-server.d.ts +4 -2
  163. package/dist/server/server/websocket-server.d.ts.map +1 -1
  164. package/dist/server/server/websocket-server.js +65 -12
  165. package/dist/server/server/websocket-server.js.map +1 -1
  166. package/dist/server/server/workspace-directory.d.ts +69 -0
  167. package/dist/server/server/workspace-directory.d.ts.map +1 -0
  168. package/dist/server/server/workspace-directory.js +229 -0
  169. package/dist/server/server/workspace-directory.js.map +1 -0
  170. package/dist/server/server/worktree-bootstrap.d.ts.map +1 -1
  171. package/dist/server/server/worktree-bootstrap.js +6 -2
  172. package/dist/server/server/worktree-bootstrap.js.map +1 -1
  173. package/dist/server/server/worktree-core.d.ts +2 -0
  174. package/dist/server/server/worktree-core.d.ts.map +1 -1
  175. package/dist/server/server/worktree-core.js.map +1 -1
  176. package/dist/server/server/worktree-errors.d.ts +1 -1
  177. package/dist/server/server/worktree-errors.d.ts.map +1 -1
  178. package/dist/server/server/worktree-errors.js +1 -4
  179. package/dist/server/server/worktree-errors.js.map +1 -1
  180. package/dist/server/server/worktree-session.d.ts +47 -20
  181. package/dist/server/server/worktree-session.d.ts.map +1 -1
  182. package/dist/server/server/worktree-session.js +68 -25
  183. package/dist/server/server/worktree-session.js.map +1 -1
  184. package/dist/server/shared/binary-frames/file-transfer.d.ts +56 -0
  185. package/dist/server/shared/binary-frames/file-transfer.d.ts.map +1 -0
  186. package/dist/server/shared/binary-frames/file-transfer.js +108 -0
  187. package/dist/server/shared/binary-frames/file-transfer.js.map +1 -0
  188. package/dist/server/shared/binary-frames/index.d.ts +3 -0
  189. package/dist/server/shared/binary-frames/index.d.ts.map +1 -0
  190. package/dist/server/shared/binary-frames/index.js +3 -0
  191. package/dist/server/shared/binary-frames/index.js.map +1 -0
  192. package/dist/server/shared/{terminal-stream-protocol.d.ts → binary-frames/terminal.d.ts} +2 -2
  193. package/dist/server/shared/binary-frames/terminal.d.ts.map +1 -0
  194. package/dist/server/shared/{terminal-stream-protocol.js → binary-frames/terminal.js} +2 -2
  195. package/dist/server/shared/binary-frames/terminal.js.map +1 -0
  196. package/dist/server/shared/client-capabilities.d.ts +5 -0
  197. package/dist/server/shared/client-capabilities.d.ts.map +1 -0
  198. package/dist/server/shared/client-capabilities.js +4 -0
  199. package/dist/server/shared/client-capabilities.js.map +1 -0
  200. package/dist/server/shared/connection-offer.d.ts +8 -0
  201. package/dist/server/shared/connection-offer.d.ts.map +1 -1
  202. package/dist/server/shared/connection-offer.js +35 -0
  203. package/dist/server/shared/connection-offer.js.map +1 -1
  204. package/dist/server/shared/daemon-endpoints.d.ts +16 -1
  205. package/dist/server/shared/daemon-endpoints.d.ts.map +1 -1
  206. package/dist/server/shared/daemon-endpoints.js +65 -6
  207. package/dist/server/shared/daemon-endpoints.js.map +1 -1
  208. package/dist/server/shared/host-connection-schema.d.ts +23 -0
  209. package/dist/server/shared/host-connection-schema.d.ts.map +1 -0
  210. package/dist/server/shared/host-connection-schema.js +9 -0
  211. package/dist/server/shared/host-connection-schema.js.map +1 -0
  212. package/dist/server/shared/messages.d.ts +3242 -535
  213. package/dist/server/shared/messages.d.ts.map +1 -1
  214. package/dist/server/shared/messages.js +73 -34
  215. package/dist/server/shared/messages.js.map +1 -1
  216. package/dist/server/terminal/terminal-manager-factory.d.ts +7 -0
  217. package/dist/server/terminal/terminal-manager-factory.d.ts.map +1 -0
  218. package/dist/server/terminal/terminal-manager-factory.js +13 -0
  219. package/dist/server/terminal/terminal-manager-factory.js.map +1 -0
  220. package/dist/server/terminal/terminal-manager.d.ts +7 -1
  221. package/dist/server/terminal/terminal-manager.d.ts.map +1 -1
  222. package/dist/server/terminal/terminal-manager.js +14 -1
  223. package/dist/server/terminal/terminal-manager.js.map +1 -1
  224. package/dist/server/terminal/terminal-session-controller.d.ts +63 -0
  225. package/dist/server/terminal/terminal-session-controller.d.ts.map +1 -0
  226. package/dist/server/terminal/terminal-session-controller.js +615 -0
  227. package/dist/server/terminal/terminal-session-controller.js.map +1 -0
  228. package/dist/server/terminal/terminal-ts-loader.mjs +20 -0
  229. package/dist/server/terminal/terminal-worker-process.d.ts +2 -0
  230. package/dist/server/terminal/terminal-worker-process.d.ts.map +1 -0
  231. package/dist/server/terminal/terminal-worker-process.js +221 -0
  232. package/dist/server/terminal/terminal-worker-process.js.map +1 -0
  233. package/dist/server/terminal/terminal-worker-protocol.d.ts +113 -0
  234. package/dist/server/terminal/terminal-worker-protocol.d.ts.map +1 -0
  235. package/dist/server/terminal/terminal-worker-protocol.js +2 -0
  236. package/dist/server/terminal/terminal-worker-protocol.js.map +1 -0
  237. package/dist/server/terminal/terminal.d.ts +7 -0
  238. package/dist/server/terminal/terminal.d.ts.map +1 -1
  239. package/dist/server/terminal/terminal.js +22 -9
  240. package/dist/server/terminal/terminal.js.map +1 -1
  241. package/dist/server/terminal/worker-terminal-manager.d.ts +19 -0
  242. package/dist/server/terminal/worker-terminal-manager.d.ts.map +1 -0
  243. package/dist/server/terminal/worker-terminal-manager.js +466 -0
  244. package/dist/server/terminal/worker-terminal-manager.js.map +1 -0
  245. package/dist/server/utils/directory-suggestions.d.ts.map +1 -1
  246. package/dist/server/utils/directory-suggestions.js +10 -1
  247. package/dist/server/utils/directory-suggestions.js.map +1 -1
  248. package/dist/server/utils/process-tree.d.ts +25 -0
  249. package/dist/server/utils/process-tree.d.ts.map +1 -0
  250. package/dist/server/utils/process-tree.js +96 -0
  251. package/dist/server/utils/process-tree.js.map +1 -0
  252. package/dist/server/utils/windows-command.d.ts.map +1 -1
  253. package/dist/server/utils/windows-command.js +5 -1
  254. package/dist/server/utils/windows-command.js.map +1 -1
  255. package/dist/server/utils/worktree-metadata.d.ts +44 -0
  256. package/dist/server/utils/worktree-metadata.d.ts.map +1 -1
  257. package/dist/server/utils/worktree-metadata.js +58 -0
  258. package/dist/server/utils/worktree-metadata.js.map +1 -1
  259. package/dist/server/utils/worktree.d.ts +14 -2
  260. package/dist/server/utils/worktree.d.ts.map +1 -1
  261. package/dist/server/utils/worktree.js +22 -13
  262. package/dist/server/utils/worktree.js.map +1 -1
  263. package/package.json +5 -4
  264. package/dist/server/shared/terminal-stream-protocol.d.ts.map +0 -1
  265. package/dist/server/shared/terminal-stream-protocol.js.map +0 -1
@@ -26,6 +26,7 @@ export declare class MockLoadTestAgentSession implements AgentSession {
26
26
  private readonly history;
27
27
  private readonly logger?;
28
28
  private activeTurn;
29
+ private pendingPermissions;
29
30
  private modeId;
30
31
  private modelId;
31
32
  constructor(options: {
@@ -44,7 +45,7 @@ export declare class MockLoadTestAgentSession implements AgentSession {
44
45
  getCurrentMode(): Promise<string | null>;
45
46
  setMode(modeId: string): Promise<void>;
46
47
  getPendingPermissions(): AgentPermissionRequest[];
47
- respondToPermission(_requestId: string, _response: AgentPermissionResponse): Promise<AgentPermissionResult | void>;
48
+ respondToPermission(requestId: string, response: AgentPermissionResponse): Promise<AgentPermissionResult | void>;
48
49
  describePersistence(): AgentPersistenceHandle | null;
49
50
  interrupt(): Promise<void>;
50
51
  close(): Promise<void>;
@@ -52,11 +53,14 @@ export declare class MockLoadTestAgentSession implements AgentSession {
52
53
  private schedule;
53
54
  private scheduleLargePayloadTurn;
54
55
  private scheduleStressTurn;
56
+ private schedulePlanApprovalTurn;
57
+ private emitPlanApprovalTurn;
55
58
  private emitStressTurn;
56
59
  private emitLargePayloadTurn;
57
60
  private tick;
58
- private emitIteration;
61
+ private dispatchCycleEvent;
59
62
  private finishTurn;
63
+ private finishTurnWithText;
60
64
  private emitTimeline;
61
65
  private emit;
62
66
  private clearTurnTimer;
@@ -1 +1 @@
1
- {"version":3,"file":"mock-load-test-agent.d.ts","sourceRoot":"","sources":["../../../../../src/server/agent/providers/mock-load-test-agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mock-load-test-agent.d.ts","sourceRoot":"","sources":["../../../../../src/server/agent/providers/mock-load-test-agent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,KAAK,EACV,oBAAoB,EACpB,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,SAAS,EACT,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAEhB,gBAAgB,EAChB,iBAAiB,EACjB,0BAA0B,EAC1B,wBAAwB,EAGzB,MAAM,uBAAuB,CAAC;AAG/B,eAAO,MAAM,0BAA0B,SAAS,CAAC;AACjD,eAAO,MAAM,+BAA+B,uBAAuB,CAAC;AAuVpE,qBAAa,uBAAwB,YAAW,WAAW;IAI7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAHpC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAA8B;IAC9D,QAAQ,CAAC,YAAY,uBAAgB;gBAER,MAAM,CAAC,EAAE,MAAM,YAAA;IAEtC,aAAa,CACjB,MAAM,EAAE,kBAAkB,EAC1B,cAAc,CAAC,EAAE,kBAAkB,GAClC,OAAO,CAAC,YAAY,CAAC;IAQlB,aAAa,CACjB,MAAM,EAAE,sBAAsB,EAC9B,SAAS,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,EACvC,cAAc,CAAC,EAAE,kBAAkB,GAClC,OAAO,CAAC,YAAY,CAAC;IAclB,UAAU,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAIxE,SAAS,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAI3D,mBAAmB,CACvB,QAAQ,CAAC,EAAE,0BAA0B,GACpC,OAAO,CAAC,wBAAwB,EAAE,CAAC;IAIhC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAI/B,aAAa,IAAI,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CAKvD;AAED,qBAAa,wBAAyB,YAAW,YAAY;IAC3D,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAA8B;IAC9D,QAAQ,CAAC,YAAY,uBAAgB;IACrC,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE,CAAM;IACvC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgD;IAC1E,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,kBAAkB,CAA6C;IACvE,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,OAAO,CAAgB;gBAEnB,OAAO,EAAE;QAAE,MAAM,EAAE,kBAAkB,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAOjF,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IASjF,SAAS,CACb,MAAM,EAAE,gBAAgB,EACxB,QAAQ,CAAC,EAAE,eAAe,GACzB,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAyC9B,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,GAAG,MAAM,IAAI;IAO3D,aAAa,IAAI,cAAc,CAAC,gBAAgB,CAAC;IAMlD,cAAc,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAS3C,iBAAiB,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAIzC,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIxC,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5C,qBAAqB,IAAI,sBAAsB,EAAE;IAI3C,mBAAmB,CACvB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,uBAAuB,GAChC,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IAoBxC,mBAAmB,IAAI,sBAAsB,GAAG,IAAI;IAW9C,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,wBAAwB;IAUhC,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,wBAAwB;IAOhC,OAAO,CAAC,oBAAoB;IAoD5B,OAAO,CAAC,cAAc;IAiDtB,OAAO,CAAC,oBAAoB;IAyE5B,OAAO,CAAC,IAAI;IAkCZ,OAAO,CAAC,kBAAkB;IAgD1B,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,kBAAkB;IAuB1B,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,IAAI;IAWZ,OAAO,CAAC,cAAc;CAOvB"}
@@ -4,7 +4,7 @@ export const MOCK_LOAD_TEST_PROVIDER_ID = "mock";
4
4
  export const MOCK_LOAD_TEST_DEFAULT_MODEL_ID = "five-minute-stream";
5
5
  const MOCK_LOAD_TEST_MODE_ID = "load-test";
6
6
  const MOCK_LOAD_TEST_DURATION_MS = 5 * 60 * 1000;
7
- const MOCK_LOAD_TEST_INTERVAL_MS = 1000;
7
+ const MOCK_LOAD_TEST_INTERVAL_MS = 40;
8
8
  const CAPABILITIES = {
9
9
  supportsStreaming: true,
10
10
  supportsSessionPersistence: true,
@@ -18,34 +18,47 @@ const MODELS = [
18
18
  provider: MOCK_LOAD_TEST_PROVIDER_ID,
19
19
  id: MOCK_LOAD_TEST_DEFAULT_MODEL_ID,
20
20
  label: "Five minute stream",
21
- description: "Repeats synthetic markdown and tool-call timeline traffic for five minutes.",
21
+ description: "Realistic agent flow streamed as sub-word tokens for five minutes (good for scroll/coalesce debugging).",
22
22
  isDefault: true,
23
23
  metadata: {
24
24
  durationMs: MOCK_LOAD_TEST_DURATION_MS,
25
25
  intervalMs: MOCK_LOAD_TEST_INTERVAL_MS,
26
26
  },
27
27
  },
28
+ {
29
+ provider: MOCK_LOAD_TEST_PROVIDER_ID,
30
+ id: "thirty-minute-stream",
31
+ label: "Thirty minute stream",
32
+ description: "Long-running realistic stream for extended scroll-anchor debugging.",
33
+ metadata: {
34
+ durationMs: 30 * 60 * 1000,
35
+ intervalMs: 50,
36
+ },
37
+ },
28
38
  {
29
39
  provider: MOCK_LOAD_TEST_PROVIDER_ID,
30
40
  id: "one-minute-stream",
31
41
  label: "One minute stream",
32
- description: "Shorter synthetic load stream for quick manual checks.",
42
+ description: "Shorter realistic stream for quick manual checks.",
33
43
  metadata: {
34
44
  durationMs: 60000,
35
- intervalMs: 500,
45
+ intervalMs: 40,
36
46
  },
37
47
  },
38
48
  {
39
49
  provider: MOCK_LOAD_TEST_PROVIDER_ID,
40
50
  id: "ten-second-stream",
41
51
  label: "Ten second stream",
42
- description: "Fast synthetic load stream for tests and smoke checks.",
52
+ description: "Fast realistic stream for tests and smoke checks.",
43
53
  metadata: {
44
54
  durationMs: 10000,
45
- intervalMs: 250,
55
+ intervalMs: 5,
46
56
  },
47
57
  },
48
58
  ];
59
+ function shouldEmitPlanApprovalPrompt(prompt) {
60
+ return /emit\s+(?:a\s+)?synthetic\s+plan\s+approval/i.test(promptToText(prompt));
61
+ }
49
62
  function resolveModelProfile(modelId) {
50
63
  const model = MODELS.find((entry) => entry.id === modelId) ?? MODELS[0];
51
64
  const metadata = model.metadata ?? {};
@@ -102,39 +115,151 @@ function buildRepeatedPayload(bytes, prefix) {
102
115
  }
103
116
  return output.slice(0, bytes);
104
117
  }
105
- function buildMarkdownDocument(iteration, prompt) {
106
- const promptPreview = promptToText(prompt).slice(0, 160) || "No prompt text supplied.";
118
+ function tokenize(text) {
119
+ const tokens = [];
120
+ const regex = /(\s*)(\S+)|(\s+)/g;
121
+ let match;
122
+ while ((match = regex.exec(text)) !== null) {
123
+ const [, leadingWs, word, lonelyWs] = match;
124
+ if (lonelyWs !== undefined) {
125
+ tokens.push(lonelyWs);
126
+ continue;
127
+ }
128
+ const ws = leadingWs ?? "";
129
+ const w = word ?? "";
130
+ if (w.length <= 5) {
131
+ tokens.push(ws + w);
132
+ continue;
133
+ }
134
+ tokens.push(ws + w.slice(0, 4));
135
+ for (let i = 4; i < w.length; i += 4) {
136
+ tokens.push(w.slice(i, i + 4));
137
+ }
138
+ }
139
+ return tokens;
140
+ }
141
+ function buildIntroParagraph(cycle) {
107
142
  return [
108
- `## Synthetic Load Cycle ${iteration}`,
109
- "",
110
- `Prompt preview: ${promptPreview}`,
143
+ `## Cycle ${cycle}`,
111
144
  "",
112
- "| Signal | Value |",
113
- "| --- | --- |",
114
- `| cycle | ${iteration} |`,
115
- "| stream | markdown + reasoning + tools |",
145
+ "I'll take a look at the scroll anchor behavior you described. Let me start by walking through how the conversation list currently handles streaming updates and where the auto-scroll logic actually lives. My instinct is that the anchor is supposed to pin to the bottom only when the user is already there, but I want to confirm that against the code rather than guess. This kind of behavior is usually a thin layout effect over a ref, and the bugs tend to come from event ordering rather than the math itself, so the first useful step is to read the relevant files.",
146
+ ].join("\n");
147
+ }
148
+ function buildReasoningText() {
149
+ return "Need to find the scroll container, the layout effect that watches for new messages, and any gesture handler that might fight with programmatic scrolling. Probably a ref on the FlatList plus a near-bottom threshold.";
150
+ }
151
+ function buildMidParagraph() {
152
+ return [
153
+ "Now I have a clearer picture. The auto-scroll uses a ref on the FlatList and tracks whether the user has scrolled away from the bottom by comparing the offset against the content size. There are a few subtle issues worth flagging before we change anything:",
116
154
  "",
117
- "```ts",
118
- `const cycle = ${iteration};`,
119
- 'const purpose = "exercise app parsing and terminal rendering under load";',
120
- "```",
155
+ "- The threshold for 'near the bottom' is hardcoded at 80px, which feels too tight on dense content where headers and tool calls take up a lot of vertical space.",
156
+ "- We rely on `onContentSizeChange` to detect new content, but that fires after layout, not as the streaming delta arrives, so we end up scrolling one frame late on fast streams.",
157
+ "- The gesture handler does not pause scroll-to-bottom while the user is actively dragging, which means a drag in progress can be visually overridden mid-frame.",
158
+ "- Coalescing happens upstream, so the FlatList sees fewer updates than the wire — but each batch can still cause a relayout.",
121
159
  "",
122
- "This paragraph is intentionally stable so repeated cycles produce predictable UI pressure.",
160
+ "Let me make a small adjustment to the threshold and add a flag for active gestures, then run a quick command to confirm the order of events when streaming is fast.",
161
+ ].join("\n");
162
+ }
163
+ function buildClosingParagraph() {
164
+ return "The change should keep scroll-to-bottom working when the user is at the bottom while not yanking the viewport when they are reading earlier messages. The bash output confirms the `userIsAtBottom` flag flips correctly during a simulated streaming burst, and the gesture flag suppresses scroll while a drag is active. If you want, I can follow up with a regression test that drives the FlatList with synthetic deltas at high frequency to lock in the behavior. For now, I'll stop here so you can take a look.";
165
+ }
166
+ function buildEditDiff(filePath) {
167
+ return [
168
+ `diff --git a/${filePath} b/${filePath}`,
169
+ `--- a/${filePath}`,
170
+ `+++ b/${filePath}`,
171
+ "@@ -42,7 +42,9 @@",
172
+ " const ref = useRef<FlatList>(null);",
173
+ " const [userIsAtBottom, setUserIsAtBottom] = useState(true);",
174
+ "- const NEAR_BOTTOM_PX = 80;",
175
+ "+ const NEAR_BOTTOM_PX = 160;",
176
+ "+ const isDraggingRef = useRef(false);",
123
177
  "",
178
+ "- if (userIsAtBottom) ref.current?.scrollToEnd({ animated: true });",
179
+ "+ if (userIsAtBottom && !isDraggingRef.current) {",
180
+ "+ ref.current?.scrollToEnd({ animated: true });",
181
+ "+ }",
124
182
  ].join("\n");
125
183
  }
126
- function splitText(text, chunks) {
127
- const size = Math.ceil(text.length / chunks);
128
- const parts = [];
129
- for (let index = 0; index < text.length; index += size) {
130
- parts.push(text.slice(index, index + size));
184
+ function buildCycleQueue(turnId, cycle) {
185
+ const queue = [];
186
+ for (const tok of tokenize(buildIntroParagraph(cycle))) {
187
+ queue.push({ kind: "assistant_token", text: tok });
188
+ }
189
+ for (const tok of tokenize(buildReasoningText())) {
190
+ queue.push({ kind: "reasoning_token", text: tok });
131
191
  }
132
- return parts;
192
+ const readDetail = {
193
+ type: "read",
194
+ filePath: "packages/app/src/components/conversation-list.tsx",
195
+ };
196
+ const readId = `${turnId}:read:${cycle}`;
197
+ queue.push({ kind: "tool_running", callId: readId, name: "read", detail: readDetail });
198
+ queue.push({
199
+ kind: "tool_completed",
200
+ callId: readId,
201
+ name: "read",
202
+ detail: {
203
+ ...readDetail,
204
+ content: "export function ConversationList() {\n const ref = useRef<FlatList>(null);\n // ...\n}",
205
+ },
206
+ });
207
+ const grepDetail = {
208
+ type: "search",
209
+ query: "scrollToEnd",
210
+ toolName: "grep",
211
+ mode: "files_with_matches",
212
+ };
213
+ const grepId = `${turnId}:grep:${cycle}`;
214
+ queue.push({ kind: "tool_running", callId: grepId, name: "grep", detail: grepDetail });
215
+ queue.push({
216
+ kind: "tool_completed",
217
+ callId: grepId,
218
+ name: "grep",
219
+ detail: {
220
+ ...grepDetail,
221
+ filePaths: [
222
+ "packages/app/src/components/conversation-list.tsx",
223
+ "packages/app/src/hooks/use-scroll-anchor.ts",
224
+ ],
225
+ numFiles: 2,
226
+ numMatches: 5,
227
+ },
228
+ });
229
+ for (const tok of tokenize(buildMidParagraph())) {
230
+ queue.push({ kind: "assistant_token", text: tok });
231
+ }
232
+ const editFile = "packages/app/src/hooks/use-scroll-anchor.ts";
233
+ const editDetail = {
234
+ type: "edit",
235
+ filePath: editFile,
236
+ oldString: "const NEAR_BOTTOM_PX = 80;",
237
+ newString: "const NEAR_BOTTOM_PX = 160;",
238
+ unifiedDiff: buildEditDiff(editFile),
239
+ };
240
+ const editId = `${turnId}:edit:${cycle}`;
241
+ queue.push({ kind: "tool_running", callId: editId, name: "edit", detail: editDetail });
242
+ queue.push({ kind: "tool_completed", callId: editId, name: "edit", detail: editDetail });
243
+ const shellDetail = {
244
+ type: "shell",
245
+ command: "node scripts/simulate-stream-burst.mjs",
246
+ cwd: "/tmp/paseo-mock-load",
247
+ output: "[burst] tick 1 userIsAtBottom=true\n[burst] tick 2 userIsAtBottom=true\n[burst] drag-start isDragging=true\n[burst] tick 3 suppressed\n[burst] drag-end isDragging=false\n",
248
+ exitCode: 0,
249
+ };
250
+ const shellId = `${turnId}:bash:${cycle}`;
251
+ queue.push({ kind: "tool_running", callId: shellId, name: "bash", detail: shellDetail });
252
+ queue.push({ kind: "tool_completed", callId: shellId, name: "bash", detail: shellDetail });
253
+ for (const tok of tokenize(buildClosingParagraph())) {
254
+ queue.push({ kind: "assistant_token", text: tok });
255
+ }
256
+ queue.push({ kind: "usage" });
257
+ return queue;
133
258
  }
134
259
  function createToolCall(input) {
135
260
  return {
136
261
  type: "tool_call",
137
- callId: `${input.turnId}:${input.name}:${input.iteration}`,
262
+ callId: input.callId,
138
263
  name: input.name,
139
264
  status: input.status,
140
265
  error: null,
@@ -193,6 +318,7 @@ export class MockLoadTestAgentSession {
193
318
  this.listeners = new Set();
194
319
  this.history = [];
195
320
  this.activeTurn = null;
321
+ this.pendingPermissions = new Map();
196
322
  this.id = options.sessionId;
197
323
  this.logger = options.logger;
198
324
  this.modeId = options.config.modeId ?? MOCK_LOAD_TEST_MODE_ID;
@@ -220,17 +346,23 @@ export class MockLoadTestAgentSession {
220
346
  turnId,
221
347
  prompt,
222
348
  startedAt: Date.now(),
223
- iteration: 0,
349
+ cycle: 0,
224
350
  durationMs: profile.durationMs,
225
351
  intervalMs: profile.intervalMs,
226
352
  timer: null,
227
353
  resolve,
228
354
  completed,
355
+ queue: [],
356
+ emittedTokens: 0,
357
+ turnStarted: false,
229
358
  };
230
359
  this.activeTurn = turn;
231
360
  const largePayload = parseLargeAgentStreamPayloadPrompt(prompt);
232
361
  const stress = parseAgentStreamStressPrompt(prompt);
233
- if (largePayload) {
362
+ if (shouldEmitPlanApprovalPrompt(prompt)) {
363
+ this.schedulePlanApprovalTurn(turn);
364
+ }
365
+ else if (largePayload) {
234
366
  this.scheduleLargePayloadTurn(turn, largePayload);
235
367
  }
236
368
  else if (stress) {
@@ -270,9 +402,23 @@ export class MockLoadTestAgentSession {
270
402
  this.modeId = modeId;
271
403
  }
272
404
  getPendingPermissions() {
273
- return [];
405
+ return Array.from(this.pendingPermissions.values());
274
406
  }
275
- async respondToPermission(_requestId, _response) {
407
+ async respondToPermission(requestId, response) {
408
+ if (!this.pendingPermissions.delete(requestId)) {
409
+ return undefined;
410
+ }
411
+ const turn = this.activeTurn;
412
+ this.emit({
413
+ type: "permission_resolved",
414
+ provider: this.provider,
415
+ requestId,
416
+ resolution: response,
417
+ ...(turn ? { turnId: turn.turnId } : {}),
418
+ });
419
+ if (turn) {
420
+ this.finishTurnWithText(turn, "Synthetic plan approval resolved");
421
+ }
276
422
  return undefined;
277
423
  }
278
424
  describePersistence() {
@@ -331,6 +477,60 @@ export class MockLoadTestAgentSession {
331
477
  }, 0);
332
478
  turn.timer.unref?.();
333
479
  }
480
+ schedulePlanApprovalTurn(turn) {
481
+ turn.timer = setTimeout(() => {
482
+ this.emitPlanApprovalTurn(turn);
483
+ }, 0);
484
+ turn.timer.unref?.();
485
+ }
486
+ emitPlanApprovalTurn(turn) {
487
+ if (this.activeTurn !== turn) {
488
+ return;
489
+ }
490
+ this.clearTurnTimer(turn);
491
+ this.emit({
492
+ type: "turn_started",
493
+ provider: this.provider,
494
+ turnId: turn.turnId,
495
+ });
496
+ const request = {
497
+ id: `mock-plan-${turn.turnId}`,
498
+ provider: this.provider,
499
+ name: "MockPlanApproval",
500
+ kind: "plan",
501
+ title: "Plan",
502
+ description: "Review the proposed plan before implementation starts.",
503
+ input: {
504
+ plan: "1. Add the README note.\n2. Keep the change scoped.\n3. Verify the diff.",
505
+ },
506
+ actions: [
507
+ {
508
+ id: "implement",
509
+ label: "Implement",
510
+ behavior: "allow",
511
+ variant: "primary",
512
+ intent: "implement",
513
+ },
514
+ {
515
+ id: "dismiss",
516
+ label: "Dismiss",
517
+ behavior: "deny",
518
+ variant: "secondary",
519
+ intent: "dismiss",
520
+ },
521
+ ],
522
+ metadata: {
523
+ source: "mock_plan_approval",
524
+ },
525
+ };
526
+ this.pendingPermissions.set(request.id, request);
527
+ this.emit({
528
+ type: "permission_requested",
529
+ provider: this.provider,
530
+ request,
531
+ turnId: turn.turnId,
532
+ });
533
+ }
334
534
  emitStressTurn(turn, stress) {
335
535
  if (this.activeTurn !== turn) {
336
536
  return;
@@ -386,8 +586,7 @@ export class MockLoadTestAgentSession {
386
586
  const payload = buildRepeatedPayload(largePayload.bytes, largePayload.kind);
387
587
  if (largePayload.kind === "diff") {
388
588
  this.emitTimeline(turn.turnId, createToolCall({
389
- turnId: turn.turnId,
390
- iteration: 0,
589
+ callId: `${turn.turnId}:edit:large`,
391
590
  name: "edit",
392
591
  status: "completed",
393
592
  detail: {
@@ -399,8 +598,7 @@ export class MockLoadTestAgentSession {
399
598
  }
400
599
  else if (largePayload.kind === "file") {
401
600
  this.emitTimeline(turn.turnId, createToolCall({
402
- turnId: turn.turnId,
403
- iteration: 0,
601
+ callId: `${turn.turnId}:read:large`,
404
602
  name: "read",
405
603
  status: "completed",
406
604
  detail: {
@@ -442,7 +640,8 @@ export class MockLoadTestAgentSession {
442
640
  return;
443
641
  }
444
642
  this.clearTurnTimer(turn);
445
- if (turn.iteration === 0) {
643
+ if (!turn.turnStarted) {
644
+ turn.turnStarted = true;
446
645
  this.emit({
447
646
  type: "turn_started",
448
647
  provider: this.provider,
@@ -454,91 +653,73 @@ export class MockLoadTestAgentSession {
454
653
  this.finishTurn(turn);
455
654
  return;
456
655
  }
457
- turn.iteration += 1;
458
- this.emitIteration(turn);
656
+ if (turn.queue.length === 0) {
657
+ turn.cycle += 1;
658
+ turn.queue = buildCycleQueue(turn.turnId, turn.cycle);
659
+ }
660
+ const event = turn.queue.shift();
661
+ if (event) {
662
+ this.dispatchCycleEvent(turn, event);
663
+ }
459
664
  this.schedule(turn, turn.intervalMs);
460
665
  }
461
- emitIteration(turn) {
462
- const { turnId, iteration, prompt } = turn;
463
- this.emitTimeline(turnId, {
464
- type: "reasoning",
465
- text: `Thinking chunk ${iteration}: simulate planning pressure before rendering markdown.\n`,
466
- });
467
- for (const chunk of splitText(buildMarkdownDocument(iteration, prompt), 4)) {
468
- this.emitTimeline(turnId, {
469
- type: "assistant_message",
470
- text: chunk,
471
- });
666
+ dispatchCycleEvent(turn, event) {
667
+ switch (event.kind) {
668
+ case "assistant_token": {
669
+ turn.emittedTokens += 1;
670
+ this.emitTimeline(turn.turnId, {
671
+ type: "assistant_message",
672
+ text: event.text,
673
+ });
674
+ return;
675
+ }
676
+ case "reasoning_token": {
677
+ turn.emittedTokens += 1;
678
+ this.emitTimeline(turn.turnId, {
679
+ type: "reasoning",
680
+ text: event.text,
681
+ });
682
+ return;
683
+ }
684
+ case "tool_running":
685
+ case "tool_completed": {
686
+ this.emitTimeline(turn.turnId, createToolCall({
687
+ callId: event.callId,
688
+ name: event.name,
689
+ status: event.kind === "tool_running" ? "running" : "completed",
690
+ detail: event.detail,
691
+ }));
692
+ return;
693
+ }
694
+ case "usage": {
695
+ this.emit({
696
+ type: "usage_updated",
697
+ provider: this.provider,
698
+ turnId: turn.turnId,
699
+ usage: {
700
+ inputTokens: turn.cycle * 32,
701
+ outputTokens: turn.emittedTokens,
702
+ contextWindowUsedTokens: turn.emittedTokens * 2,
703
+ contextWindowMaxTokens: 128000,
704
+ },
705
+ });
706
+ return;
707
+ }
472
708
  }
473
- const editDetail = {
474
- type: "edit",
475
- filePath: `src/load-test-${iteration}.ts`,
476
- oldString: "before",
477
- newString: "after",
478
- unifiedDiff: [
479
- `diff --git a/src/load-test-${iteration}.ts b/src/load-test-${iteration}.ts`,
480
- "@@",
481
- "-before",
482
- "+after",
483
- ].join("\n"),
484
- };
485
- this.emitTimeline(turnId, createToolCall({
486
- turnId,
487
- iteration,
488
- name: "edit",
489
- status: "running",
490
- detail: editDetail,
491
- }));
492
- this.emitTimeline(turnId, createToolCall({
493
- turnId,
494
- iteration,
495
- name: "edit",
496
- status: "completed",
497
- detail: editDetail,
498
- }));
499
- const shellDetail = {
500
- type: "shell",
501
- command: `printf 'mock load cycle ${iteration}\\n'`,
502
- cwd: "/tmp/paseo-mock-load",
503
- output: `mock load cycle ${iteration}\n`,
504
- exitCode: 0,
505
- };
506
- this.emitTimeline(turnId, createToolCall({
507
- turnId,
508
- iteration,
509
- name: "bash",
510
- status: "running",
511
- detail: shellDetail,
512
- }));
513
- this.emitTimeline(turnId, createToolCall({
514
- turnId,
515
- iteration,
516
- name: "bash",
517
- status: "completed",
518
- detail: shellDetail,
519
- }));
520
- this.emit({
521
- type: "usage_updated",
522
- provider: this.provider,
523
- turnId,
524
- usage: {
525
- inputTokens: iteration * 32,
526
- outputTokens: iteration * 128,
527
- contextWindowUsedTokens: iteration * 160,
528
- contextWindowMaxTokens: 128000,
529
- },
530
- });
531
709
  }
532
710
  finishTurn(turn) {
533
- this.activeTurn = null;
534
711
  this.emitTimeline(turn.turnId, {
535
712
  type: "assistant_message",
536
- text: "## Synthetic load test complete\n\nThe mock provider finished its foreground turn.\n",
713
+ text: "\n\n_(end of synthetic stream)_\n",
537
714
  });
715
+ this.finishTurnWithText(turn, "Synthetic load test complete");
716
+ }
717
+ finishTurnWithText(turn, finalText) {
718
+ this.activeTurn = null;
538
719
  const usage = {
539
- inputTokens: turn.iteration * 32,
540
- outputTokens: turn.iteration * 128,
541
- contextWindowUsedTokens: turn.iteration * 160,
720
+ inputTokens: turn.cycle * 32,
721
+ outputTokens: turn.emittedTokens,
722
+ contextWindowUsedTokens: turn.emittedTokens * 2,
542
723
  contextWindowMaxTokens: 128000,
543
724
  };
544
725
  this.emit({
@@ -549,7 +730,7 @@ export class MockLoadTestAgentSession {
549
730
  });
550
731
  turn.resolve({
551
732
  sessionId: this.id,
552
- finalText: "Synthetic load test complete",
733
+ finalText,
553
734
  usage,
554
735
  timeline: [],
555
736
  canceled: false,