grinta 1.0.0__py3-none-any.whl

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 (1082) hide show
  1. backend/README.md +83 -0
  2. backend/README_GRINTA.md +9 -0
  3. backend/__init__.py +103 -0
  4. backend/_canonical.py +67 -0
  5. backend/app/__init__.py +36 -0
  6. backend/app/agent_control_loop.py +223 -0
  7. backend/app/main.py +707 -0
  8. backend/app/setup.py +573 -0
  9. backend/cli/__init__.py +8 -0
  10. backend/cli/_typing.py +115 -0
  11. backend/cli/display/__init__.py +1 -0
  12. backend/cli/display/diff_renderer.py +437 -0
  13. backend/cli/display/hud.py +680 -0
  14. backend/cli/display/layout_tokens.py +98 -0
  15. backend/cli/display/notifications.py +137 -0
  16. backend/cli/display/path_links.py +114 -0
  17. backend/cli/display/reasoning_display.py +379 -0
  18. backend/cli/display/status_chrome.py +643 -0
  19. backend/cli/display/text_truncation.py +86 -0
  20. backend/cli/display/tool_call_display.py +68 -0
  21. backend/cli/display/transcript.py +454 -0
  22. backend/cli/doctor/__init__.py +5 -0
  23. backend/cli/doctor/checks.py +561 -0
  24. backend/cli/doctor/doctor_cli.py +129 -0
  25. backend/cli/entry.py +420 -0
  26. backend/cli/event_renderer.py +244 -0
  27. backend/cli/event_rendering/__init__.py +9 -0
  28. backend/cli/event_rendering/actions/__init__.py +30 -0
  29. backend/cli/event_rendering/actions/browser.py +78 -0
  30. backend/cli/event_rendering/actions/dispatch.py +223 -0
  31. backend/cli/event_rendering/actions/exploration.py +53 -0
  32. backend/cli/event_rendering/actions/file.py +88 -0
  33. backend/cli/event_rendering/actions/mcp.py +62 -0
  34. backend/cli/event_rendering/actions/message.py +219 -0
  35. backend/cli/event_rendering/actions/meta.py +71 -0
  36. backend/cli/event_rendering/actions/shell.py +66 -0
  37. backend/cli/event_rendering/actions/terminal.py +134 -0
  38. backend/cli/event_rendering/activity_mixin.py +253 -0
  39. backend/cli/event_rendering/constants.py +169 -0
  40. backend/cli/event_rendering/delegate.py +312 -0
  41. backend/cli/event_rendering/error_categories/__init__.py +132 -0
  42. backend/cli/event_rendering/error_categories/auth_errors.py +55 -0
  43. backend/cli/event_rendering/error_categories/browser_errors.py +36 -0
  44. backend/cli/event_rendering/error_categories/matchers.py +76 -0
  45. backend/cli/event_rendering/error_categories/model_errors.py +61 -0
  46. backend/cli/event_rendering/error_categories/network_errors.py +40 -0
  47. backend/cli/event_rendering/error_categories/rate_limit_errors.py +59 -0
  48. backend/cli/event_rendering/error_categories/system_errors.py +189 -0
  49. backend/cli/event_rendering/error_categories/timeout_errors.py +59 -0
  50. backend/cli/event_rendering/error_panel.py +497 -0
  51. backend/cli/event_rendering/live_mixin.py +219 -0
  52. backend/cli/event_rendering/messages_mixin.py +283 -0
  53. backend/cli/event_rendering/observations/__init__.py +32 -0
  54. backend/cli/event_rendering/observations/dispatch.py +112 -0
  55. backend/cli/event_rendering/observations/error.py +118 -0
  56. backend/cli/event_rendering/observations/exploration.py +246 -0
  57. backend/cli/event_rendering/observations/file.py +68 -0
  58. backend/cli/event_rendering/observations/mcp.py +100 -0
  59. backend/cli/event_rendering/observations/misc.py +141 -0
  60. backend/cli/event_rendering/observations/shell.py +160 -0
  61. backend/cli/event_rendering/observations/shell_helpers.py +69 -0
  62. backend/cli/event_rendering/observations/status.py +247 -0
  63. backend/cli/event_rendering/observations/terminal.py +100 -0
  64. backend/cli/event_rendering/observations/think_browser.py +42 -0
  65. backend/cli/event_rendering/panels.py +385 -0
  66. backend/cli/event_rendering/panels_mixin.py +171 -0
  67. backend/cli/event_rendering/renderer_constants.py +28 -0
  68. backend/cli/event_rendering/sidebar.py +263 -0
  69. backend/cli/event_rendering/state_mixin.py +183 -0
  70. backend/cli/event_rendering/streaming_mixin.py +295 -0
  71. backend/cli/event_rendering/subscription_mixin.py +121 -0
  72. backend/cli/event_rendering/text_utils.py +287 -0
  73. backend/cli/event_rendering/unified_renderer/__init__.py +18 -0
  74. backend/cli/event_rendering/unified_renderer/mixins/__init__.py +1 -0
  75. backend/cli/event_rendering/unified_renderer/mixins/browser.py +72 -0
  76. backend/cli/event_rendering/unified_renderer/mixins/code.py +44 -0
  77. backend/cli/event_rendering/unified_renderer/mixins/delegate.py +56 -0
  78. backend/cli/event_rendering/unified_renderer/mixins/exploration.py +257 -0
  79. backend/cli/event_rendering/unified_renderer/mixins/file.py +108 -0
  80. backend/cli/event_rendering/unified_renderer/mixins/mcp.py +298 -0
  81. backend/cli/event_rendering/unified_renderer/mixins/shell.py +225 -0
  82. backend/cli/event_rendering/unified_renderer/mixins/status.py +72 -0
  83. backend/cli/event_rendering/unified_renderer/mixins/terminal.py +131 -0
  84. backend/cli/event_rendering/unified_renderer/renderer.py +29 -0
  85. backend/cli/event_rendering/unified_renderer/types.py +85 -0
  86. backend/cli/event_rendering/unified_renderer/utils.py +119 -0
  87. backend/cli/main.py +661 -0
  88. backend/cli/onboarding/__init__.py +19 -0
  89. backend/cli/onboarding/connection_check.py +125 -0
  90. backend/cli/onboarding/flow.py +304 -0
  91. backend/cli/onboarding/init_noninteractive.py +192 -0
  92. backend/cli/onboarding/init_wizard.py +633 -0
  93. backend/cli/onboarding/menu_prompts.py +77 -0
  94. backend/cli/onboarding/provider_presets.py +69 -0
  95. backend/cli/onboarding/settings_defaults.py +81 -0
  96. backend/cli/repl/__init__.py +12 -0
  97. backend/cli/repl/debug.py +11 -0
  98. backend/cli/repl/noninteractive.py +296 -0
  99. backend/cli/repl/run_helpers_dispatch.py +457 -0
  100. backend/cli/repl/slash_command_actions.py +450 -0
  101. backend/cli/repl/slash_command_checkpoint.py +191 -0
  102. backend/cli/repl/slash_command_diff.py +234 -0
  103. backend/cli/repl/slash_command_dispatch.py +128 -0
  104. backend/cli/repl/slash_command_registry.py +40 -0
  105. backend/cli/repl/slash_command_status.py +447 -0
  106. backend/cli/repl/slash_commands_mixin.py +339 -0
  107. backend/cli/repl/slash_registry_clipboard.py +53 -0
  108. backend/cli/repl/slash_registry_commands.py +350 -0
  109. backend/cli/repl/slash_registry_help.py +269 -0
  110. backend/cli/repl/slash_registry_models.py +36 -0
  111. backend/cli/repl/slash_registry_parsing.py +81 -0
  112. backend/cli/repl/slash_registry_prompt.py +188 -0
  113. backend/cli/repl/slash_registry_terminal.py +66 -0
  114. backend/cli/session/__init__.py +1 -0
  115. backend/cli/session/session_manager.py +697 -0
  116. backend/cli/session/sessions_cli.py +383 -0
  117. backend/cli/session/storage_cleanup.py +327 -0
  118. backend/cli/settings/__init__.py +93 -0
  119. backend/cli/settings/bootstrap_sync.py +39 -0
  120. backend/cli/settings/confirmation.py +248 -0
  121. backend/cli/settings/constants.py +52 -0
  122. backend/cli/settings/mcp.py +213 -0
  123. backend/cli/settings/mode_runtime.py +109 -0
  124. backend/cli/settings/query.py +535 -0
  125. backend/cli/settings/settings_tui.py +455 -0
  126. backend/cli/settings/storage.py +158 -0
  127. backend/cli/terminal_mouse.py +25 -0
  128. backend/cli/terminal_restore.py +183 -0
  129. backend/cli/terminal_sanitize.py +94 -0
  130. backend/cli/theme/__init__.py +470 -0
  131. backend/cli/theme/cards.py +82 -0
  132. backend/cli/theme/env.py +75 -0
  133. backend/cli/theme/navy.py +112 -0
  134. backend/cli/theme/presets.py +245 -0
  135. backend/cli/theme/spacing.py +31 -0
  136. backend/cli/theme/styles.py +148 -0
  137. backend/cli/theme/syntax_theme.py +268 -0
  138. backend/cli/theme/tokens.py +167 -0
  139. backend/cli/tool_display/__init__.py +5 -0
  140. backend/cli/tool_display/constants.py +115 -0
  141. backend/cli/tool_display/headline.py +209 -0
  142. backend/cli/tool_display/orient_tools.py +758 -0
  143. backend/cli/tool_display/preview.py +615 -0
  144. backend/cli/tool_display/redact.py +570 -0
  145. backend/cli/tool_display/renderers/__init__.py +89 -0
  146. backend/cli/tool_display/renderers/_syntax.py +41 -0
  147. backend/cli/tool_display/renderers/badge.py +110 -0
  148. backend/cli/tool_display/renderers/browser.py +68 -0
  149. backend/cli/tool_display/renderers/delegation.py +72 -0
  150. backend/cli/tool_display/renderers/file_editor.py +183 -0
  151. backend/cli/tool_display/renderers/lsp.py +41 -0
  152. backend/cli/tool_display/renderers/mcp.py +241 -0
  153. backend/cli/tool_display/renderers/memory.py +48 -0
  154. backend/cli/tool_display/renderers/output_parsers.py +447 -0
  155. backend/cli/tool_display/renderers/search.py +232 -0
  156. backend/cli/tool_display/renderers/shell.py +249 -0
  157. backend/cli/tool_display/renderers/tasks.py +98 -0
  158. backend/cli/tool_display/renderers/terminal.py +256 -0
  159. backend/cli/tool_display/renderers/think.py +105 -0
  160. backend/cli/tool_display/summarize.py +610 -0
  161. backend/cli/tui/__init__.py +1 -0
  162. backend/cli/tui/_a11y.py +45 -0
  163. backend/cli/tui/app.py +426 -0
  164. backend/cli/tui/constants.py +126 -0
  165. backend/cli/tui/dialogs/__init__.py +27 -0
  166. backend/cli/tui/dialogs/add_mcp.py +87 -0
  167. backend/cli/tui/dialogs/add_skill.py +115 -0
  168. backend/cli/tui/dialogs/confirm.py +251 -0
  169. backend/cli/tui/dialogs/help.py +63 -0
  170. backend/cli/tui/dialogs/manage_mcp.py +308 -0
  171. backend/cli/tui/dialogs/manage_skills.py +206 -0
  172. backend/cli/tui/dialogs/sessions.py +421 -0
  173. backend/cli/tui/dialogs/settings.py +562 -0
  174. backend/cli/tui/helpers.py +354 -0
  175. backend/cli/tui/image_attachments.py +323 -0
  176. backend/cli/tui/image_input_gate.py +35 -0
  177. backend/cli/tui/main.py +203 -0
  178. backend/cli/tui/renderer/README.md +44 -0
  179. backend/cli/tui/renderer/__init__.py +7 -0
  180. backend/cli/tui/renderer/classify.py +64 -0
  181. backend/cli/tui/renderer/diff.py +194 -0
  182. backend/cli/tui/renderer/drain.py +821 -0
  183. backend/cli/tui/renderer/event_helpers.py +65 -0
  184. backend/cli/tui/renderer/handlers/__init__.py +1 -0
  185. backend/cli/tui/renderer/handlers/acceptance_criteria.py +85 -0
  186. backend/cli/tui/renderer/handlers/browser.py +70 -0
  187. backend/cli/tui/renderer/handlers/compaction.py +88 -0
  188. backend/cli/tui/renderer/handlers/debugger.py +25 -0
  189. backend/cli/tui/renderer/handlers/delegate.py +122 -0
  190. backend/cli/tui/renderer/handlers/exploration.py +203 -0
  191. backend/cli/tui/renderer/handlers/fallback.py +81 -0
  192. backend/cli/tui/renderer/handlers/file.py +384 -0
  193. backend/cli/tui/renderer/handlers/mcp.py +92 -0
  194. backend/cli/tui/renderer/handlers/memory.py +133 -0
  195. backend/cli/tui/renderer/handlers/shell.py +58 -0
  196. backend/cli/tui/renderer/handlers/status.py +379 -0
  197. backend/cli/tui/renderer/handlers/task_state.py +33 -0
  198. backend/cli/tui/renderer/handlers/task_tracking.py +71 -0
  199. backend/cli/tui/renderer/handlers/terminal.py +142 -0
  200. backend/cli/tui/renderer/handlers/thinking.py +55 -0
  201. backend/cli/tui/renderer/helpers/__init__.py +1 -0
  202. backend/cli/tui/renderer/helpers/browser.py +39 -0
  203. backend/cli/tui/renderer/helpers/delegate.py +29 -0
  204. backend/cli/tui/renderer/helpers/exploration.py +115 -0
  205. backend/cli/tui/renderer/helpers/file.py +79 -0
  206. backend/cli/tui/renderer/helpers/mcp.py +21 -0
  207. backend/cli/tui/renderer/helpers/shell.py +37 -0
  208. backend/cli/tui/renderer/helpers/status.py +17 -0
  209. backend/cli/tui/renderer/helpers/terminal.py +22 -0
  210. backend/cli/tui/renderer/mixins/__init__.py +6 -0
  211. backend/cli/tui/renderer/mixins/action_handlers.py +435 -0
  212. backend/cli/tui/renderer/mixins/debugger.py +126 -0
  213. backend/cli/tui/renderer/mixins/display.py +864 -0
  214. backend/cli/tui/renderer/mixins/event_processor.py +109 -0
  215. backend/cli/tui/renderer/mixins/live.py +315 -0
  216. backend/cli/tui/renderer/mixins/terminal.py +362 -0
  217. backend/cli/tui/renderer/mixins/thinking.py +420 -0
  218. backend/cli/tui/renderer/prep.py +396 -0
  219. backend/cli/tui/renderer/processor.py +497 -0
  220. backend/cli/tui/renderer/step_draft.py +87 -0
  221. backend/cli/tui/screen/__init__.py +21 -0
  222. backend/cli/tui/screen/actions.py +214 -0
  223. backend/cli/tui/screen/communicate.py +185 -0
  224. backend/cli/tui/screen/input.py +780 -0
  225. backend/cli/tui/screen/lifecycle.py +454 -0
  226. backend/cli/tui/screen/lifecycle_bootstrap.py +360 -0
  227. backend/cli/tui/screen/lifecycle_dispatch.py +331 -0
  228. backend/cli/tui/screen/messages.py +452 -0
  229. backend/cli/tui/screen/settings.py +544 -0
  230. backend/cli/tui/screen/slash.py +203 -0
  231. backend/cli/tui/screen/state.py +825 -0
  232. backend/cli/tui/screen/welcome.py +99 -0
  233. backend/cli/tui/screens/detail/__init__.py +39 -0
  234. backend/cli/tui/screens/detail/acceptance_criteria.py +114 -0
  235. backend/cli/tui/screens/detail/base.py +283 -0
  236. backend/cli/tui/screens/detail/browser.py +83 -0
  237. backend/cli/tui/screens/detail/debugger.py +66 -0
  238. backend/cli/tui/screens/detail/edit.py +105 -0
  239. backend/cli/tui/screens/detail/helpers.py +250 -0
  240. backend/cli/tui/screens/detail/message.py +34 -0
  241. backend/cli/tui/screens/detail/payload.py +106 -0
  242. backend/cli/tui/screens/detail/shell.py +60 -0
  243. backend/cli/tui/screens/detail/terminal.py +64 -0
  244. backend/cli/tui/services/__init__.py +1 -0
  245. backend/cli/tui/services/mcp_reload_adapter.py +193 -0
  246. backend/cli/tui/services/settings_watcher.py +238 -0
  247. backend/cli/tui/strings.py +80 -0
  248. backend/cli/tui/styles.tcss +1141 -0
  249. backend/cli/tui/transcript_tiers.py +57 -0
  250. backend/cli/tui/transcript_typography.py +76 -0
  251. backend/cli/tui/widgets/__init__.py +1 -0
  252. backend/cli/tui/widgets/activity_card/__init__.py +23 -0
  253. backend/cli/tui/widgets/activity_card/message_widgets.py +320 -0
  254. backend/cli/tui/widgets/activity_card/orient.py +103 -0
  255. backend/cli/tui/widgets/collapsible.py +811 -0
  256. backend/cli/tui/widgets/command_list.py +270 -0
  257. backend/cli/tui/widgets/detail_terminal_frame.py +73 -0
  258. backend/cli/tui/widgets/dialogs.py +75 -0
  259. backend/cli/tui/widgets/error_block.py +61 -0
  260. backend/cli/tui/widgets/glyphs.py +94 -0
  261. backend/cli/tui/widgets/prompt_text_area.py +207 -0
  262. backend/cli/tui/widgets/scan_line/__init__.py +50 -0
  263. backend/cli/tui/widgets/scan_line/card.py +265 -0
  264. backend/cli/tui/widgets/scan_line/cards.py +946 -0
  265. backend/cli/tui/widgets/small.py +688 -0
  266. backend/cli/tui/widgets/transcript_notice.py +28 -0
  267. backend/cli/tui/widgets/unified_diff_view.py +644 -0
  268. backend/cli/tui/widgets/welcome.py +263 -0
  269. backend/cli/win32_console.py +166 -0
  270. backend/cli/workspace_trust_prompt.py +124 -0
  271. backend/context/README.md +20 -0
  272. backend/context/__init__.py +26 -0
  273. backend/context/canonical_state/__init__.py +159 -0
  274. backend/context/canonical_state/ops.py +654 -0
  275. backend/context/canonical_state/private.py +715 -0
  276. backend/context/canonical_state/types.py +379 -0
  277. backend/context/coding_preflight.py +224 -0
  278. backend/context/compactor/__init__.py +61 -0
  279. backend/context/compactor/compact_boundary.py +77 -0
  280. backend/context/compactor/compaction_finalizer.py +31 -0
  281. backend/context/compactor/compactor.py +649 -0
  282. backend/context/compactor/condensed_history.py +19 -0
  283. backend/context/compactor/microcompact.py +162 -0
  284. backend/context/compactor/pre_condensation_snapshot.py +1250 -0
  285. backend/context/compactor/strategies/__init__.py +31 -0
  286. backend/context/compactor/strategies/composition_pipeline.py +160 -0
  287. backend/context/compactor/strategies/layers/__init__.py +213 -0
  288. backend/context/compactor/strategies/microcompact_compactor.py +156 -0
  289. backend/context/compactor/strategies/no_op_compactor.py +50 -0
  290. backend/context/compactor/strategies/observation_masking_compactor.py +99 -0
  291. backend/context/compactor/strategies/pipeline.py +107 -0
  292. backend/context/compactor/strategies/recent_events_compactor.py +92 -0
  293. backend/context/compactor/strategies/smart_compactor.py +573 -0
  294. backend/context/compactor/strategies/structured_summary_compactor.py +887 -0
  295. backend/context/context_budget.py +112 -0
  296. backend/context/context_explorer.py +397 -0
  297. backend/context/context_pipeline/__init__.py +38 -0
  298. backend/context/context_pipeline/compaction.py +508 -0
  299. backend/context/context_pipeline/goal_context.py +117 -0
  300. backend/context/context_pipeline/grouping.py +73 -0
  301. backend/context/context_pipeline/helpers.py +68 -0
  302. backend/context/context_pipeline/pipeline.py +659 -0
  303. backend/context/context_pipeline/post_compact_reinject.py +32 -0
  304. backend/context/context_pipeline/types.py +22 -0
  305. backend/context/context_tracking.py +187 -0
  306. backend/context/continuity_eval.py +238 -0
  307. backend/context/memory/__init__.py +1 -0
  308. backend/context/memory/agent_memory.py +721 -0
  309. backend/context/memory/conversation_memory.py +1270 -0
  310. backend/context/memory/project_memory.py +360 -0
  311. backend/context/memory/session_context.py +112 -0
  312. backend/context/memory/session_memory.py +401 -0
  313. backend/context/memory/types.py +112 -0
  314. backend/context/memory/working_set.py +529 -0
  315. backend/context/processors/__init__.py +1 -0
  316. backend/context/processors/action_processors.py +500 -0
  317. backend/context/processors/observation_processors.py +744 -0
  318. backend/context/prompt/__init__.py +1 -0
  319. backend/context/prompt/compact_snapshot.py +50 -0
  320. backend/context/prompt/context_packet.py +599 -0
  321. backend/context/prompt/context_packet_cache.py +233 -0
  322. backend/context/prompt/message_formatting.py +151 -0
  323. backend/context/prompt/prompt_assembly.py +281 -0
  324. backend/context/prompt/prompt_window.py +1393 -0
  325. backend/context/prompt/turn_context.py +102 -0
  326. backend/context/prompt/user_turns.py +99 -0
  327. backend/context/render/__init__.py +23 -0
  328. backend/context/render/execution_contract.py +234 -0
  329. backend/context/render/task_context.py +144 -0
  330. backend/context/symbol_index/__init__.py +23 -0
  331. backend/context/symbol_index/aps_bridge.py +89 -0
  332. backend/context/symbol_index/builder.py +220 -0
  333. backend/context/symbol_index/imports.py +10 -0
  334. backend/context/symbol_index/paths.py +16 -0
  335. backend/context/symbol_index/query.py +36 -0
  336. backend/context/symbol_index/rank.py +114 -0
  337. backend/context/symbol_index/repo_map.py +126 -0
  338. backend/context/symbol_index/store.py +404 -0
  339. backend/context/tool_call_tracker.py +134 -0
  340. backend/context/tool_result_storage.py +278 -0
  341. backend/context/vector_store/__init__.py +35 -0
  342. backend/context/vector_store/_local_vector_store.py +971 -0
  343. backend/context/vector_store/_vector_store.py +813 -0
  344. backend/context/view.py +179 -0
  345. backend/core/__init__.py +5 -0
  346. backend/core/app_paths.py +54 -0
  347. backend/core/autonomy.py +75 -0
  348. backend/core/bounded_result.py +16 -0
  349. backend/core/cache/__init__.py +5 -0
  350. backend/core/cache/_serializer.py +55 -0
  351. backend/core/cache/async_smart_cache.py +156 -0
  352. backend/core/cache/cache_utils.py +26 -0
  353. backend/core/cache/smart_config_cache.py +147 -0
  354. backend/core/config/README.md +95 -0
  355. backend/core/config/__init__.py +57 -0
  356. backend/core/config/agent_config.py +693 -0
  357. backend/core/config/api_key_manager.py +496 -0
  358. backend/core/config/app_config.py +342 -0
  359. backend/core/config/arg_utils.py +91 -0
  360. backend/core/config/cli_config.py +131 -0
  361. backend/core/config/compactor_config.py +353 -0
  362. backend/core/config/config_loader.py +831 -0
  363. backend/core/config/config_telemetry.py +44 -0
  364. backend/core/config/config_utils.py +62 -0
  365. backend/core/config/dotenv_keys.py +150 -0
  366. backend/core/config/env_loader.py +188 -0
  367. backend/core/config/extended_config.py +53 -0
  368. backend/core/config/llm_config.py +506 -0
  369. backend/core/config/mcp_config.py +546 -0
  370. backend/core/config/mcp_defaults.py +64 -0
  371. backend/core/config/model_rebuild.py +83 -0
  372. backend/core/config/permissions_config.py +374 -0
  373. backend/core/config/provider_config.py +311 -0
  374. backend/core/config/quickstart.py +132 -0
  375. backend/core/config/runtime_config.py +57 -0
  376. backend/core/config/security_config.py +163 -0
  377. backend/core/config/tool_integration_defaults.py +31 -0
  378. backend/core/constants.py +730 -0
  379. backend/core/content_escape_repair.py +442 -0
  380. backend/core/contracts/__init__.py +10 -0
  381. backend/core/contracts/plugins.py +67 -0
  382. backend/core/criteria/__init__.py +23 -0
  383. backend/core/criteria/acceptance_criteria_store.py +190 -0
  384. backend/core/criteria/criterion_item.py +136 -0
  385. backend/core/enums.py +285 -0
  386. backend/core/errors/__init__.py +471 -0
  387. backend/core/errors/structured_edit_errors.py +450 -0
  388. backend/core/external_service.py +122 -0
  389. backend/core/file_history.py +72 -0
  390. backend/core/interaction_modes.py +152 -0
  391. backend/core/io_adapters/__init__.py +13 -0
  392. backend/core/io_adapters/cli_input.py +35 -0
  393. backend/core/io_adapters/json.py +109 -0
  394. backend/core/json_compat.py +129 -0
  395. backend/core/json_stdout.py +52 -0
  396. backend/core/logging/__init__.py +0 -0
  397. backend/core/logging/log_formatters.py +294 -0
  398. backend/core/logging/log_shipping.py +320 -0
  399. backend/core/logging/logger.py +719 -0
  400. backend/core/logging/session_context.py +158 -0
  401. backend/core/logging/session_event_logger.py +439 -0
  402. backend/core/logging/session_log_audit.py +434 -0
  403. backend/core/logging/session_log_renderer.py +104 -0
  404. backend/core/message.py +280 -0
  405. backend/core/os_capabilities.py +182 -0
  406. backend/core/plugin.py +534 -0
  407. backend/core/prompt_role_debug.py +82 -0
  408. backend/core/providers/__init__.py +9 -0
  409. backend/core/providers/configurations.py +565 -0
  410. backend/core/providers/provider_handler.py +129 -0
  411. backend/core/providers/provider_models.py +211 -0
  412. backend/core/runtime_paths.py +61 -0
  413. backend/core/schemas/__init__.py +128 -0
  414. backend/core/schemas/actions.py +562 -0
  415. backend/core/schemas/base.py +82 -0
  416. backend/core/schemas/metadata.py +91 -0
  417. backend/core/schemas/observations.py +148 -0
  418. backend/core/schemas/retry.py +23 -0
  419. backend/core/schemas/serialization.py +236 -0
  420. backend/core/step_phase.py +33 -0
  421. backend/core/task_tracker.py +5 -0
  422. backend/core/tasks/__init__.py +5 -0
  423. backend/core/tasks/plan_step.py +90 -0
  424. backend/core/tasks/task_status.py +63 -0
  425. backend/core/tasks/task_tracker.py +189 -0
  426. backend/core/timeouts/__init__.py +0 -0
  427. backend/core/timeouts/llm_step_timeout.py +38 -0
  428. backend/core/timeouts/loop_watchdog.py +298 -0
  429. backend/core/timeouts/suspend_aware_deadline.py +90 -0
  430. backend/core/timeouts/timeout_policy.py +82 -0
  431. backend/core/tools/__init__.py +1 -0
  432. backend/core/tools/tool_arguments_json.py +80 -0
  433. backend/core/tools/tool_names.py +82 -0
  434. backend/core/tools/tool_transport.py +40 -0
  435. backend/core/tracing.py +317 -0
  436. backend/core/type_safety/__init__.py +51 -0
  437. backend/core/type_safety/path_validation.py +699 -0
  438. backend/core/type_safety/sentinels.py +163 -0
  439. backend/core/type_safety/type_safety.py +203 -0
  440. backend/core/workspace_resolution.py +355 -0
  441. backend/core/workspace_trust.py +91 -0
  442. backend/core/wsl.py +171 -0
  443. backend/engine/README.md +16 -0
  444. backend/engine/__init__.py +24 -0
  445. backend/engine/contracts.py +175 -0
  446. backend/engine/executor.py +352 -0
  447. backend/engine/executor_mixins/__init__.py +29 -0
  448. backend/engine/executor_mixins/_executor_lifecycle_mixin.py +410 -0
  449. backend/engine/executor_mixins/_executor_response_mixin.py +147 -0
  450. backend/engine/executor_mixins/_executor_streaming_mixin.py +1129 -0
  451. backend/engine/executor_mixins/_executor_types.py +90 -0
  452. backend/engine/executor_response_helpers.py +230 -0
  453. backend/engine/file_reads.py +97 -0
  454. backend/engine/function_calling/__init__.py +1 -0
  455. backend/engine/function_calling/dispatch.py +331 -0
  456. backend/engine/function_calling/helpers.py +97 -0
  457. backend/engine/llm_message_serializer.py +97 -0
  458. backend/engine/memory_manager.py +482 -0
  459. backend/engine/memory_prompt_cache.py +57 -0
  460. backend/engine/orchestrator.py +460 -0
  461. backend/engine/orchestrator_helpers/__init__.py +22 -0
  462. backend/engine/orchestrator_helpers/actions.py +85 -0
  463. backend/engine/orchestrator_helpers/condensation.py +102 -0
  464. backend/engine/orchestrator_helpers/helpers.py +91 -0
  465. backend/engine/orchestrator_helpers/prompts.py +181 -0
  466. backend/engine/orchestrator_helpers/protocol.py +95 -0
  467. backend/engine/orchestrator_helpers/recovery.py +99 -0
  468. backend/engine/orchestrator_helpers/step.py +522 -0
  469. backend/engine/planner.py +1101 -0
  470. backend/engine/prompts/prompt_builder.py +915 -0
  471. backend/engine/prompts/section_renderers/__init__.py +101 -0
  472. backend/engine/prompts/section_renderers/_autonomy.py +242 -0
  473. backend/engine/prompts/section_renderers/_capabilities.py +337 -0
  474. backend/engine/prompts/section_renderers/_common.py +59 -0
  475. backend/engine/prompts/section_renderers/_critical.py +209 -0
  476. backend/engine/prompts/section_renderers/_env_hints.py +214 -0
  477. backend/engine/prompts/section_renderers/_examples.py +124 -0
  478. backend/engine/prompts/section_renderers/_interaction.py +44 -0
  479. backend/engine/prompts/section_renderers/_mcp.py +105 -0
  480. backend/engine/prompts/section_renderers/_permissions.py +74 -0
  481. backend/engine/prompts/section_renderers/_routing.py +110 -0
  482. backend/engine/prompts/section_renderers/_security.py +54 -0
  483. backend/engine/prompts/section_renderers/_tools.py +108 -0
  484. backend/engine/prompts/system_partial_00_routing.md +42 -0
  485. backend/engine/prompts/system_partial_01_autonomy.md +44 -0
  486. backend/engine/prompts/system_partial_02_tools.md +3 -0
  487. backend/engine/prompts/system_partial_03_tail.md +23 -0
  488. backend/engine/prompts/system_partial_04_critical.md +14 -0
  489. backend/engine/prompts/system_partial_05_examples.md +10 -0
  490. backend/engine/reflection.py +113 -0
  491. backend/engine/response_processing.py +860 -0
  492. backend/engine/streaming_checkpoint.py +314 -0
  493. backend/engine/tool_registry.py +82 -0
  494. backend/engine/tools/__init__.py +55 -0
  495. backend/engine/tools/_aps_callers_coverage.py +154 -0
  496. backend/engine/tools/_aps_dependencies.py +257 -0
  497. backend/engine/tools/_aps_file_modes.py +286 -0
  498. backend/engine/tools/_aps_shared.py +135 -0
  499. backend/engine/tools/_aps_tree.py +295 -0
  500. backend/engine/tools/_file_edits.py +70 -0
  501. backend/engine/tools/_file_edits_common.py +45 -0
  502. backend/engine/tools/_file_edits_handlers.py +147 -0
  503. backend/engine/tools/_file_edits_multi.py +425 -0
  504. backend/engine/tools/_file_edits_symbols.py +135 -0
  505. backend/engine/tools/_file_ops.py +405 -0
  506. backend/engine/tools/_search_helpers.py +587 -0
  507. backend/engine/tools/_tool_handlers.py +880 -0
  508. backend/engine/tools/acceptance_criteria.py +119 -0
  509. backend/engine/tools/analyze_project_structure.py +223 -0
  510. backend/engine/tools/atomic_refactor.py +694 -0
  511. backend/engine/tools/blackboard.py +53 -0
  512. backend/engine/tools/browser_native.py +255 -0
  513. backend/engine/tools/checkpoint.py +538 -0
  514. backend/engine/tools/debugger.py +327 -0
  515. backend/engine/tools/delegate_task.py +131 -0
  516. backend/engine/tools/docs_tools.py +129 -0
  517. backend/engine/tools/execute_mcp_tool.py +104 -0
  518. backend/engine/tools/glob.py +179 -0
  519. backend/engine/tools/grep.py +358 -0
  520. backend/engine/tools/health_check.py +188 -0
  521. backend/engine/tools/ignore_filter.py +83 -0
  522. backend/engine/tools/lesson_store.py +141 -0
  523. backend/engine/tools/lsp_query.py +151 -0
  524. backend/engine/tools/memory.py +141 -0
  525. backend/engine/tools/meta_cognition.py +59 -0
  526. backend/engine/tools/native_file_tools.py +179 -0
  527. backend/engine/tools/param_defs.py +197 -0
  528. backend/engine/tools/scratchpad.py +237 -0
  529. backend/engine/tools/semantic_analyzer.py +86 -0
  530. backend/engine/tools/session_lessons.py +264 -0
  531. backend/engine/tools/smart_errors.py +240 -0
  532. backend/engine/tools/structure_editor.py +986 -0
  533. backend/engine/tools/task_state.py +92 -0
  534. backend/engine/tools/task_tracker.py +115 -0
  535. backend/engine/tools/terminal.py +180 -0
  536. backend/engine/tools/treesitter_editor.py +19 -0
  537. backend/engine/tools/web_tools.py +218 -0
  538. backend/engine/tools/whitespace_handler.py +575 -0
  539. backend/engine/tools/working_memory.py +475 -0
  540. backend/engine/tools/workspace_memory.py +293 -0
  541. backend/execution/README.md +86 -0
  542. backend/execution/__init__.py +69 -0
  543. backend/execution/acceptance_criteria.py +299 -0
  544. backend/execution/aes/__init__.py +1 -0
  545. backend/execution/aes/file_operations.py +1264 -0
  546. backend/execution/aes/helpers.py +1314 -0
  547. backend/execution/aes/policy_block_messages.py +53 -0
  548. backend/execution/aes/security_enforcement.py +688 -0
  549. backend/execution/browser/__init__.py +5 -0
  550. backend/execution/browser/_browser_cdp.py +47 -0
  551. backend/execution/browser/_browser_interaction.py +512 -0
  552. backend/execution/browser/_browser_navigation.py +220 -0
  553. backend/execution/browser/_browser_shared.py +75 -0
  554. backend/execution/browser/_browser_snapshot.py +254 -0
  555. backend/execution/browser/grinta_browser.py +361 -0
  556. backend/execution/capabilities.py +125 -0
  557. backend/execution/dap/__init__.py +47 -0
  558. backend/execution/dap/_dap_adapters.py +376 -0
  559. backend/execution/dap/_dap_client.py +479 -0
  560. backend/execution/dap/_dap_errors.py +25 -0
  561. backend/execution/dap/_dap_logging.py +52 -0
  562. backend/execution/dap/_dap_manager.py +436 -0
  563. backend/execution/dap/_dap_session.py +650 -0
  564. backend/execution/dap/_dap_spawn_utils.py +197 -0
  565. backend/execution/dap/dap_aliases.py +23 -0
  566. backend/execution/document_readers.py +64 -0
  567. backend/execution/drivers/__init__.py +31 -0
  568. backend/execution/drivers/local/__init__.py +7 -0
  569. backend/execution/drivers/local/local_runtime_inprocess.py +941 -0
  570. backend/execution/executor_protocol.py +149 -0
  571. backend/execution/io_mixins/__init__.py +36 -0
  572. backend/execution/io_mixins/_aes_io_file_mixin.py +165 -0
  573. backend/execution/io_mixins/_aes_io_init_mixin.py +100 -0
  574. backend/execution/io_mixins/_aes_io_run_mixin.py +307 -0
  575. backend/execution/io_mixins/_aes_io_terminal_mixin.py +1039 -0
  576. backend/execution/io_mixins/_aes_io_workspace_mixin.py +112 -0
  577. backend/execution/mcp/config.json +22 -0
  578. backend/execution/playbook_loader.py +298 -0
  579. backend/execution/plugin_loader.py +28 -0
  580. backend/execution/plugins/__init__.py +136 -0
  581. backend/execution/plugins/agent_skills/README.md +38 -0
  582. backend/execution/plugins/agent_skills/__init__.py +31 -0
  583. backend/execution/plugins/agent_skills/agentskills.py +48 -0
  584. backend/execution/plugins/agent_skills/database/__init__.py +545 -0
  585. backend/execution/plugins/agent_skills/file_editor/README.md +3 -0
  586. backend/execution/plugins/agent_skills/file_editor/__init__.py +20 -0
  587. backend/execution/plugins/agent_skills/file_ops/__init__.py +23 -0
  588. backend/execution/plugins/agent_skills/file_ops/file_ops.py +512 -0
  589. backend/execution/plugins/agent_skills/file_reader/__init__.py +23 -0
  590. backend/execution/plugins/agent_skills/file_reader/file_readers.py +213 -0
  591. backend/execution/plugins/agent_skills/repo_ops/__init__.py +14 -0
  592. backend/execution/plugins/agent_skills/utils/config.py +109 -0
  593. backend/execution/plugins/agent_skills/utils/dependency.py +25 -0
  594. backend/execution/rollback/__init__.py +21 -0
  595. backend/execution/rollback/rollback_manager.py +632 -0
  596. backend/execution/rollback/shadow_repo.py +508 -0
  597. backend/execution/rollback/workspace_checkpoint.py +360 -0
  598. backend/execution/runtime/__init__.py +1 -0
  599. backend/execution/runtime/factory.py +41 -0
  600. backend/execution/runtime/orchestrator.py +247 -0
  601. backend/execution/runtime/pool.py +208 -0
  602. backend/execution/runtime_mixins/__init__.py +0 -0
  603. backend/execution/runtime_mixins/command_timeout.py +54 -0
  604. backend/execution/runtime_mixins/editor_only_shell_policy.py +163 -0
  605. backend/execution/runtime_mixins/env_manager.py +132 -0
  606. backend/execution/runtime_mixins/git_setup.py +354 -0
  607. backend/execution/sandbox_helpers/__init__.py +1 -0
  608. backend/execution/sandbox_helpers/appcontainer_runner.py +427 -0
  609. backend/execution/sandboxing.py +236 -0
  610. backend/execution/server/__init__.py +0 -0
  611. backend/execution/server/action_execution_server.py +503 -0
  612. backend/execution/server/action_execution_server_io.py +30 -0
  613. backend/execution/server/base.py +1098 -0
  614. backend/execution/server/supervisor.py +128 -0
  615. backend/execution/task_state.py +22 -0
  616. backend/execution/task_tracking.py +238 -0
  617. backend/execution/telemetry.py +76 -0
  618. backend/execution/utils/__init__.py +8 -0
  619. backend/execution/utils/fallbacks/__init__.py +6 -0
  620. backend/execution/utils/fallbacks/file_ops.py +193 -0
  621. backend/execution/utils/fallbacks/search.py +164 -0
  622. backend/execution/utils/file_editor/__init__.py +360 -0
  623. backend/execution/utils/file_editor/_file_editor_diff_helpers.py +136 -0
  624. backend/execution/utils/file_editor/_file_editor_edit_helpers.py +690 -0
  625. backend/execution/utils/file_editor/_file_editor_io_helpers.py +107 -0
  626. backend/execution/utils/file_editor/_file_editor_read_write_helpers.py +213 -0
  627. backend/execution/utils/file_editor/_file_editor_types.py +24 -0
  628. backend/execution/utils/file_editor/file_editor_edit_mixin.py +269 -0
  629. backend/execution/utils/file_editor/file_editor_edit_ops.py +160 -0
  630. backend/execution/utils/file_editor/file_editor_ops_mixin.py +295 -0
  631. backend/execution/utils/file_editor/file_editor_rollback_mixin.py +230 -0
  632. backend/execution/utils/file_editor/file_editor_view_mixin.py +218 -0
  633. backend/execution/utils/files/__init__.py +0 -0
  634. backend/execution/utils/files/bounded_io.py +369 -0
  635. backend/execution/utils/files/diff.py +173 -0
  636. backend/execution/utils/files/file_transaction.py +390 -0
  637. backend/execution/utils/files/file_viewer.py +60 -0
  638. backend/execution/utils/files/files.py +224 -0
  639. backend/execution/utils/git/__init__.py +1 -0
  640. backend/execution/utils/git/git_changes.py +119 -0
  641. backend/execution/utils/git/git_common.py +124 -0
  642. backend/execution/utils/git/git_diff.py +111 -0
  643. backend/execution/utils/git/git_handler.py +134 -0
  644. backend/execution/utils/log_capture.py +39 -0
  645. backend/execution/utils/mcp_runtime.py +243 -0
  646. backend/execution/utils/memory_monitor.py +85 -0
  647. backend/execution/utils/process/__init__.py +0 -0
  648. backend/execution/utils/process/process_manager.py +392 -0
  649. backend/execution/utils/process/process_registry.py +265 -0
  650. backend/execution/utils/process/server_detector.py +265 -0
  651. backend/execution/utils/shell/__init__.py +1 -0
  652. backend/execution/utils/shell/_bash_command.py +205 -0
  653. backend/execution/utils/shell/_bash_detached.py +127 -0
  654. backend/execution/utils/shell/_bash_pane.py +234 -0
  655. backend/execution/utils/shell/_bash_server.py +44 -0
  656. backend/execution/utils/shell/_bash_timeouts.py +431 -0
  657. backend/execution/utils/shell/background_turn_sync.py +153 -0
  658. backend/execution/utils/shell/bash.py +455 -0
  659. backend/execution/utils/shell/bash_constants.py +5 -0
  660. backend/execution/utils/shell/bash_support.py +193 -0
  661. backend/execution/utils/shell/blocking_heuristics.py +71 -0
  662. backend/execution/utils/shell/idle_detach_policy.py +66 -0
  663. backend/execution/utils/shell/prompt_detector.py +342 -0
  664. backend/execution/utils/shell/pty_session.py +849 -0
  665. backend/execution/utils/shell/pty_shell_session.py +616 -0
  666. backend/execution/utils/shell/session_manager.py +260 -0
  667. backend/execution/utils/shell/shell_utils.py +74 -0
  668. backend/execution/utils/shell/simple_bash.py +249 -0
  669. backend/execution/utils/shell/stall_hints.py +102 -0
  670. backend/execution/utils/shell/subprocess_background.py +172 -0
  671. backend/execution/utils/shell/unified_shell.py +765 -0
  672. backend/execution/utils/shell/windows_bash.py +537 -0
  673. backend/execution/utils/shell/windows_exceptions.py +16 -0
  674. backend/execution/utils/system.py +81 -0
  675. backend/execution/utils/system_stats.py +79 -0
  676. backend/execution/utils/tenacity_stop.py +18 -0
  677. backend/execution/utils/test_output_summary.py +193 -0
  678. backend/execution/utils/tool_registry.py +533 -0
  679. backend/execution/watchdog.py +216 -0
  680. backend/inference/README.md +802 -0
  681. backend/inference/__init__.py +25 -0
  682. backend/inference/caching/__init__.py +1 -0
  683. backend/inference/caching/gemini_cache.py +145 -0
  684. backend/inference/caching/prompt_cache.py +130 -0
  685. backend/inference/caching/prompt_caching.py +189 -0
  686. backend/inference/capabilities/__init__.py +16 -0
  687. backend/inference/capabilities/context_limits.py +194 -0
  688. backend/inference/capabilities/model_features.py +248 -0
  689. backend/inference/capabilities/param_profiles.py +85 -0
  690. backend/inference/capabilities/provider_capabilities.py +280 -0
  691. backend/inference/catalog/__init__.py +0 -0
  692. backend/inference/catalog/catalog_loader.py +1176 -0
  693. backend/inference/catalog/catalog_validator.py +481 -0
  694. backend/inference/catalog/model_catalog.py +25 -0
  695. backend/inference/catalog/provider_catalog.py +442 -0
  696. backend/inference/catalogs/anthropic.json +240 -0
  697. backend/inference/catalogs/cerebras.json +40 -0
  698. backend/inference/catalogs/deepinfra.json +66 -0
  699. backend/inference/catalogs/deepseek.json +68 -0
  700. backend/inference/catalogs/digitalocean.json +113 -0
  701. backend/inference/catalogs/fireworks.json +67 -0
  702. backend/inference/catalogs/google.json +96 -0
  703. backend/inference/catalogs/groq.json +132 -0
  704. backend/inference/catalogs/lightning.json +84 -0
  705. backend/inference/catalogs/mistral.json +66 -0
  706. backend/inference/catalogs/moonshot.json +97 -0
  707. backend/inference/catalogs/nvidia.json +40 -0
  708. backend/inference/catalogs/openai.json +672 -0
  709. backend/inference/catalogs/opencode-go.json +909 -0
  710. backend/inference/catalogs/opencode.json +4908 -0
  711. backend/inference/catalogs/openrouter.json +72 -0
  712. backend/inference/catalogs/perplexity.json +53 -0
  713. backend/inference/catalogs/together.json +67 -0
  714. backend/inference/catalogs/vercel.json +943 -0
  715. backend/inference/catalogs/xai.json +109 -0
  716. backend/inference/catalogs/zai.json +40 -0
  717. backend/inference/clients/__init__.py +74 -0
  718. backend/inference/clients/anthropic_client.py +90 -0
  719. backend/inference/clients/base.py +679 -0
  720. backend/inference/clients/factory.py +322 -0
  721. backend/inference/clients/openai_client.py +124 -0
  722. backend/inference/cost_tracker.py +104 -0
  723. backend/inference/debug_mixin.py +130 -0
  724. backend/inference/discover_models.py +140 -0
  725. backend/inference/exceptions.py +213 -0
  726. backend/inference/fn_call/__init__.py +106 -0
  727. backend/inference/fn_call/_fn_call_convert.py +246 -0
  728. backend/inference/fn_call/_fn_call_examples.py +386 -0
  729. backend/inference/fn_call/_fn_call_to_messages.py +766 -0
  730. backend/inference/llm/__init__.py +67 -0
  731. backend/inference/llm/config.py +259 -0
  732. backend/inference/llm/core.py +787 -0
  733. backend/inference/llm/exceptions.py +231 -0
  734. backend/inference/llm/stream.py +93 -0
  735. backend/inference/llm/utils.py +255 -0
  736. backend/inference/llm_registry.py +260 -0
  737. backend/inference/local_model.py +42 -0
  738. backend/inference/mappers/__init__.py +1 -0
  739. backend/inference/mappers/anthropic.py +456 -0
  740. backend/inference/mappers/gemini.py +565 -0
  741. backend/inference/mappers/openai.py +90 -0
  742. backend/inference/metrics.py +360 -0
  743. backend/inference/provider_resolver.py +459 -0
  744. backend/inference/providers/__init__.py +1 -0
  745. backend/inference/providers/anthropic_ops.py +417 -0
  746. backend/inference/providers/gemini_ops.py +596 -0
  747. backend/inference/providers/openai_ops.py +633 -0
  748. backend/inference/providers/opencode_gemini_ops.py +165 -0
  749. backend/inference/providers/opencode_responses_ops.py +213 -0
  750. backend/inference/rate_limit_parser.py +265 -0
  751. backend/inference/reasoning.py +678 -0
  752. backend/inference/reasoning_profiles.py +130 -0
  753. backend/inference/retry_mixin.py +230 -0
  754. backend/inference/runtime_profile.py +170 -0
  755. backend/inference/tool_support/__init__.py +0 -0
  756. backend/inference/tool_support/tool_history.py +47 -0
  757. backend/inference/tool_support/tool_result_format.py +50 -0
  758. backend/inference/tool_support/tool_types.py +73 -0
  759. backend/inference/transport.py +16 -0
  760. backend/inference/utils/batching.py +249 -0
  761. backend/integrations/README.md +32 -0
  762. backend/integrations/__init__.py +31 -0
  763. backend/integrations/mcp/README.md +24 -0
  764. backend/integrations/mcp/__init__.py +65 -0
  765. backend/integrations/mcp/cache.py +125 -0
  766. backend/integrations/mcp/client.py +493 -0
  767. backend/integrations/mcp/config_bus.py +353 -0
  768. backend/integrations/mcp/error_collector.py +79 -0
  769. backend/integrations/mcp/mcp_bootstrap_status.py +64 -0
  770. backend/integrations/mcp/mcp_tool_aliases.py +56 -0
  771. backend/integrations/mcp/mcp_utils.py +1165 -0
  772. backend/integrations/mcp/native_backends.py +60 -0
  773. backend/integrations/mcp/rigour_bootstrap.py +72 -0
  774. backend/integrations/mcp/tool.py +44 -0
  775. backend/integrations/mcp/wrappers.py +94 -0
  776. backend/knowledge/__init__.py +17 -0
  777. backend/knowledge/knowledge_base_manager.py +537 -0
  778. backend/knowledge/query_expansion.py +120 -0
  779. backend/knowledge/smart_chunking.py +559 -0
  780. backend/ledger/__init__.py +21 -0
  781. backend/ledger/action/__init__.py +105 -0
  782. backend/ledger/action/action.py +49 -0
  783. backend/ledger/action/agent.py +360 -0
  784. backend/ledger/action/browse.py +33 -0
  785. backend/ledger/action/browser_tool.py +31 -0
  786. backend/ledger/action/code_nav.py +41 -0
  787. backend/ledger/action/commands.py +59 -0
  788. backend/ledger/action/debugger.py +86 -0
  789. backend/ledger/action/empty.py +46 -0
  790. backend/ledger/action/files.py +102 -0
  791. backend/ledger/action/mcp.py +43 -0
  792. backend/ledger/action/memory_tools.py +114 -0
  793. backend/ledger/action/message.py +113 -0
  794. backend/ledger/action/search.py +91 -0
  795. backend/ledger/action/terminal.py +167 -0
  796. backend/ledger/event/__init__.py +26 -0
  797. backend/ledger/event/_event.py +244 -0
  798. backend/ledger/event/event_filter.py +146 -0
  799. backend/ledger/event/event_store.py +561 -0
  800. backend/ledger/event/event_store_abc.py +119 -0
  801. backend/ledger/event/event_utils.py +76 -0
  802. backend/ledger/infra/__init__.py +1 -0
  803. backend/ledger/infra/adapter.py +98 -0
  804. backend/ledger/infra/config.py +130 -0
  805. backend/ledger/infra/integrity.py +118 -0
  806. backend/ledger/infra/secret_masker.py +129 -0
  807. backend/ledger/infra/tool.py +64 -0
  808. backend/ledger/model_response_lite.py +111 -0
  809. backend/ledger/observation/__init__.py +107 -0
  810. backend/ledger/observation/acceptance_criteria.py +21 -0
  811. backend/ledger/observation/agent.py +161 -0
  812. backend/ledger/observation/browser_screenshot.py +44 -0
  813. backend/ledger/observation/code_nav.py +40 -0
  814. backend/ledger/observation/commands.py +266 -0
  815. backend/ledger/observation/debugger.py +26 -0
  816. backend/ledger/observation/empty.py +22 -0
  817. backend/ledger/observation/error.py +64 -0
  818. backend/ledger/observation/file_download.py +29 -0
  819. backend/ledger/observation/files.py +302 -0
  820. backend/ledger/observation/mcp.py +21 -0
  821. backend/ledger/observation/memory_tools.py +104 -0
  822. backend/ledger/observation/observation.py +43 -0
  823. backend/ledger/observation/reject.py +19 -0
  824. backend/ledger/observation/search.py +94 -0
  825. backend/ledger/observation/server.py +32 -0
  826. backend/ledger/observation/status.py +34 -0
  827. backend/ledger/observation/success.py +19 -0
  828. backend/ledger/observation/task_state.py +15 -0
  829. backend/ledger/observation/task_tracking.py +21 -0
  830. backend/ledger/observation/terminal.py +31 -0
  831. backend/ledger/observation_cause.py +62 -0
  832. backend/ledger/serialization/__init__.py +17 -0
  833. backend/ledger/serialization/action.py +197 -0
  834. backend/ledger/serialization/common.py +21 -0
  835. backend/ledger/serialization/event.py +455 -0
  836. backend/ledger/serialization/observation.py +253 -0
  837. backend/ledger/serialization/serialization_utils.py +24 -0
  838. backend/ledger/stream/__init__.py +39 -0
  839. backend/ledger/stream/async_event_store_wrapper.py +37 -0
  840. backend/ledger/stream/backpressure.py +264 -0
  841. backend/ledger/stream/coalescing.py +168 -0
  842. backend/ledger/stream/compaction.py +176 -0
  843. backend/ledger/stream/durable_writer.py +358 -0
  844. backend/ledger/stream/event_stream.py +1132 -0
  845. backend/ledger/stream/nested_event_store.py +191 -0
  846. backend/ledger/stream/persistence.py +764 -0
  847. backend/ledger/stream/stream_stats.py +82 -0
  848. backend/orchestration/__init__.py +6 -0
  849. backend/orchestration/action_scheduler.py +199 -0
  850. backend/orchestration/agent/__init__.py +303 -0
  851. backend/orchestration/agent/agent_protocol.py +180 -0
  852. backend/orchestration/agent/autonomy.py +237 -0
  853. backend/orchestration/agent/circuit_breaker.py +632 -0
  854. backend/orchestration/agent/tools.py +88 -0
  855. backend/orchestration/blackboard.py +156 -0
  856. backend/orchestration/file_edits/__init__.py +1 -0
  857. backend/orchestration/file_edits/file_edit_transaction.py +418 -0
  858. backend/orchestration/file_edits/file_state_tracker.py +310 -0
  859. backend/orchestration/file_edits/pre_exec_diff.py +219 -0
  860. backend/orchestration/health.py +377 -0
  861. backend/orchestration/memory_pressure.py +366 -0
  862. backend/orchestration/middleware/__init__.py +34 -0
  863. backend/orchestration/middleware/auto_check.py +99 -0
  864. backend/orchestration/middleware/blackboard.py +103 -0
  865. backend/orchestration/middleware/circuit_breaker.py +135 -0
  866. backend/orchestration/middleware/context_window.py +121 -0
  867. backend/orchestration/middleware/cost_quota.py +65 -0
  868. backend/orchestration/middleware/destructive_command.py +200 -0
  869. backend/orchestration/middleware/logging_mw.py +39 -0
  870. backend/orchestration/middleware/post_edit_diagnostics.py +350 -0
  871. backend/orchestration/middleware/progress_policy.py +123 -0
  872. backend/orchestration/middleware/rollback_middleware.py +263 -0
  873. backend/orchestration/middleware/safety_validator.py +69 -0
  874. backend/orchestration/middleware/symbol_index_invalidation.py +52 -0
  875. backend/orchestration/middleware/telemetry.py +31 -0
  876. backend/orchestration/middleware/tool_result_validator.py +392 -0
  877. backend/orchestration/mixins/__init__.py +59 -0
  878. backend/orchestration/mixins/action.py +171 -0
  879. backend/orchestration/mixins/lifecycle.py +357 -0
  880. backend/orchestration/mixins/parallel.py +537 -0
  881. backend/orchestration/mixins/state.py +436 -0
  882. backend/orchestration/mixins/step.py +253 -0
  883. backend/orchestration/mixins/watchdog.py +194 -0
  884. backend/orchestration/orchestration_config.py +107 -0
  885. backend/orchestration/rate_governor.py +238 -0
  886. backend/orchestration/replay.py +220 -0
  887. backend/orchestration/safety_validator.py +368 -0
  888. backend/orchestration/services/__init__.py +67 -0
  889. backend/orchestration/services/action_execution_service.py +856 -0
  890. backend/orchestration/services/action_service.py +239 -0
  891. backend/orchestration/services/autonomy_service.py +89 -0
  892. backend/orchestration/services/circuit_breaker_service.py +142 -0
  893. backend/orchestration/services/confirmation_service.py +174 -0
  894. backend/orchestration/services/error_formatting.py +214 -0
  895. backend/orchestration/services/event_router_mixins/__init__.py +33 -0
  896. backend/orchestration/services/event_router_mixins/_event_router_actions_mixin.py +286 -0
  897. backend/orchestration/services/event_router_mixins/_event_router_delegate_helpers.py +280 -0
  898. backend/orchestration/services/event_router_mixins/_event_router_delegate_mixin.py +818 -0
  899. backend/orchestration/services/event_router_mixins/_event_router_state_mixin.py +85 -0
  900. backend/orchestration/services/event_router_mixins/_event_router_user_message_mixin.py +201 -0
  901. backend/orchestration/services/event_router_service.py +52 -0
  902. backend/orchestration/services/exception_handler_service.py +106 -0
  903. backend/orchestration/services/guard_bus.py +186 -0
  904. backend/orchestration/services/iteration_guard_service.py +139 -0
  905. backend/orchestration/services/iteration_service.py +104 -0
  906. backend/orchestration/services/lifecycle_service.py +105 -0
  907. backend/orchestration/services/observation_service.py +508 -0
  908. backend/orchestration/services/orchestration_context.py +279 -0
  909. backend/orchestration/services/pending_action_service.py +642 -0
  910. backend/orchestration/services/recovery_service.py +717 -0
  911. backend/orchestration/services/retry_queue.py +353 -0
  912. backend/orchestration/services/retry_service.py +657 -0
  913. backend/orchestration/services/safety_service.py +157 -0
  914. backend/orchestration/services/state_transition_service.py +267 -0
  915. backend/orchestration/services/step_decision_service.py +119 -0
  916. backend/orchestration/services/step_guard_service.py +580 -0
  917. backend/orchestration/services/step_prerequisite_service.py +64 -0
  918. backend/orchestration/services/stuck_detection_service.py +50 -0
  919. backend/orchestration/services/task_validation_service.py +113 -0
  920. backend/orchestration/session_orchestrator.py +582 -0
  921. backend/orchestration/session_orchestrator_accessors.py +121 -0
  922. backend/orchestration/state/__init__.py +46 -0
  923. backend/orchestration/state/control_flags.py +118 -0
  924. backend/orchestration/state/session_checkpoint_manager.py +131 -0
  925. backend/orchestration/state/state.py +980 -0
  926. backend/orchestration/state/state_tracker.py +427 -0
  927. backend/orchestration/stuck/__init__.py +5 -0
  928. backend/orchestration/stuck/detector.py +772 -0
  929. backend/orchestration/stuck/patterns.py +187 -0
  930. backend/orchestration/telemetry/__init__.py +1 -0
  931. backend/orchestration/telemetry/conversation_stats.py +231 -0
  932. backend/orchestration/telemetry/progress_tracker.py +281 -0
  933. backend/orchestration/telemetry/tool_telemetry.py +580 -0
  934. backend/orchestration/tool_pipeline.py +155 -0
  935. backend/persistence/README.md +32 -0
  936. backend/persistence/__init__.py +56 -0
  937. backend/persistence/auth.py +57 -0
  938. backend/persistence/conversation/__init__.py +1 -0
  939. backend/persistence/conversation/conversation_resumer.py +156 -0
  940. backend/persistence/conversation/conversation_store.py +78 -0
  941. backend/persistence/conversation/conversation_validator.py +195 -0
  942. backend/persistence/conversation/file_conversation_store.py +257 -0
  943. backend/persistence/data_models/__init__.py +1 -0
  944. backend/persistence/data_models/conversation_metadata.py +52 -0
  945. backend/persistence/data_models/conversation_metadata_result_set.py +19 -0
  946. backend/persistence/data_models/conversation_status.py +43 -0
  947. backend/persistence/data_models/conversation_template.py +96 -0
  948. backend/persistence/data_models/knowledge_base.py +164 -0
  949. backend/persistence/data_models/settings.py +354 -0
  950. backend/persistence/data_models/user_secrets.py +263 -0
  951. backend/persistence/file_store/__init__.py +0 -0
  952. backend/persistence/file_store/atomic_write.py +42 -0
  953. backend/persistence/file_store/files.py +65 -0
  954. backend/persistence/file_store/in_memory_file_store.py +95 -0
  955. backend/persistence/file_store/local_file_store.py +241 -0
  956. backend/persistence/knowledge_base/__init__.py +1 -0
  957. backend/persistence/knowledge_base/knowledge_base_store.py +302 -0
  958. backend/persistence/knowledge_base/migrations/001_create_knowledge_base_tables.sql +38 -0
  959. backend/persistence/knowledge_base/migrations/__init__.py +1 -0
  960. backend/persistence/knowledge_base/migrations/run_migrations.py +81 -0
  961. backend/persistence/locations.py +341 -0
  962. backend/persistence/secrets/__init__.py +1 -0
  963. backend/persistence/secrets/file_secrets_store.py +101 -0
  964. backend/persistence/secrets/secrets_store.py +39 -0
  965. backend/persistence/settings/__init__.py +1 -0
  966. backend/persistence/settings/file_settings_store.py +150 -0
  967. backend/persistence/settings/settings_store.py +40 -0
  968. backend/persistence/sqlite_event_store.py +588 -0
  969. backend/persistence/user/__init__.py +0 -0
  970. backend/playbooks/README.md +73 -0
  971. backend/playbooks/__init__.py +1 -0
  972. backend/playbooks/add_repo_inst.md +65 -0
  973. backend/playbooks/address_pr_comments.md +28 -0
  974. backend/playbooks/agent_memory.md +32 -0
  975. backend/playbooks/api.md +70 -0
  976. backend/playbooks/code-review.md +50 -0
  977. backend/playbooks/database.md +33 -0
  978. backend/playbooks/debug.md +42 -0
  979. backend/playbooks/deps.md +67 -0
  980. backend/playbooks/documentation.md +36 -0
  981. backend/playbooks/engine/__init__.py +18 -0
  982. backend/playbooks/engine/playbook.py +673 -0
  983. backend/playbooks/engine/types.py +97 -0
  984. backend/playbooks/feature.md +36 -0
  985. backend/playbooks/git-wizard.md +66 -0
  986. backend/playbooks/incident.md +51 -0
  987. backend/playbooks/log-fu.md +86 -0
  988. backend/playbooks/migration.md +54 -0
  989. backend/playbooks/net-diag.md +95 -0
  990. backend/playbooks/perf.md +60 -0
  991. backend/playbooks/python.md +50 -0
  992. backend/playbooks/react.md +40 -0
  993. backend/playbooks/refactoring.md +33 -0
  994. backend/playbooks/security.md +52 -0
  995. backend/playbooks/shell.md +41 -0
  996. backend/playbooks/testing.md +63 -0
  997. backend/playbooks/tool.md +50 -0
  998. backend/playbooks/typescript.md +50 -0
  999. backend/playbooks/update_pr_description.md +33 -0
  1000. backend/playbooks/update_test.md +20 -0
  1001. backend/py.typed +0 -0
  1002. backend/scripts/README.md +30 -0
  1003. backend/scripts/build_tree_sitter_lang.py +89 -0
  1004. backend/scripts/sanitize_trajectories.py +319 -0
  1005. backend/scripts/verify/README.md +31 -0
  1006. backend/scripts/verify/check_fastmcp_import.py +14 -0
  1007. backend/scripts/verify/check_file_size.py +131 -0
  1008. backend/scripts/verify/check_layer_imports.py +214 -0
  1009. backend/scripts/verify/ga_onboarding_gate.py +222 -0
  1010. backend/scripts/verify/reliability_gate.py +238 -0
  1011. backend/scripts/verify/verify_api_versioning.py +175 -0
  1012. backend/scripts/verify/verify_optional_imports.py +75 -0
  1013. backend/security/__init__.py +15 -0
  1014. backend/security/analyzer.py +131 -0
  1015. backend/security/command_analyzer.py +686 -0
  1016. backend/security/options.py +36 -0
  1017. backend/security/safety_config.py +54 -0
  1018. backend/task_state/__init__.py +7 -0
  1019. backend/task_state/models.py +118 -0
  1020. backend/task_state/service.py +262 -0
  1021. backend/task_state/store.py +57 -0
  1022. backend/telemetry/__init__.py +6 -0
  1023. backend/telemetry/audit_logger.py +370 -0
  1024. backend/telemetry/models.py +137 -0
  1025. backend/utils/README.md +18 -0
  1026. backend/utils/__init__.py +5 -0
  1027. backend/utils/async_helpers/__init__.py +1 -0
  1028. backend/utils/async_helpers/async_utils.py +679 -0
  1029. backend/utils/async_helpers/circuit_breaker.py +196 -0
  1030. backend/utils/async_helpers/retry.py +260 -0
  1031. backend/utils/async_helpers/subprocess_bridge.py +56 -0
  1032. backend/utils/async_helpers/tenacity_metrics.py +131 -0
  1033. backend/utils/async_helpers/tenacity_stop.py +35 -0
  1034. backend/utils/conversation_summary.py +250 -0
  1035. backend/utils/core_utils.py +73 -0
  1036. backend/utils/http/__init__.py +1 -0
  1037. backend/utils/http/http_session.py +89 -0
  1038. backend/utils/http/stdio_json_rpc.py +106 -0
  1039. backend/utils/impact_analysis.py +488 -0
  1040. backend/utils/import_utils.py +124 -0
  1041. backend/utils/linux_host_tools.py +213 -0
  1042. backend/utils/lsp/__init__.py +1 -0
  1043. backend/utils/lsp/lsp_capabilities.py +46 -0
  1044. backend/utils/lsp/lsp_client.py +1173 -0
  1045. backend/utils/lsp/lsp_project_routing.py +129 -0
  1046. backend/utils/lsp/lsp_session.py +557 -0
  1047. backend/utils/lsp/lsp_timeouts.py +61 -0
  1048. backend/utils/metrics_labels.py +27 -0
  1049. backend/utils/model_prewarm.py +102 -0
  1050. backend/utils/optional_extras.py +78 -0
  1051. backend/utils/path_normalize.py +156 -0
  1052. backend/utils/prompt.py +388 -0
  1053. backend/utils/regex_limits.py +24 -0
  1054. backend/utils/runtime_detect.py +1028 -0
  1055. backend/utils/search_utils.py +65 -0
  1056. backend/utils/shutdown_listener.py +97 -0
  1057. backend/utils/stdio_restore.py +55 -0
  1058. backend/utils/terminal/__init__.py +1 -0
  1059. backend/utils/terminal/term_color.py +29 -0
  1060. backend/utils/terminal/terminal_contract.py +124 -0
  1061. backend/utils/treesitter/__init__.py +1 -0
  1062. backend/utils/treesitter/_tse_errors.py +165 -0
  1063. backend/utils/treesitter/_tse_languages.py +167 -0
  1064. backend/utils/treesitter/_tse_query.py +328 -0
  1065. backend/utils/treesitter/_tse_runtime.py +57 -0
  1066. backend/utils/treesitter/_tse_types.py +49 -0
  1067. backend/utils/treesitter/chunk_localizer.py +116 -0
  1068. backend/utils/treesitter/syntax_check.py +281 -0
  1069. backend/utils/treesitter/treesitter_editor.py +767 -0
  1070. backend/validation/__init__.py +5 -0
  1071. backend/validation/code_quality/__init__.py +9 -0
  1072. backend/validation/code_quality/linter.py +339 -0
  1073. backend/validation/command_classification.py +272 -0
  1074. backend/validation/task_metadata.py +185 -0
  1075. backend/validation/task_validator.py +925 -0
  1076. grinta-1.0.0.dist-info/METADATA +197 -0
  1077. grinta-1.0.0.dist-info/RECORD +1082 -0
  1078. grinta-1.0.0.dist-info/WHEEL +4 -0
  1079. grinta-1.0.0.dist-info/entry_points.txt +2 -0
  1080. grinta-1.0.0.dist-info/licenses/LICENSE +24 -0
  1081. launch/__init__.py +1 -0
  1082. launch/entry.py +103 -0
backend/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # Backend
2
+
3
+ This folder contains all backend-related code and resources for the Grinta project.
4
+
5
+ ## Structure
6
+
7
+ ```text
8
+ backend/
9
+ ├── cli/ # Terminal UI, REPL, and CLI entry
10
+ ├── context/ # Context memory and compaction
11
+ ├── core/ # Shared config, schemas, logging, and bootstrap
12
+ ├── engine/ # LLM-facing agent engine and tools
13
+ ├── evaluation/ # Agent eval pack and related helpers
14
+ ├── execution/ # Local runtime execution and policy enforcement
15
+ ├── inference/ # Model/provider abstraction layer
16
+ ├── integrations/ # External adapters (e.g. MCP plumbing)
17
+ ├── knowledge/ # Knowledge base logic
18
+ ├── ledger/ # Record stream, event types, serialization
19
+ ├── orchestration/ # Session orchestration loop and services
20
+ ├── persistence/ # Local file-backed persistence
21
+ ├── playbooks/ # Built-in playbook content and engine
22
+ ├── scripts/ # Backend utility scripts
23
+ ├── security/ # Security analysis and policy checks
24
+ ├── telemetry/ # Lightweight instrumentation
25
+ ├── tools/ # Repo maintenance utilities (e.g. trajectory sanitization)
26
+ ├── utils/ # Shared utilities (LSP client, imports, etc.)
27
+ ├── validation/ # Validation and completion guards
28
+ ├── tests/ # Test suite
29
+ └── conftest.py # Pytest configuration
30
+ ```
31
+
32
+ ## Package Structure
33
+
34
+ Most application code lives under `backend/`. The supported interactive surface is the terminal CLI in `backend/cli/`, launched through `launch.entry` or `python -m backend.cli.entry`.
35
+
36
+ ## Running Tests
37
+
38
+ From the project root, `uv run pytest` (no path) discovers all of `backend/tests` per the repo [`pytest.ini`](../pytest.ini). To match the required PR gates (unit only):
39
+
40
+ ```bash
41
+ uv run pytest backend/tests/unit
42
+ ```
43
+
44
+ To run the full tree explicitly:
45
+
46
+ ```bash
47
+ uv run pytest backend/tests
48
+ ```
49
+
50
+ Or use the Makefile:
51
+
52
+ ```bash
53
+ make test-unit
54
+ ```
55
+
56
+ ## Scripts
57
+
58
+ `backend/scripts/` currently holds **verification** utilities used in CI and local gates (`verify/`). One-off automation, smoke installs, and eval helpers live under the repository root [`scripts/`](../scripts/) instead — see [`scripts/README.md`](../scripts/README.md) for the full index.
59
+
60
+ From the project root:
61
+
62
+ ```bash
63
+ python backend/scripts/verify/check_layer_imports.py
64
+ python backend/scripts/verify/reliability_gate.py --phase full
65
+ ```
66
+
67
+ See [`backend/scripts/README.md`](scripts/README.md) for the full list.
68
+
69
+ ## Development
70
+
71
+ Backend code imports from `backend.*`. The supported entrypoints are the CLI under `backend/cli/` and the portable launcher in `launch/`.
72
+
73
+ ### CLI Mixin Typing Convention
74
+
75
+ When extracting logic into CLI mixins (for example in `backend/cli/repl/` or
76
+ `backend/cli/event_rendering/`), define host interfaces in
77
+ `backend/cli/_typing.py` and import them into mixins instead of re-declaring
78
+ `TYPE_CHECKING`-only host stubs per file.
79
+
80
+ - Keep shared host contracts in `backend/cli/_typing.py` as `Protocol` classes.
81
+ - In mixins, cast `self` to the relevant host protocol where needed.
82
+ - Prefer this shared protocol approach over file-local structural stubs so
83
+ typing and lint behavior stays consistent across extracted modules.
@@ -0,0 +1,9 @@
1
+ # backend/ — see docs instead
2
+
3
+ This file is **legacy**. For current architecture and module layout, read:
4
+
5
+ - [docs/ARCHITECTURE.md](../docs/ARCHITECTURE.md)
6
+ - [docs/CLI_MODULE_MAP.md](../docs/CLI_MODULE_MAP.md)
7
+ - [docs/CONTRIBUTOR_MAP.md](../docs/CONTRIBUTOR_MAP.md)
8
+
9
+ The runtime is organized into `cli/`, `orchestration/`, `execution/`, `inference/`, and `ledger/` packages — not the class-centric overview that used to live here.
backend/__init__.py ADDED
@@ -0,0 +1,103 @@
1
+ """Grinta package."""
2
+
3
+ import warnings
4
+
5
+ # Suppress only known, specific third-party DeprecationWarnings.
6
+ # Do NOT use a blanket `category=DeprecationWarning` filter — that silences
7
+ # warnings from Grinta's own code and newly added dependencies too.
8
+ #
9
+ # Pattern: warnings.filterwarnings('ignore', message=<regex>, category=DeprecationWarning, module=<regex>)
10
+ # Add a new entry for each third-party library that produces noise, scoped as
11
+ # narrowly as possible (prefer `module=` + `message=` over category-only).
12
+
13
+ # asttokens / astroid: fires from frozen importlib frames; cannot be caught by
14
+ # module-based filters alone because the source frame is internal to importlib.
15
+ warnings.filterwarnings(
16
+ 'ignore',
17
+ message=r'.*asttokens.*',
18
+ category=DeprecationWarning,
19
+ )
20
+ warnings.filterwarnings(
21
+ 'ignore',
22
+ message=r'.*astroid.*',
23
+ category=DeprecationWarning,
24
+ )
25
+
26
+ # google-genai (Gemini SDK) subclasses aiohttp.ClientSession — noisy on import.
27
+ warnings.filterwarnings(
28
+ 'ignore',
29
+ message=r'Inheritance class AiohttpClientSession from ClientSession is discouraged',
30
+ category=DeprecationWarning,
31
+ )
32
+
33
+ # anthropic SDK: uses deprecated pkg_resources internals in some versions.
34
+ warnings.filterwarnings(
35
+ 'ignore',
36
+ message=r'.*pkg_resources.*',
37
+ category=DeprecationWarning,
38
+ module=r'anthropic.*',
39
+ )
40
+
41
+ # tree-sitter <0.25 exposes a deprecated Language constructor form.
42
+ warnings.filterwarnings(
43
+ 'ignore',
44
+ message=r'.*Language\(\) with a shared library.*',
45
+ category=DeprecationWarning,
46
+ module=r'tree_sitter.*',
47
+ )
48
+
49
+ from importlib.metadata import PackageNotFoundError, version # noqa: E402
50
+ from pathlib import Path # noqa: E402
51
+
52
+ _DEFAULT_VERSION = '1.0.0'
53
+ __version__ = _DEFAULT_VERSION
54
+ __package_name__ = 'grinta'
55
+
56
+
57
+ def get_version() -> str:
58
+ """Get the package version, preferring the local source tree when present."""
59
+ from_pyproject = _version_from_pyproject()
60
+ if from_pyproject:
61
+ return from_pyproject
62
+ from_metadata = _version_from_metadata()
63
+ if from_metadata:
64
+ return from_metadata
65
+ return _DEFAULT_VERSION
66
+
67
+
68
+ def _version_from_metadata() -> str | None:
69
+ """Try to get version from installed package metadata."""
70
+ try:
71
+ return version(__package_name__)
72
+ except PackageNotFoundError:
73
+ return None
74
+
75
+
76
+ def _version_from_pyproject() -> str | None:
77
+ """Try to get version from pyproject.toml (local dev)."""
78
+ try:
79
+ root_dir = Path(__file__).resolve().parent.parent
80
+ pyproject_path = root_dir / 'pyproject.toml'
81
+ if not pyproject_path.exists():
82
+ return None
83
+ with pyproject_path.open('r', encoding='utf-8') as f:
84
+ for line in f:
85
+ if line.strip().startswith('version ='):
86
+ return line.split('=', 1)[1].strip().strip('"').strip("'")
87
+ except Exception:
88
+ pass
89
+ return None
90
+
91
+
92
+ try:
93
+ __version__ = get_version()
94
+ except Exception as _exc:
95
+ warnings.warn(
96
+ f'Grinta: could not determine package version ({_exc!r}); reporting '
97
+ f'{_DEFAULT_VERSION!r}.',
98
+ stacklevel=1,
99
+ )
100
+ __version__ = _DEFAULT_VERSION
101
+
102
+
103
+ __all__ = ['__version__', '__package_name__', 'get_version']
backend/_canonical.py ADDED
@@ -0,0 +1,67 @@
1
+ """Shared registry for canonical classes across reloads."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from pydantic._internal._model_construction import ModelMetaclass
8
+
9
+
10
+ def _canonical_model_instancecheck(cls: type[Any], instance: Any) -> bool:
11
+ if type.__instancecheck__(cls, instance):
12
+ return True
13
+ # Check if the class names match. This allows isinstance(reloaded_obj, original_class) to be True.
14
+ return type(instance).__name__ == cls.__name__
15
+
16
+
17
+ def _canonical_model_subclasscheck(cls: type[Any], subclass: type[Any]) -> bool:
18
+ if type.__subclasscheck__(cls, subclass):
19
+ return True
20
+ # Check if the class names match. This allows issubclass(reloaded_class, original_class) to be True.
21
+ return getattr(subclass, '__name__', None) == cls.__name__
22
+
23
+
24
+ class CanonicalModelMetaclass(ModelMetaclass):
25
+ """Metaclass that ensures Pydantic models behave consistently across reloads.
26
+
27
+ Instead of trying to return the same class object (which causes issues with super()),
28
+ this metaclass overrides ``isinstance`` / ``issubclass`` behavior across reloads.
29
+ """
30
+
31
+ __instancecheck__ = _canonical_model_instancecheck # type: ignore[assignment]
32
+ __subclasscheck__ = _canonical_model_subclasscheck # type: ignore[assignment]
33
+
34
+
35
+ class CanonicalMeta(type):
36
+ """Metaclass that ensures non-Pydantic classes behave consistently across reloads.
37
+
38
+ Supports isinstance() and issubclass() checks across reloaded versions of the
39
+ same class by comparing class names.
40
+ """
41
+
42
+ def __instancecheck__(cls, instance: object) -> bool:
43
+ if super().__instancecheck__(instance):
44
+ return True
45
+ # Check if the class names match.
46
+ inst_type = type(instance)
47
+ if getattr(inst_type, '__name__', None) != getattr(cls, '__name__', None):
48
+ # Special case for base classes to allow subclasses from other reloads
49
+ if cls.__name__ in ('Action', 'Observation', 'Event'):
50
+ return any(b.__name__ == cls.__name__ for b in inst_type.__mro__)
51
+ return False
52
+
53
+ # If it's an Action/Observation, we can also check the type attribute
54
+ cls_type = getattr(cls, 'action', getattr(cls, 'observation', None))
55
+ inst_type_attr = getattr(
56
+ instance, 'action', getattr(instance, 'observation', None)
57
+ )
58
+ if cls_type and inst_type_attr:
59
+ return cls_type == inst_type_attr
60
+
61
+ return True
62
+
63
+ def __subclasscheck__(cls, subclass: type) -> bool:
64
+ if super().__subclasscheck__(subclass):
65
+ return True
66
+ # Check if the class names match.
67
+ return getattr(subclass, '__name__', None) == cls.__name__
@@ -0,0 +1,36 @@
1
+ """Bootstrap modules that wire together cross-layer components.
2
+
3
+ These modules are intentionally allowed to import from higher layers
4
+ (controller, engines, memory, runtime) because they serve as the
5
+ application composition root. They are the only modules in ``core``
6
+ that cross layer boundaries.
7
+
8
+ Modules:
9
+ agent_control_loop - Polling loop that drives the agent until a terminal state
10
+ main - CLI / headless entry point, run_controller orchestration
11
+ setup - Factory functions: create_agent, create_controller, create_memory, create_runtime
12
+ """
13
+
14
+ from backend.app.agent_control_loop import run_agent_until_done
15
+ from backend.app.setup import (
16
+ create_agent,
17
+ create_controller,
18
+ create_memory,
19
+ create_runtime,
20
+ filter_plugins_by_config,
21
+ generate_sid,
22
+ get_provider_tokens,
23
+ initialize_repository_for_runtime,
24
+ )
25
+
26
+ __all__ = [
27
+ 'create_agent',
28
+ 'create_controller',
29
+ 'create_memory',
30
+ 'create_runtime',
31
+ 'filter_plugins_by_config',
32
+ 'generate_sid',
33
+ 'get_provider_tokens',
34
+ 'initialize_repository_for_runtime',
35
+ 'run_agent_until_done',
36
+ ]
@@ -0,0 +1,223 @@
1
+ """Agent control loop helpers for running runtimes and handling status callbacks."""
2
+
3
+ import asyncio
4
+ from collections.abc import Callable
5
+
6
+ from backend.context.memory.agent_memory import Memory
7
+ from backend.core.enums import RuntimeStatus
8
+ from backend.core.logging.logger import app_logger as logger
9
+ from backend.core.schemas import AgentState
10
+ from backend.core.timeouts.suspend_aware_deadline import SuspendAwareDeadline
11
+ from backend.execution.server.base import Runtime
12
+ from backend.orchestration import SessionOrchestrator
13
+ from backend.utils.async_helpers.async_utils import run_or_schedule
14
+
15
+
16
+ def _handle_error_status(
17
+ controller: SessionOrchestrator, runtime_status: RuntimeStatus, msg: str
18
+ ) -> None:
19
+ """Handle error status in the status callback."""
20
+ if controller:
21
+ controller.state.set_last_error(msg, source='loop.status_callback')
22
+ try:
23
+ if runtime_status == RuntimeStatus.ERROR_MEMORY:
24
+ setattr(
25
+ controller.state,
26
+ '_memory_error_boundary',
27
+ controller.state.iteration_flag.current_value,
28
+ )
29
+ logger.info(
30
+ 'LOOP.status_callback: memory error boundary recorded at iteration %s',
31
+ controller.state.iteration_flag.current_value,
32
+ )
33
+ except Exception:
34
+ logger.debug('Failed to record memory error boundary', exc_info=True)
35
+ # Late runtime callbacks may fire after the user stopped/finished the
36
+ # agent; do not promote those diagnostics to ERROR. The agent's
37
+ # state stays STOPPED/FINISHED — a transition to ERROR would raise
38
+ # InvalidStateTransitionError and blur the WAL semantics.
39
+ if controller.get_agent_state() in (
40
+ AgentState.STOPPED,
41
+ AgentState.FINISHED,
42
+ ):
43
+ logger.info(
44
+ 'Runtime error callback: skipping agent ERROR transition while state is %s',
45
+ controller.get_agent_state().value,
46
+ )
47
+ else:
48
+ try:
49
+ run_or_schedule(controller.set_agent_state_to(AgentState.ERROR))
50
+ except Exception:
51
+ logger.warning(
52
+ 'Failed to schedule ERROR state transition via run_or_schedule',
53
+ exc_info=True,
54
+ )
55
+ try:
56
+ from backend.utils.async_helpers.async_utils import (
57
+ create_tracked_task,
58
+ )
59
+
60
+ create_tracked_task(
61
+ controller.set_agent_state_to(AgentState.ERROR),
62
+ name='error-state-fallback',
63
+ )
64
+ except Exception:
65
+ logger.error(
66
+ 'All attempts to transition agent to ERROR state failed',
67
+ exc_info=True,
68
+ )
69
+
70
+
71
+ def _create_status_callback(
72
+ controller: SessionOrchestrator,
73
+ ) -> Callable[[str, RuntimeStatus, str], None]:
74
+ """Create the status callback function."""
75
+
76
+ def status_callback(msg_type: str, runtime_status: RuntimeStatus, msg: str) -> None:
77
+ """Handle runtime status updates.
78
+
79
+ Args:
80
+ msg_type: Message type (error, info, etc.)
81
+ runtime_status: Runtime status object
82
+ msg: Status message
83
+
84
+ """
85
+ if msg_type == 'error':
86
+ logger.error(msg)
87
+ _handle_error_status(controller, runtime_status, msg)
88
+ else:
89
+ logger.info(msg)
90
+
91
+ return status_callback
92
+
93
+
94
+ def _validate_status_callbacks(
95
+ runtime: Runtime, controller: SessionOrchestrator
96
+ ) -> None:
97
+ """Validate that status callbacks are not already set."""
98
+ if getattr(runtime, 'status_callback', None):
99
+ logger.debug('Runtime status_callback already set; overriding in run loop')
100
+ if getattr(controller, 'status_callback', None):
101
+ logger.debug('Controller status_callback already set; overriding in run loop')
102
+
103
+
104
+ def _set_status_callbacks(
105
+ runtime: Runtime,
106
+ controller: SessionOrchestrator,
107
+ memory: Memory,
108
+ status_callback: Callable[[str, RuntimeStatus, str], None],
109
+ ) -> None:
110
+ """Set status callbacks on runtime, controller, and memory."""
111
+ runtime.status_callback = status_callback
112
+ controller.status_callback = status_callback
113
+ memory.status_callback = status_callback
114
+
115
+
116
+ def _apply_freeze_credit(
117
+ started: float, slept: float, poll_interval: float, grace: float
118
+ ) -> tuple[float, float]:
119
+ """Credit a detected freeze back to the run deadline (test/helper shim)."""
120
+ overrun = slept - poll_interval
121
+ if overrun > grace:
122
+ return started + overrun, overrun
123
+ return started, 0.0
124
+
125
+
126
+ async def run_agent_until_done(
127
+ controller: SessionOrchestrator,
128
+ runtime: Runtime,
129
+ memory: Memory,
130
+ end_states: list[AgentState],
131
+ ) -> None:
132
+ """run_agent_until_done takes a controller and a runtime, and will run.
133
+
134
+ the agent until it reaches a terminal state.
135
+
136
+ Note that runtime must be connected before being passed in here.
137
+ """
138
+ _validate_status_callbacks(runtime, controller)
139
+
140
+ # Set session ID for working memory scoping — isolates working memory
141
+ # across concurrent/sequential sessions on the same workspace.
142
+ try:
143
+ from backend.context.memory.session_context import bind_session_context
144
+
145
+ session_id = getattr(controller, 'id', None)
146
+ bind_session_context(session_id=session_id)
147
+ except Exception:
148
+ logger.debug('Failed to bind session context', exc_info=True)
149
+
150
+ status_callback = _create_status_callback(controller)
151
+ _set_status_callbacks(runtime, controller, memory, status_callback)
152
+
153
+ # Skip the initial step if the controller is already in an end state or not
154
+ # in a stepping-compatible state (e.g. restored from a crashed session).
155
+ if controller.state.agent_state not in end_states:
156
+ try:
157
+ controller.step()
158
+ except Exception:
159
+ logger.warning('Initial controller.step() failed', exc_info=True)
160
+
161
+ # Wait for the agent to reach an end state. Steps are driven by the
162
+ # event-driven mechanism (observation_service.trigger_step, _on_event ->
163
+ # should_step, etc.) rather than by polling. The initial step() above kicks
164
+ # things off; all subsequent steps are triggered by events.
165
+ #
166
+ # A timeout guard prevents orphaned polling when the event-driven state
167
+ # machine stalls (e.g. due to a provider outage or infinite loop).
168
+ import time as _time
169
+
170
+ from backend.core.constants import (
171
+ DEFAULT_AGENT_RUN_FREEZE_GRACE_SECONDS,
172
+ DEFAULT_AGENT_RUN_HARD_TIMEOUT_SECONDS,
173
+ )
174
+
175
+ _POLL_INTERVAL = 0.5
176
+ _max_poll_seconds = DEFAULT_AGENT_RUN_HARD_TIMEOUT_SECONDS
177
+ _freeze_grace = DEFAULT_AGENT_RUN_FREEZE_GRACE_SECONDS
178
+ deadline = SuspendAwareDeadline(
179
+ _max_poll_seconds,
180
+ poll_interval=_POLL_INTERVAL,
181
+ freeze_grace_seconds=_freeze_grace,
182
+ )
183
+ _ran_loop = False
184
+ try:
185
+ while controller.state.agent_state not in end_states: # noqa: ASYNC110
186
+ _ran_loop = True
187
+ _before_sleep = _time.monotonic()
188
+ await asyncio.sleep(_POLL_INTERVAL)
189
+ _slept = _time.monotonic() - _before_sleep
190
+ _credited = deadline.credit_poll_sleep(_slept)
191
+ if _credited > 0:
192
+ logger.warning(
193
+ 'run_agent_until_done: detected ~%.0fs freeze (poll sleep '
194
+ 'overran by %.0fs) — likely OS suspend or a blocked loop. '
195
+ 'Frozen time credited back to the run budget; not counted '
196
+ 'as an agent hang.',
197
+ _slept,
198
+ _credited,
199
+ extra={
200
+ 'msg_type': 'AGENT_RUN_FREEZE_CREDIT',
201
+ 'frozen_seconds': round(_credited, 1),
202
+ },
203
+ )
204
+ if deadline.expired():
205
+ logger.error(
206
+ 'run_agent_until_done: HARD TIMEOUT after %.0fs in state=%s',
207
+ _max_poll_seconds,
208
+ controller.state.agent_state,
209
+ extra={'msg_type': 'AGENT_HARD_TIMEOUT'},
210
+ )
211
+ try:
212
+ await controller.set_agent_state_to(AgentState.ERROR)
213
+ except Exception:
214
+ pass
215
+ break
216
+ finally:
217
+ deadline.close()
218
+ if _ran_loop:
219
+ # Drain is intentionally omitted here — the TUI gates new messages on
220
+ # _agent_task.done(), and this cleanup delays completion. Background
221
+ # tasks are independently scheduled and don't need this coroutine to
222
+ # wait for them. The TUI's run_tui finally block handles final drain.
223
+ pass