jutul-agent 0.1.0__tar.gz

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 (332) hide show
  1. jutul_agent-0.1.0/.gitignore +53 -0
  2. jutul_agent-0.1.0/AGENTS.md +142 -0
  3. jutul_agent-0.1.0/LICENSE +21 -0
  4. jutul_agent-0.1.0/PKG-INFO +139 -0
  5. jutul_agent-0.1.0/README.md +102 -0
  6. jutul_agent-0.1.0/docs/README.md +107 -0
  7. jutul_agent-0.1.0/docs/adding-a-simulator.md +120 -0
  8. jutul_agent-0.1.0/docs/agent-first.md +182 -0
  9. jutul_agent-0.1.0/docs/approval.md +73 -0
  10. jutul_agent-0.1.0/docs/architecture.md +212 -0
  11. jutul_agent-0.1.0/docs/assets/architecture-dark.svg +708 -0
  12. jutul_agent-0.1.0/docs/assets/architecture-light.svg +708 -0
  13. jutul_agent-0.1.0/docs/assets/architecture.tex +170 -0
  14. jutul_agent-0.1.0/docs/assets/favicon.svg +4 -0
  15. jutul_agent-0.1.0/docs/assets/render-architecture.sh +14 -0
  16. jutul_agent-0.1.0/docs/benchmark-records.jsonl +492 -0
  17. jutul_agent-0.1.0/docs/benchmark.md +236 -0
  18. jutul_agent-0.1.0/docs/cli.md +185 -0
  19. jutul_agent-0.1.0/docs/configuration.md +102 -0
  20. jutul_agent-0.1.0/docs/context.md +101 -0
  21. jutul_agent-0.1.0/docs/development.md +147 -0
  22. jutul_agent-0.1.0/docs/evaluation.md +279 -0
  23. jutul_agent-0.1.0/docs/extending-for-your-application.md +118 -0
  24. jutul_agent-0.1.0/docs/filesystem.md +59 -0
  25. jutul_agent-0.1.0/docs/images/review-dashboard.png +0 -0
  26. jutul_agent-0.1.0/docs/images/web-battmo.png +0 -0
  27. jutul_agent-0.1.0/docs/images/web-fimbul.png +0 -0
  28. jutul_agent-0.1.0/docs/images/web-jutuldarcy.png +0 -0
  29. jutul_agent-0.1.0/docs/improving-the-agent.md +89 -0
  30. jutul_agent-0.1.0/docs/julia-kernel.md +105 -0
  31. jutul_agent-0.1.0/docs/lab.md +110 -0
  32. jutul_agent-0.1.0/docs/memory.md +58 -0
  33. jutul_agent-0.1.0/docs/models.md +105 -0
  34. jutul_agent-0.1.0/docs/review.md +187 -0
  35. jutul_agent-0.1.0/docs/server-interface.md +265 -0
  36. jutul_agent-0.1.0/docs/stylesheets/extra.css +223 -0
  37. jutul_agent-0.1.0/docs/testing.md +98 -0
  38. jutul_agent-0.1.0/docs/trace.md +80 -0
  39. jutul_agent-0.1.0/docs/turns.md +76 -0
  40. jutul_agent-0.1.0/docs/usage.md +274 -0
  41. jutul_agent-0.1.0/docs/web-ui.md +94 -0
  42. jutul_agent-0.1.0/examples/demo-app/README.md +49 -0
  43. jutul_agent-0.1.0/pyproject.toml +138 -0
  44. jutul_agent-0.1.0/src/jutul_agent/__init__.py +33 -0
  45. jutul_agent-0.1.0/src/jutul_agent/__main__.py +13 -0
  46. jutul_agent-0.1.0/src/jutul_agent/_version.py +24 -0
  47. jutul_agent-0.1.0/src/jutul_agent/agent/__init__.py +0 -0
  48. jutul_agent-0.1.0/src/jutul_agent/agent/added_dirs.py +117 -0
  49. jutul_agent-0.1.0/src/jutul_agent/agent/approval.py +271 -0
  50. jutul_agent-0.1.0/src/jutul_agent/agent/backend.py +180 -0
  51. jutul_agent-0.1.0/src/jutul_agent/agent/builder.py +495 -0
  52. jutul_agent-0.1.0/src/jutul_agent/agent/capabilities.py +200 -0
  53. jutul_agent-0.1.0/src/jutul_agent/agent/context_editing.py +74 -0
  54. jutul_agent-0.1.0/src/jutul_agent/agent/memory.py +267 -0
  55. jutul_agent-0.1.0/src/jutul_agent/agent/plot_julia.py +538 -0
  56. jutul_agent-0.1.0/src/jutul_agent/agent/plot_julia_src.py +274 -0
  57. jutul_agent-0.1.0/src/jutul_agent/agent/prompts.py +239 -0
  58. jutul_agent-0.1.0/src/jutul_agent/agent/recovery.py +127 -0
  59. jutul_agent-0.1.0/src/jutul_agent/agent/summarization.py +120 -0
  60. jutul_agent-0.1.0/src/jutul_agent/agent/titling.py +60 -0
  61. jutul_agent-0.1.0/src/jutul_agent/agent/tool_output.py +62 -0
  62. jutul_agent-0.1.0/src/jutul_agent/agent/tools.py +346 -0
  63. jutul_agent-0.1.0/src/jutul_agent/agent/turns.py +365 -0
  64. jutul_agent-0.1.0/src/jutul_agent/agent/windows_paths.py +133 -0
  65. jutul_agent-0.1.0/src/jutul_agent/credentials.py +163 -0
  66. jutul_agent-0.1.0/src/jutul_agent/display.py +188 -0
  67. jutul_agent-0.1.0/src/jutul_agent/eval/__init__.py +22 -0
  68. jutul_agent-0.1.0/src/jutul_agent/eval/_gemini_compat.py +65 -0
  69. jutul_agent-0.1.0/src/jutul_agent/eval/report.py +474 -0
  70. jutul_agent-0.1.0/src/jutul_agent/eval/runconfig.py +91 -0
  71. jutul_agent-0.1.0/src/jutul_agent/eval/scorers.py +761 -0
  72. jutul_agent-0.1.0/src/jutul_agent/eval/solver.py +317 -0
  73. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/__init__.py +1 -0
  74. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/_corpus/MiniRes/Project.toml +3 -0
  75. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/_corpus/MiniRes/README.md +4 -0
  76. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/_corpus/MiniRes/docs/api.md +7 -0
  77. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/_corpus/MiniRes/examples/advanced/sweep.jl +8 -0
  78. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/_corpus/MiniRes/examples/quickstart.jl +6 -0
  79. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/_corpus/MiniRes/src/MiniRes.jl +13 -0
  80. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/_corpus/MiniRes/src/grid.jl +8 -0
  81. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/_corpus/MiniRes/src/physics/darcy.jl +13 -0
  82. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/_corpus/MiniRes/src/physics/wells.jl +15 -0
  83. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/_corpus/MiniRes/src/solver/newton.jl +15 -0
  84. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/_corpus/__init__.py +54 -0
  85. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/api_discovery.py +122 -0
  86. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/battmo.py +88 -0
  87. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/calibration.py +82 -0
  88. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/canary.py +41 -0
  89. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/ensembles.py +209 -0
  90. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/filesystem.py +290 -0
  91. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/filesystem_source.py +82 -0
  92. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/fimbul.py +51 -0
  93. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/guardrails.py +47 -0
  94. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/jutuldarcy.py +139 -0
  95. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/mocca.py +90 -0
  96. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/plotting.py +111 -0
  97. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/search.py +211 -0
  98. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/search_source.py +71 -0
  99. jutul_agent-0.1.0/src/jutul_agent/eval/tasks/usage.py +138 -0
  100. jutul_agent-0.1.0/src/jutul_agent/interfaces/__init__.py +0 -0
  101. jutul_agent-0.1.0/src/jutul_agent/interfaces/cli/__init__.py +10 -0
  102. jutul_agent-0.1.0/src/jutul_agent/interfaces/cli/_helpers.py +120 -0
  103. jutul_agent-0.1.0/src/jutul_agent/interfaces/cli/doctor.py +377 -0
  104. jutul_agent-0.1.0/src/jutul_agent/interfaces/cli/eval.py +188 -0
  105. jutul_agent-0.1.0/src/jutul_agent/interfaces/cli/init.py +240 -0
  106. jutul_agent-0.1.0/src/jutul_agent/interfaces/cli/key.py +117 -0
  107. jutul_agent-0.1.0/src/jutul_agent/interfaces/cli/main.py +168 -0
  108. jutul_agent-0.1.0/src/jutul_agent/interfaces/cli/review.py +538 -0
  109. jutul_agent-0.1.0/src/jutul_agent/interfaces/cli/run.py +541 -0
  110. jutul_agent-0.1.0/src/jutul_agent/interfaces/cli/sessions.py +44 -0
  111. jutul_agent-0.1.0/src/jutul_agent/interfaces/cli/transcript.py +97 -0
  112. jutul_agent-0.1.0/src/jutul_agent/interfaces/cli/upgrade.py +146 -0
  113. jutul_agent-0.1.0/src/jutul_agent/interfaces/cli/web.py +158 -0
  114. jutul_agent-0.1.0/src/jutul_agent/interfaces/server/__init__.py +13 -0
  115. jutul_agent-0.1.0/src/jutul_agent/interfaces/server/app.py +1214 -0
  116. jutul_agent-0.1.0/src/jutul_agent/interfaces/server/manager.py +241 -0
  117. jutul_agent-0.1.0/src/jutul_agent/interfaces/server/protocol.py +230 -0
  118. jutul_agent-0.1.0/src/jutul_agent/interfaces/server/session_host.py +405 -0
  119. jutul_agent-0.1.0/src/jutul_agent/interfaces/server/web_dist/assets/index-CD3UEX23.js +84 -0
  120. jutul_agent-0.1.0/src/jutul_agent/interfaces/server/web_dist/assets/index-DVwOzoT5.css +1 -0
  121. jutul_agent-0.1.0/src/jutul_agent/interfaces/server/web_dist/index.html +17 -0
  122. jutul_agent-0.1.0/src/jutul_agent/interfaces/server/web_overlay.py +91 -0
  123. jutul_agent-0.1.0/src/jutul_agent/interfaces/tui/__init__.py +5 -0
  124. jutul_agent-0.1.0/src/jutul_agent/interfaces/tui/_rendering.py +57 -0
  125. jutul_agent-0.1.0/src/jutul_agent/interfaces/tui/app.py +1830 -0
  126. jutul_agent-0.1.0/src/jutul_agent/interfaces/tui/approval.py +265 -0
  127. jutul_agent-0.1.0/src/jutul_agent/interfaces/tui/approval_menu.py +227 -0
  128. jutul_agent-0.1.0/src/jutul_agent/interfaces/tui/commands.py +143 -0
  129. jutul_agent-0.1.0/src/jutul_agent/interfaces/tui/context_panel.py +209 -0
  130. jutul_agent-0.1.0/src/jutul_agent/interfaces/tui/model_menu.py +404 -0
  131. jutul_agent-0.1.0/src/jutul_agent/interfaces/tui/prompt.py +210 -0
  132. jutul_agent-0.1.0/src/jutul_agent/interfaces/tui/tool_display.py +446 -0
  133. jutul_agent-0.1.0/src/jutul_agent/interfaces/tui/widgets.py +988 -0
  134. jutul_agent-0.1.0/src/jutul_agent/julia/__init__.py +0 -0
  135. jutul_agent-0.1.0/src/jutul_agent/julia/requirements.py +101 -0
  136. jutul_agent-0.1.0/src/jutul_agent/julia/session.py +49 -0
  137. jutul_agent-0.1.0/src/jutul_agent/julia/threads.py +126 -0
  138. jutul_agent-0.1.0/src/jutul_agent/julia_runtime/JutulAgent/Project.toml +20 -0
  139. jutul_agent-0.1.0/src/jutul_agent/julia_runtime/JutulAgent/src/JutulAgent.jl +52 -0
  140. jutul_agent-0.1.0/src/jutul_agent/julia_runtime/JutulAgent/src/ensemble.jl +104 -0
  141. jutul_agent-0.1.0/src/jutul_agent/julia_runtime/JutulAgent/src/plots.jl +207 -0
  142. jutul_agent-0.1.0/src/jutul_agent/julia_runtime/web_overlay/Project.toml +10 -0
  143. jutul_agent-0.1.0/src/jutul_agent/juliakernel/__init__.py +19 -0
  144. jutul_agent-0.1.0/src/jutul_agent/juliakernel/config.py +35 -0
  145. jutul_agent-0.1.0/src/jutul_agent/juliakernel/connection.py +238 -0
  146. jutul_agent-0.1.0/src/jutul_agent/juliakernel/kernel.py +413 -0
  147. jutul_agent-0.1.0/src/jutul_agent/juliakernel/result.py +37 -0
  148. jutul_agent-0.1.0/src/jutul_agent/juliakernel/server.jl +229 -0
  149. jutul_agent-0.1.0/src/jutul_agent/juliakernel/text.py +211 -0
  150. jutul_agent-0.1.0/src/jutul_agent/lab/__init__.py +19 -0
  151. jutul_agent-0.1.0/src/jutul_agent/lab/fakes.py +742 -0
  152. jutul_agent-0.1.0/src/jutul_agent/lab/live.py +225 -0
  153. jutul_agent-0.1.0/src/jutul_agent/lab/profile_startup.py +144 -0
  154. jutul_agent-0.1.0/src/jutul_agent/lab/profile_turn.py +70 -0
  155. jutul_agent-0.1.0/src/jutul_agent/lab/rasterize.py +73 -0
  156. jutul_agent-0.1.0/src/jutul_agent/lab/scenarios.py +255 -0
  157. jutul_agent-0.1.0/src/jutul_agent/lab/tui.py +194 -0
  158. jutul_agent-0.1.0/src/jutul_agent/models.py +240 -0
  159. jutul_agent-0.1.0/src/jutul_agent/ollama_client.py +177 -0
  160. jutul_agent-0.1.0/src/jutul_agent/open_file.py +52 -0
  161. jutul_agent-0.1.0/src/jutul_agent/paths.py +183 -0
  162. jutul_agent-0.1.0/src/jutul_agent/py.typed +0 -0
  163. jutul_agent-0.1.0/src/jutul_agent/recent_models.py +47 -0
  164. jutul_agent-0.1.0/src/jutul_agent/review/__init__.py +40 -0
  165. jutul_agent-0.1.0/src/jutul_agent/review/curate.py +135 -0
  166. jutul_agent-0.1.0/src/jutul_agent/review/dashboard.py +218 -0
  167. jutul_agent-0.1.0/src/jutul_agent/review/dashboard_template.html +384 -0
  168. jutul_agent-0.1.0/src/jutul_agent/review/discovery.py +178 -0
  169. jutul_agent-0.1.0/src/jutul_agent/review/eval_link.py +77 -0
  170. jutul_agent-0.1.0/src/jutul_agent/review/export.py +74 -0
  171. jutul_agent-0.1.0/src/jutul_agent/review/findings.py +176 -0
  172. jutul_agent-0.1.0/src/jutul_agent/review/issues.py +190 -0
  173. jutul_agent-0.1.0/src/jutul_agent/review/prompt.py +195 -0
  174. jutul_agent-0.1.0/src/jutul_agent/review/reviewer.py +195 -0
  175. jutul_agent-0.1.0/src/jutul_agent/review/server.py +109 -0
  176. jutul_agent-0.1.0/src/jutul_agent/review/settings.py +28 -0
  177. jutul_agent-0.1.0/src/jutul_agent/session.py +419 -0
  178. jutul_agent-0.1.0/src/jutul_agent/simulators/README.md +50 -0
  179. jutul_agent-0.1.0/src/jutul_agent/simulators/__init__.py +0 -0
  180. jutul_agent-0.1.0/src/jutul_agent/simulators/base.py +63 -0
  181. jutul_agent-0.1.0/src/jutul_agent/simulators/battmo/__init__.py +3 -0
  182. jutul_agent-0.1.0/src/jutul_agent/simulators/battmo/adapter.py +39 -0
  183. jutul_agent-0.1.0/src/jutul_agent/simulators/battmo/julia_env/JutulAgentBattMo/Project.toml +18 -0
  184. jutul_agent-0.1.0/src/jutul_agent/simulators/battmo/julia_env/JutulAgentBattMo/src/JutulAgentBattMo.jl +31 -0
  185. jutul_agent-0.1.0/src/jutul_agent/simulators/battmo/julia_env/Project.toml +29 -0
  186. jutul_agent-0.1.0/src/jutul_agent/simulators/battmo/skills/battmo-cycling/SKILL.md +60 -0
  187. jutul_agent-0.1.0/src/jutul_agent/simulators/battmo/skills/battmo-overview/SKILL.md +98 -0
  188. jutul_agent-0.1.0/src/jutul_agent/simulators/env_setup.py +623 -0
  189. jutul_agent-0.1.0/src/jutul_agent/simulators/fimbul/__init__.py +3 -0
  190. jutul_agent-0.1.0/src/jutul_agent/simulators/fimbul/adapter.py +43 -0
  191. jutul_agent-0.1.0/src/jutul_agent/simulators/fimbul/julia_env/JutulAgentFimbul/Project.toml +20 -0
  192. jutul_agent-0.1.0/src/jutul_agent/simulators/fimbul/julia_env/JutulAgentFimbul/src/JutulAgentFimbul.jl +46 -0
  193. jutul_agent-0.1.0/src/jutul_agent/simulators/fimbul/julia_env/Project.toml +35 -0
  194. jutul_agent-0.1.0/src/jutul_agent/simulators/fimbul/skills/fimbul-overview/SKILL.md +102 -0
  195. jutul_agent-0.1.0/src/jutul_agent/simulators/jutuldarcy/__init__.py +3 -0
  196. jutul_agent-0.1.0/src/jutul_agent/simulators/jutuldarcy/adapter.py +41 -0
  197. jutul_agent-0.1.0/src/jutul_agent/simulators/jutuldarcy/julia_env/JutulAgentJutulDarcy/Project.toml +20 -0
  198. jutul_agent-0.1.0/src/jutul_agent/simulators/jutuldarcy/julia_env/JutulAgentJutulDarcy/src/JutulAgentJutulDarcy.jl +63 -0
  199. jutul_agent-0.1.0/src/jutul_agent/simulators/jutuldarcy/julia_env/Project.toml +31 -0
  200. jutul_agent-0.1.0/src/jutul_agent/simulators/jutuldarcy/skills/jutuldarcy-overview/SKILL.md +158 -0
  201. jutul_agent-0.1.0/src/jutul_agent/simulators/jutuldarcy/skills/jutuldarcy-wells/SKILL.md +96 -0
  202. jutul_agent-0.1.0/src/jutul_agent/simulators/mocca/__init__.py +3 -0
  203. jutul_agent-0.1.0/src/jutul_agent/simulators/mocca/adapter.py +40 -0
  204. jutul_agent-0.1.0/src/jutul_agent/simulators/mocca/julia_env/JutulAgentMocca/Project.toml +19 -0
  205. jutul_agent-0.1.0/src/jutul_agent/simulators/mocca/julia_env/JutulAgentMocca/src/JutulAgentMocca.jl +34 -0
  206. jutul_agent-0.1.0/src/jutul_agent/simulators/mocca/julia_env/Project.toml +29 -0
  207. jutul_agent-0.1.0/src/jutul_agent/simulators/mocca/skills/mocca-overview/SKILL.md +125 -0
  208. jutul_agent-0.1.0/src/jutul_agent/simulators/registry.py +107 -0
  209. jutul_agent-0.1.0/src/jutul_agent/simulators/shared_skills/ensembles/SKILL.md +94 -0
  210. jutul_agent-0.1.0/src/jutul_agent/simulators/shared_skills/investigation-loop/SKILL.md +101 -0
  211. jutul_agent-0.1.0/src/jutul_agent/simulators/shared_skills/julia-and-repl/SKILL.md +93 -0
  212. jutul_agent-0.1.0/src/jutul_agent/simulators/shared_skills/plotting-basics/SKILL.md +128 -0
  213. jutul_agent-0.1.0/src/jutul_agent/simulators/shared_skills/workspace-and-source/SKILL.md +110 -0
  214. jutul_agent-0.1.0/src/jutul_agent/simulators/warmup.py +79 -0
  215. jutul_agent-0.1.0/src/jutul_agent/tool_labels.py +32 -0
  216. jutul_agent-0.1.0/src/jutul_agent/trace/__init__.py +6 -0
  217. jutul_agent-0.1.0/src/jutul_agent/trace/log.py +115 -0
  218. jutul_agent-0.1.0/src/jutul_agent/trace/messages.py +46 -0
  219. jutul_agent-0.1.0/src/jutul_agent/trace/recorder.py +123 -0
  220. jutul_agent-0.1.0/src/jutul_agent/transcript/__init__.py +8 -0
  221. jutul_agent-0.1.0/src/jutul_agent/transcript/attempts.py +67 -0
  222. jutul_agent-0.1.0/src/jutul_agent/transcript/bundle.py +18 -0
  223. jutul_agent-0.1.0/src/jutul_agent/transcript/events.py +77 -0
  224. jutul_agent-0.1.0/src/jutul_agent/transcript/highlight.py +143 -0
  225. jutul_agent-0.1.0/src/jutul_agent/transcript/html.py +1057 -0
  226. jutul_agent-0.1.0/src/jutul_agent/transcript/markdown.py +169 -0
  227. jutul_agent-0.1.0/src/jutul_agent/transcript/markdown_html.py +61 -0
  228. jutul_agent-0.1.0/src/jutul_agent/transcript/report.py +1091 -0
  229. jutul_agent-0.1.0/src/jutul_agent/update_check.py +295 -0
  230. jutul_agent-0.1.0/src/jutul_agent/user_config.py +49 -0
  231. jutul_agent-0.1.0/src/jutul_agent/workspace.py +651 -0
  232. jutul_agent-0.1.0/tests/__snapshots__/test_report_renderer.ambr +340 -0
  233. jutul_agent-0.1.0/tests/__snapshots__/test_transcript.ambr +75 -0
  234. jutul_agent-0.1.0/tests/__snapshots__/test_transcript_html.ambr +7149 -0
  235. jutul_agent-0.1.0/tests/_tui.py +27 -0
  236. jutul_agent-0.1.0/tests/conftest.py +92 -0
  237. jutul_agent-0.1.0/tests/fakes.py +9 -0
  238. jutul_agent-0.1.0/tests/integration/test_julia_plot_integration.py +250 -0
  239. jutul_agent-0.1.0/tests/live/README.md +48 -0
  240. jutul_agent-0.1.0/tests/live/test_live_smoke.py +90 -0
  241. jutul_agent-0.1.0/tests/snapshots/tui/answer.txt +32 -0
  242. jutul_agent-0.1.0/tests/snapshots/tui/approval.txt +32 -0
  243. jutul_agent-0.1.0/tests/snapshots/tui/approval_resolved.txt +32 -0
  244. jutul_agent-0.1.0/tests/snapshots/tui/empty_answer.txt +32 -0
  245. jutul_agent-0.1.0/tests/snapshots/tui/long_output.txt +32 -0
  246. jutul_agent-0.1.0/tests/snapshots/tui/multi_turn.txt +32 -0
  247. jutul_agent-0.1.0/tests/snapshots/tui/narrow.txt +24 -0
  248. jutul_agent-0.1.0/tests/snapshots/tui/reasoning.txt +32 -0
  249. jutul_agent-0.1.0/tests/snapshots/tui/streaming.txt +32 -0
  250. jutul_agent-0.1.0/tests/snapshots/tui/tool_call.txt +32 -0
  251. jutul_agent-0.1.0/tests/snapshots/tui/tool_error.txt +32 -0
  252. jutul_agent-0.1.0/tests/snapshots/tui/unicode_output.txt +32 -0
  253. jutul_agent-0.1.0/tests/snapshots/tui/welcome.txt +32 -0
  254. jutul_agent-0.1.0/tests/snapshots/tui/wide_line.txt +32 -0
  255. jutul_agent-0.1.0/tests/test_added_dirs.py +102 -0
  256. jutul_agent-0.1.0/tests/test_approval.py +171 -0
  257. jutul_agent-0.1.0/tests/test_approval_menu.py +28 -0
  258. jutul_agent-0.1.0/tests/test_approval_mode.py +63 -0
  259. jutul_agent-0.1.0/tests/test_attempt_tree.py +56 -0
  260. jutul_agent-0.1.0/tests/test_builder.py +182 -0
  261. jutul_agent-0.1.0/tests/test_capabilities.py +234 -0
  262. jutul_agent-0.1.0/tests/test_chat_app.py +1460 -0
  263. jutul_agent-0.1.0/tests/test_chat_integration.py +166 -0
  264. jutul_agent-0.1.0/tests/test_cli_init.py +165 -0
  265. jutul_agent-0.1.0/tests/test_cli_key.py +57 -0
  266. jutul_agent-0.1.0/tests/test_cli_resume.py +64 -0
  267. jutul_agent-0.1.0/tests/test_cli_startup.py +28 -0
  268. jutul_agent-0.1.0/tests/test_cli_transcript.py +163 -0
  269. jutul_agent-0.1.0/tests/test_cli_upgrade.py +112 -0
  270. jutul_agent-0.1.0/tests/test_context_editing.py +89 -0
  271. jutul_agent-0.1.0/tests/test_context_panel.py +117 -0
  272. jutul_agent-0.1.0/tests/test_credentials.py +138 -0
  273. jutul_agent-0.1.0/tests/test_demo_app.py +56 -0
  274. jutul_agent-0.1.0/tests/test_display.py +133 -0
  275. jutul_agent-0.1.0/tests/test_doctor.py +85 -0
  276. jutul_agent-0.1.0/tests/test_doctor_plotting.py +49 -0
  277. jutul_agent-0.1.0/tests/test_end_to_end.py +334 -0
  278. jutul_agent-0.1.0/tests/test_env_setup.py +304 -0
  279. jutul_agent-0.1.0/tests/test_env_template_stamp.py +180 -0
  280. jutul_agent-0.1.0/tests/test_ephemeral_memory.py +57 -0
  281. jutul_agent-0.1.0/tests/test_eval_bench.py +599 -0
  282. jutul_agent-0.1.0/tests/test_eval_report.py +156 -0
  283. jutul_agent-0.1.0/tests/test_eval_scorers.py +35 -0
  284. jutul_agent-0.1.0/tests/test_highlight.py +37 -0
  285. jutul_agent-0.1.0/tests/test_julia_requirements.py +94 -0
  286. jutul_agent-0.1.0/tests/test_julia_streaming.py +75 -0
  287. jutul_agent-0.1.0/tests/test_julia_text.py +62 -0
  288. jutul_agent-0.1.0/tests/test_julia_threads.py +114 -0
  289. jutul_agent-0.1.0/tests/test_juliakernel.py +397 -0
  290. jutul_agent-0.1.0/tests/test_lab.py +98 -0
  291. jutul_agent-0.1.0/tests/test_markdown_render.py +56 -0
  292. jutul_agent-0.1.0/tests/test_memory.py +128 -0
  293. jutul_agent-0.1.0/tests/test_messages.py +35 -0
  294. jutul_agent-0.1.0/tests/test_model_menu.py +182 -0
  295. jutul_agent-0.1.0/tests/test_models.py +90 -0
  296. jutul_agent-0.1.0/tests/test_ollama_client.py +183 -0
  297. jutul_agent-0.1.0/tests/test_paths.py +93 -0
  298. jutul_agent-0.1.0/tests/test_plot_web.py +170 -0
  299. jutul_agent-0.1.0/tests/test_prompts.py +73 -0
  300. jutul_agent-0.1.0/tests/test_recent_models.py +42 -0
  301. jutul_agent-0.1.0/tests/test_recorder.py +168 -0
  302. jutul_agent-0.1.0/tests/test_recovery.py +127 -0
  303. jutul_agent-0.1.0/tests/test_registry.py +85 -0
  304. jutul_agent-0.1.0/tests/test_report_renderer.py +401 -0
  305. jutul_agent-0.1.0/tests/test_reset_julia.py +101 -0
  306. jutul_agent-0.1.0/tests/test_review.py +528 -0
  307. jutul_agent-0.1.0/tests/test_server_session.py +1067 -0
  308. jutul_agent-0.1.0/tests/test_session_layout.py +282 -0
  309. jutul_agent-0.1.0/tests/test_simulators_smoke.py +95 -0
  310. jutul_agent-0.1.0/tests/test_skills_and_prompt.py +144 -0
  311. jutul_agent-0.1.0/tests/test_smoke.py +85 -0
  312. jutul_agent-0.1.0/tests/test_summarization.py +78 -0
  313. jutul_agent-0.1.0/tests/test_titling.py +52 -0
  314. jutul_agent-0.1.0/tests/test_tool_display.py +232 -0
  315. jutul_agent-0.1.0/tests/test_tool_eviction.py +58 -0
  316. jutul_agent-0.1.0/tests/test_tool_output.py +25 -0
  317. jutul_agent-0.1.0/tests/test_tools_julia_plot.py +393 -0
  318. jutul_agent-0.1.0/tests/test_trace.py +61 -0
  319. jutul_agent-0.1.0/tests/test_transcript.py +84 -0
  320. jutul_agent-0.1.0/tests/test_transcript_html.py +369 -0
  321. jutul_agent-0.1.0/tests/test_turns.py +278 -0
  322. jutul_agent-0.1.0/tests/test_update_check.py +192 -0
  323. jutul_agent-0.1.0/tests/test_user_config.py +36 -0
  324. jutul_agent-0.1.0/tests/test_warm_source_refresh.py +108 -0
  325. jutul_agent-0.1.0/tests/test_warmup.py +97 -0
  326. jutul_agent-0.1.0/tests/test_warmup_package.py +79 -0
  327. jutul_agent-0.1.0/tests/test_web_serving.py +41 -0
  328. jutul_agent-0.1.0/tests/test_widgets.py +186 -0
  329. jutul_agent-0.1.0/tests/test_windows_paths.py +134 -0
  330. jutul_agent-0.1.0/tests/test_wire_protocol.py +245 -0
  331. jutul_agent-0.1.0/tests/test_workspace.py +255 -0
  332. jutul_agent-0.1.0/tests/test_workspace_backend.py +149 -0
@@ -0,0 +1,53 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .venv/
6
+ .pytest_cache/
7
+ .ruff_cache/
8
+ .mypy_cache/
9
+ dist/
10
+ build/
11
+
12
+ # uv.lock is committed for reproducible installs (see [tool.uv] in pyproject.toml).
13
+
14
+ # Generated by hatch-vcs at build time from the latest git tag (see pyproject.toml).
15
+ src/jutul_agent/_version.py
16
+
17
+ # Secrets and local editor config
18
+ .env
19
+ .env.*
20
+ !.env.example
21
+ .mcp.json
22
+
23
+ # Project state
24
+ .jutul-agent/
25
+
26
+ # Julia lockfiles
27
+ src/jutul_agent/**/Manifest.toml
28
+
29
+ # The shared JutulAgent package synced into a sim env template for in-place
30
+ # instantiate (CI/tests). The canonical source lives in julia_runtime/ and the
31
+ # per-sim JutulAgent<Sim> packages are tracked; only these synced copies are not.
32
+ src/jutul_agent/simulators/*/julia_env/JutulAgent/
33
+
34
+ # IDE
35
+ .vscode/
36
+ .idea/
37
+
38
+ # Claude Code: share project commands, keep local settings/worktrees out.
39
+ .claude/*
40
+ !.claude/commands/
41
+ .claude/settings.local.json
42
+
43
+ # Scratch findings the `/review-mine` command writes before ingesting.
44
+ .jutul-review/
45
+
46
+ # OS
47
+ .DS_Store
48
+ Thumbs.db
49
+ site/
50
+
51
+ # Local scratch / lab output
52
+ .jutul-review/
53
+ lab-out/
@@ -0,0 +1,142 @@
1
+ # jutul-agent
2
+
3
+ ## Purpose
4
+
5
+ jutul-agent is an assistant for Julia scientific simulation work on the Jutul
6
+ ecosystem, built on Deep Agents.
7
+
8
+ ## Working rules
9
+
10
+ - Prefer the live Julia session and simulator source code over model memory.
11
+ - Use the persistent Julia REPL incrementally. Run the smallest useful probe
12
+ first, inspect the result, then extend.
13
+ - Treat the installed simulator packages as the source of truth for APIs and
14
+ examples.
15
+ - Keep Julia execution serialized unless the runtime explicitly supports
16
+ concurrency.
17
+ - Prefer Deep Agents memory and skills for reusable guidance; keep custom
18
+ Python focused on Julia execution, simulator inspection, and trace capture.
19
+
20
+ ## Validation
21
+
22
+ - Default suite (no Julia): `uv run pytest -q -m "not integration"`
23
+ - Integration suite (requires Julia + an instantiated env): `uv run pytest -q -m integration`.
24
+ Envs instantiate from `Project.toml` + `[sources]`.
25
+ `tests/test_simulators_smoke.py` loads each simulator with `using <Sim>`.
26
+ - Live LLM (humans only, needs API key): `uv run pytest tests/live/`
27
+ - Update transcript / report snapshots after renderer changes:
28
+ `uv run pytest --snapshot-update tests/test_transcript_html.py tests/test_transcript.py tests/test_report_renderer.py`
29
+ - Python style (matches CI): `uv run ruff check .` then `uv run ruff format .`
30
+ - After editing Python, run `uv run ruff format` on touched paths (or rely on
31
+ format-on-save / pre-commit if installed).
32
+ - Web UI (React + TypeScript in `interfaces/server/webapp`): `npm install`, then
33
+ `npm test` (vitest) and `npm run typecheck`. It ships **pre-built** — after any
34
+ change under `webapp/src`, run `npm run build` and commit the regenerated
35
+ `interfaces/server/web_dist`. That committed bundle is what the server serves,
36
+ so end users install with `uv`/`pip` and never need Node.
37
+
38
+ ## Continuous integration
39
+
40
+ Two GitHub Actions workflows:
41
+
42
+ - `ci.yml`: every push/PR. `lint` (ruff); `test` across Linux/Windows/macOS
43
+ (`pytest -m "not integration"`, no Julia); `julia-integration` (Linux only:
44
+ runs `test_juliakernel.py` against base Julia, which needs no env).
45
+ - `simulators.yml`: per-simulator smoke matrix (`jutuldarcy`, `battmo`,
46
+ `fimbul`, `mocca`; Linux). On PR + push to `main`, a weekly Monday run
47
+ (catches upstream breakage), and manual dispatch. Each job instantiates the
48
+ env from `Project.toml` and runs `test_simulators_smoke.py`.
49
+
50
+ ## Local git hooks
51
+
52
+ One-time per clone: `uv run pre-commit install`. Commits then run Ruff format
53
+ and check on staged `.py` files. To verify the whole tree like CI:
54
+ `uv run pre-commit run --all-files`.
55
+
56
+ ## Important paths
57
+
58
+ - `src/jutul_agent/paths.py`: the three runtime anchors (`PACKAGE_ROOT`
59
+ (install), `workspace_root()` (CWD), `state_home()` (sessions)) and the path
60
+ policy (`resolve_in_workspace`, `is_host_path`), the one place that maps
61
+ agent-visible paths to real files.
62
+ - `src/jutul_agent/workspace.py`: workspace config
63
+ (`.jutul-agent/config.toml`), simulator auto-detect, Julia-env bootstrap.
64
+ - `src/jutul_agent/session.py`: `Session`, the unit of work for one
65
+ invocation.
66
+ - `src/jutul_agent/models.py`: provider metadata and the model catalog
67
+ discovery. `src/jutul_agent/display.py`: display detection and Xvfb
68
+ management for headless plotting.
69
+ - `src/jutul_agent/agent/builder.py`: deepagents wiring (composite backend,
70
+ HarnessProfile registration, `build_agent` entry point). Custom tools sit
71
+ alongside (`tools.py`, `plot_julia.py`, `memory.py`, `approval.py`,
72
+ `turns.py`, and `added_dirs.py`, which records `/add-dir` folders);
73
+ `tool_labels.py` holds the one friendly name per tool shared by the TUI,
74
+ approval prompt, and transcript. The Julia-side plot capture lives in the
75
+ `julia_runtime/JutulAgent` package. The full system prompt is assembled in
76
+ `prompts.py` (each rule stated once).
77
+ - `src/jutul_agent/simulators/`: adapter dataclass, registry, env bootstrap +
78
+ launch-time preparation (`env_setup.prepare_workspace_env`), shared skills,
79
+ and one folder per simulator (see below).
80
+ - `src/jutul_agent/julia/`: the `JuliaSession` Protocol (`session.py`) and the
81
+ Julia toolchain checks (`requirements.py`).
82
+ - `src/jutul_agent/juliakernel/`: the backend, a self-contained, supervised
83
+ Julia runtime (`kernel.py` + stdlib-only `server.jl`) with live output and
84
+ SIGINT interrupt. Splittable into a standalone package.
85
+ - `src/jutul_agent/trace/`: SQLite event log and `TraceRecorder` middleware.
86
+ - `src/jutul_agent/transcript/`: renderers that consume a trace
87
+ (HTML transcript, markdown transcript, investigation report).
88
+ - `src/jutul_agent/interfaces/tui/approval.py`: HITL decision policy and the
89
+ approval card markdown.
90
+ - `src/jutul_agent/interfaces/`: `cli`, the Textual `tui`, and the `server`
91
+ (FastAPI REST + per-session WebSocket). The browser UI is a React + TypeScript
92
+ app in `server/webapp/` (see its README), built into `server/web_dist/`
93
+ (committed and shipped, so an install needs no Node).
94
+ - `tests/`: end-to-end, chat, CLI, and tool coverage. `tests/integration/`
95
+ needs Julia; `tests/live/` needs an LLM provider key.
96
+
97
+ ## Per-simulator layout
98
+
99
+ Each simulator lives under `src/jutul_agent/simulators/<name>/` and owns
100
+ exactly three things:
101
+
102
+ - `adapter.py`: constructs the `SimulatorAdapter`. Set
103
+ `module_dir = Path(__file__).resolve().parent` so the base class can
104
+ derive `julia_env_template_path` and `skills_dir`.
105
+ - `julia_env/`: `Project.toml` declaring the deps the agent can `using`, plus a
106
+ per-simulator `JutulAgent<Sim>/` warm package (a local `[sources]` path dep whose
107
+ `@recompile_invalidations` + `@compile_workload` bakes that simulator's
108
+ GLMakie-aware solve/plot into the precompile cache, so the first solve is fast).
109
+ The shared, sim-agnostic `JutulAgent` package (figure capture, ensemble helpers,
110
+ generic-Makie warm-up) has a single source in `src/jutul_agent/julia_runtime/` and
111
+ is copied into the env at bootstrap (also a relative `[sources]` dep). The
112
+ `Manifest.toml` is generated on instantiate (gitignored). The whole `julia_env/`
113
+ folder is copied into a workspace on bootstrap, so the relative `[sources]` paths
114
+ keep resolving.
115
+ - `skills/<skill-name>/SKILL.md`: markdown skills surfaced via the
116
+ deep-agents skill system.
117
+
118
+ Add a simulator by creating that folder and one entry in
119
+ `simulators/registry.py`. Custom subagent factories, when they land, go on
120
+ the adapter's `subagent_factories` tuple.
121
+
122
+ ## deepagents / langgraph private-surface contacts
123
+
124
+ We pin deepagents (see `[tool.uv] exclude-newer` in `pyproject.toml`) and
125
+ touch a few non-public surfaces. When bumping the pin, re-verify each:
126
+
127
+ - `agent/tools.py`: reads `langgraph.pregel._tools._tool_call_writer`
128
+ (ContextVar) to stream live Julia output as tool-output deltas.
129
+ Import-guarded: if it moves, streaming silently disables.
130
+ - `agent/turns.py` + `tests/fakes.py`: consume the v3 `astream_events`
131
+ typed projections (`run.messages` / `run.tool_calls` / `run.interrupts` /
132
+ `run.output`); the fakes mirror that shape, so a projection change shows up
133
+ as test failures.
134
+ - `agent/backend.py`: subclasses `CompositeBackend` (overriding `grep`/`glob`
135
+ so patterns recurse) and `LocalShellBackend` (overriding `write`/`edit`/
136
+ `execute` to refuse depot writes, reading `cwd` to resolve relative paths).
137
+ A subclass breaks loudly if a base method's signature moves. After the
138
+ real-paths refactor nothing routes through a mount, so `added_dirs.py` only
139
+ records the added folders; every tool already reaches them by absolute path.
140
+ - `tests/test_builder.py`: imports
141
+ `deepagents.profiles.harness.harness_profiles._harness_profile_for_model`
142
+ to assert our profile resolves for built model instances.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SINTEF
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,139 @@
1
+ Metadata-Version: 2.4
2
+ Name: jutul-agent
3
+ Version: 0.1.0
4
+ Summary: Specialized scientific agent for AD-enabled simulators built on the Jutul framework.
5
+ Project-URL: Homepage, https://github.com/SINTEF-agentlab/jutul-agent
6
+ Project-URL: Documentation, https://sintef-agentlab.github.io/jutul-agent/
7
+ Project-URL: Repository, https://github.com/SINTEF-agentlab/jutul-agent
8
+ Project-URL: Issues, https://github.com/SINTEF-agentlab/jutul-agent/issues
9
+ Author-email: Jakob Torben <jakob.torben@sintef.no>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Scientific/Engineering
17
+ Requires-Python: >=3.12
18
+ Requires-Dist: deepagents>=0.6.10
19
+ Requires-Dist: fastapi>=0.115
20
+ Requires-Dist: httpx>=0.27
21
+ Requires-Dist: langchain-google-genai>=4.2.2
22
+ Requires-Dist: langchain-ollama>=1.1.0
23
+ Requires-Dist: langchain-openai>=0.2
24
+ Requires-Dist: langgraph-checkpoint-sqlite>=3.1.0
25
+ Requires-Dist: markdown-it-py[linkify]>=4.0
26
+ Requires-Dist: pillow>=12.2.0
27
+ Requires-Dist: pygments>=2.17
28
+ Requires-Dist: python-dotenv>=1.0
29
+ Requires-Dist: python-multipart>=0.0.9
30
+ Requires-Dist: textual>=8.2.6
31
+ Requires-Dist: uvicorn[standard]>=0.30
32
+ Provides-Extra: eval
33
+ Requires-Dist: anthropic>=0.105.0; extra == 'eval'
34
+ Requires-Dist: inspect-ai<0.4,>=0.3.238; extra == 'eval'
35
+ Requires-Dist: openai>=2.40.0; extra == 'eval'
36
+ Description-Content-Type: text/markdown
37
+
38
+ # jutul-agent
39
+
40
+ [![CI](https://github.com/SINTEF-agentlab/jutul-agent/actions/workflows/ci.yml/badge.svg)](https://github.com/SINTEF-agentlab/jutul-agent/actions/workflows/ci.yml)
41
+ [![Simulators](https://github.com/SINTEF-agentlab/jutul-agent/actions/workflows/simulators.yml/badge.svg)](https://github.com/SINTEF-agentlab/jutul-agent/actions/workflows/simulators.yml)
42
+ [![Docs](https://img.shields.io/badge/docs-website-0f4c5c)](https://sintef-agentlab.github.io/jutul-agent/)
43
+ [![PyPI](https://img.shields.io/pypi/v/jutul-agent.svg)](https://pypi.org/project/jutul-agent/)
44
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
45
+
46
+ A scientific AI agent for differentiable simulators built on the
47
+ [Jutul](https://github.com/sintefmath/Jutul.jl) framework. Ask for a
48
+ simulation in plain language. The agent sets it up, runs it, analyses and
49
+ plots the results, and iterates: fixing mistakes and refining the next run.
50
+
51
+ <p align="center">
52
+ <a href="https://github.com/sintefmath/JutulDarcy.jl"><img src="https://raw.githubusercontent.com/sintefmath/JutulDarcy.jl/main/docs/src/assets/logo_wide.png" alt="JutulDarcy" height="42"></a>&nbsp;&nbsp;&nbsp;
53
+ <a href="https://github.com/BattMoTeam/BattMo.jl"><img src="https://raw.githubusercontent.com/BattMoTeam/BattMo.jl/main/docs/src/assets/battmologo_text.png" alt="BattMo" height="74"></a>&nbsp;&nbsp;&nbsp;
54
+ <a href="https://github.com/sintefmath/Fimbul.jl"><img src="https://raw.githubusercontent.com/sintefmath/Fimbul.jl/main/docs/src/assets/logo_text_wide.png" alt="Fimbul" height="50"></a>&nbsp;&nbsp;&nbsp;
55
+ <a href="https://github.com/sintefmath/Mocca.jl"><img src="https://raw.githubusercontent.com/sintefmath/Mocca.jl/main/docs/src/assets/mocca_small_transparent.png" alt="Mocca" height="62"></a>
56
+ </p>
57
+
58
+ <p align="center">
59
+ <img src="docs/images/web-fimbul.png" alt="jutul-agent web UI: a Fimbul geothermal doublet with the 3D temperature field over time" width="47%">
60
+ &nbsp;&nbsp;&nbsp;
61
+ <img src="docs/images/web-battmo.png" alt="jutul-agent web UI: a BattMo discharge-rate investigation with plots and a report" width="47%">
62
+ </p>
63
+ <p align="center"><sub>The browser UI (<code>jutul-agent web</code>): chat on the left; interactive plots and reports pinned in a canvas on the right. On the left, a Fimbul geothermal doublet showing the 3D temperature field around the wells over time. On the right, a BattMo C-rate study with voltage curves, an attempts map, and a written report.</sub></p>
64
+
65
+ ## Quickstart
66
+
67
+ Install [uv](https://docs.astral.sh/uv/getting-started/installation/) and Julia
68
+ (via [juliaup](https://github.com/JuliaLang/juliaup)). Then:
69
+
70
+ ```sh
71
+ uv tool install jutul-agent
72
+ jutul-agent key openai # save a provider key (Anthropic and Google work too)
73
+
74
+ mkdir my-study && cd my-study
75
+ jutul-agent init --sim battmo # jutuldarcy | battmo | fimbul | mocca
76
+ jutul-agent web # browser UI, or: tui, or run "<prompt>"
77
+ ```
78
+
79
+ Local models through [Ollama](https://ollama.com) need no key. `init`
80
+ precompiles the Julia and plotting stacks once (a few minutes), so sessions
81
+ then start in seconds, and `jutul-agent doctor` checks the setup if anything
82
+ looks wrong. Keep it current with `jutul-agent upgrade`.
83
+
84
+ One folder is bound to one simulator and its Julia environment, so use a
85
+ separate folder for each. The browser UI opens at <http://127.0.0.1:8742> and
86
+ runs locally for a single trusted user. The full [installation and usage
87
+ guide](https://sintef-agentlab.github.io/jutul-agent/usage/) covers workspaces,
88
+ interfaces, and models; to work on jutul-agent itself, clone the repo (see
89
+ [Development](#development)).
90
+
91
+ ## Supported simulators
92
+
93
+ | `--sim` | Package | Domain |
94
+ |---|---|---|
95
+ | `jutuldarcy` | [JutulDarcy.jl](https://github.com/sintefmath/JutulDarcy.jl) | Reservoir / multi-phase flow |
96
+ | `battmo` | [BattMo.jl](https://github.com/BattMoTeam/BattMo.jl) | Lithium-ion (and other) battery cells |
97
+ | `fimbul` | [Fimbul.jl](https://github.com/sintefmath/Fimbul.jl) | Geothermal (ATES, BTES, doublet, EGS) |
98
+ | `mocca` | [Mocca.jl](https://github.com/sintefmath/Mocca.jl) | Adsorption-based CO₂ capture (PSA / VSA / TSA) |
99
+
100
+ ## What makes it work for scientific computing
101
+
102
+ - A persistent Julia REPL per session. State, loaded packages, and compiled
103
+ methods carry across turns, and a first solve is fast because each
104
+ simulator ships a precompiled warm package.
105
+ - The agent reads real source. Every package in the environment is on disk at
106
+ its real `pkgdir` path (read-only in the shared depot), so answers come from
107
+ the installed version, not from memory.
108
+ - Everything is recorded. Each session writes a trace of every message, tool
109
+ call, and artifact. Transcripts and the benchmark grade against it.
110
+ - Models are interchangeable: OpenAI, Anthropic, Google, or local models via
111
+ Ollama, switchable mid-session.
112
+
113
+ ## Documentation
114
+
115
+ The full documentation lives at
116
+ [sintef-agentlab.github.io/jutul-agent](https://sintef-agentlab.github.io/jutul-agent/)
117
+ (source in [docs/](docs/)): using the agent, how it works (architecture,
118
+ the Julia kernel, the trace), and extending it (adding a simulator,
119
+ improving the agent, evaluation).
120
+
121
+ ## Development
122
+
123
+ Work from a clone instead of a tool install. `uv run` resolves the
124
+ `jutul-agent` command from the checkout, so run every command through it
125
+ (`uv run jutul-agent ...`); upgrade with `git pull && uv sync`.
126
+
127
+ ```sh
128
+ git clone https://github.com/SINTEF-agentlab/jutul-agent
129
+ cd jutul-agent
130
+ uv sync --extra eval
131
+ uv run pre-commit install
132
+
133
+ uv run ruff check . # lint
134
+ uv run pytest # unit tests (integration and live skipped)
135
+ uv run pytest -m integration # adds the Julia-requiring tests
136
+ uv run jutul-agent eval canary # bench canary
137
+ ```
138
+
139
+ Developed at [SINTEF](https://www.sintef.no/en/).
@@ -0,0 +1,102 @@
1
+ # jutul-agent
2
+
3
+ [![CI](https://github.com/SINTEF-agentlab/jutul-agent/actions/workflows/ci.yml/badge.svg)](https://github.com/SINTEF-agentlab/jutul-agent/actions/workflows/ci.yml)
4
+ [![Simulators](https://github.com/SINTEF-agentlab/jutul-agent/actions/workflows/simulators.yml/badge.svg)](https://github.com/SINTEF-agentlab/jutul-agent/actions/workflows/simulators.yml)
5
+ [![Docs](https://img.shields.io/badge/docs-website-0f4c5c)](https://sintef-agentlab.github.io/jutul-agent/)
6
+ [![PyPI](https://img.shields.io/pypi/v/jutul-agent.svg)](https://pypi.org/project/jutul-agent/)
7
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
8
+
9
+ A scientific AI agent for differentiable simulators built on the
10
+ [Jutul](https://github.com/sintefmath/Jutul.jl) framework. Ask for a
11
+ simulation in plain language. The agent sets it up, runs it, analyses and
12
+ plots the results, and iterates: fixing mistakes and refining the next run.
13
+
14
+ <p align="center">
15
+ <a href="https://github.com/sintefmath/JutulDarcy.jl"><img src="https://raw.githubusercontent.com/sintefmath/JutulDarcy.jl/main/docs/src/assets/logo_wide.png" alt="JutulDarcy" height="42"></a>&nbsp;&nbsp;&nbsp;
16
+ <a href="https://github.com/BattMoTeam/BattMo.jl"><img src="https://raw.githubusercontent.com/BattMoTeam/BattMo.jl/main/docs/src/assets/battmologo_text.png" alt="BattMo" height="74"></a>&nbsp;&nbsp;&nbsp;
17
+ <a href="https://github.com/sintefmath/Fimbul.jl"><img src="https://raw.githubusercontent.com/sintefmath/Fimbul.jl/main/docs/src/assets/logo_text_wide.png" alt="Fimbul" height="50"></a>&nbsp;&nbsp;&nbsp;
18
+ <a href="https://github.com/sintefmath/Mocca.jl"><img src="https://raw.githubusercontent.com/sintefmath/Mocca.jl/main/docs/src/assets/mocca_small_transparent.png" alt="Mocca" height="62"></a>
19
+ </p>
20
+
21
+ <p align="center">
22
+ <img src="docs/images/web-fimbul.png" alt="jutul-agent web UI: a Fimbul geothermal doublet with the 3D temperature field over time" width="47%">
23
+ &nbsp;&nbsp;&nbsp;
24
+ <img src="docs/images/web-battmo.png" alt="jutul-agent web UI: a BattMo discharge-rate investigation with plots and a report" width="47%">
25
+ </p>
26
+ <p align="center"><sub>The browser UI (<code>jutul-agent web</code>): chat on the left; interactive plots and reports pinned in a canvas on the right. On the left, a Fimbul geothermal doublet showing the 3D temperature field around the wells over time. On the right, a BattMo C-rate study with voltage curves, an attempts map, and a written report.</sub></p>
27
+
28
+ ## Quickstart
29
+
30
+ Install [uv](https://docs.astral.sh/uv/getting-started/installation/) and Julia
31
+ (via [juliaup](https://github.com/JuliaLang/juliaup)). Then:
32
+
33
+ ```sh
34
+ uv tool install jutul-agent
35
+ jutul-agent key openai # save a provider key (Anthropic and Google work too)
36
+
37
+ mkdir my-study && cd my-study
38
+ jutul-agent init --sim battmo # jutuldarcy | battmo | fimbul | mocca
39
+ jutul-agent web # browser UI, or: tui, or run "<prompt>"
40
+ ```
41
+
42
+ Local models through [Ollama](https://ollama.com) need no key. `init`
43
+ precompiles the Julia and plotting stacks once (a few minutes), so sessions
44
+ then start in seconds, and `jutul-agent doctor` checks the setup if anything
45
+ looks wrong. Keep it current with `jutul-agent upgrade`.
46
+
47
+ One folder is bound to one simulator and its Julia environment, so use a
48
+ separate folder for each. The browser UI opens at <http://127.0.0.1:8742> and
49
+ runs locally for a single trusted user. The full [installation and usage
50
+ guide](https://sintef-agentlab.github.io/jutul-agent/usage/) covers workspaces,
51
+ interfaces, and models; to work on jutul-agent itself, clone the repo (see
52
+ [Development](#development)).
53
+
54
+ ## Supported simulators
55
+
56
+ | `--sim` | Package | Domain |
57
+ |---|---|---|
58
+ | `jutuldarcy` | [JutulDarcy.jl](https://github.com/sintefmath/JutulDarcy.jl) | Reservoir / multi-phase flow |
59
+ | `battmo` | [BattMo.jl](https://github.com/BattMoTeam/BattMo.jl) | Lithium-ion (and other) battery cells |
60
+ | `fimbul` | [Fimbul.jl](https://github.com/sintefmath/Fimbul.jl) | Geothermal (ATES, BTES, doublet, EGS) |
61
+ | `mocca` | [Mocca.jl](https://github.com/sintefmath/Mocca.jl) | Adsorption-based CO₂ capture (PSA / VSA / TSA) |
62
+
63
+ ## What makes it work for scientific computing
64
+
65
+ - A persistent Julia REPL per session. State, loaded packages, and compiled
66
+ methods carry across turns, and a first solve is fast because each
67
+ simulator ships a precompiled warm package.
68
+ - The agent reads real source. Every package in the environment is on disk at
69
+ its real `pkgdir` path (read-only in the shared depot), so answers come from
70
+ the installed version, not from memory.
71
+ - Everything is recorded. Each session writes a trace of every message, tool
72
+ call, and artifact. Transcripts and the benchmark grade against it.
73
+ - Models are interchangeable: OpenAI, Anthropic, Google, or local models via
74
+ Ollama, switchable mid-session.
75
+
76
+ ## Documentation
77
+
78
+ The full documentation lives at
79
+ [sintef-agentlab.github.io/jutul-agent](https://sintef-agentlab.github.io/jutul-agent/)
80
+ (source in [docs/](docs/)): using the agent, how it works (architecture,
81
+ the Julia kernel, the trace), and extending it (adding a simulator,
82
+ improving the agent, evaluation).
83
+
84
+ ## Development
85
+
86
+ Work from a clone instead of a tool install. `uv run` resolves the
87
+ `jutul-agent` command from the checkout, so run every command through it
88
+ (`uv run jutul-agent ...`); upgrade with `git pull && uv sync`.
89
+
90
+ ```sh
91
+ git clone https://github.com/SINTEF-agentlab/jutul-agent
92
+ cd jutul-agent
93
+ uv sync --extra eval
94
+ uv run pre-commit install
95
+
96
+ uv run ruff check . # lint
97
+ uv run pytest # unit tests (integration and live skipped)
98
+ uv run pytest -m integration # adds the Julia-requiring tests
99
+ uv run jutul-agent eval canary # bench canary
100
+ ```
101
+
102
+ Developed at [SINTEF](https://www.sintef.no/en/).
@@ -0,0 +1,107 @@
1
+ ---
2
+ hide:
3
+ - navigation
4
+ - toc
5
+ ---
6
+
7
+ <div class="ja-hero" markdown>
8
+ <div class="ja-hero-text" markdown>
9
+ <h1>jutul-agent</h1>
10
+ <p class="ja-tagline">A scientific AI agent for differentiable simulators built
11
+ on the <a href="https://github.com/sintefmath/Jutul.jl">Jutul</a> framework.
12
+ Ask for a simulation in plain language. The agent sets it up, runs it in a
13
+ persistent Julia session, analyses and plots the results, and iterates:
14
+ fixing mistakes and refining the next run.</p>
15
+
16
+ [Get started](usage.md){ .md-button .md-button--primary }
17
+ [How it works](architecture.md){ .md-button }
18
+ </div>
19
+ <div class="ja-terminal">
20
+ <div class="ja-terminal-bar"><span></span><span></span><span></span>
21
+ <div class="ja-terminal-title">jutul-agent · my-battery-run</div></div>
22
+ <pre><code><span class="ja-t-dim">$</span> jutul-agent tui
23
+ <span class="ja-t-prompt">&gt;</span> Set up a constant-current discharge for the
24
+ chen_2020 cell and plot the voltage curve.
25
+
26
+ <span class="ja-t-tool">run_julia</span> output = solve(cell_setup)
27
+ <span class="ja-t-tool">plot_julia</span> voltage vs time
28
+ <span class="ja-t-ok">saved</span> artifacts/voltage_curve.png</code></pre>
29
+ </div>
30
+ </div>
31
+
32
+ <p align="center">
33
+ <img src="images/web-fimbul.png" alt="jutul-agent web UI: a Fimbul geothermal doublet with the 3D temperature field over time" width="47%">
34
+ &nbsp;&nbsp;&nbsp;
35
+ <img src="images/web-battmo.png" alt="jutul-agent web UI: a BattMo discharge-rate investigation with plots and a report" width="47%">
36
+ </p>
37
+ <p align="center" markdown><small>The browser UI (`jutul-agent web`): chat on the left; interactive plots and
38
+ reports pinned in a canvas on the right.</small></p>
39
+
40
+ <div class="grid cards" markdown>
41
+
42
+ - :material-rocket-launch:{ .lg .middle } **Usage**
43
+
44
+ ---
45
+
46
+ Install, initialise a workspace, drive the TUI, pick models.
47
+
48
+ [:octicons-arrow-right-24: Installation and usage](usage.md) ·
49
+ [CLI](cli.md) ·
50
+ [Configuration](configuration.md) ·
51
+ [Models](models.md) ·
52
+ [Approval and safety](approval.md)
53
+
54
+ - :material-cog-outline:{ .lg .middle } **How it works**
55
+
56
+ ---
57
+
58
+ The component map and the pieces behind it: the persistent Julia
59
+ kernel, the filesystem, memory, context, and the trace.
60
+
61
+ [:octicons-arrow-right-24: Architecture](architecture.md) ·
62
+ [Turns](turns.md) ·
63
+ [Kernel](julia-kernel.md) ·
64
+ [Filesystem](filesystem.md) ·
65
+ [Memory](memory.md) ·
66
+ [Context](context.md) ·
67
+ [Trace](trace.md)
68
+
69
+ - :material-puzzle-plus:{ .lg .middle } **Extending the agent**
70
+
71
+ ---
72
+
73
+ Add a simulator as data, improve behavior with the right lever, and
74
+ prove every change against the benchmark.
75
+
76
+ [:octicons-arrow-right-24: Adding a simulator](adding-a-simulator.md) ·
77
+ [Improving the agent](improving-the-agent.md) ·
78
+ [Evaluation](evaluation.md)
79
+
80
+ - :material-flask-outline:{ .lg .middle } **Development**
81
+
82
+ ---
83
+
84
+ Repo layout, the test tiers and what CI runs, dependency policy, and
85
+ the agent-first working method behind it all.
86
+
87
+ [:octicons-arrow-right-24: Development](development.md) ·
88
+ [Testing](testing.md) ·
89
+ [Agent-first](agent-first.md)
90
+
91
+ </div>
92
+
93
+ ## Supported simulators
94
+
95
+ <p class="ja-logos">
96
+ <a href="https://github.com/sintefmath/JutulDarcy.jl"><img src="https://raw.githubusercontent.com/sintefmath/JutulDarcy.jl/main/docs/src/assets/logo_wide.png" alt="JutulDarcy" style="height:1.6rem"></a>
97
+ <a href="https://github.com/BattMoTeam/BattMo.jl"><img src="https://raw.githubusercontent.com/BattMoTeam/BattMo.jl/main/docs/src/assets/battmologo_text.png" alt="BattMo" style="height:2.8rem"></a>
98
+ <a href="https://github.com/sintefmath/Fimbul.jl"><img src="https://raw.githubusercontent.com/sintefmath/Fimbul.jl/main/docs/src/assets/logo_text_wide.png" alt="Fimbul" style="height:1.9rem"></a>
99
+ <a href="https://github.com/sintefmath/Mocca.jl"><img src="https://raw.githubusercontent.com/sintefmath/Mocca.jl/main/docs/src/assets/mocca_small_transparent.png" alt="Mocca" style="height:2.4rem"></a>
100
+ </p>
101
+
102
+ | Simulator | Package | Domain |
103
+ |---|---|---|
104
+ | `jutuldarcy` | [JutulDarcy.jl](https://github.com/sintefmath/JutulDarcy.jl) | Reservoir / multi-phase flow |
105
+ | `battmo` | [BattMo.jl](https://github.com/BattMoTeam/BattMo.jl) | Lithium-ion (and other) battery cells |
106
+ | `fimbul` | [Fimbul.jl](https://github.com/sintefmath/Fimbul.jl) | Geothermal (ATES, BTES, doublet, EGS) |
107
+ | `mocca` | [Mocca.jl](https://github.com/sintefmath/Mocca.jl) | Adsorption-based CO₂ capture |