@gajae-code/coding-agent 0.14.2 → 0.15.0

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 (345) hide show
  1. package/CHANGELOG.md +120 -1
  2. package/dist/types/async/job-manager.d.ts +4 -1
  3. package/dist/types/autoresearch/dashboard.d.ts +29 -4
  4. package/dist/types/autoresearch/data-context.d.ts +25 -0
  5. package/dist/types/autoresearch/git.d.ts +65 -7
  6. package/dist/types/autoresearch/harness.d.ts +58 -0
  7. package/dist/types/autoresearch/prompts.d.ts +51 -0
  8. package/dist/types/autoresearch/runs.d.ts +173 -0
  9. package/dist/types/autoresearch/types.d.ts +9 -139
  10. package/dist/types/capability/types.d.ts +20 -0
  11. package/dist/types/cli/accounts-cli.d.ts +1 -0
  12. package/dist/types/commands/{rlm.d.ts → autoresearch.d.ts} +2 -4
  13. package/dist/types/config/autorouting-contract.d.ts +146 -0
  14. package/dist/types/config/autorouting-generator.d.ts +40 -0
  15. package/dist/types/config/autorouting-tier-map.d.ts +16844 -0
  16. package/dist/types/config/autorouting.d.ts +35 -0
  17. package/dist/types/config/model-discovery-manager.d.ts +8 -1
  18. package/dist/types/config/model-registry.d.ts +30 -1
  19. package/dist/types/config/provider-selection-policy.d.ts +23 -0
  20. package/dist/types/config/settings-schema.d.ts +61 -3
  21. package/dist/types/config/settings.d.ts +3 -0
  22. package/dist/types/coordinator/contract.d.ts +1 -1
  23. package/dist/types/coordinator-mcp/durability.d.ts +29 -0
  24. package/dist/types/coordinator-mcp/event-webhook.d.ts +50 -0
  25. package/dist/types/coordinator-mcp/question-state.d.ts +1 -1
  26. package/dist/types/coordinator-mcp/server.d.ts +14 -0
  27. package/dist/types/crash/index-store.d.ts +3 -0
  28. package/dist/types/crash/record-loader.d.ts +2 -0
  29. package/dist/types/crash/upstream/relay.d.ts +5 -3
  30. package/dist/types/cursor.d.ts +12 -0
  31. package/dist/types/defaults/gjc-defaults.d.ts +35 -1
  32. package/dist/types/defaults/gjc-skills.generated.d.ts +1 -1
  33. package/dist/types/discovery/helpers.d.ts +1 -1
  34. package/dist/types/edit/index.d.ts +2 -1
  35. package/dist/types/eval/py/executor.d.ts +2 -0
  36. package/dist/types/extensibility/extensions/loader.d.ts +32 -0
  37. package/dist/types/extensibility/gjc-plugins/types.d.ts +1 -1
  38. package/dist/types/extensibility/skills.d.ts +2 -0
  39. package/dist/types/gjc-runtime/autoresearch-runtime.d.ts +194 -0
  40. package/dist/types/gjc-runtime/gc-runtime.d.ts +1 -1
  41. package/dist/types/gjc-runtime/psmux-detect.d.ts +1 -1
  42. package/dist/types/gjc-runtime/python-transcript.d.ts +19 -0
  43. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +2 -8
  44. package/dist/types/gjc-runtime/session-layout.d.ts +6 -3
  45. package/dist/types/gjc-runtime/state-renderer.d.ts +0 -22
  46. package/dist/types/gjc-runtime/state-schema.d.ts +7 -7
  47. package/dist/types/gjc-runtime/tmux-common.d.ts +2 -2
  48. package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +38 -1
  49. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +2 -24
  50. package/dist/types/gjc-runtime/ultragoal-validation-policy.d.ts +73 -0
  51. package/dist/types/gjc-runtime/workflow-recovery-projection.d.ts +100 -0
  52. package/dist/types/hooks/skill-keywords.d.ts +1 -1
  53. package/dist/types/main.d.ts +0 -10
  54. package/dist/types/modes/acp/acp-agent.d.ts +13 -6
  55. package/dist/types/modes/components/model-selector.d.ts +14 -0
  56. package/dist/types/modes/components/skill-hud/render.d.ts +6 -1
  57. package/dist/types/modes/components/smart-routing-panel.d.ts +82 -0
  58. package/dist/types/modes/controllers/selector-controller.d.ts +14 -0
  59. package/dist/types/modes/interactive-mode.d.ts +3 -0
  60. package/dist/types/modes/types.d.ts +9 -0
  61. package/dist/types/rlm/artifacts.d.ts +4 -4
  62. package/dist/types/runtime/optional-runtime-services.d.ts +2 -1
  63. package/dist/types/runtime/workspace-tree-service.d.ts +5 -1
  64. package/dist/types/runtime-mcp/config.d.ts +6 -0
  65. package/dist/types/runtime-mcp/manager.d.ts +10 -0
  66. package/dist/types/sdk/acp/adapter.d.ts +0 -4
  67. package/dist/types/sdk/broker/broker.d.ts +1 -1
  68. package/dist/types/sdk/broker/lifecycle.d.ts +57 -2
  69. package/dist/types/sdk/broker/session-index.d.ts +15 -0
  70. package/dist/types/sdk/bus/chat-daemon-control.d.ts +6 -0
  71. package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +4 -0
  72. package/dist/types/sdk/bus/index.d.ts +8 -0
  73. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +2 -0
  74. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -2
  75. package/dist/types/sdk/client/client.d.ts +39 -4
  76. package/dist/types/sdk/host/host.d.ts +1 -0
  77. package/dist/types/sdk/host/internal-autorouting-state.d.ts +3 -0
  78. package/dist/types/sdk/host/model-pin.d.ts +29 -0
  79. package/dist/types/sdk/host/session-runtime.d.ts +2 -1
  80. package/dist/types/sdk/lifecycle-session.d.ts +13 -0
  81. package/dist/types/sdk/router/session-router.d.ts +27 -1
  82. package/dist/types/sdk/session.d.ts +11 -1
  83. package/dist/types/session/agent-session.d.ts +36 -6
  84. package/dist/types/session/artifacts.d.ts +16 -1
  85. package/dist/types/session/internal/managed-session-storage.d.ts +7 -0
  86. package/dist/types/session/session-manager.d.ts +84 -2
  87. package/dist/types/session/session-staging-paths.d.ts +3 -0
  88. package/dist/types/skill-state/canonical-skills.d.ts +1 -1
  89. package/dist/types/skill-state/workflow-hud.d.ts +12 -21
  90. package/dist/types/skill-state/workflow-mutation-guard.d.ts +1 -0
  91. package/dist/types/slash-commands/helpers/autorouting-status.d.ts +8 -0
  92. package/dist/types/system-prompt.d.ts +23 -0
  93. package/dist/types/task/executor.d.ts +35 -4
  94. package/dist/types/task/index.d.ts +17 -3
  95. package/dist/types/task/receipt.d.ts +3 -1
  96. package/dist/types/task/types.d.ts +144 -0
  97. package/dist/types/tools/atomic-file-write.d.ts +72 -0
  98. package/dist/types/tools/descriptors.d.ts +1 -0
  99. package/dist/types/tools/index.d.ts +36 -1
  100. package/dist/types/tools/move-session.d.ts +40 -0
  101. package/dist/types/tools/python.d.ts +12 -0
  102. package/dist/types/tools/resource-gc.d.ts +0 -3
  103. package/dist/types/tools/search.d.ts +8 -1
  104. package/dist/types/tools/skill.d.ts +9 -4
  105. package/dist/types/tools/subagent.d.ts +33 -3
  106. package/dist/types/utils/xml-escape.d.ts +2 -0
  107. package/dist/types/workflow/workflow-intent-diff.d.ts +2 -2
  108. package/dist/types/workflow/workflow-intent-report-consumer.d.ts +1 -1
  109. package/package.json +11 -12
  110. package/scripts/build-sdk-package-smoke.ts +7 -5
  111. package/scripts/check-autorouting-tier-map.ts +183 -0
  112. package/scripts/generate-sdk-operation-inventory.ts +12 -0
  113. package/scripts/generate-tool-catalog.ts +40 -5
  114. package/src/async/job-manager.ts +5 -2
  115. package/src/autoresearch/dashboard.ts +134 -314
  116. package/src/autoresearch/data-context.ts +35 -0
  117. package/src/autoresearch/git.ts +186 -26
  118. package/src/autoresearch/{helpers.ts → harness.ts} +65 -40
  119. package/src/autoresearch/{prompt-setup.md → prompts/prompt-setup.md} +7 -7
  120. package/src/autoresearch/prompts/prompt.md +103 -0
  121. package/src/autoresearch/prompts.ts +126 -0
  122. package/src/autoresearch/runs.ts +708 -0
  123. package/src/autoresearch/types.ts +9 -150
  124. package/src/capability/index.ts +4 -4
  125. package/src/capability/types.ts +20 -0
  126. package/src/cli/accounts-cli.ts +21 -5
  127. package/src/cli/config-cli.ts +25 -1
  128. package/src/cli/fast-help.ts +1 -2
  129. package/src/cli/list-models.ts +5 -8
  130. package/src/cli/setup-cli.ts +8 -0
  131. package/src/cli.ts +2 -21
  132. package/src/commands/autoresearch.ts +33 -0
  133. package/src/commands/coordinator.ts +15 -0
  134. package/src/commands/launch.ts +2 -4
  135. package/src/commands/quick-lane.ts +1 -1
  136. package/src/commands/sdk.ts +24 -0
  137. package/src/commands/state.ts +1 -1
  138. package/src/config/autorouting-contract.ts +474 -0
  139. package/src/config/autorouting-generator.ts +238 -0
  140. package/src/config/autorouting-tier-map.ts +6108 -0
  141. package/src/config/autorouting.ts +120 -0
  142. package/src/config/model-discovery-manager.ts +42 -11
  143. package/src/config/model-registry.ts +348 -68
  144. package/src/config/provider-selection-policy.ts +60 -9
  145. package/src/config/settings-schema.ts +195 -6
  146. package/src/config/settings.ts +62 -1
  147. package/src/config.ts +2 -3
  148. package/src/coordinator/contract.ts +0 -1
  149. package/src/coordinator-mcp/codex-handoff.ts +68 -42
  150. package/src/coordinator-mcp/durability.ts +200 -0
  151. package/src/coordinator-mcp/event-webhook.ts +278 -0
  152. package/src/coordinator-mcp/question-state.ts +109 -46
  153. package/src/coordinator-mcp/server.ts +932 -504
  154. package/src/crash/index-store.ts +126 -22
  155. package/src/crash/record-loader.ts +7 -0
  156. package/src/crash/upstream/relay.ts +82 -34
  157. package/src/cursor.ts +84 -1
  158. package/src/debug/index.ts +26 -0
  159. package/src/defaults/gjc/skills/autoresearch/SKILL.md +116 -0
  160. package/src/defaults/gjc/skills/autoresearch/auto-critic.md +46 -0
  161. package/src/defaults/gjc/skills/autoresearch/auto-iterate.md +42 -0
  162. package/src/defaults/gjc/skills/deep-interview/SKILL.md +17 -37
  163. package/src/defaults/gjc/skills/ralplan/SKILL.md +21 -18
  164. package/src/defaults/gjc/skills/ultragoal/SKILL.md +6 -17
  165. package/src/defaults/gjc/skills/ultragoal/ai-slop-cleaner.md +2 -2
  166. package/src/defaults/gjc-defaults.ts +89 -2
  167. package/src/defaults/gjc-skills.generated.ts +24 -17
  168. package/src/discovery/builtin.ts +18 -5
  169. package/src/discovery/helpers.ts +6 -6
  170. package/src/edit/index.ts +5 -2
  171. package/src/eval/py/executor.ts +8 -0
  172. package/src/extensibility/extensions/loader.ts +135 -13
  173. package/src/extensibility/extensions/wrapper.ts +1 -2
  174. package/src/extensibility/gjc-plugins/schema.ts +1 -1
  175. package/src/extensibility/runtime-skill-discovery.ts +2 -2
  176. package/src/extensibility/skill-management.ts +2 -3
  177. package/src/extensibility/skills.ts +16 -8
  178. package/src/gjc-runtime/autoresearch-runtime.ts +1509 -0
  179. package/src/gjc-runtime/gc-render.ts +0 -1
  180. package/src/gjc-runtime/gc-runtime.ts +1 -11
  181. package/src/gjc-runtime/launch-tmux.ts +3 -3
  182. package/src/gjc-runtime/psmux-detect.ts +2 -2
  183. package/src/gjc-runtime/python-transcript.ts +58 -0
  184. package/src/gjc-runtime/ralplan-runtime.ts +6 -18
  185. package/src/gjc-runtime/session-layout.ts +18 -7
  186. package/src/gjc-runtime/session-state-sidecar.ts +58 -9
  187. package/src/gjc-runtime/state-renderer.ts +0 -38
  188. package/src/gjc-runtime/state-runtime.ts +43 -22
  189. package/src/gjc-runtime/state-schema.ts +1 -1
  190. package/src/gjc-runtime/tmux-common.ts +7 -7
  191. package/src/gjc-runtime/ultragoal-change-set.ts +232 -11
  192. package/src/gjc-runtime/ultragoal-runtime.ts +309 -114
  193. package/src/gjc-runtime/ultragoal-validation-policy.ts +247 -0
  194. package/src/gjc-runtime/workflow-command-ref.ts +15 -11
  195. package/src/gjc-runtime/workflow-manifest.generated.json +413 -532
  196. package/src/gjc-runtime/workflow-manifest.ts +43 -83
  197. package/src/gjc-runtime/workflow-recovery-projection.ts +616 -0
  198. package/src/hooks/skill-keywords.ts +3 -3
  199. package/src/hooks/skill-state.ts +2 -2
  200. package/src/internal-urls/docs-index.generated.ts +26 -24
  201. package/src/lsp/index.ts +25 -5
  202. package/src/main.ts +2 -27
  203. package/src/modes/acp/acp-agent.ts +200 -75
  204. package/src/modes/components/model-selector.ts +216 -13
  205. package/src/modes/components/oauth-selector.ts +5 -5
  206. package/src/modes/components/skill-hud/render.ts +173 -35
  207. package/src/modes/components/smart-routing-panel.ts +531 -0
  208. package/src/modes/components/tool-status-header.ts +6 -3
  209. package/src/modes/controllers/command-controller.ts +17 -7
  210. package/src/modes/controllers/input-controller.ts +44 -9
  211. package/src/modes/controllers/runtime-mcp-command-controller.ts +4 -0
  212. package/src/modes/controllers/selector-controller.ts +298 -65
  213. package/src/modes/interactive-mode.ts +8 -1
  214. package/src/modes/shared/agent-wire/workflow-gate-types.ts +1 -1
  215. package/src/modes/types.ts +9 -1
  216. package/src/prompts/agents/planner.md +1 -1
  217. package/src/prompts/system/system-prompt.md +1 -1
  218. package/src/prompts/system/volatile-project-context.md +2 -1
  219. package/src/prompts/tools/move-session.md +15 -0
  220. package/src/prompts/tools/python.md +12 -0
  221. package/src/prompts/tools/skill-discovery.md +1 -1
  222. package/src/prompts/tools/skill.md +2 -2
  223. package/src/prompts/tools/task-summary.md +1 -0
  224. package/src/prompts/tools/task.md +6 -0
  225. package/src/rlm/artifacts.ts +12 -10
  226. package/src/runtime/optional-runtime-services.ts +3 -2
  227. package/src/runtime/workspace-tree-service.ts +11 -3
  228. package/src/runtime-mcp/config.ts +8 -1
  229. package/src/runtime-mcp/manager.ts +33 -0
  230. package/src/sdk/acp/adapter.ts +48 -1
  231. package/src/sdk/broker/broker.ts +30 -2
  232. package/src/sdk/broker/discovery.ts +217 -2
  233. package/src/sdk/broker/lifecycle.ts +385 -59
  234. package/src/sdk/broker/session-index.ts +243 -48
  235. package/src/sdk/broker/transport.ts +1 -0
  236. package/src/sdk/bus/chat-daemon-control.ts +8 -2
  237. package/src/sdk/bus/chat-daemon-runtime.ts +5 -0
  238. package/src/sdk/bus/index.ts +208 -11
  239. package/src/sdk/bus/kind-aware-reconciliation.ts +16 -0
  240. package/src/sdk/bus/reconciliation-store.ts +27 -5
  241. package/src/sdk/bus/telegram-daemon-contract.ts +12 -2
  242. package/src/sdk/client/client.ts +204 -22
  243. package/src/sdk/host/host.ts +16 -0
  244. package/src/sdk/host/internal-autorouting-state.ts +13 -0
  245. package/src/sdk/host/model-pin.ts +101 -0
  246. package/src/sdk/host/reverse-leases.ts +2 -1
  247. package/src/sdk/host/session-runtime.test.ts +224 -1
  248. package/src/sdk/host/session-runtime.ts +125 -37
  249. package/src/sdk/lifecycle/service.ts +3 -1
  250. package/src/sdk/lifecycle-session.ts +42 -1
  251. package/src/sdk/protocol/operation-inventory.generated.json +66 -0
  252. package/src/sdk/router/session-router.ts +375 -36
  253. package/src/sdk/session.ts +547 -47
  254. package/src/session/account-inventory.ts +1 -1
  255. package/src/session/agent-session.ts +765 -189
  256. package/src/session/artifacts.ts +234 -4
  257. package/src/session/internal/managed-session-storage.ts +91 -4
  258. package/src/session/provider-safety-stop-hint.ts +3 -2
  259. package/src/session/session-manager.ts +775 -16
  260. package/src/session/session-staging-paths.ts +8 -0
  261. package/src/setup/hermes/templates/operator-instructions.v1.md +0 -1
  262. package/src/setup/host-plugin-setup.ts +2 -2
  263. package/src/skill-state/active-state.ts +2 -2
  264. package/src/skill-state/canonical-skills.ts +1 -1
  265. package/src/skill-state/initial-phase.ts +1 -1
  266. package/src/skill-state/workflow-hud.ts +41 -41
  267. package/src/skill-state/workflow-mutation-guard.ts +26 -7
  268. package/src/slash-commands/builtin-registry.ts +77 -0
  269. package/src/slash-commands/helpers/autorouting-status.ts +55 -0
  270. package/src/system-prompt.ts +102 -5
  271. package/src/task/discovery.ts +2 -3
  272. package/src/task/executor.ts +617 -43
  273. package/src/task/index.ts +262 -15
  274. package/src/task/receipt.ts +30 -0
  275. package/src/task/render.ts +11 -1
  276. package/src/task/types.ts +316 -0
  277. package/src/tools/atomic-file-write.ts +594 -0
  278. package/src/tools/bisect.ts +3 -2
  279. package/src/tools/descriptors.test.ts +3 -0
  280. package/src/tools/descriptors.ts +24 -0
  281. package/src/tools/image-gen.ts +5 -1
  282. package/src/tools/index.ts +62 -5
  283. package/src/tools/move-session.ts +107 -0
  284. package/src/tools/python.ts +205 -0
  285. package/src/tools/read.ts +88 -15
  286. package/src/tools/renderers.ts +2 -0
  287. package/src/tools/resource-gc.ts +8 -177
  288. package/src/tools/search.ts +30 -6
  289. package/src/tools/skill-discovery.ts +1 -0
  290. package/src/tools/skill.ts +37 -7
  291. package/src/tools/subagent-render.ts +119 -13
  292. package/src/tools/subagent.ts +91 -74
  293. package/src/tools/tool-catalog.generated.ts +64 -2
  294. package/src/tools/write.ts +16 -12
  295. package/src/utils/xml-escape.ts +14 -0
  296. package/src/web/search/providers/codex.ts +2 -2
  297. package/src/workflow/workflow-intent-diff.ts +13 -12
  298. package/src/workflow/workflow-intent-report-consumer.ts +6 -6
  299. package/dist/types/autoresearch/helpers.d.ts +0 -24
  300. package/dist/types/autoresearch/index.d.ts +0 -2
  301. package/dist/types/autoresearch/state.d.ts +0 -17
  302. package/dist/types/autoresearch/storage.d.ts +0 -142
  303. package/dist/types/autoresearch/tools/init-experiment.d.ts +0 -31
  304. package/dist/types/autoresearch/tools/log-experiment.d.ts +0 -23
  305. package/dist/types/autoresearch/tools/run-experiment.d.ts +0 -8
  306. package/dist/types/autoresearch/tools/update-notes.d.ts +0 -12
  307. package/dist/types/commands/team.d.ts +0 -24
  308. package/dist/types/gjc-runtime/team-gc.d.ts +0 -7
  309. package/dist/types/gjc-runtime/team-launch.d.ts +0 -61
  310. package/dist/types/gjc-runtime/team-notify.d.ts +0 -45
  311. package/dist/types/gjc-runtime/team-runtime.d.ts +0 -336
  312. package/dist/types/gjc-runtime/team-store.d.ts +0 -168
  313. package/dist/types/gjc-runtime/team-worker-heartbeat.d.ts +0 -43
  314. package/dist/types/gjc-runtime/team-worker-memory-guard.d.ts +0 -92
  315. package/dist/types/gjc-runtime/team-workers.d.ts +0 -83
  316. package/dist/types/rlm/index.d.ts +0 -47
  317. package/dist/types/rlm/preset.d.ts +0 -23
  318. package/dist/types/rlm/python-tool.d.ts +0 -16
  319. package/src/autoresearch/command-resume.md +0 -14
  320. package/src/autoresearch/index.ts +0 -536
  321. package/src/autoresearch/prompt.md +0 -103
  322. package/src/autoresearch/resume-message.md +0 -10
  323. package/src/autoresearch/state.ts +0 -273
  324. package/src/autoresearch/storage.ts +0 -699
  325. package/src/autoresearch/tools/init-experiment.ts +0 -272
  326. package/src/autoresearch/tools/log-experiment.ts +0 -524
  327. package/src/autoresearch/tools/run-experiment.ts +0 -475
  328. package/src/autoresearch/tools/update-notes.ts +0 -109
  329. package/src/commands/rlm.ts +0 -19
  330. package/src/commands/team.ts +0 -238
  331. package/src/defaults/gjc/skills/deep-interview/auto-research-greenfield.md +0 -42
  332. package/src/defaults/gjc/skills/team/SKILL.md +0 -467
  333. package/src/gjc-runtime/team-gc.ts +0 -49
  334. package/src/gjc-runtime/team-launch.ts +0 -404
  335. package/src/gjc-runtime/team-notify.ts +0 -326
  336. package/src/gjc-runtime/team-runtime.ts +0 -5923
  337. package/src/gjc-runtime/team-store.ts +0 -878
  338. package/src/gjc-runtime/team-worker-heartbeat.ts +0 -149
  339. package/src/gjc-runtime/team-worker-memory-guard.ts +0 -363
  340. package/src/gjc-runtime/team-workers.ts +0 -1123
  341. package/src/prompts/system/rlm-report-command.md +0 -1
  342. package/src/prompts/system/rlm-research.md +0 -23
  343. package/src/rlm/index.ts +0 -365
  344. package/src/rlm/preset.ts +0 -76
  345. package/src/rlm/python-tool.ts +0 -68
@@ -1 +0,0 @@
1
- Call complete_research with final=false and a concise summary of the current notebook-backed findings. Do not mark the goal complete unless the full research objective is satisfied.
@@ -1,23 +0,0 @@
1
- You are operating in **RLM research mode** — a Jupyter-notebook-style research session backed by a persistent Python kernel. Your job is to investigate a question or dataset through iterative, reproducible Python analysis and then synthesize what you found.
2
-
3
- ## How you work
4
-
5
- - Drive the investigation with the `python` tool. The kernel is **persistent**: variables, imports, and loaded data survive across calls, exactly like notebook cells. Build up state incrementally instead of re-running everything each time.
6
- - Each `python` call is recorded as a notebook cell (code + output) in this session's `notebook.ipynb`. Write focused cells that each make one clear step of progress.
7
- - Prefer the managed scientific stack (`numpy`, `pandas`, `matplotlib`, `polars`) when useful. If an additional package is missing, use the kernel's `%pip install …` magic only when it is necessary for the investigation; that install cell is recorded in the notebook as provenance.
8
- - Use `read` to inspect local files, `web_search` to gather external facts, and read-only `bash` only for simple inspection commands where shell-native views are materially useful (`grep`, `rg`, `tree`, `ls`, `pwd`, `wc`, `du`, `file`, `stat`). The `bash` surface is restricted to a single command with no pipelines, redirects, env overrides, command substitution, shell expansion, or write-capable flags. You do **not** have file-editing or arbitrary-mutation tools in this mode by design: keep all work inside the Python kernel, read-only inspection, and the notebook/report artifacts.
9
- - RLM always runs under goal mode. Use `goal({"op":"get"})` to inspect the active research goal. When the research objective is actually satisfied and the report-worthy conclusions are grounded in notebook outputs, call `goal({"op":"complete"})`, then call `complete_research` with a concise final summary. Do not present the session as complete without both tool calls.
10
-
11
- ## Evidence discipline
12
-
13
- - Ground every claim in an actual cell output you can point to. Do not report a metric, finding, or conclusion you have not computed and seen.
14
- - When a cell fails, read the error, fix the specific cause, and continue — do not paper over failures.
15
- - Distinguish what the data shows from what you infer. State assumptions explicitly.
16
-
17
- ## Data context
18
-
19
- - If a `DATA.md` file (or a `--data` path) was provided, treat it as the authoritative description of the available data and honor it.
20
-
21
- ## Reporting
22
-
23
- - When the investigation is complete (or when asked), produce a clear Markdown research report covering the question, the method, the key findings with their supporting evidence, and the conclusions and caveats. The session's `report.md` is synthesized from your notebook and final summary.
package/src/rlm/index.ts DELETED
@@ -1,365 +0,0 @@
1
- /**
2
- * RLM (research) mode entry point.
3
- *
4
- * Composes a research session over the existing agent/session loop (python
5
- * kernel + read + web_search + read-only bash), optional DATA.md context, live
6
- * notebook.ipynb, first-class complete_research report synthesis, autonomous
7
- * goal-arg execution, and resumable .gjc/rlm/<session> artifacts.
8
- */
9
- import * as fs from "node:fs/promises";
10
- import { getProjectDir } from "@gajae-code/utils";
11
- import { type Args, parseArgs } from "../cli/args";
12
- import { disposeKernelSessionsByOwner } from "../eval/py/executor";
13
- import type { CustomTool } from "../extensibility/custom-tools/types";
14
- import { resolveSessionIdFromSources, writeSessionActivityMarker } from "../gjc-runtime/session-resolution";
15
- import { type RlmPreset, runRootCommand } from "../main";
16
- import rlmReportCommandPrompt from "../prompts/system/rlm-report-command.md" with { type: "text" };
17
- import type { CreateAgentSessionOptions } from "../sdk";
18
- import type { AgentSession } from "../session/agent-session";
19
- import {
20
- ensureRlmSessionDir,
21
- generateRlmSessionId,
22
- readRlmNotebookIfPresent,
23
- resolveRlmArtifactPaths,
24
- rlmSessionExists,
25
- } from "./artifacts";
26
- import {
27
- countSuccessfulNotebookRuns,
28
- createRlmCompleteResearchTool,
29
- summarizeNotebookForReplay,
30
- writeRlmReport,
31
- } from "./complete-research-tool";
32
- import { loadRlmDataContext, type RlmDataContext } from "./data-context";
33
- import { RlmNotebookWriter } from "./notebook";
34
- import { assertRlmToolAllowlist, buildRlmSystemPrompt, isRlmToolAllowed, RLM_READ_ONLY_BASH_PREFIXES } from "./preset";
35
- import { createRlmPythonTool } from "./python-tool";
36
- import type { RlmArtifactPaths, RlmSessionMetadata } from "./types";
37
-
38
- interface ExtractedRlmFlags {
39
- dataPath: string | undefined;
40
- resumeSessionId: string | undefined;
41
- minSuccessfulRuns: number;
42
- rest: string[];
43
- }
44
-
45
- export interface RlmPresetOptions {
46
- dataContext: RlmDataContext | null;
47
- pythonTool: CustomTool;
48
- completeResearchTool?: CustomTool;
49
- objective?: string;
50
- resumeContext?: string;
51
- onSessionReady?: (session: AgentSession) => void;
52
- }
53
-
54
- interface RlmRunController {
55
- completed: boolean;
56
- finalSummary: string | undefined;
57
- session: AgentSession | undefined;
58
- }
59
-
60
- function parseNonNegativeIntegerFlag(name: string, value: string | undefined): number {
61
- if (value === undefined || value.trim().length === 0) {
62
- throw new Error(`${name} requires a non-negative integer value.`);
63
- }
64
- const parsed = Number(value);
65
- if (!Number.isInteger(parsed) || parsed < 0) {
66
- throw new Error(`${name} requires a non-negative integer value.`);
67
- }
68
- return parsed;
69
- }
70
-
71
- /** Pull RLM-owned flags out of argv; the remainder is forwarded to the root command. */
72
- export function extractRlmFlags(argv: string[]): ExtractedRlmFlags {
73
- const rest: string[] = [];
74
- let dataPath: string | undefined;
75
- let resumeSessionId: string | undefined;
76
- let minSuccessfulRuns = 0;
77
- for (let i = 0; i < argv.length; i++) {
78
- const arg = argv[i];
79
- if (arg === "--data") {
80
- dataPath = argv[i + 1];
81
- i += 1;
82
- } else if (arg.startsWith("--data=")) {
83
- dataPath = arg.slice("--data=".length);
84
- } else if (arg === "--resume" || arg === "-r") {
85
- const next = argv[i + 1];
86
- if (!next || next.startsWith("-")) throw new Error("gjc rlm --resume requires an RLM session id.");
87
- resumeSessionId = next;
88
- i += 1;
89
- } else if (arg.startsWith("--resume=")) {
90
- resumeSessionId = arg.slice("--resume=".length);
91
- } else if (arg === "--min-successful-runs") {
92
- minSuccessfulRuns = parseNonNegativeIntegerFlag(arg, argv[i + 1]);
93
- i += 1;
94
- } else if (arg.startsWith("--min-successful-runs=")) {
95
- minSuccessfulRuns = parseNonNegativeIntegerFlag(
96
- "--min-successful-runs",
97
- arg.slice("--min-successful-runs=".length),
98
- );
99
- } else {
100
- rest.push(arg);
101
- }
102
- }
103
- return { dataPath, resumeSessionId, minSuccessfulRuns, rest };
104
- }
105
-
106
- /** @deprecated use extractRlmFlags; retained for tests and compatibility. */
107
- export function extractDataFlag(argv: string[]): { dataPath: string | undefined; rest: string[] } {
108
- const { dataPath, rest } = extractRlmFlags(argv);
109
- return { dataPath, rest };
110
- }
111
-
112
- export function createRlmPreset({
113
- dataContext,
114
- pythonTool,
115
- completeResearchTool,
116
- objective,
117
- resumeContext,
118
- onSessionReady,
119
- }: RlmPresetOptions): RlmPreset {
120
- const resolvedObjective = objective ?? buildRlmGoalObjective({ messages: [], dataContext });
121
- const customTools = completeResearchTool ? [pythonTool, completeResearchTool] : [pythonTool];
122
- return {
123
- applyOptions: (options: CreateAgentSessionOptions, settings) => {
124
- options.systemPrompt = buildRlmSystemPrompt(dataContext, resumeContext);
125
- options.customTools = customTools;
126
- options.toolNames = ["read", "web_search", "search_tool_bm25", "bash", "goal"];
127
- options.requireYieldTool = false;
128
- options.skills = [];
129
- options.rules = [];
130
- options.disableExtensionDiscovery = true;
131
- options.extensions = [];
132
- options.additionalExtensionPaths = [];
133
- options.preloadedExtensions = undefined;
134
- options.bashAllowedPrefixes = [...RLM_READ_ONLY_BASH_PREFIXES];
135
- options.bashRestrictionProfile = "read-only";
136
- options.goalToolAllowedOps = ["get", "complete"];
137
- options.discoverableToolAllowedNames = [];
138
- options.slashCommands = [
139
- ...(options.slashCommands ?? []),
140
- {
141
- name: "report",
142
- description: "Synthesize a draft RLM report from the current notebook",
143
- content: rlmReportCommandPrompt,
144
- source: "rlm",
145
- },
146
- ];
147
- // RLM always runs in goal mode; recipe injection stays outside the research surface.
148
- settings.override("goal.enabled", true);
149
- settings.override("tools.discoveryMode", "all");
150
- settings.override("recipe.enabled", false);
151
- },
152
- onSessionCreated: async (session: AgentSession) => {
153
- onSessionReady?.(session);
154
- await ensureRlmGoalMode(session, resolvedObjective);
155
- // Hard boundary: fail launch if any non-allowlisted tool slipped into the active set.
156
- assertRlmToolAllowlist(session.getActiveToolNames());
157
- },
158
- };
159
- }
160
-
161
- async function ensureRlmGoalMode(session: AgentSession, objective: string): Promise<void> {
162
- const current = session.getGoalModeState();
163
- if (current?.goal && current.goal.status !== "complete" && current.goal.status !== "dropped") {
164
- if (!current.enabled || current.goal.status === "paused") {
165
- await session.goalRuntime.resumeGoal();
166
- }
167
- } else {
168
- await session.goalRuntime.createGoal({ objective });
169
- }
170
- await session.setActiveToolsByName([...new Set([...session.getActiveToolNames().filter(isRlmToolAllowed), "goal"])]);
171
- }
172
-
173
- export function buildRlmGoalObjective(input: {
174
- messages: readonly string[];
175
- dataContext: RlmDataContext | null;
176
- }): string {
177
- const prompt = input.messages
178
- .map(message => message.trim())
179
- .filter(Boolean)
180
- .join("\n\n");
181
- if (prompt.length > 0) return prompt;
182
- if (input.dataContext) {
183
- return `Complete an RLM research session using data context ${input.dataContext.path}, grounding conclusions in notebook outputs and finishing with a report.`;
184
- }
185
- return "Complete this RLM research session, grounding conclusions in notebook outputs and finishing with a report.";
186
- }
187
- export function isRlmAutonomousRun(parsed: Pick<Args, "print" | "mode" | "messages">, pipedStdin: boolean): boolean {
188
- return parsed.print === true || parsed.mode !== undefined || pipedStdin;
189
- }
190
-
191
- export function prepareRlmLaunchMode(parsed: Args, pipedStdin: boolean): boolean {
192
- const autonomous = isRlmAutonomousRun(parsed, pipedStdin);
193
- if (autonomous && parsed.mode === undefined) {
194
- parsed.print = true;
195
- }
196
- return autonomous;
197
- }
198
-
199
- async function loadExistingMetadata(paths: RlmArtifactPaths): Promise<RlmSessionMetadata | undefined> {
200
- try {
201
- return (await Bun.file(paths.metadataPath).json()) as RlmSessionMetadata;
202
- } catch {
203
- return undefined;
204
- }
205
- }
206
-
207
- async function writeRlmMetadata(input: {
208
- paths: RlmArtifactPaths;
209
- sessionId: string;
210
- createdAt: string;
211
- cwd: string;
212
- dataPath: string | null;
213
- cellCount: number;
214
- mode: "interactive" | "autonomous";
215
- resumedFrom: string | null;
216
- completedAt: string | null;
217
- finalSummary: string | null;
218
- minSuccessfulRuns: number;
219
- successfulRuns: number;
220
- }): Promise<void> {
221
- const metadata: RlmSessionMetadata = {
222
- sessionId: input.sessionId,
223
- createdAt: input.createdAt,
224
- cwd: input.cwd,
225
- dataPath: input.dataPath,
226
- cellCount: input.cellCount,
227
- mode: input.mode,
228
- resumedFrom: input.resumedFrom,
229
- completedAt: input.completedAt,
230
- finalSummary: input.finalSummary,
231
- minSuccessfulRuns: input.minSuccessfulRuns,
232
- successfulRuns: input.successfulRuns,
233
- };
234
- await Bun.write(input.paths.metadataPath, `${JSON.stringify(metadata, null, 2)}\n`);
235
- // Best-effort: update the per-session activity marker so latest-session auto-detect
236
- // accounts for RLM-only generated output (AC2). Never let marker failure break RLM.
237
- const gjcSessionId = resolveSessionIdFromSources({ envSessionId: process.env.GJC_SESSION_ID })?.gjcSessionId;
238
- if (gjcSessionId) {
239
- await writeSessionActivityMarker(input.cwd, gjcSessionId, { writer: "rlm" }).catch(() => {});
240
- }
241
- }
242
-
243
- /**
244
- * RLM artifacts are scoped under a GJC session directory and resolving their
245
- * paths is a *write* (it must pick a concrete session). When `gjc rlm` runs
246
- * standalone — no parent agent, no `GJC_SESSION_ID` in the environment — there is
247
- * no session to resolve and `resolveGjcSessionForWrite` throws
248
- * `missing_for_write`. Establish a dedicated GJC session id in that case and pin
249
- * it into the environment so artifact-path resolution, the per-session activity
250
- * marker, and the child agent's workflow state all share one writable session.
251
- *
252
- * Returns the resolved (existing or freshly generated) GJC session id.
253
- */
254
- export function ensureRlmGjcSessionId(): string {
255
- const existing = resolveSessionIdFromSources({ envSessionId: process.env.GJC_SESSION_ID })?.gjcSessionId;
256
- if (existing) return existing;
257
- const generated = `rlm-${generateRlmSessionId()}`;
258
- process.env.GJC_SESSION_ID = generated;
259
- return generated;
260
- }
261
- export async function runRlmCommand(argv: string[]): Promise<void> {
262
- const cwd = getProjectDir();
263
- ensureRlmGjcSessionId();
264
- const { dataPath, resumeSessionId, minSuccessfulRuns, rest } = extractRlmFlags(argv);
265
- const parsed = parseArgs(rest, "local");
266
- const dataContext = await loadRlmDataContext(cwd, dataPath);
267
-
268
- const sessionId = resumeSessionId ?? generateRlmSessionId();
269
- const paths = resolveRlmArtifactPaths(cwd, sessionId);
270
- if (resumeSessionId && !(await rlmSessionExists(cwd, resumeSessionId))) {
271
- throw new Error(`RLM session not found: ${resumeSessionId}`);
272
- }
273
- await ensureRlmSessionDir(paths);
274
- await fs.mkdir(paths.agentSessionDir, { recursive: true });
275
-
276
- const existingNotebook = resumeSessionId ? await readRlmNotebookIfPresent(cwd, sessionId) : undefined;
277
- const existingMetadata = await loadExistingMetadata(paths);
278
- const notebook = new RlmNotebookWriter(paths.notebookPath, existingNotebook);
279
- const pythonTool = createRlmPythonTool({
280
- cwd,
281
- sessionId,
282
- artifactsDir: paths.dir,
283
- notebook,
284
- managedWorkspaceVenv: true,
285
- });
286
- const controller: RlmRunController = { completed: false, finalSummary: undefined, session: undefined };
287
- const reportTitle = `RLM research session ${sessionId}`;
288
- const completeResearchTool = createRlmCompleteResearchTool({
289
- paths,
290
- notebook,
291
- title: reportTitle,
292
- dataPath: dataContext?.path ?? null,
293
- minSuccessfulRuns,
294
- getGoalStatus: () => controller.session?.getGoalModeState()?.goal.status,
295
- markCompleted: summary => {
296
- controller.completed = true;
297
- controller.finalSummary = summary;
298
- },
299
- });
300
-
301
- parsed.sessionDir = paths.agentSessionDir;
302
- if (resumeSessionId) {
303
- parsed.continue = true;
304
- }
305
- // Piped stdin (non-TTY), explicit --print, and explicit --mode run as autonomous
306
- // research. Positional argv messages seed the interactive RLM shell, so
307
- // `gjc rlm "question"` still loads the TUI instead of being coerced into
308
- // print mode.
309
- const pipedStdin = process.stdin.isTTY === false;
310
- const autonomous = prepareRlmLaunchMode(parsed, pipedStdin);
311
- const resumeContext = existingNotebook ? summarizeNotebookForReplay(existingNotebook) : undefined;
312
- const preset = createRlmPreset({
313
- dataContext,
314
- pythonTool,
315
- completeResearchTool,
316
- objective: buildRlmGoalObjective({ messages: parsed.messages, dataContext }),
317
- resumeContext,
318
- onSessionReady: session => {
319
- controller.session = session;
320
- },
321
- });
322
- if (autonomous) {
323
- preset.applyOptions = ((applyOptions: RlmPreset["applyOptions"]) => (options, settings) => {
324
- applyOptions(options, settings);
325
- options.shouldPause = () => controller.completed;
326
- })(preset.applyOptions);
327
- }
328
-
329
- let runError: unknown;
330
- try {
331
- await runRootCommand(parsed, rest, { rlmPreset: preset, suppressProcessExit: autonomous });
332
- } catch (error) {
333
- runError = error;
334
- throw error;
335
- } finally {
336
- // The RLM python tool owns a retained kernel keyed by `rlm:<sessionId>`; the
337
- // session's own dispose targets a different owner id, so release it here so
338
- // the persistent kernel subprocess is reaped on every exit path.
339
- await disposeKernelSessionsByOwner(`rlm:${sessionId}`).catch(() => {});
340
- await writeRlmReport({
341
- paths,
342
- notebook,
343
- title: reportTitle,
344
- summary: controller.finalSummary,
345
- dataPath: dataContext?.path ?? null,
346
- });
347
- await writeRlmMetadata({
348
- paths,
349
- sessionId,
350
- createdAt: existingMetadata?.createdAt ?? new Date().toISOString(),
351
- cwd,
352
- dataPath: dataContext?.path ?? null,
353
- cellCount: notebook.cellCount,
354
- mode: autonomous ? "autonomous" : "interactive",
355
- resumedFrom: resumeSessionId ?? null,
356
- completedAt: controller.completed ? new Date().toISOString() : null,
357
- finalSummary: controller.finalSummary ?? null,
358
- minSuccessfulRuns,
359
- successfulRuns: countSuccessfulNotebookRuns(notebook.document),
360
- });
361
- }
362
- if (autonomous && !controller.completed && runError === undefined) {
363
- throw new Error("RLM autonomous session ended before complete_research finalized the report.");
364
- }
365
- }
package/src/rlm/preset.ts DELETED
@@ -1,76 +0,0 @@
1
- /**
2
- * RLM research preset: the static research system prompt, the exact tool
3
- * allowlist, and a hard boundary assertion that fails launch if any
4
- * non-allowlisted tool is active.
5
- */
6
- import rlmResearchPrompt from "../prompts/system/rlm-research.md" with { type: "text" };
7
- import type { RlmDataContext } from "./data-context";
8
-
9
- /**
10
- * tool; `read` and `web_search` are the existing built-ins. `bash` is exposed
11
- * through the read-only restriction profile below for inspection commands only,
12
- * and `goal` is required so RLM sessions cannot finish without explicit goal
13
- * completion. Everything else (edit, write, task, skill, browser, eval-js, ...) is excluded.
14
- */
15
- export const RLM_READ_ONLY_BASH_PREFIXES: readonly string[] = [
16
- "grep",
17
- "rg",
18
- "tree",
19
- "ls",
20
- "pwd",
21
- "wc",
22
- "du",
23
- "file",
24
- "stat",
25
- ];
26
- export const RLM_TOOL_ALLOWLIST: readonly string[] = [
27
- "python",
28
- "read",
29
- "web_search",
30
- "search_tool_bm25",
31
- "bash",
32
- "goal",
33
- "complete_research",
34
- ];
35
-
36
- export function isRlmToolAllowed(name: string): boolean {
37
- return RLM_TOOL_ALLOWLIST.includes(name.toLowerCase());
38
- }
39
-
40
- /**
41
- * Hard boundary: throws if any active tool is outside the allowlist. Call this
42
- * after the session's tool registry is fully assembled and before running, so a
43
- * tool leaked in by defaults/discovery/extensions fails the launch loudly.
44
- */
45
- export function assertRlmToolAllowlist(activeToolNames: readonly string[]): void {
46
- const leaked = activeToolNames.filter(name => !isRlmToolAllowed(name));
47
- if (leaked.length > 0) {
48
- throw new Error(
49
- `RLM tool boundary violation: non-allowlisted active tool(s) [${leaked.join(", ")}]. ` +
50
- `RLM mode allows only: ${RLM_TOOL_ALLOWLIST.join(", ")}.`,
51
- );
52
- }
53
- }
54
-
55
- /** The research prompt text (exported for testing / prompt assembly). */
56
- export const RLM_RESEARCH_PROMPT: string = rlmResearchPrompt;
57
-
58
- /**
59
- * Build the systemPrompt transform for createAgentSession: appends the research
60
- * prompt, data context, and prior-notebook replay context to the default blocks.
61
- */
62
- export function buildRlmSystemPrompt(
63
- dataContext: RlmDataContext | null,
64
- resumeContext?: string,
65
- ): (defaultPrompt: string[]) => string[] {
66
- return (defaultPrompt: string[]): string[] => {
67
- const blocks = [...defaultPrompt, rlmResearchPrompt];
68
- if (dataContext) {
69
- blocks.push(`# Data context (from ${dataContext.path})\n\n${dataContext.content}`);
70
- }
71
- if (resumeContext && resumeContext.trim().length > 0) {
72
- blocks.push(`# Prior notebook replay context\n\n${resumeContext}`);
73
- }
74
- return blocks;
75
- };
76
- }
@@ -1,68 +0,0 @@
1
- /**
2
- * RLM `python` tool: the model-facing research execution tool. Wraps the shared
3
- * persistent Python kernel executor and records every call as a notebook cell.
4
- */
5
- import type { AgentToolResult } from "@gajae-code/agent-core";
6
- import { type Static, z } from "@gajae-code/ai/core";
7
- import { executePython } from "../eval/py/executor";
8
- import { RLM_MANAGED_PYTHON_PACKAGES } from "../eval/py/runtime";
9
- import type { CustomTool } from "../extensibility/custom-tools/types";
10
- import type { RlmNotebookWriter } from "./notebook";
11
- import type { RlmCellResult } from "./types";
12
-
13
- export const RLM_PYTHON_TOOL_NAME = "python";
14
-
15
- export interface RlmPythonToolContext {
16
- cwd: string;
17
- sessionId: string;
18
- artifactsDir: string;
19
- notebook: RlmNotebookWriter;
20
- managedWorkspaceVenv?: boolean;
21
- }
22
-
23
- const paramsSchema = z.object({
24
- code: z
25
- .string()
26
- .describe("Python source to execute in the persistent research kernel. State persists across calls."),
27
- });
28
-
29
- export function createRlmPythonTool(rlm: RlmPythonToolContext): CustomTool<typeof paramsSchema> {
30
- return {
31
- name: RLM_PYTHON_TOOL_NAME,
32
- label: "Python",
33
- description:
34
- "Execute Python in the persistent research kernel. Variables, imports, and loaded data persist across calls like notebook cells. Every call is recorded as a cell in the session notebook.",
35
- parameters: paramsSchema,
36
- strict: true,
37
- concurrency: "exclusive",
38
- async execute(
39
- _toolCallId: string,
40
- params: Static<typeof paramsSchema>,
41
- _onUpdate,
42
- _ctx,
43
- signal?: AbortSignal,
44
- ): Promise<AgentToolResult> {
45
- const result = await executePython(params.code, {
46
- cwd: rlm.cwd,
47
- kernelMode: "session",
48
- sessionId: `rlm:${rlm.sessionId}`,
49
- kernelOwnerId: `rlm:${rlm.sessionId}`,
50
- artifactsDir: rlm.artifactsDir,
51
- runtimeOptions: rlm.managedWorkspaceVenv
52
- ? { managedWorkspaceVenv: true, seedPackages: RLM_MANAGED_PYTHON_PACKAGES }
53
- : undefined,
54
- signal,
55
- });
56
- const cell: RlmCellResult = {
57
- output: result.output,
58
- exitCode: result.exitCode,
59
- cancelled: result.cancelled,
60
- truncated: result.truncated,
61
- displayOutputs: result.displayOutputs,
62
- };
63
- await rlm.notebook.appendCode(params.code, cell);
64
- const text = result.output.length > 0 ? result.output : "(no output)";
65
- return { content: [{ type: "text", text }] };
66
- },
67
- };
68
- }