homegraph 1.4.1 → 1.5.1

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 (483) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +305 -268
  3. package/dist/bin/command-supervision.d.ts.map +1 -1
  4. package/dist/bin/command-supervision.js +7 -4
  5. package/dist/bin/command-supervision.js.map +1 -1
  6. package/dist/bin/homegraph.js +304 -81
  7. package/dist/bin/homegraph.js.map +1 -1
  8. package/dist/context/index.d.ts.map +1 -1
  9. package/dist/context/index.js +32 -11
  10. package/dist/context/index.js.map +1 -1
  11. package/dist/db/index.d.ts +143 -1
  12. package/dist/db/index.d.ts.map +1 -1
  13. package/dist/db/index.js +305 -28
  14. package/dist/db/index.js.map +1 -1
  15. package/dist/db/migrations.js +37 -37
  16. package/dist/db/queries.d.ts +43 -4
  17. package/dist/db/queries.d.ts.map +1 -1
  18. package/dist/db/queries.js +294 -170
  19. package/dist/db/queries.js.map +1 -1
  20. package/dist/db/schema.sql +203 -203
  21. package/dist/db/sqlite-adapter.d.ts +24 -17
  22. package/dist/db/sqlite-adapter.d.ts.map +1 -1
  23. package/dist/db/sqlite-adapter.js +292 -36
  24. package/dist/db/sqlite-adapter.js.map +1 -1
  25. package/dist/db/wal-valve.d.ts +15 -2
  26. package/dist/db/wal-valve.d.ts.map +1 -1
  27. package/dist/db/wal-valve.js +88 -6
  28. package/dist/db/wal-valve.js.map +1 -1
  29. package/dist/directory.js +5 -5
  30. package/dist/extraction/arkts-batch-worker.js +3 -2
  31. package/dist/extraction/arkts-batch-worker.js.map +1 -1
  32. package/dist/extraction/default-ignore.d.ts +39 -0
  33. package/dist/extraction/default-ignore.d.ts.map +1 -0
  34. package/dist/extraction/default-ignore.js +221 -0
  35. package/dist/extraction/default-ignore.js.map +1 -0
  36. package/dist/extraction/index.d.ts +9 -10
  37. package/dist/extraction/index.d.ts.map +1 -1
  38. package/dist/extraction/index.js +227 -323
  39. package/dist/extraction/index.js.map +1 -1
  40. package/dist/extraction/languages/arkts-viewtree.d.ts +2 -4
  41. package/dist/extraction/languages/arkts-viewtree.d.ts.map +1 -1
  42. package/dist/extraction/languages/arkts-viewtree.js +6 -21
  43. package/dist/extraction/languages/arkts-viewtree.js.map +1 -1
  44. package/dist/extraction/languages/arkts.d.ts +100 -6
  45. package/dist/extraction/languages/arkts.d.ts.map +1 -1
  46. package/dist/extraction/languages/arkts.js +1777 -173
  47. package/dist/extraction/languages/arkts.js.map +1 -1
  48. package/dist/extraction/store-worker.d.ts +20 -0
  49. package/dist/extraction/store-worker.d.ts.map +1 -0
  50. package/dist/extraction/store-worker.js +102 -0
  51. package/dist/extraction/store-worker.js.map +1 -0
  52. package/dist/extraction/store-writer.d.ts +48 -0
  53. package/dist/extraction/store-writer.d.ts.map +1 -0
  54. package/dist/extraction/store-writer.js +167 -0
  55. package/dist/extraction/store-writer.js.map +1 -0
  56. package/dist/extraction/tree-sitter.d.ts.map +1 -1
  57. package/dist/extraction/tree-sitter.js +47 -0
  58. package/dist/extraction/tree-sitter.js.map +1 -1
  59. package/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
  60. package/dist/extraction/wasm/tree-sitter-cfml.wasm +0 -0
  61. package/dist/extraction/wasm/tree-sitter-cfquery.wasm +0 -0
  62. package/dist/extraction/wasm/tree-sitter-cfscript.wasm +0 -0
  63. package/dist/extraction/wasm/tree-sitter-cobol.wasm +0 -0
  64. package/dist/extraction/wasm/tree-sitter-erlang.wasm +0 -0
  65. package/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
  66. package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
  67. package/dist/extraction/wasm/tree-sitter-vbnet.wasm +0 -0
  68. package/dist/extraction/wasm-runtime-flags.d.ts +14 -4
  69. package/dist/extraction/wasm-runtime-flags.d.ts.map +1 -1
  70. package/dist/extraction/wasm-runtime-flags.js +55 -7
  71. package/dist/extraction/wasm-runtime-flags.js.map +1 -1
  72. package/dist/index.d.ts +16 -5
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +135 -97
  75. package/dist/index.js.map +1 -1
  76. package/dist/installer/instructions-template.js +9 -9
  77. package/dist/mcp/liveness-watchdog.d.ts +18 -0
  78. package/dist/mcp/liveness-watchdog.d.ts.map +1 -1
  79. package/dist/mcp/liveness-watchdog.js +185 -73
  80. package/dist/mcp/liveness-watchdog.js.map +1 -1
  81. package/dist/mcp/query-worker.d.ts +2 -2
  82. package/dist/mcp/query-worker.js +2 -2
  83. package/dist/mcp/server-instructions.js +47 -47
  84. package/dist/mcp/tools.d.ts.map +1 -1
  85. package/dist/mcp/tools.js +42 -26
  86. package/dist/mcp/tools.js.map +1 -1
  87. package/dist/reasoning/reasoner.js +32 -32
  88. package/dist/resolution/callback-synthesizer.d.ts +52 -16
  89. package/dist/resolution/callback-synthesizer.d.ts.map +1 -1
  90. package/dist/resolution/callback-synthesizer.js +234 -180
  91. package/dist/resolution/callback-synthesizer.js.map +1 -1
  92. package/dist/resolution/cooperative-yield.d.ts +10 -2
  93. package/dist/resolution/cooperative-yield.d.ts.map +1 -1
  94. package/dist/resolution/cooperative-yield.js +6 -4
  95. package/dist/resolution/cooperative-yield.js.map +1 -1
  96. package/dist/resolution/frameworks/go.d.ts.map +1 -1
  97. package/dist/resolution/frameworks/go.js +29 -6
  98. package/dist/resolution/frameworks/go.js.map +1 -1
  99. package/dist/resolution/import-resolver.d.ts +2 -3
  100. package/dist/resolution/import-resolver.d.ts.map +1 -1
  101. package/dist/resolution/import-resolver.js +166 -7
  102. package/dist/resolution/import-resolver.js.map +1 -1
  103. package/dist/resolution/index.d.ts +87 -2
  104. package/dist/resolution/index.d.ts.map +1 -1
  105. package/dist/resolution/index.js +739 -131
  106. package/dist/resolution/index.js.map +1 -1
  107. package/dist/resolution/memory-budget.d.ts +48 -0
  108. package/dist/resolution/memory-budget.d.ts.map +1 -0
  109. package/dist/resolution/memory-budget.js +162 -0
  110. package/dist/resolution/memory-budget.js.map +1 -0
  111. package/dist/resolution/name-matcher.d.ts +12 -1
  112. package/dist/resolution/name-matcher.d.ts.map +1 -1
  113. package/dist/resolution/name-matcher.js +439 -97
  114. package/dist/resolution/name-matcher.js.map +1 -1
  115. package/dist/resolution/resolver-pool.d.ts +106 -0
  116. package/dist/resolution/resolver-pool.d.ts.map +1 -0
  117. package/dist/resolution/resolver-pool.js +344 -0
  118. package/dist/resolution/resolver-pool.js.map +1 -0
  119. package/dist/resolution/resolver-worker.d.ts +17 -0
  120. package/dist/resolution/resolver-worker.d.ts.map +1 -0
  121. package/dist/resolution/resolver-worker.js +141 -0
  122. package/dist/resolution/resolver-worker.js.map +1 -0
  123. package/dist/resolution/types.d.ts +3 -0
  124. package/dist/resolution/types.d.ts.map +1 -1
  125. package/dist/spec/build/diff-parser.d.ts +55 -0
  126. package/dist/spec/build/diff-parser.d.ts.map +1 -0
  127. package/dist/spec/build/diff-parser.js +205 -0
  128. package/dist/spec/build/diff-parser.js.map +1 -0
  129. package/dist/spec/build/pipeline.d.ts +54 -0
  130. package/dist/spec/build/pipeline.d.ts.map +1 -0
  131. package/dist/spec/build/pipeline.js +170 -0
  132. package/dist/spec/build/pipeline.js.map +1 -0
  133. package/dist/spec/build/scan.d.ts +48 -0
  134. package/dist/spec/build/scan.d.ts.map +1 -0
  135. package/dist/spec/build/scan.js +89 -0
  136. package/dist/spec/build/scan.js.map +1 -0
  137. package/dist/spec/build/scope-resolver.d.ts +50 -0
  138. package/dist/spec/build/scope-resolver.d.ts.map +1 -0
  139. package/dist/spec/build/scope-resolver.js +105 -0
  140. package/dist/spec/build/scope-resolver.js.map +1 -0
  141. package/dist/spec/build/spec-extractor.d.ts +74 -0
  142. package/dist/spec/build/spec-extractor.d.ts.map +1 -0
  143. package/dist/spec/build/spec-extractor.js +344 -0
  144. package/dist/spec/build/spec-extractor.js.map +1 -0
  145. package/dist/spec/config.d.ts +35 -1
  146. package/dist/spec/config.d.ts.map +1 -1
  147. package/dist/spec/config.js +30 -5
  148. package/dist/spec/config.js.map +1 -1
  149. package/dist/spec/db/commit-node.js +4 -4
  150. package/dist/spec/db/fragment-node.js +10 -10
  151. package/dist/spec/db/fts.d.ts.map +1 -1
  152. package/dist/spec/db/fts.js +27 -58
  153. package/dist/spec/db/fts.js.map +1 -1
  154. package/dist/spec/db/index.d.ts +5 -3
  155. package/dist/spec/db/index.d.ts.map +1 -1
  156. package/dist/spec/db/index.js +16 -1
  157. package/dist/spec/db/index.js.map +1 -1
  158. package/dist/spec/db/persist.d.ts +45 -0
  159. package/dist/spec/db/persist.d.ts.map +1 -0
  160. package/dist/spec/db/persist.js +66 -0
  161. package/dist/spec/db/persist.js.map +1 -0
  162. package/dist/spec/db/relations.d.ts +80 -1
  163. package/dist/spec/db/relations.d.ts.map +1 -1
  164. package/dist/spec/db/relations.js +218 -47
  165. package/dist/spec/db/relations.js.map +1 -1
  166. package/dist/spec/db/schema.d.ts +4 -0
  167. package/dist/spec/db/schema.d.ts.map +1 -1
  168. package/dist/spec/db/schema.js +10 -6
  169. package/dist/spec/db/schema.js.map +1 -1
  170. package/dist/spec/db/schema.sql +121 -117
  171. package/dist/spec/db/spec-node.d.ts +5 -0
  172. package/dist/spec/db/spec-node.d.ts.map +1 -1
  173. package/dist/spec/db/spec-node.js +15 -9
  174. package/dist/spec/db/spec-node.js.map +1 -1
  175. package/dist/spec/db/sql-utils.d.ts +11 -0
  176. package/dist/spec/db/sql-utils.d.ts.map +1 -0
  177. package/dist/spec/db/sql-utils.js +19 -0
  178. package/dist/spec/db/sql-utils.js.map +1 -0
  179. package/dist/spec/evolve/cluster-context.d.ts +30 -0
  180. package/dist/spec/evolve/cluster-context.d.ts.map +1 -0
  181. package/dist/spec/evolve/cluster-context.js +78 -0
  182. package/dist/spec/evolve/cluster-context.js.map +1 -0
  183. package/dist/spec/evolve/commit-spec-analyzer.d.ts +51 -0
  184. package/dist/spec/evolve/commit-spec-analyzer.d.ts.map +1 -0
  185. package/dist/spec/evolve/commit-spec-analyzer.js +88 -0
  186. package/dist/spec/evolve/commit-spec-analyzer.js.map +1 -0
  187. package/dist/spec/evolve/commit-spec-persister.d.ts +53 -0
  188. package/dist/spec/evolve/commit-spec-persister.d.ts.map +1 -0
  189. package/dist/spec/evolve/commit-spec-persister.js +93 -0
  190. package/dist/spec/evolve/commit-spec-persister.js.map +1 -0
  191. package/dist/spec/evolve/impact-locator.d.ts +23 -7
  192. package/dist/spec/evolve/impact-locator.d.ts.map +1 -1
  193. package/dist/spec/evolve/impact-locator.js +58 -14
  194. package/dist/spec/evolve/impact-locator.js.map +1 -1
  195. package/dist/spec/evolve/pipeline.d.ts +62 -25
  196. package/dist/spec/evolve/pipeline.d.ts.map +1 -1
  197. package/dist/spec/evolve/pipeline.js +436 -457
  198. package/dist/spec/evolve/pipeline.js.map +1 -1
  199. package/dist/spec/evolve/spec-rewriter.d.ts +13 -13
  200. package/dist/spec/evolve/spec-rewriter.d.ts.map +1 -1
  201. package/dist/spec/evolve/spec-rewriter.js +45 -45
  202. package/dist/spec/evolve/spec-rewriter.js.map +1 -1
  203. package/dist/spec/git/commits.d.ts +85 -0
  204. package/dist/spec/git/commits.d.ts.map +1 -0
  205. package/dist/spec/git/commits.js +218 -0
  206. package/dist/spec/git/commits.js.map +1 -0
  207. package/dist/spec/git/exec.d.ts +13 -0
  208. package/dist/spec/git/exec.d.ts.map +1 -0
  209. package/dist/spec/git/exec.js +19 -0
  210. package/dist/spec/git/exec.js.map +1 -0
  211. package/dist/spec/git/index.d.ts +9 -0
  212. package/dist/spec/git/index.d.ts.map +1 -0
  213. package/dist/spec/git/index.js +22 -0
  214. package/dist/spec/git/index.js.map +1 -0
  215. package/dist/spec/graph/index.d.ts +8 -0
  216. package/dist/spec/graph/index.d.ts.map +1 -0
  217. package/dist/spec/graph/index.js +17 -0
  218. package/dist/spec/graph/index.js.map +1 -0
  219. package/dist/spec/graph/queries.d.ts +6 -35
  220. package/dist/spec/graph/queries.d.ts.map +1 -1
  221. package/dist/spec/graph/queries.js +71 -248
  222. package/dist/spec/graph/queries.js.map +1 -1
  223. package/dist/spec/llm/agent-client.d.ts +59 -0
  224. package/dist/spec/llm/agent-client.d.ts.map +1 -0
  225. package/dist/spec/llm/agent-client.js +213 -0
  226. package/dist/spec/llm/agent-client.js.map +1 -0
  227. package/dist/spec/llm/agents/claude-code.d.ts +32 -0
  228. package/dist/spec/llm/agents/claude-code.d.ts.map +1 -0
  229. package/dist/spec/llm/agents/claude-code.js +125 -0
  230. package/dist/spec/llm/agents/claude-code.js.map +1 -0
  231. package/dist/spec/llm/agents/codex.d.ts +32 -0
  232. package/dist/spec/llm/agents/codex.d.ts.map +1 -0
  233. package/dist/spec/llm/agents/codex.js +145 -0
  234. package/dist/spec/llm/agents/codex.js.map +1 -0
  235. package/dist/spec/llm/agents/detect-utils.d.ts +28 -0
  236. package/dist/spec/llm/agents/detect-utils.d.ts.map +1 -0
  237. package/dist/spec/llm/agents/detect-utils.js +91 -0
  238. package/dist/spec/llm/agents/detect-utils.js.map +1 -0
  239. package/dist/spec/llm/agents/deveco-code.d.ts +33 -0
  240. package/dist/spec/llm/agents/deveco-code.d.ts.map +1 -0
  241. package/dist/spec/llm/agents/deveco-code.js +165 -0
  242. package/dist/spec/llm/agents/deveco-code.js.map +1 -0
  243. package/dist/spec/llm/agents/index.d.ts +31 -0
  244. package/dist/spec/llm/agents/index.d.ts.map +1 -0
  245. package/dist/spec/llm/agents/index.js +65 -0
  246. package/dist/spec/llm/agents/index.js.map +1 -0
  247. package/dist/spec/llm/agents/types.d.ts +76 -0
  248. package/dist/spec/llm/agents/types.d.ts.map +1 -0
  249. package/dist/spec/llm/agents/types.js +15 -0
  250. package/dist/spec/llm/agents/types.js.map +1 -0
  251. package/dist/spec/llm/client.d.ts +31 -11
  252. package/dist/spec/llm/client.d.ts.map +1 -1
  253. package/dist/spec/llm/client.js +143 -81
  254. package/dist/spec/llm/client.js.map +1 -1
  255. package/dist/spec/llm/factory.d.ts +41 -0
  256. package/dist/spec/llm/factory.d.ts.map +1 -0
  257. package/dist/spec/llm/factory.js +80 -0
  258. package/dist/spec/llm/factory.js.map +1 -0
  259. package/dist/spec/llm/prompts.d.ts +24 -8
  260. package/dist/spec/llm/prompts.d.ts.map +1 -1
  261. package/dist/spec/llm/prompts.js +112 -62
  262. package/dist/spec/llm/prompts.js.map +1 -1
  263. package/dist/spec/llm/retry.d.ts +53 -0
  264. package/dist/spec/llm/retry.d.ts.map +1 -0
  265. package/dist/spec/llm/retry.js +153 -0
  266. package/dist/spec/llm/retry.js.map +1 -0
  267. package/dist/spec/mine/clustering/features.d.ts +38 -0
  268. package/dist/spec/mine/clustering/features.d.ts.map +1 -0
  269. package/dist/spec/mine/clustering/features.js +108 -0
  270. package/dist/spec/mine/clustering/features.js.map +1 -0
  271. package/dist/spec/mine/clustering/index.d.ts +62 -0
  272. package/dist/spec/mine/clustering/index.d.ts.map +1 -0
  273. package/dist/spec/mine/clustering/index.js +259 -0
  274. package/dist/spec/mine/clustering/index.js.map +1 -0
  275. package/dist/spec/mine/clustering/leiden.d.ts +61 -0
  276. package/dist/spec/mine/clustering/leiden.d.ts.map +1 -0
  277. package/dist/spec/mine/clustering/leiden.js +489 -0
  278. package/dist/spec/mine/clustering/leiden.js.map +1 -0
  279. package/dist/spec/mine/clustering/text-similarity.d.ts +22 -0
  280. package/dist/spec/mine/clustering/text-similarity.d.ts.map +1 -0
  281. package/dist/spec/mine/clustering/text-similarity.js +98 -0
  282. package/dist/spec/mine/clustering/text-similarity.js.map +1 -0
  283. package/dist/spec/mine/generator.d.ts +54 -0
  284. package/dist/spec/mine/generator.d.ts.map +1 -0
  285. package/dist/spec/mine/generator.js +267 -0
  286. package/dist/spec/mine/generator.js.map +1 -0
  287. package/dist/spec/mine/persist.d.ts +37 -0
  288. package/dist/spec/mine/persist.d.ts.map +1 -0
  289. package/dist/spec/mine/persist.js +170 -0
  290. package/dist/spec/mine/persist.js.map +1 -0
  291. package/dist/spec/mine/pipeline.d.ts +41 -0
  292. package/dist/spec/mine/pipeline.d.ts.map +1 -0
  293. package/dist/spec/mine/pipeline.js +236 -0
  294. package/dist/spec/mine/pipeline.js.map +1 -0
  295. package/dist/spec/mine/scanner.d.ts +59 -0
  296. package/dist/spec/mine/scanner.d.ts.map +1 -0
  297. package/dist/spec/mine/scanner.js +383 -0
  298. package/dist/spec/mine/scanner.js.map +1 -0
  299. package/dist/spec/types.d.ts +32 -0
  300. package/dist/spec/types.d.ts.map +1 -1
  301. package/dist/spec/ui/index.d.ts +9 -0
  302. package/dist/spec/ui/index.d.ts.map +1 -0
  303. package/dist/spec/ui/index.js +16 -0
  304. package/dist/spec/ui/index.js.map +1 -0
  305. package/dist/spec/ui/progress-handler.d.ts +33 -0
  306. package/dist/spec/ui/progress-handler.d.ts.map +1 -0
  307. package/dist/spec/ui/progress-handler.js +132 -0
  308. package/dist/spec/ui/progress-handler.js.map +1 -0
  309. package/dist/spec/ui/progress.d.ts +24 -0
  310. package/dist/spec/ui/progress.d.ts.map +1 -0
  311. package/dist/spec/ui/progress.js +13 -0
  312. package/dist/spec/ui/progress.js.map +1 -0
  313. package/dist/spec/utils/fs.d.ts +45 -0
  314. package/dist/spec/utils/fs.d.ts.map +1 -0
  315. package/dist/spec/utils/fs.js +163 -0
  316. package/dist/spec/utils/fs.js.map +1 -0
  317. package/dist/spec/utils/index.d.ts +12 -0
  318. package/dist/spec/utils/index.d.ts.map +1 -0
  319. package/dist/spec/utils/index.js +26 -0
  320. package/dist/spec/utils/index.js.map +1 -0
  321. package/dist/spec/utils/meta.d.ts +32 -0
  322. package/dist/spec/utils/meta.d.ts.map +1 -0
  323. package/dist/spec/utils/meta.js +122 -0
  324. package/dist/spec/utils/meta.js.map +1 -0
  325. package/dist/spec/utils/truncate.d.ts +86 -0
  326. package/dist/spec/utils/truncate.d.ts.map +1 -0
  327. package/dist/spec/utils/truncate.js +172 -0
  328. package/dist/spec/utils/truncate.js.map +1 -0
  329. package/dist/sync/watcher.d.ts +25 -1
  330. package/dist/sync/watcher.d.ts.map +1 -1
  331. package/dist/sync/watcher.js +76 -3
  332. package/dist/sync/watcher.js.map +1 -1
  333. package/dist/telemetry/index.js +3 -3
  334. package/dist/telemetry/index.js.map +1 -1
  335. package/dist/types.d.ts +3 -0
  336. package/dist/types.d.ts.map +1 -1
  337. package/package.json +62 -58
  338. package/scripts/_tmp-cfwk-resolve.log +0 -0
  339. package/scripts/_tmp-cfwk-sig.log +0 -0
  340. package/scripts/_tmp-cfwk-vt.log +0 -0
  341. package/scripts/add-lang/bench.sh +60 -60
  342. package/scripts/add-lang/check-grammar.mjs +75 -75
  343. package/scripts/add-lang/dump-ast.mjs +103 -103
  344. package/scripts/add-lang/verify-extraction.mjs +70 -70
  345. package/scripts/agent-eval/ab-adoption.sh +91 -91
  346. package/scripts/agent-eval/ab-hook.sh +86 -86
  347. package/scripts/agent-eval/ab-impl.sh +78 -78
  348. package/scripts/agent-eval/ab-new-vs-baseline.sh +102 -102
  349. package/scripts/agent-eval/ab-sufficiency.sh +78 -78
  350. package/scripts/agent-eval/arms-F.sh +21 -21
  351. package/scripts/agent-eval/arms-matrix.sh +37 -37
  352. package/scripts/agent-eval/audit.sh +68 -68
  353. package/scripts/agent-eval/bench-readme.sh +28 -28
  354. package/scripts/agent-eval/bench-why-repo.sh +22 -22
  355. package/scripts/agent-eval/block-read-hook.sh +19 -19
  356. package/scripts/agent-eval/hook-settings.json +15 -15
  357. package/scripts/agent-eval/itrun.sh +120 -120
  358. package/scripts/agent-eval/offload-eval-3arm.sh +72 -72
  359. package/scripts/agent-eval/offload-eval-cost.mjs +133 -133
  360. package/scripts/agent-eval/offload-eval-effort.mjs +108 -108
  361. package/scripts/agent-eval/offload-eval-frontload-matrix.sh +25 -25
  362. package/scripts/agent-eval/offload-eval-frontload.sh +47 -47
  363. package/scripts/agent-eval/offload-eval-ground-truth.json +18 -18
  364. package/scripts/agent-eval/offload-eval-hook.mjs +84 -84
  365. package/scripts/agent-eval/offload-eval-judge.mjs +103 -103
  366. package/scripts/agent-eval/offload-eval-matrix.sh +20 -20
  367. package/scripts/agent-eval/offload-eval-metrics.mjs +94 -94
  368. package/scripts/agent-eval/offload-eval-refs1.sh +50 -50
  369. package/scripts/agent-eval/offload-eval-setup.sh +24 -24
  370. package/scripts/agent-eval/offload-eval-styles.sh +71 -71
  371. package/scripts/agent-eval/offload-eval-summarize.mjs +68 -68
  372. package/scripts/agent-eval/offload-eval.md +76 -76
  373. package/scripts/agent-eval/parse-arms.mjs +116 -116
  374. package/scripts/agent-eval/parse-bench-readme.mjs +84 -84
  375. package/scripts/agent-eval/parse-run.mjs +45 -45
  376. package/scripts/agent-eval/parse-session.mjs +93 -93
  377. package/scripts/agent-eval/probe-context.mjs +21 -21
  378. package/scripts/agent-eval/probe-explore.mjs +40 -40
  379. package/scripts/agent-eval/probe-node.mjs +20 -20
  380. package/scripts/agent-eval/probe-sweep.mjs +119 -119
  381. package/scripts/agent-eval/probe-trace.mjs +20 -20
  382. package/scripts/agent-eval/redirect-read-hook.sh +38 -38
  383. package/scripts/agent-eval/repro-concurrent-explore.mjs +119 -119
  384. package/scripts/agent-eval/repro-daemon-clients.mjs +125 -125
  385. package/scripts/agent-eval/run-agent.sh +34 -34
  386. package/scripts/agent-eval/run-all.sh +75 -75
  387. package/scripts/agent-eval/run-arms.sh +56 -56
  388. package/scripts/agent-eval/seq-matrix.mjs +137 -137
  389. package/scripts/bench-arkts-init-rss.log +0 -0
  390. package/scripts/build-bundle.sh +123 -123
  391. package/scripts/exp_boundary_eval/README.md +247 -247
  392. package/scripts/exp_boundary_eval/__pycache__/_utils.cpython-310.pyc +0 -0
  393. package/scripts/exp_boundary_eval/__pycache__/_utils.cpython-38.pyc +0 -0
  394. package/scripts/exp_boundary_eval/__pycache__/analyze.cpython-310.pyc +0 -0
  395. package/scripts/exp_boundary_eval/__pycache__/analyze.cpython-38.pyc +0 -0
  396. package/scripts/exp_boundary_eval/__pycache__/deveco_arm.cpython-38.pyc +0 -0
  397. package/scripts/exp_boundary_eval/__pycache__/run_all.cpython-310.pyc +0 -0
  398. package/scripts/exp_boundary_eval/__pycache__/run_all.cpython-38.pyc +0 -0
  399. package/scripts/exp_boundary_eval/__pycache__/run_one.cpython-310.pyc +0 -0
  400. package/scripts/exp_boundary_eval/__pycache__/run_one.cpython-38.pyc +0 -0
  401. package/scripts/exp_boundary_eval/__pycache__/run_session.cpython-310.pyc +0 -0
  402. package/scripts/exp_boundary_eval/__pycache__/run_session.cpython-38.pyc +0 -0
  403. package/scripts/exp_boundary_eval/__pycache__/setup.cpython-310.pyc +0 -0
  404. package/scripts/exp_boundary_eval/__pycache__/setup.cpython-38.pyc +0 -0
  405. package/scripts/exp_boundary_eval/__pycache__/win_mcp_launcher.cpython-38.pyc +0 -0
  406. package/scripts/exp_boundary_eval/_test_mcp_chain.py +78 -78
  407. package/scripts/exp_boundary_eval/_test_stdin.py +8 -8
  408. package/scripts/exp_boundary_eval/_utils.py +1116 -1116
  409. package/scripts/exp_boundary_eval/analyze.py +1313 -1313
  410. package/scripts/exp_boundary_eval/deveco_arm.py +519 -519
  411. package/scripts/exp_boundary_eval/run_all.py +378 -378
  412. package/scripts/exp_boundary_eval/run_one.py +165 -165
  413. package/scripts/exp_boundary_eval/run_session.py +158 -158
  414. package/scripts/exp_boundary_eval/setup.py +120 -120
  415. package/scripts/exp_boundary_eval/win_mcp_launcher.py +73 -73
  416. package/scripts/exp_boundary_eval/win_mcp_stdio_wrap.js +36 -36
  417. package/scripts/exp_boundary_eval/win_node_launcher.py +24 -24
  418. package/scripts/extract-release-notes.mjs +130 -130
  419. package/scripts/local-install.sh +41 -41
  420. package/scripts/npm-sdk.js +75 -75
  421. package/scripts/npm-shim.js +275 -275
  422. package/scripts/ohos-sdk-publish.mjs +133 -133
  423. package/scripts/pack-npm.sh +119 -119
  424. package/scripts/prepare-release.mjs +270 -270
  425. package/scripts/probe-arkts-mem-why-run.log +0 -0
  426. package/scripts/probe-banner-livecard-ir.log +0 -0
  427. package/scripts/probe-cfwk-ast.stderr.log +0 -0
  428. package/scripts/probe-cfwk-ast.stdout.log +0 -0
  429. package/scripts/probe-cfwk-attr-shape.log +0 -0
  430. package/scripts/probe-cfwk-cfgdump.stderr.log +0 -0
  431. package/scripts/probe-cfwk-cfgdump.stdout.log +0 -0
  432. package/scripts/probe-cfwk-cvc.stderr.log +0 -0
  433. package/scripts/probe-cfwk-cvc.stdout.log +0 -0
  434. package/scripts/probe-cfwk-diag2.log +0 -0
  435. package/scripts/probe-cfwk-diag3.log +0 -0
  436. package/scripts/probe-cfwk-fedbg.stderr.log +0 -0
  437. package/scripts/probe-cfwk-fedbg.stdout.log +0 -0
  438. package/scripts/probe-cfwk-fileresult.log +0 -0
  439. package/scripts/probe-cfwk-fix.stderr.log +0 -0
  440. package/scripts/probe-cfwk-fix.stdout.log +0 -0
  441. package/scripts/probe-cfwk-fix2.stderr.log +0 -0
  442. package/scripts/probe-cfwk-fix2.stdout.log +0 -0
  443. package/scripts/probe-cfwk-fix3.stderr.log +0 -0
  444. package/scripts/probe-cfwk-fix3.stdout.log +0 -0
  445. package/scripts/probe-cfwk-foreach.log +0 -0
  446. package/scripts/probe-cfwk-getmethod-throw.log +0 -0
  447. package/scripts/probe-cfwk-hg-extract.log +0 -0
  448. package/scripts/probe-cfwk-pr1003-noprior.stderr.log +0 -0
  449. package/scripts/probe-cfwk-pr1003-noprior.stdout.log +0 -0
  450. package/scripts/probe-cfwk-pr1003.stderr.log +0 -0
  451. package/scripts/probe-cfwk-pr1003.stdout.log +0 -0
  452. package/scripts/probe-cfwk-preroot-noprior.stderr.log +0 -0
  453. package/scripts/probe-cfwk-preroot-noprior.stdout.log +0 -0
  454. package/scripts/probe-cfwk-preroot-prior.stderr.log +0 -0
  455. package/scripts/probe-cfwk-preroot-prior.stdout.log +0 -0
  456. package/scripts/probe-cfwk-preroot-skipstate.stderr.log +0 -0
  457. package/scripts/probe-cfwk-preroot-skipstate.stdout.log +0 -0
  458. package/scripts/probe-cfwk-resolve-sim.log +0 -0
  459. package/scripts/probe-cfwk-tree-shape.log +0 -0
  460. package/scripts/probe-cfwk-walk-abort.log +0 -0
  461. package/scripts/probe-cfwk.log +0 -0
  462. package/scripts/probe-force-index.log +0 -0
  463. package/scripts/probe-no-force-index.log +0 -0
  464. package/scripts/probe-samefile-ir.stderr.log +0 -0
  465. package/scripts/probe-samefile-ir.stdout.log +224 -0
  466. package/scripts/probe-sdk-vs-project.log +0 -0
  467. package/scripts/probe-viewtree-downgrade.log +0 -0
  468. package/dist/arkts/ohos-api-index.d.ts +0 -15
  469. package/dist/arkts/ohos-api-index.d.ts.map +0 -1
  470. package/dist/arkts/ohos-api-index.js +0 -190
  471. package/dist/arkts/ohos-api-index.js.map +0 -1
  472. package/dist/arkts/ohos-sdk-input.d.ts +0 -36
  473. package/dist/arkts/ohos-sdk-input.d.ts.map +0 -1
  474. package/dist/arkts/ohos-sdk-input.js +0 -214
  475. package/dist/arkts/ohos-sdk-input.js.map +0 -1
  476. package/dist/extraction/languages/arkts-state-decorators.d.ts +0 -13
  477. package/dist/extraction/languages/arkts-state-decorators.d.ts.map +0 -1
  478. package/dist/extraction/languages/arkts-state-decorators.js +0 -26
  479. package/dist/extraction/languages/arkts-state-decorators.js.map +0 -1
  480. package/dist/extraction/languages/ohos-api-consumer.d.ts +0 -34
  481. package/dist/extraction/languages/ohos-api-consumer.d.ts.map +0 -1
  482. package/dist/extraction/languages/ohos-api-consumer.js +0 -283
  483. package/dist/extraction/languages/ohos-api-consumer.js.map +0 -1
@@ -1,165 +1,165 @@
1
- #!/usr/bin/env python3
2
- """Run a single one-shot experiment. Supports multiple agents via --agent."""
3
-
4
- import os
5
- import subprocess
6
- import sys
7
- from pathlib import Path
8
- from typing import Optional
9
-
10
- import setup as setup_mod
11
- from _utils import (OUTPUT_DIR, append_run_log, build_agent_cmd, current_time_ms,
12
- error, find_experiment, get_agent, info, header,
13
- parse_output, resolve_agent_model, run_monitored_subprocess,
14
- subprocess_no_window_kwargs, warn, write_json)
15
- from deveco_arm import analyze_homegraph_stream
16
-
17
-
18
- def run_experiment(exp_id: str, skip_permissions: bool = True,
19
- agent_name: str = "",
20
- results_dir: Optional[Path] = None,
21
- state_dir: Optional[Path] = None) -> bool:
22
- exp = find_experiment(exp_id)
23
- if exp is None:
24
- error(f"Experiment {exp_id} not found in config")
25
- return False
26
- if exp.get("type") == "session":
27
- error(f"Experiment {exp_id} is session type. Use run_session.py.")
28
- return False
29
-
30
- agent = get_agent(agent_name)
31
- clone_path = os.environ.get("REPO_CLONE", "")
32
- local_repo = os.environ.get("REPO_PATH", "")
33
- if clone_path:
34
- repo_root = Path(clone_path)
35
- elif local_repo:
36
- repo_root = Path(local_repo)
37
- else:
38
- error("No repo. Use run_all.py to clone, or set REPO_PATH / REPO_CLONE.")
39
- return False
40
-
41
- title = exp["title"]
42
- prompt = exp["prompt"]
43
- max_turns = exp.get("max_turns", 15)
44
-
45
- header(f"Experiment {exp_id}: {title}")
46
- info(f"Agent: {agent['name']} ({agent['binary']}) | Repo: {repo_root}")
47
- info(f"Max turns: {max_turns} | Permissions: {'skip' if skip_permissions else 'ask'}")
48
-
49
- session_id, _ = setup_mod.prepare_environment(exp_id, "full", agent_name,
50
- state_dir=state_dir)
51
-
52
- result_dir = results_dir / exp_id if results_dir else OUTPUT_DIR / exp_id
53
- result_dir.mkdir(parents=True, exist_ok=True)
54
- (result_dir / "prompt.txt").write_text(prompt, encoding="utf-8")
55
- write_json(result_dir / "experiment_config.json", {**exp, "agent": agent_name or "default"})
56
-
57
- info("Starting agent...")
58
- start_ms = current_time_ms()
59
- os.chdir(repo_root)
60
-
61
- cmd = build_agent_cmd(agent, session_id, max_turns, prompt,
62
- resume=False, skip_permissions=skip_permissions,
63
- repo_root=repo_root)
64
-
65
- stream_path = result_dir / "stream_output.jsonl"
66
- text_path = result_dir / "raw_output.txt"
67
- track_hg = os.environ.get("EVAL_ARM", "") == "homegraph"
68
-
69
- with open(stream_path, "w", encoding="utf-8") as stream_f:
70
- result, mem = run_monitored_subprocess(
71
- cmd, stdout=stream_f, stderr=subprocess.STDOUT, text=True,
72
- track_homegraph=track_hg,
73
- )
74
- exit_code = result.returncode
75
-
76
- end_ms = current_time_ms()
77
- dur_ms = end_ms - start_ms
78
- dur_s = f"{dur_ms / 1000:.1f}"
79
- info(f"Completed in {dur_s}s (exit={exit_code})")
80
-
81
- # Parse agent output
82
- parser_name = agent.get("parser", "claude_stream_json")
83
- stats = parse_output(stream_path, parser_name)
84
-
85
- if exit_code != 0:
86
- error(f"Agent 退出码 {exit_code}")
87
- for err in stats.errors[:3]:
88
- error(f" {err}")
89
- if "Unexpected server error" in " ".join(stats.errors):
90
- warn("DevEco 服务端报错 — 通常为 API/网络/配额问题,与评测脚本无关。"
91
- "请检查 DevEco 登录状态、模型配置,稍后重试 `deveco run`。")
92
- elif stats.tool_calls == 0 and not stats.errors:
93
- warn("无工具调用且无错误事件 — 检查 stream_output.jsonl 是否为空。")
94
-
95
- # Human-readable text
96
- text_content = "\n".join(stats.text_lines)
97
- text_path.write_text(text_content or "(no text output)", encoding="utf-8")
98
-
99
- # Modified files
100
- r2 = subprocess.run(
101
- ["git", "diff", "--name-only"], capture_output=True, text=True, cwd=repo_root,
102
- **subprocess_no_window_kwargs(),
103
- )
104
- mod_files = len([l for l in r2.stdout.strip().split("\n") if l])
105
-
106
- hg_stream = analyze_homegraph_stream(stream_path)
107
-
108
- results = {
109
- "experiment_id": exp_id, "title": title, "agent": agent["name"],
110
- "agent_binary": agent["binary"], "session_id": session_id,
111
- "start_time_ms": start_ms, "end_time_ms": end_ms,
112
- "duration_ms": dur_ms, "duration_s": dur_s,
113
- "exit_code": exit_code, "max_turns": max_turns,
114
- "skip_permissions": skip_permissions,
115
- "tool_calls": stats.tool_calls, "tool_names": stats.tool_names,
116
- "homegraph_tool_calls": stats.homegraph_tool_calls,
117
- "used_homegraph": stats.used_homegraph,
118
- **hg_stream,
119
- "eval_arm": os.environ.get("EVAL_ARM", ""),
120
- "files_read": list(set(stats.files_read)),
121
- "files_edited": list(set(stats.files_edited)),
122
- "model": resolve_agent_model(agent, stats),
123
- "deveco_session_id": stats.deveco_session_id,
124
- "input_tokens": stats.total_input_tokens,
125
- "output_tokens": stats.total_output_tokens,
126
- "assistant_messages": stats.assistant_messages,
127
- "max_turns_hit": stats.max_turns_hit,
128
- "errors": stats.errors[:5],
129
- "modified_files": mod_files,
130
- "memory": mem.to_dict(),
131
- }
132
- write_json(result_dir / "results.json", results)
133
-
134
- if state_dir:
135
- append_run_log(state_dir, f"Exp {exp_id} finished in {dur_s}s, tools={stats.tool_calls}, exit={exit_code}")
136
- info(f"Results saved: {result_dir}/")
137
- print(f" Duration: {dur_s}s | Tool calls: {stats.tool_calls} | "
138
- f"HG tools: {stats.homegraph_tool_calls} | "
139
- f"Files read: {len(set(stats.files_read))} | Edited: {mod_files} | "
140
- f"Peak mem: {mem.peak_combined_rss_mb:.0f} MB")
141
- if stats.max_turns_hit:
142
- print(f" ⚠️ Max turns ({max_turns}) hit")
143
- return exit_code == 0
144
-
145
-
146
- if __name__ == "__main__":
147
- # Parse: python run_one.py <id> [--agent <name>] [--no-skip-permissions]
148
- args = sys.argv[1:]
149
- exp_id = args[0] if args else ""
150
- agent_name = ""
151
- skip = True
152
-
153
- i = 1
154
- while i < len(args):
155
- if args[i] == "--agent" and i + 1 < len(args):
156
- agent_name = args[i + 1]; i += 2
157
- elif args[i] == "--no-skip-permissions":
158
- skip = False; i += 1
159
- else:
160
- i += 1
161
-
162
- if not exp_id:
163
- error("Usage: python run_one.py <experiment_id> [--agent <name>]")
164
- sys.exit(1)
165
- sys.exit(0 if run_experiment(exp_id, skip, agent_name) else 1)
1
+ #!/usr/bin/env python3
2
+ """Run a single one-shot experiment. Supports multiple agents via --agent."""
3
+
4
+ import os
5
+ import subprocess
6
+ import sys
7
+ from pathlib import Path
8
+ from typing import Optional
9
+
10
+ import setup as setup_mod
11
+ from _utils import (OUTPUT_DIR, append_run_log, build_agent_cmd, current_time_ms,
12
+ error, find_experiment, get_agent, info, header,
13
+ parse_output, resolve_agent_model, run_monitored_subprocess,
14
+ subprocess_no_window_kwargs, warn, write_json)
15
+ from deveco_arm import analyze_homegraph_stream
16
+
17
+
18
+ def run_experiment(exp_id: str, skip_permissions: bool = True,
19
+ agent_name: str = "",
20
+ results_dir: Optional[Path] = None,
21
+ state_dir: Optional[Path] = None) -> bool:
22
+ exp = find_experiment(exp_id)
23
+ if exp is None:
24
+ error(f"Experiment {exp_id} not found in config")
25
+ return False
26
+ if exp.get("type") == "session":
27
+ error(f"Experiment {exp_id} is session type. Use run_session.py.")
28
+ return False
29
+
30
+ agent = get_agent(agent_name)
31
+ clone_path = os.environ.get("REPO_CLONE", "")
32
+ local_repo = os.environ.get("REPO_PATH", "")
33
+ if clone_path:
34
+ repo_root = Path(clone_path)
35
+ elif local_repo:
36
+ repo_root = Path(local_repo)
37
+ else:
38
+ error("No repo. Use run_all.py to clone, or set REPO_PATH / REPO_CLONE.")
39
+ return False
40
+
41
+ title = exp["title"]
42
+ prompt = exp["prompt"]
43
+ max_turns = exp.get("max_turns", 15)
44
+
45
+ header(f"Experiment {exp_id}: {title}")
46
+ info(f"Agent: {agent['name']} ({agent['binary']}) | Repo: {repo_root}")
47
+ info(f"Max turns: {max_turns} | Permissions: {'skip' if skip_permissions else 'ask'}")
48
+
49
+ session_id, _ = setup_mod.prepare_environment(exp_id, "full", agent_name,
50
+ state_dir=state_dir)
51
+
52
+ result_dir = results_dir / exp_id if results_dir else OUTPUT_DIR / exp_id
53
+ result_dir.mkdir(parents=True, exist_ok=True)
54
+ (result_dir / "prompt.txt").write_text(prompt, encoding="utf-8")
55
+ write_json(result_dir / "experiment_config.json", {**exp, "agent": agent_name or "default"})
56
+
57
+ info("Starting agent...")
58
+ start_ms = current_time_ms()
59
+ os.chdir(repo_root)
60
+
61
+ cmd = build_agent_cmd(agent, session_id, max_turns, prompt,
62
+ resume=False, skip_permissions=skip_permissions,
63
+ repo_root=repo_root)
64
+
65
+ stream_path = result_dir / "stream_output.jsonl"
66
+ text_path = result_dir / "raw_output.txt"
67
+ track_hg = os.environ.get("EVAL_ARM", "") == "homegraph"
68
+
69
+ with open(stream_path, "w", encoding="utf-8") as stream_f:
70
+ result, mem = run_monitored_subprocess(
71
+ cmd, stdout=stream_f, stderr=subprocess.STDOUT, text=True,
72
+ track_homegraph=track_hg,
73
+ )
74
+ exit_code = result.returncode
75
+
76
+ end_ms = current_time_ms()
77
+ dur_ms = end_ms - start_ms
78
+ dur_s = f"{dur_ms / 1000:.1f}"
79
+ info(f"Completed in {dur_s}s (exit={exit_code})")
80
+
81
+ # Parse agent output
82
+ parser_name = agent.get("parser", "claude_stream_json")
83
+ stats = parse_output(stream_path, parser_name)
84
+
85
+ if exit_code != 0:
86
+ error(f"Agent 退出码 {exit_code}")
87
+ for err in stats.errors[:3]:
88
+ error(f" {err}")
89
+ if "Unexpected server error" in " ".join(stats.errors):
90
+ warn("DevEco 服务端报错 — 通常为 API/网络/配额问题,与评测脚本无关。"
91
+ "请检查 DevEco 登录状态、模型配置,稍后重试 `deveco run`。")
92
+ elif stats.tool_calls == 0 and not stats.errors:
93
+ warn("无工具调用且无错误事件 — 检查 stream_output.jsonl 是否为空。")
94
+
95
+ # Human-readable text
96
+ text_content = "\n".join(stats.text_lines)
97
+ text_path.write_text(text_content or "(no text output)", encoding="utf-8")
98
+
99
+ # Modified files
100
+ r2 = subprocess.run(
101
+ ["git", "diff", "--name-only"], capture_output=True, text=True, cwd=repo_root,
102
+ **subprocess_no_window_kwargs(),
103
+ )
104
+ mod_files = len([l for l in r2.stdout.strip().split("\n") if l])
105
+
106
+ hg_stream = analyze_homegraph_stream(stream_path)
107
+
108
+ results = {
109
+ "experiment_id": exp_id, "title": title, "agent": agent["name"],
110
+ "agent_binary": agent["binary"], "session_id": session_id,
111
+ "start_time_ms": start_ms, "end_time_ms": end_ms,
112
+ "duration_ms": dur_ms, "duration_s": dur_s,
113
+ "exit_code": exit_code, "max_turns": max_turns,
114
+ "skip_permissions": skip_permissions,
115
+ "tool_calls": stats.tool_calls, "tool_names": stats.tool_names,
116
+ "homegraph_tool_calls": stats.homegraph_tool_calls,
117
+ "used_homegraph": stats.used_homegraph,
118
+ **hg_stream,
119
+ "eval_arm": os.environ.get("EVAL_ARM", ""),
120
+ "files_read": list(set(stats.files_read)),
121
+ "files_edited": list(set(stats.files_edited)),
122
+ "model": resolve_agent_model(agent, stats),
123
+ "deveco_session_id": stats.deveco_session_id,
124
+ "input_tokens": stats.total_input_tokens,
125
+ "output_tokens": stats.total_output_tokens,
126
+ "assistant_messages": stats.assistant_messages,
127
+ "max_turns_hit": stats.max_turns_hit,
128
+ "errors": stats.errors[:5],
129
+ "modified_files": mod_files,
130
+ "memory": mem.to_dict(),
131
+ }
132
+ write_json(result_dir / "results.json", results)
133
+
134
+ if state_dir:
135
+ append_run_log(state_dir, f"Exp {exp_id} finished in {dur_s}s, tools={stats.tool_calls}, exit={exit_code}")
136
+ info(f"Results saved: {result_dir}/")
137
+ print(f" Duration: {dur_s}s | Tool calls: {stats.tool_calls} | "
138
+ f"HG tools: {stats.homegraph_tool_calls} | "
139
+ f"Files read: {len(set(stats.files_read))} | Edited: {mod_files} | "
140
+ f"Peak mem: {mem.peak_combined_rss_mb:.0f} MB")
141
+ if stats.max_turns_hit:
142
+ print(f" ⚠️ Max turns ({max_turns}) hit")
143
+ return exit_code == 0
144
+
145
+
146
+ if __name__ == "__main__":
147
+ # Parse: python run_one.py <id> [--agent <name>] [--no-skip-permissions]
148
+ args = sys.argv[1:]
149
+ exp_id = args[0] if args else ""
150
+ agent_name = ""
151
+ skip = True
152
+
153
+ i = 1
154
+ while i < len(args):
155
+ if args[i] == "--agent" and i + 1 < len(args):
156
+ agent_name = args[i + 1]; i += 2
157
+ elif args[i] == "--no-skip-permissions":
158
+ skip = False; i += 1
159
+ else:
160
+ i += 1
161
+
162
+ if not exp_id:
163
+ error("Usage: python run_one.py <experiment_id> [--agent <name>]")
164
+ sys.exit(1)
165
+ sys.exit(0 if run_experiment(exp_id, skip, agent_name) else 1)
@@ -1,158 +1,158 @@
1
- #!/usr/bin/env python3
2
- """Run multi-turn session experiment (5). Supports multiple agents via --agent."""
3
-
4
- import os
5
- import subprocess
6
- import sys
7
- import time
8
- from pathlib import Path
9
- from typing import Optional
10
-
11
- import setup as setup_mod
12
- from _utils import (OUTPUT_DIR, append_run_log, build_agent_cmd,
13
- current_time_ms, find_experiment, get_agent, info, header,
14
- log, parse_output, resolve_agent_model, run_monitored_subprocess,
15
- subprocess_no_window_kwargs, write_json, warn)
16
-
17
-
18
- def run_session(exp_id: str = "5", skip_permissions: bool = True,
19
- agent_name: str = "",
20
- results_dir: Optional[Path] = None,
21
- state_dir: Optional[Path] = None) -> bool:
22
- exp = find_experiment(exp_id)
23
- if exp is None:
24
- print(f"ERROR: Experiment {exp_id} not found")
25
- return False
26
-
27
- agent = get_agent(agent_name)
28
- clone_path = os.environ.get("REPO_CLONE", "")
29
- local_repo = os.environ.get("REPO_PATH", "")
30
- if clone_path:
31
- repo_root = Path(clone_path)
32
- elif local_repo:
33
- repo_root = Path(local_repo)
34
- else:
35
- print("ERROR: No repo. Use run_all.py to clone, or set REPO_PATH / REPO_CLONE.")
36
- return False
37
- max_turns = exp.get("max_turns_per_round", 25)
38
-
39
- header("Experiment 5: Session Persistence & Context Decay")
40
- info(f"Agent: {agent['name']} ({agent['binary']}) | Repo: {repo_root}")
41
- info(f"Max turns/round: {max_turns} | Permissions: {'skip' if skip_permissions else 'ask'}")
42
-
43
- session_id, _ = setup_mod.prepare_environment("5", "full", agent_name,
44
- state_dir=state_dir)
45
- log(f"Shared Session ID: {session_id}")
46
-
47
- result_dir = results_dir / "5" if results_dir else OUTPUT_DIR / "5"
48
- result_dir.mkdir(parents=True, exist_ok=True)
49
-
50
- rounds_data = []
51
- session_model = ""
52
- deveco_session_id = ""
53
- for round_num in range(1, 6):
54
- ri = next((r for r in exp["rounds"] if r["round"] == round_num), None)
55
- if not ri: continue
56
-
57
- header(f"Round {round_num} of 5")
58
- info(f"Title: {ri['title']}")
59
-
60
- round_dir = result_dir / f"round_{round_num}"
61
- round_dir.mkdir(parents=True, exist_ok=True)
62
- (round_dir / "prompt.txt").write_text(ri["prompt"], encoding="utf-8")
63
-
64
- start_ms = current_time_ms()
65
- is_resume = round_num > 1
66
-
67
- cmd = build_agent_cmd(agent, session_id, max_turns, ri["prompt"],
68
- resume=is_resume, skip_permissions=skip_permissions,
69
- repo_root=repo_root)
70
-
71
- stream_path = round_dir / "stream_output.jsonl"
72
- text_path = round_dir / "raw_output.txt"
73
- track_hg = os.environ.get("EVAL_ARM", "") == "homegraph"
74
-
75
- with open(stream_path, "w", encoding="utf-8") as stream_f:
76
- result, mem = run_monitored_subprocess(
77
- cmd, stdout=stream_f, stderr=subprocess.STDOUT, text=True,
78
- track_homegraph=track_hg,
79
- )
80
- exit_code = result.returncode
81
-
82
- end_ms = current_time_ms()
83
- dur_ms = end_ms - start_ms
84
- dur_s = f"{dur_ms / 1000:.1f}"
85
-
86
- parser_name = agent.get("parser", "claude_stream_json")
87
- stats = parse_output(stream_path, parser_name)
88
- if not session_model:
89
- session_model = resolve_agent_model(agent, stats)
90
- if not deveco_session_id and stats.deveco_session_id:
91
- deveco_session_id = stats.deveco_session_id
92
-
93
- text_content = "\n".join(stats.text_lines)
94
- text_path.write_text(text_content or "(no text output)", encoding="utf-8")
95
-
96
- r2 = subprocess.run(
97
- ["git", "diff", "--name-only"], capture_output=True, text=True, cwd=repo_root,
98
- **subprocess_no_window_kwargs(),
99
- )
100
- mod_files = len([l for l in r2.stdout.strip().split("\n") if l])
101
-
102
- rr = {"round": round_num, "title": ri["title"], "duration_ms": dur_ms,
103
- "duration_s": dur_s, "exit_code": exit_code,
104
- "tool_calls": stats.tool_calls, "tool_names": stats.tool_names,
105
- "files_read": list(set(stats.files_read)),
106
- "files_edited": list(set(stats.files_edited)),
107
- "assistant_messages": stats.assistant_messages,
108
- "max_turns_hit": stats.max_turns_hit,
109
- "modified_files": mod_files, "max_turns": max_turns,
110
- "memory": mem.to_dict()}
111
- write_json(round_dir / "round_results.json", rr)
112
- rounds_data.append(rr)
113
-
114
- info(f"Round {round_num} done: {dur_s}s | Tool calls: {stats.tool_calls} | "
115
- f"Files read: {len(set(stats.files_read))} | Edited: {mod_files}")
116
- if stats.max_turns_hit:
117
- warn(f" Max turns ({max_turns}) hit in round {round_num}")
118
- if round_num < 5:
119
- time.sleep(2)
120
-
121
- summary = {
122
- "experiment_id": "5", "session_id": session_id, "agent": agent["name"],
123
- "model": session_model,
124
- "deveco_session_id": deveco_session_id,
125
- "total_rounds": len(rounds_data),
126
- "total_duration_ms": sum(r["duration_ms"] for r in rounds_data),
127
- "total_tool_calls": sum(int(r["tool_calls"]) for r in rounds_data),
128
- "memory_retention_curve": [
129
- {"round": r["round"], "tool_calls": int(r["tool_calls"]),
130
- "files_read": r.get("files_read", [])} for r in rounds_data
131
- ],
132
- }
133
- write_json(result_dir / "session_results.json", summary)
134
-
135
- print("\nMemory Retention Curve:")
136
- for r in rounds_data:
137
- tc = int(r["tool_calls"])
138
- fr = len(r.get("files_read", []))
139
- print(f" Round {r['round']}: {'#' * (tc // 2)} ({tc} tool calls, {fr} files read)")
140
-
141
- log(f"Results: {result_dir}/session_results.json")
142
- return True
143
-
144
-
145
- if __name__ == "__main__":
146
- args = sys.argv[1:]
147
- exp_id = args[0] if args else "5"
148
- agent_name = ""
149
- skip = True
150
- i = 1
151
- while i < len(args):
152
- if args[i] == "--agent" and i + 1 < len(args):
153
- agent_name = args[i + 1]; i += 2
154
- elif args[i] == "--no-skip-permissions":
155
- skip = False; i += 1
156
- else:
157
- i += 1
158
- sys.exit(0 if run_session(exp_id, skip, agent_name) else 1)
1
+ #!/usr/bin/env python3
2
+ """Run multi-turn session experiment (5). Supports multiple agents via --agent."""
3
+
4
+ import os
5
+ import subprocess
6
+ import sys
7
+ import time
8
+ from pathlib import Path
9
+ from typing import Optional
10
+
11
+ import setup as setup_mod
12
+ from _utils import (OUTPUT_DIR, append_run_log, build_agent_cmd,
13
+ current_time_ms, find_experiment, get_agent, info, header,
14
+ log, parse_output, resolve_agent_model, run_monitored_subprocess,
15
+ subprocess_no_window_kwargs, write_json, warn)
16
+
17
+
18
+ def run_session(exp_id: str = "5", skip_permissions: bool = True,
19
+ agent_name: str = "",
20
+ results_dir: Optional[Path] = None,
21
+ state_dir: Optional[Path] = None) -> bool:
22
+ exp = find_experiment(exp_id)
23
+ if exp is None:
24
+ print(f"ERROR: Experiment {exp_id} not found")
25
+ return False
26
+
27
+ agent = get_agent(agent_name)
28
+ clone_path = os.environ.get("REPO_CLONE", "")
29
+ local_repo = os.environ.get("REPO_PATH", "")
30
+ if clone_path:
31
+ repo_root = Path(clone_path)
32
+ elif local_repo:
33
+ repo_root = Path(local_repo)
34
+ else:
35
+ print("ERROR: No repo. Use run_all.py to clone, or set REPO_PATH / REPO_CLONE.")
36
+ return False
37
+ max_turns = exp.get("max_turns_per_round", 25)
38
+
39
+ header("Experiment 5: Session Persistence & Context Decay")
40
+ info(f"Agent: {agent['name']} ({agent['binary']}) | Repo: {repo_root}")
41
+ info(f"Max turns/round: {max_turns} | Permissions: {'skip' if skip_permissions else 'ask'}")
42
+
43
+ session_id, _ = setup_mod.prepare_environment("5", "full", agent_name,
44
+ state_dir=state_dir)
45
+ log(f"Shared Session ID: {session_id}")
46
+
47
+ result_dir = results_dir / "5" if results_dir else OUTPUT_DIR / "5"
48
+ result_dir.mkdir(parents=True, exist_ok=True)
49
+
50
+ rounds_data = []
51
+ session_model = ""
52
+ deveco_session_id = ""
53
+ for round_num in range(1, 6):
54
+ ri = next((r for r in exp["rounds"] if r["round"] == round_num), None)
55
+ if not ri: continue
56
+
57
+ header(f"Round {round_num} of 5")
58
+ info(f"Title: {ri['title']}")
59
+
60
+ round_dir = result_dir / f"round_{round_num}"
61
+ round_dir.mkdir(parents=True, exist_ok=True)
62
+ (round_dir / "prompt.txt").write_text(ri["prompt"], encoding="utf-8")
63
+
64
+ start_ms = current_time_ms()
65
+ is_resume = round_num > 1
66
+
67
+ cmd = build_agent_cmd(agent, session_id, max_turns, ri["prompt"],
68
+ resume=is_resume, skip_permissions=skip_permissions,
69
+ repo_root=repo_root)
70
+
71
+ stream_path = round_dir / "stream_output.jsonl"
72
+ text_path = round_dir / "raw_output.txt"
73
+ track_hg = os.environ.get("EVAL_ARM", "") == "homegraph"
74
+
75
+ with open(stream_path, "w", encoding="utf-8") as stream_f:
76
+ result, mem = run_monitored_subprocess(
77
+ cmd, stdout=stream_f, stderr=subprocess.STDOUT, text=True,
78
+ track_homegraph=track_hg,
79
+ )
80
+ exit_code = result.returncode
81
+
82
+ end_ms = current_time_ms()
83
+ dur_ms = end_ms - start_ms
84
+ dur_s = f"{dur_ms / 1000:.1f}"
85
+
86
+ parser_name = agent.get("parser", "claude_stream_json")
87
+ stats = parse_output(stream_path, parser_name)
88
+ if not session_model:
89
+ session_model = resolve_agent_model(agent, stats)
90
+ if not deveco_session_id and stats.deveco_session_id:
91
+ deveco_session_id = stats.deveco_session_id
92
+
93
+ text_content = "\n".join(stats.text_lines)
94
+ text_path.write_text(text_content or "(no text output)", encoding="utf-8")
95
+
96
+ r2 = subprocess.run(
97
+ ["git", "diff", "--name-only"], capture_output=True, text=True, cwd=repo_root,
98
+ **subprocess_no_window_kwargs(),
99
+ )
100
+ mod_files = len([l for l in r2.stdout.strip().split("\n") if l])
101
+
102
+ rr = {"round": round_num, "title": ri["title"], "duration_ms": dur_ms,
103
+ "duration_s": dur_s, "exit_code": exit_code,
104
+ "tool_calls": stats.tool_calls, "tool_names": stats.tool_names,
105
+ "files_read": list(set(stats.files_read)),
106
+ "files_edited": list(set(stats.files_edited)),
107
+ "assistant_messages": stats.assistant_messages,
108
+ "max_turns_hit": stats.max_turns_hit,
109
+ "modified_files": mod_files, "max_turns": max_turns,
110
+ "memory": mem.to_dict()}
111
+ write_json(round_dir / "round_results.json", rr)
112
+ rounds_data.append(rr)
113
+
114
+ info(f"Round {round_num} done: {dur_s}s | Tool calls: {stats.tool_calls} | "
115
+ f"Files read: {len(set(stats.files_read))} | Edited: {mod_files}")
116
+ if stats.max_turns_hit:
117
+ warn(f" Max turns ({max_turns}) hit in round {round_num}")
118
+ if round_num < 5:
119
+ time.sleep(2)
120
+
121
+ summary = {
122
+ "experiment_id": "5", "session_id": session_id, "agent": agent["name"],
123
+ "model": session_model,
124
+ "deveco_session_id": deveco_session_id,
125
+ "total_rounds": len(rounds_data),
126
+ "total_duration_ms": sum(r["duration_ms"] for r in rounds_data),
127
+ "total_tool_calls": sum(int(r["tool_calls"]) for r in rounds_data),
128
+ "memory_retention_curve": [
129
+ {"round": r["round"], "tool_calls": int(r["tool_calls"]),
130
+ "files_read": r.get("files_read", [])} for r in rounds_data
131
+ ],
132
+ }
133
+ write_json(result_dir / "session_results.json", summary)
134
+
135
+ print("\nMemory Retention Curve:")
136
+ for r in rounds_data:
137
+ tc = int(r["tool_calls"])
138
+ fr = len(r.get("files_read", []))
139
+ print(f" Round {r['round']}: {'#' * (tc // 2)} ({tc} tool calls, {fr} files read)")
140
+
141
+ log(f"Results: {result_dir}/session_results.json")
142
+ return True
143
+
144
+
145
+ if __name__ == "__main__":
146
+ args = sys.argv[1:]
147
+ exp_id = args[0] if args else "5"
148
+ agent_name = ""
149
+ skip = True
150
+ i = 1
151
+ while i < len(args):
152
+ if args[i] == "--agent" and i + 1 < len(args):
153
+ agent_name = args[i + 1]; i += 2
154
+ elif args[i] == "--no-skip-permissions":
155
+ skip = False; i += 1
156
+ else:
157
+ i += 1
158
+ sys.exit(0 if run_session(exp_id, skip, agent_name) else 1)