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.
- backend/README.md +83 -0
- backend/README_GRINTA.md +9 -0
- backend/__init__.py +103 -0
- backend/_canonical.py +67 -0
- backend/app/__init__.py +36 -0
- backend/app/agent_control_loop.py +223 -0
- backend/app/main.py +707 -0
- backend/app/setup.py +573 -0
- backend/cli/__init__.py +8 -0
- backend/cli/_typing.py +115 -0
- backend/cli/display/__init__.py +1 -0
- backend/cli/display/diff_renderer.py +437 -0
- backend/cli/display/hud.py +680 -0
- backend/cli/display/layout_tokens.py +98 -0
- backend/cli/display/notifications.py +137 -0
- backend/cli/display/path_links.py +114 -0
- backend/cli/display/reasoning_display.py +379 -0
- backend/cli/display/status_chrome.py +643 -0
- backend/cli/display/text_truncation.py +86 -0
- backend/cli/display/tool_call_display.py +68 -0
- backend/cli/display/transcript.py +454 -0
- backend/cli/doctor/__init__.py +5 -0
- backend/cli/doctor/checks.py +561 -0
- backend/cli/doctor/doctor_cli.py +129 -0
- backend/cli/entry.py +420 -0
- backend/cli/event_renderer.py +244 -0
- backend/cli/event_rendering/__init__.py +9 -0
- backend/cli/event_rendering/actions/__init__.py +30 -0
- backend/cli/event_rendering/actions/browser.py +78 -0
- backend/cli/event_rendering/actions/dispatch.py +223 -0
- backend/cli/event_rendering/actions/exploration.py +53 -0
- backend/cli/event_rendering/actions/file.py +88 -0
- backend/cli/event_rendering/actions/mcp.py +62 -0
- backend/cli/event_rendering/actions/message.py +219 -0
- backend/cli/event_rendering/actions/meta.py +71 -0
- backend/cli/event_rendering/actions/shell.py +66 -0
- backend/cli/event_rendering/actions/terminal.py +134 -0
- backend/cli/event_rendering/activity_mixin.py +253 -0
- backend/cli/event_rendering/constants.py +169 -0
- backend/cli/event_rendering/delegate.py +312 -0
- backend/cli/event_rendering/error_categories/__init__.py +132 -0
- backend/cli/event_rendering/error_categories/auth_errors.py +55 -0
- backend/cli/event_rendering/error_categories/browser_errors.py +36 -0
- backend/cli/event_rendering/error_categories/matchers.py +76 -0
- backend/cli/event_rendering/error_categories/model_errors.py +61 -0
- backend/cli/event_rendering/error_categories/network_errors.py +40 -0
- backend/cli/event_rendering/error_categories/rate_limit_errors.py +59 -0
- backend/cli/event_rendering/error_categories/system_errors.py +189 -0
- backend/cli/event_rendering/error_categories/timeout_errors.py +59 -0
- backend/cli/event_rendering/error_panel.py +497 -0
- backend/cli/event_rendering/live_mixin.py +219 -0
- backend/cli/event_rendering/messages_mixin.py +283 -0
- backend/cli/event_rendering/observations/__init__.py +32 -0
- backend/cli/event_rendering/observations/dispatch.py +112 -0
- backend/cli/event_rendering/observations/error.py +118 -0
- backend/cli/event_rendering/observations/exploration.py +246 -0
- backend/cli/event_rendering/observations/file.py +68 -0
- backend/cli/event_rendering/observations/mcp.py +100 -0
- backend/cli/event_rendering/observations/misc.py +141 -0
- backend/cli/event_rendering/observations/shell.py +160 -0
- backend/cli/event_rendering/observations/shell_helpers.py +69 -0
- backend/cli/event_rendering/observations/status.py +247 -0
- backend/cli/event_rendering/observations/terminal.py +100 -0
- backend/cli/event_rendering/observations/think_browser.py +42 -0
- backend/cli/event_rendering/panels.py +385 -0
- backend/cli/event_rendering/panels_mixin.py +171 -0
- backend/cli/event_rendering/renderer_constants.py +28 -0
- backend/cli/event_rendering/sidebar.py +263 -0
- backend/cli/event_rendering/state_mixin.py +183 -0
- backend/cli/event_rendering/streaming_mixin.py +295 -0
- backend/cli/event_rendering/subscription_mixin.py +121 -0
- backend/cli/event_rendering/text_utils.py +287 -0
- backend/cli/event_rendering/unified_renderer/__init__.py +18 -0
- backend/cli/event_rendering/unified_renderer/mixins/__init__.py +1 -0
- backend/cli/event_rendering/unified_renderer/mixins/browser.py +72 -0
- backend/cli/event_rendering/unified_renderer/mixins/code.py +44 -0
- backend/cli/event_rendering/unified_renderer/mixins/delegate.py +56 -0
- backend/cli/event_rendering/unified_renderer/mixins/exploration.py +257 -0
- backend/cli/event_rendering/unified_renderer/mixins/file.py +108 -0
- backend/cli/event_rendering/unified_renderer/mixins/mcp.py +298 -0
- backend/cli/event_rendering/unified_renderer/mixins/shell.py +225 -0
- backend/cli/event_rendering/unified_renderer/mixins/status.py +72 -0
- backend/cli/event_rendering/unified_renderer/mixins/terminal.py +131 -0
- backend/cli/event_rendering/unified_renderer/renderer.py +29 -0
- backend/cli/event_rendering/unified_renderer/types.py +85 -0
- backend/cli/event_rendering/unified_renderer/utils.py +119 -0
- backend/cli/main.py +661 -0
- backend/cli/onboarding/__init__.py +19 -0
- backend/cli/onboarding/connection_check.py +125 -0
- backend/cli/onboarding/flow.py +304 -0
- backend/cli/onboarding/init_noninteractive.py +192 -0
- backend/cli/onboarding/init_wizard.py +633 -0
- backend/cli/onboarding/menu_prompts.py +77 -0
- backend/cli/onboarding/provider_presets.py +69 -0
- backend/cli/onboarding/settings_defaults.py +81 -0
- backend/cli/repl/__init__.py +12 -0
- backend/cli/repl/debug.py +11 -0
- backend/cli/repl/noninteractive.py +296 -0
- backend/cli/repl/run_helpers_dispatch.py +457 -0
- backend/cli/repl/slash_command_actions.py +450 -0
- backend/cli/repl/slash_command_checkpoint.py +191 -0
- backend/cli/repl/slash_command_diff.py +234 -0
- backend/cli/repl/slash_command_dispatch.py +128 -0
- backend/cli/repl/slash_command_registry.py +40 -0
- backend/cli/repl/slash_command_status.py +447 -0
- backend/cli/repl/slash_commands_mixin.py +339 -0
- backend/cli/repl/slash_registry_clipboard.py +53 -0
- backend/cli/repl/slash_registry_commands.py +350 -0
- backend/cli/repl/slash_registry_help.py +269 -0
- backend/cli/repl/slash_registry_models.py +36 -0
- backend/cli/repl/slash_registry_parsing.py +81 -0
- backend/cli/repl/slash_registry_prompt.py +188 -0
- backend/cli/repl/slash_registry_terminal.py +66 -0
- backend/cli/session/__init__.py +1 -0
- backend/cli/session/session_manager.py +697 -0
- backend/cli/session/sessions_cli.py +383 -0
- backend/cli/session/storage_cleanup.py +327 -0
- backend/cli/settings/__init__.py +93 -0
- backend/cli/settings/bootstrap_sync.py +39 -0
- backend/cli/settings/confirmation.py +248 -0
- backend/cli/settings/constants.py +52 -0
- backend/cli/settings/mcp.py +213 -0
- backend/cli/settings/mode_runtime.py +109 -0
- backend/cli/settings/query.py +535 -0
- backend/cli/settings/settings_tui.py +455 -0
- backend/cli/settings/storage.py +158 -0
- backend/cli/terminal_mouse.py +25 -0
- backend/cli/terminal_restore.py +183 -0
- backend/cli/terminal_sanitize.py +94 -0
- backend/cli/theme/__init__.py +470 -0
- backend/cli/theme/cards.py +82 -0
- backend/cli/theme/env.py +75 -0
- backend/cli/theme/navy.py +112 -0
- backend/cli/theme/presets.py +245 -0
- backend/cli/theme/spacing.py +31 -0
- backend/cli/theme/styles.py +148 -0
- backend/cli/theme/syntax_theme.py +268 -0
- backend/cli/theme/tokens.py +167 -0
- backend/cli/tool_display/__init__.py +5 -0
- backend/cli/tool_display/constants.py +115 -0
- backend/cli/tool_display/headline.py +209 -0
- backend/cli/tool_display/orient_tools.py +758 -0
- backend/cli/tool_display/preview.py +615 -0
- backend/cli/tool_display/redact.py +570 -0
- backend/cli/tool_display/renderers/__init__.py +89 -0
- backend/cli/tool_display/renderers/_syntax.py +41 -0
- backend/cli/tool_display/renderers/badge.py +110 -0
- backend/cli/tool_display/renderers/browser.py +68 -0
- backend/cli/tool_display/renderers/delegation.py +72 -0
- backend/cli/tool_display/renderers/file_editor.py +183 -0
- backend/cli/tool_display/renderers/lsp.py +41 -0
- backend/cli/tool_display/renderers/mcp.py +241 -0
- backend/cli/tool_display/renderers/memory.py +48 -0
- backend/cli/tool_display/renderers/output_parsers.py +447 -0
- backend/cli/tool_display/renderers/search.py +232 -0
- backend/cli/tool_display/renderers/shell.py +249 -0
- backend/cli/tool_display/renderers/tasks.py +98 -0
- backend/cli/tool_display/renderers/terminal.py +256 -0
- backend/cli/tool_display/renderers/think.py +105 -0
- backend/cli/tool_display/summarize.py +610 -0
- backend/cli/tui/__init__.py +1 -0
- backend/cli/tui/_a11y.py +45 -0
- backend/cli/tui/app.py +426 -0
- backend/cli/tui/constants.py +126 -0
- backend/cli/tui/dialogs/__init__.py +27 -0
- backend/cli/tui/dialogs/add_mcp.py +87 -0
- backend/cli/tui/dialogs/add_skill.py +115 -0
- backend/cli/tui/dialogs/confirm.py +251 -0
- backend/cli/tui/dialogs/help.py +63 -0
- backend/cli/tui/dialogs/manage_mcp.py +308 -0
- backend/cli/tui/dialogs/manage_skills.py +206 -0
- backend/cli/tui/dialogs/sessions.py +421 -0
- backend/cli/tui/dialogs/settings.py +562 -0
- backend/cli/tui/helpers.py +354 -0
- backend/cli/tui/image_attachments.py +323 -0
- backend/cli/tui/image_input_gate.py +35 -0
- backend/cli/tui/main.py +203 -0
- backend/cli/tui/renderer/README.md +44 -0
- backend/cli/tui/renderer/__init__.py +7 -0
- backend/cli/tui/renderer/classify.py +64 -0
- backend/cli/tui/renderer/diff.py +194 -0
- backend/cli/tui/renderer/drain.py +821 -0
- backend/cli/tui/renderer/event_helpers.py +65 -0
- backend/cli/tui/renderer/handlers/__init__.py +1 -0
- backend/cli/tui/renderer/handlers/acceptance_criteria.py +85 -0
- backend/cli/tui/renderer/handlers/browser.py +70 -0
- backend/cli/tui/renderer/handlers/compaction.py +88 -0
- backend/cli/tui/renderer/handlers/debugger.py +25 -0
- backend/cli/tui/renderer/handlers/delegate.py +122 -0
- backend/cli/tui/renderer/handlers/exploration.py +203 -0
- backend/cli/tui/renderer/handlers/fallback.py +81 -0
- backend/cli/tui/renderer/handlers/file.py +384 -0
- backend/cli/tui/renderer/handlers/mcp.py +92 -0
- backend/cli/tui/renderer/handlers/memory.py +133 -0
- backend/cli/tui/renderer/handlers/shell.py +58 -0
- backend/cli/tui/renderer/handlers/status.py +379 -0
- backend/cli/tui/renderer/handlers/task_state.py +33 -0
- backend/cli/tui/renderer/handlers/task_tracking.py +71 -0
- backend/cli/tui/renderer/handlers/terminal.py +142 -0
- backend/cli/tui/renderer/handlers/thinking.py +55 -0
- backend/cli/tui/renderer/helpers/__init__.py +1 -0
- backend/cli/tui/renderer/helpers/browser.py +39 -0
- backend/cli/tui/renderer/helpers/delegate.py +29 -0
- backend/cli/tui/renderer/helpers/exploration.py +115 -0
- backend/cli/tui/renderer/helpers/file.py +79 -0
- backend/cli/tui/renderer/helpers/mcp.py +21 -0
- backend/cli/tui/renderer/helpers/shell.py +37 -0
- backend/cli/tui/renderer/helpers/status.py +17 -0
- backend/cli/tui/renderer/helpers/terminal.py +22 -0
- backend/cli/tui/renderer/mixins/__init__.py +6 -0
- backend/cli/tui/renderer/mixins/action_handlers.py +435 -0
- backend/cli/tui/renderer/mixins/debugger.py +126 -0
- backend/cli/tui/renderer/mixins/display.py +864 -0
- backend/cli/tui/renderer/mixins/event_processor.py +109 -0
- backend/cli/tui/renderer/mixins/live.py +315 -0
- backend/cli/tui/renderer/mixins/terminal.py +362 -0
- backend/cli/tui/renderer/mixins/thinking.py +420 -0
- backend/cli/tui/renderer/prep.py +396 -0
- backend/cli/tui/renderer/processor.py +497 -0
- backend/cli/tui/renderer/step_draft.py +87 -0
- backend/cli/tui/screen/__init__.py +21 -0
- backend/cli/tui/screen/actions.py +214 -0
- backend/cli/tui/screen/communicate.py +185 -0
- backend/cli/tui/screen/input.py +780 -0
- backend/cli/tui/screen/lifecycle.py +454 -0
- backend/cli/tui/screen/lifecycle_bootstrap.py +360 -0
- backend/cli/tui/screen/lifecycle_dispatch.py +331 -0
- backend/cli/tui/screen/messages.py +452 -0
- backend/cli/tui/screen/settings.py +544 -0
- backend/cli/tui/screen/slash.py +203 -0
- backend/cli/tui/screen/state.py +825 -0
- backend/cli/tui/screen/welcome.py +99 -0
- backend/cli/tui/screens/detail/__init__.py +39 -0
- backend/cli/tui/screens/detail/acceptance_criteria.py +114 -0
- backend/cli/tui/screens/detail/base.py +283 -0
- backend/cli/tui/screens/detail/browser.py +83 -0
- backend/cli/tui/screens/detail/debugger.py +66 -0
- backend/cli/tui/screens/detail/edit.py +105 -0
- backend/cli/tui/screens/detail/helpers.py +250 -0
- backend/cli/tui/screens/detail/message.py +34 -0
- backend/cli/tui/screens/detail/payload.py +106 -0
- backend/cli/tui/screens/detail/shell.py +60 -0
- backend/cli/tui/screens/detail/terminal.py +64 -0
- backend/cli/tui/services/__init__.py +1 -0
- backend/cli/tui/services/mcp_reload_adapter.py +193 -0
- backend/cli/tui/services/settings_watcher.py +238 -0
- backend/cli/tui/strings.py +80 -0
- backend/cli/tui/styles.tcss +1141 -0
- backend/cli/tui/transcript_tiers.py +57 -0
- backend/cli/tui/transcript_typography.py +76 -0
- backend/cli/tui/widgets/__init__.py +1 -0
- backend/cli/tui/widgets/activity_card/__init__.py +23 -0
- backend/cli/tui/widgets/activity_card/message_widgets.py +320 -0
- backend/cli/tui/widgets/activity_card/orient.py +103 -0
- backend/cli/tui/widgets/collapsible.py +811 -0
- backend/cli/tui/widgets/command_list.py +270 -0
- backend/cli/tui/widgets/detail_terminal_frame.py +73 -0
- backend/cli/tui/widgets/dialogs.py +75 -0
- backend/cli/tui/widgets/error_block.py +61 -0
- backend/cli/tui/widgets/glyphs.py +94 -0
- backend/cli/tui/widgets/prompt_text_area.py +207 -0
- backend/cli/tui/widgets/scan_line/__init__.py +50 -0
- backend/cli/tui/widgets/scan_line/card.py +265 -0
- backend/cli/tui/widgets/scan_line/cards.py +946 -0
- backend/cli/tui/widgets/small.py +688 -0
- backend/cli/tui/widgets/transcript_notice.py +28 -0
- backend/cli/tui/widgets/unified_diff_view.py +644 -0
- backend/cli/tui/widgets/welcome.py +263 -0
- backend/cli/win32_console.py +166 -0
- backend/cli/workspace_trust_prompt.py +124 -0
- backend/context/README.md +20 -0
- backend/context/__init__.py +26 -0
- backend/context/canonical_state/__init__.py +159 -0
- backend/context/canonical_state/ops.py +654 -0
- backend/context/canonical_state/private.py +715 -0
- backend/context/canonical_state/types.py +379 -0
- backend/context/coding_preflight.py +224 -0
- backend/context/compactor/__init__.py +61 -0
- backend/context/compactor/compact_boundary.py +77 -0
- backend/context/compactor/compaction_finalizer.py +31 -0
- backend/context/compactor/compactor.py +649 -0
- backend/context/compactor/condensed_history.py +19 -0
- backend/context/compactor/microcompact.py +162 -0
- backend/context/compactor/pre_condensation_snapshot.py +1250 -0
- backend/context/compactor/strategies/__init__.py +31 -0
- backend/context/compactor/strategies/composition_pipeline.py +160 -0
- backend/context/compactor/strategies/layers/__init__.py +213 -0
- backend/context/compactor/strategies/microcompact_compactor.py +156 -0
- backend/context/compactor/strategies/no_op_compactor.py +50 -0
- backend/context/compactor/strategies/observation_masking_compactor.py +99 -0
- backend/context/compactor/strategies/pipeline.py +107 -0
- backend/context/compactor/strategies/recent_events_compactor.py +92 -0
- backend/context/compactor/strategies/smart_compactor.py +573 -0
- backend/context/compactor/strategies/structured_summary_compactor.py +887 -0
- backend/context/context_budget.py +112 -0
- backend/context/context_explorer.py +397 -0
- backend/context/context_pipeline/__init__.py +38 -0
- backend/context/context_pipeline/compaction.py +508 -0
- backend/context/context_pipeline/goal_context.py +117 -0
- backend/context/context_pipeline/grouping.py +73 -0
- backend/context/context_pipeline/helpers.py +68 -0
- backend/context/context_pipeline/pipeline.py +659 -0
- backend/context/context_pipeline/post_compact_reinject.py +32 -0
- backend/context/context_pipeline/types.py +22 -0
- backend/context/context_tracking.py +187 -0
- backend/context/continuity_eval.py +238 -0
- backend/context/memory/__init__.py +1 -0
- backend/context/memory/agent_memory.py +721 -0
- backend/context/memory/conversation_memory.py +1270 -0
- backend/context/memory/project_memory.py +360 -0
- backend/context/memory/session_context.py +112 -0
- backend/context/memory/session_memory.py +401 -0
- backend/context/memory/types.py +112 -0
- backend/context/memory/working_set.py +529 -0
- backend/context/processors/__init__.py +1 -0
- backend/context/processors/action_processors.py +500 -0
- backend/context/processors/observation_processors.py +744 -0
- backend/context/prompt/__init__.py +1 -0
- backend/context/prompt/compact_snapshot.py +50 -0
- backend/context/prompt/context_packet.py +599 -0
- backend/context/prompt/context_packet_cache.py +233 -0
- backend/context/prompt/message_formatting.py +151 -0
- backend/context/prompt/prompt_assembly.py +281 -0
- backend/context/prompt/prompt_window.py +1393 -0
- backend/context/prompt/turn_context.py +102 -0
- backend/context/prompt/user_turns.py +99 -0
- backend/context/render/__init__.py +23 -0
- backend/context/render/execution_contract.py +234 -0
- backend/context/render/task_context.py +144 -0
- backend/context/symbol_index/__init__.py +23 -0
- backend/context/symbol_index/aps_bridge.py +89 -0
- backend/context/symbol_index/builder.py +220 -0
- backend/context/symbol_index/imports.py +10 -0
- backend/context/symbol_index/paths.py +16 -0
- backend/context/symbol_index/query.py +36 -0
- backend/context/symbol_index/rank.py +114 -0
- backend/context/symbol_index/repo_map.py +126 -0
- backend/context/symbol_index/store.py +404 -0
- backend/context/tool_call_tracker.py +134 -0
- backend/context/tool_result_storage.py +278 -0
- backend/context/vector_store/__init__.py +35 -0
- backend/context/vector_store/_local_vector_store.py +971 -0
- backend/context/vector_store/_vector_store.py +813 -0
- backend/context/view.py +179 -0
- backend/core/__init__.py +5 -0
- backend/core/app_paths.py +54 -0
- backend/core/autonomy.py +75 -0
- backend/core/bounded_result.py +16 -0
- backend/core/cache/__init__.py +5 -0
- backend/core/cache/_serializer.py +55 -0
- backend/core/cache/async_smart_cache.py +156 -0
- backend/core/cache/cache_utils.py +26 -0
- backend/core/cache/smart_config_cache.py +147 -0
- backend/core/config/README.md +95 -0
- backend/core/config/__init__.py +57 -0
- backend/core/config/agent_config.py +693 -0
- backend/core/config/api_key_manager.py +496 -0
- backend/core/config/app_config.py +342 -0
- backend/core/config/arg_utils.py +91 -0
- backend/core/config/cli_config.py +131 -0
- backend/core/config/compactor_config.py +353 -0
- backend/core/config/config_loader.py +831 -0
- backend/core/config/config_telemetry.py +44 -0
- backend/core/config/config_utils.py +62 -0
- backend/core/config/dotenv_keys.py +150 -0
- backend/core/config/env_loader.py +188 -0
- backend/core/config/extended_config.py +53 -0
- backend/core/config/llm_config.py +506 -0
- backend/core/config/mcp_config.py +546 -0
- backend/core/config/mcp_defaults.py +64 -0
- backend/core/config/model_rebuild.py +83 -0
- backend/core/config/permissions_config.py +374 -0
- backend/core/config/provider_config.py +311 -0
- backend/core/config/quickstart.py +132 -0
- backend/core/config/runtime_config.py +57 -0
- backend/core/config/security_config.py +163 -0
- backend/core/config/tool_integration_defaults.py +31 -0
- backend/core/constants.py +730 -0
- backend/core/content_escape_repair.py +442 -0
- backend/core/contracts/__init__.py +10 -0
- backend/core/contracts/plugins.py +67 -0
- backend/core/criteria/__init__.py +23 -0
- backend/core/criteria/acceptance_criteria_store.py +190 -0
- backend/core/criteria/criterion_item.py +136 -0
- backend/core/enums.py +285 -0
- backend/core/errors/__init__.py +471 -0
- backend/core/errors/structured_edit_errors.py +450 -0
- backend/core/external_service.py +122 -0
- backend/core/file_history.py +72 -0
- backend/core/interaction_modes.py +152 -0
- backend/core/io_adapters/__init__.py +13 -0
- backend/core/io_adapters/cli_input.py +35 -0
- backend/core/io_adapters/json.py +109 -0
- backend/core/json_compat.py +129 -0
- backend/core/json_stdout.py +52 -0
- backend/core/logging/__init__.py +0 -0
- backend/core/logging/log_formatters.py +294 -0
- backend/core/logging/log_shipping.py +320 -0
- backend/core/logging/logger.py +719 -0
- backend/core/logging/session_context.py +158 -0
- backend/core/logging/session_event_logger.py +439 -0
- backend/core/logging/session_log_audit.py +434 -0
- backend/core/logging/session_log_renderer.py +104 -0
- backend/core/message.py +280 -0
- backend/core/os_capabilities.py +182 -0
- backend/core/plugin.py +534 -0
- backend/core/prompt_role_debug.py +82 -0
- backend/core/providers/__init__.py +9 -0
- backend/core/providers/configurations.py +565 -0
- backend/core/providers/provider_handler.py +129 -0
- backend/core/providers/provider_models.py +211 -0
- backend/core/runtime_paths.py +61 -0
- backend/core/schemas/__init__.py +128 -0
- backend/core/schemas/actions.py +562 -0
- backend/core/schemas/base.py +82 -0
- backend/core/schemas/metadata.py +91 -0
- backend/core/schemas/observations.py +148 -0
- backend/core/schemas/retry.py +23 -0
- backend/core/schemas/serialization.py +236 -0
- backend/core/step_phase.py +33 -0
- backend/core/task_tracker.py +5 -0
- backend/core/tasks/__init__.py +5 -0
- backend/core/tasks/plan_step.py +90 -0
- backend/core/tasks/task_status.py +63 -0
- backend/core/tasks/task_tracker.py +189 -0
- backend/core/timeouts/__init__.py +0 -0
- backend/core/timeouts/llm_step_timeout.py +38 -0
- backend/core/timeouts/loop_watchdog.py +298 -0
- backend/core/timeouts/suspend_aware_deadline.py +90 -0
- backend/core/timeouts/timeout_policy.py +82 -0
- backend/core/tools/__init__.py +1 -0
- backend/core/tools/tool_arguments_json.py +80 -0
- backend/core/tools/tool_names.py +82 -0
- backend/core/tools/tool_transport.py +40 -0
- backend/core/tracing.py +317 -0
- backend/core/type_safety/__init__.py +51 -0
- backend/core/type_safety/path_validation.py +699 -0
- backend/core/type_safety/sentinels.py +163 -0
- backend/core/type_safety/type_safety.py +203 -0
- backend/core/workspace_resolution.py +355 -0
- backend/core/workspace_trust.py +91 -0
- backend/core/wsl.py +171 -0
- backend/engine/README.md +16 -0
- backend/engine/__init__.py +24 -0
- backend/engine/contracts.py +175 -0
- backend/engine/executor.py +352 -0
- backend/engine/executor_mixins/__init__.py +29 -0
- backend/engine/executor_mixins/_executor_lifecycle_mixin.py +410 -0
- backend/engine/executor_mixins/_executor_response_mixin.py +147 -0
- backend/engine/executor_mixins/_executor_streaming_mixin.py +1129 -0
- backend/engine/executor_mixins/_executor_types.py +90 -0
- backend/engine/executor_response_helpers.py +230 -0
- backend/engine/file_reads.py +97 -0
- backend/engine/function_calling/__init__.py +1 -0
- backend/engine/function_calling/dispatch.py +331 -0
- backend/engine/function_calling/helpers.py +97 -0
- backend/engine/llm_message_serializer.py +97 -0
- backend/engine/memory_manager.py +482 -0
- backend/engine/memory_prompt_cache.py +57 -0
- backend/engine/orchestrator.py +460 -0
- backend/engine/orchestrator_helpers/__init__.py +22 -0
- backend/engine/orchestrator_helpers/actions.py +85 -0
- backend/engine/orchestrator_helpers/condensation.py +102 -0
- backend/engine/orchestrator_helpers/helpers.py +91 -0
- backend/engine/orchestrator_helpers/prompts.py +181 -0
- backend/engine/orchestrator_helpers/protocol.py +95 -0
- backend/engine/orchestrator_helpers/recovery.py +99 -0
- backend/engine/orchestrator_helpers/step.py +522 -0
- backend/engine/planner.py +1101 -0
- backend/engine/prompts/prompt_builder.py +915 -0
- backend/engine/prompts/section_renderers/__init__.py +101 -0
- backend/engine/prompts/section_renderers/_autonomy.py +242 -0
- backend/engine/prompts/section_renderers/_capabilities.py +337 -0
- backend/engine/prompts/section_renderers/_common.py +59 -0
- backend/engine/prompts/section_renderers/_critical.py +209 -0
- backend/engine/prompts/section_renderers/_env_hints.py +214 -0
- backend/engine/prompts/section_renderers/_examples.py +124 -0
- backend/engine/prompts/section_renderers/_interaction.py +44 -0
- backend/engine/prompts/section_renderers/_mcp.py +105 -0
- backend/engine/prompts/section_renderers/_permissions.py +74 -0
- backend/engine/prompts/section_renderers/_routing.py +110 -0
- backend/engine/prompts/section_renderers/_security.py +54 -0
- backend/engine/prompts/section_renderers/_tools.py +108 -0
- backend/engine/prompts/system_partial_00_routing.md +42 -0
- backend/engine/prompts/system_partial_01_autonomy.md +44 -0
- backend/engine/prompts/system_partial_02_tools.md +3 -0
- backend/engine/prompts/system_partial_03_tail.md +23 -0
- backend/engine/prompts/system_partial_04_critical.md +14 -0
- backend/engine/prompts/system_partial_05_examples.md +10 -0
- backend/engine/reflection.py +113 -0
- backend/engine/response_processing.py +860 -0
- backend/engine/streaming_checkpoint.py +314 -0
- backend/engine/tool_registry.py +82 -0
- backend/engine/tools/__init__.py +55 -0
- backend/engine/tools/_aps_callers_coverage.py +154 -0
- backend/engine/tools/_aps_dependencies.py +257 -0
- backend/engine/tools/_aps_file_modes.py +286 -0
- backend/engine/tools/_aps_shared.py +135 -0
- backend/engine/tools/_aps_tree.py +295 -0
- backend/engine/tools/_file_edits.py +70 -0
- backend/engine/tools/_file_edits_common.py +45 -0
- backend/engine/tools/_file_edits_handlers.py +147 -0
- backend/engine/tools/_file_edits_multi.py +425 -0
- backend/engine/tools/_file_edits_symbols.py +135 -0
- backend/engine/tools/_file_ops.py +405 -0
- backend/engine/tools/_search_helpers.py +587 -0
- backend/engine/tools/_tool_handlers.py +880 -0
- backend/engine/tools/acceptance_criteria.py +119 -0
- backend/engine/tools/analyze_project_structure.py +223 -0
- backend/engine/tools/atomic_refactor.py +694 -0
- backend/engine/tools/blackboard.py +53 -0
- backend/engine/tools/browser_native.py +255 -0
- backend/engine/tools/checkpoint.py +538 -0
- backend/engine/tools/debugger.py +327 -0
- backend/engine/tools/delegate_task.py +131 -0
- backend/engine/tools/docs_tools.py +129 -0
- backend/engine/tools/execute_mcp_tool.py +104 -0
- backend/engine/tools/glob.py +179 -0
- backend/engine/tools/grep.py +358 -0
- backend/engine/tools/health_check.py +188 -0
- backend/engine/tools/ignore_filter.py +83 -0
- backend/engine/tools/lesson_store.py +141 -0
- backend/engine/tools/lsp_query.py +151 -0
- backend/engine/tools/memory.py +141 -0
- backend/engine/tools/meta_cognition.py +59 -0
- backend/engine/tools/native_file_tools.py +179 -0
- backend/engine/tools/param_defs.py +197 -0
- backend/engine/tools/scratchpad.py +237 -0
- backend/engine/tools/semantic_analyzer.py +86 -0
- backend/engine/tools/session_lessons.py +264 -0
- backend/engine/tools/smart_errors.py +240 -0
- backend/engine/tools/structure_editor.py +986 -0
- backend/engine/tools/task_state.py +92 -0
- backend/engine/tools/task_tracker.py +115 -0
- backend/engine/tools/terminal.py +180 -0
- backend/engine/tools/treesitter_editor.py +19 -0
- backend/engine/tools/web_tools.py +218 -0
- backend/engine/tools/whitespace_handler.py +575 -0
- backend/engine/tools/working_memory.py +475 -0
- backend/engine/tools/workspace_memory.py +293 -0
- backend/execution/README.md +86 -0
- backend/execution/__init__.py +69 -0
- backend/execution/acceptance_criteria.py +299 -0
- backend/execution/aes/__init__.py +1 -0
- backend/execution/aes/file_operations.py +1264 -0
- backend/execution/aes/helpers.py +1314 -0
- backend/execution/aes/policy_block_messages.py +53 -0
- backend/execution/aes/security_enforcement.py +688 -0
- backend/execution/browser/__init__.py +5 -0
- backend/execution/browser/_browser_cdp.py +47 -0
- backend/execution/browser/_browser_interaction.py +512 -0
- backend/execution/browser/_browser_navigation.py +220 -0
- backend/execution/browser/_browser_shared.py +75 -0
- backend/execution/browser/_browser_snapshot.py +254 -0
- backend/execution/browser/grinta_browser.py +361 -0
- backend/execution/capabilities.py +125 -0
- backend/execution/dap/__init__.py +47 -0
- backend/execution/dap/_dap_adapters.py +376 -0
- backend/execution/dap/_dap_client.py +479 -0
- backend/execution/dap/_dap_errors.py +25 -0
- backend/execution/dap/_dap_logging.py +52 -0
- backend/execution/dap/_dap_manager.py +436 -0
- backend/execution/dap/_dap_session.py +650 -0
- backend/execution/dap/_dap_spawn_utils.py +197 -0
- backend/execution/dap/dap_aliases.py +23 -0
- backend/execution/document_readers.py +64 -0
- backend/execution/drivers/__init__.py +31 -0
- backend/execution/drivers/local/__init__.py +7 -0
- backend/execution/drivers/local/local_runtime_inprocess.py +941 -0
- backend/execution/executor_protocol.py +149 -0
- backend/execution/io_mixins/__init__.py +36 -0
- backend/execution/io_mixins/_aes_io_file_mixin.py +165 -0
- backend/execution/io_mixins/_aes_io_init_mixin.py +100 -0
- backend/execution/io_mixins/_aes_io_run_mixin.py +307 -0
- backend/execution/io_mixins/_aes_io_terminal_mixin.py +1039 -0
- backend/execution/io_mixins/_aes_io_workspace_mixin.py +112 -0
- backend/execution/mcp/config.json +22 -0
- backend/execution/playbook_loader.py +298 -0
- backend/execution/plugin_loader.py +28 -0
- backend/execution/plugins/__init__.py +136 -0
- backend/execution/plugins/agent_skills/README.md +38 -0
- backend/execution/plugins/agent_skills/__init__.py +31 -0
- backend/execution/plugins/agent_skills/agentskills.py +48 -0
- backend/execution/plugins/agent_skills/database/__init__.py +545 -0
- backend/execution/plugins/agent_skills/file_editor/README.md +3 -0
- backend/execution/plugins/agent_skills/file_editor/__init__.py +20 -0
- backend/execution/plugins/agent_skills/file_ops/__init__.py +23 -0
- backend/execution/plugins/agent_skills/file_ops/file_ops.py +512 -0
- backend/execution/plugins/agent_skills/file_reader/__init__.py +23 -0
- backend/execution/plugins/agent_skills/file_reader/file_readers.py +213 -0
- backend/execution/plugins/agent_skills/repo_ops/__init__.py +14 -0
- backend/execution/plugins/agent_skills/utils/config.py +109 -0
- backend/execution/plugins/agent_skills/utils/dependency.py +25 -0
- backend/execution/rollback/__init__.py +21 -0
- backend/execution/rollback/rollback_manager.py +632 -0
- backend/execution/rollback/shadow_repo.py +508 -0
- backend/execution/rollback/workspace_checkpoint.py +360 -0
- backend/execution/runtime/__init__.py +1 -0
- backend/execution/runtime/factory.py +41 -0
- backend/execution/runtime/orchestrator.py +247 -0
- backend/execution/runtime/pool.py +208 -0
- backend/execution/runtime_mixins/__init__.py +0 -0
- backend/execution/runtime_mixins/command_timeout.py +54 -0
- backend/execution/runtime_mixins/editor_only_shell_policy.py +163 -0
- backend/execution/runtime_mixins/env_manager.py +132 -0
- backend/execution/runtime_mixins/git_setup.py +354 -0
- backend/execution/sandbox_helpers/__init__.py +1 -0
- backend/execution/sandbox_helpers/appcontainer_runner.py +427 -0
- backend/execution/sandboxing.py +236 -0
- backend/execution/server/__init__.py +0 -0
- backend/execution/server/action_execution_server.py +503 -0
- backend/execution/server/action_execution_server_io.py +30 -0
- backend/execution/server/base.py +1098 -0
- backend/execution/server/supervisor.py +128 -0
- backend/execution/task_state.py +22 -0
- backend/execution/task_tracking.py +238 -0
- backend/execution/telemetry.py +76 -0
- backend/execution/utils/__init__.py +8 -0
- backend/execution/utils/fallbacks/__init__.py +6 -0
- backend/execution/utils/fallbacks/file_ops.py +193 -0
- backend/execution/utils/fallbacks/search.py +164 -0
- backend/execution/utils/file_editor/__init__.py +360 -0
- backend/execution/utils/file_editor/_file_editor_diff_helpers.py +136 -0
- backend/execution/utils/file_editor/_file_editor_edit_helpers.py +690 -0
- backend/execution/utils/file_editor/_file_editor_io_helpers.py +107 -0
- backend/execution/utils/file_editor/_file_editor_read_write_helpers.py +213 -0
- backend/execution/utils/file_editor/_file_editor_types.py +24 -0
- backend/execution/utils/file_editor/file_editor_edit_mixin.py +269 -0
- backend/execution/utils/file_editor/file_editor_edit_ops.py +160 -0
- backend/execution/utils/file_editor/file_editor_ops_mixin.py +295 -0
- backend/execution/utils/file_editor/file_editor_rollback_mixin.py +230 -0
- backend/execution/utils/file_editor/file_editor_view_mixin.py +218 -0
- backend/execution/utils/files/__init__.py +0 -0
- backend/execution/utils/files/bounded_io.py +369 -0
- backend/execution/utils/files/diff.py +173 -0
- backend/execution/utils/files/file_transaction.py +390 -0
- backend/execution/utils/files/file_viewer.py +60 -0
- backend/execution/utils/files/files.py +224 -0
- backend/execution/utils/git/__init__.py +1 -0
- backend/execution/utils/git/git_changes.py +119 -0
- backend/execution/utils/git/git_common.py +124 -0
- backend/execution/utils/git/git_diff.py +111 -0
- backend/execution/utils/git/git_handler.py +134 -0
- backend/execution/utils/log_capture.py +39 -0
- backend/execution/utils/mcp_runtime.py +243 -0
- backend/execution/utils/memory_monitor.py +85 -0
- backend/execution/utils/process/__init__.py +0 -0
- backend/execution/utils/process/process_manager.py +392 -0
- backend/execution/utils/process/process_registry.py +265 -0
- backend/execution/utils/process/server_detector.py +265 -0
- backend/execution/utils/shell/__init__.py +1 -0
- backend/execution/utils/shell/_bash_command.py +205 -0
- backend/execution/utils/shell/_bash_detached.py +127 -0
- backend/execution/utils/shell/_bash_pane.py +234 -0
- backend/execution/utils/shell/_bash_server.py +44 -0
- backend/execution/utils/shell/_bash_timeouts.py +431 -0
- backend/execution/utils/shell/background_turn_sync.py +153 -0
- backend/execution/utils/shell/bash.py +455 -0
- backend/execution/utils/shell/bash_constants.py +5 -0
- backend/execution/utils/shell/bash_support.py +193 -0
- backend/execution/utils/shell/blocking_heuristics.py +71 -0
- backend/execution/utils/shell/idle_detach_policy.py +66 -0
- backend/execution/utils/shell/prompt_detector.py +342 -0
- backend/execution/utils/shell/pty_session.py +849 -0
- backend/execution/utils/shell/pty_shell_session.py +616 -0
- backend/execution/utils/shell/session_manager.py +260 -0
- backend/execution/utils/shell/shell_utils.py +74 -0
- backend/execution/utils/shell/simple_bash.py +249 -0
- backend/execution/utils/shell/stall_hints.py +102 -0
- backend/execution/utils/shell/subprocess_background.py +172 -0
- backend/execution/utils/shell/unified_shell.py +765 -0
- backend/execution/utils/shell/windows_bash.py +537 -0
- backend/execution/utils/shell/windows_exceptions.py +16 -0
- backend/execution/utils/system.py +81 -0
- backend/execution/utils/system_stats.py +79 -0
- backend/execution/utils/tenacity_stop.py +18 -0
- backend/execution/utils/test_output_summary.py +193 -0
- backend/execution/utils/tool_registry.py +533 -0
- backend/execution/watchdog.py +216 -0
- backend/inference/README.md +802 -0
- backend/inference/__init__.py +25 -0
- backend/inference/caching/__init__.py +1 -0
- backend/inference/caching/gemini_cache.py +145 -0
- backend/inference/caching/prompt_cache.py +130 -0
- backend/inference/caching/prompt_caching.py +189 -0
- backend/inference/capabilities/__init__.py +16 -0
- backend/inference/capabilities/context_limits.py +194 -0
- backend/inference/capabilities/model_features.py +248 -0
- backend/inference/capabilities/param_profiles.py +85 -0
- backend/inference/capabilities/provider_capabilities.py +280 -0
- backend/inference/catalog/__init__.py +0 -0
- backend/inference/catalog/catalog_loader.py +1176 -0
- backend/inference/catalog/catalog_validator.py +481 -0
- backend/inference/catalog/model_catalog.py +25 -0
- backend/inference/catalog/provider_catalog.py +442 -0
- backend/inference/catalogs/anthropic.json +240 -0
- backend/inference/catalogs/cerebras.json +40 -0
- backend/inference/catalogs/deepinfra.json +66 -0
- backend/inference/catalogs/deepseek.json +68 -0
- backend/inference/catalogs/digitalocean.json +113 -0
- backend/inference/catalogs/fireworks.json +67 -0
- backend/inference/catalogs/google.json +96 -0
- backend/inference/catalogs/groq.json +132 -0
- backend/inference/catalogs/lightning.json +84 -0
- backend/inference/catalogs/mistral.json +66 -0
- backend/inference/catalogs/moonshot.json +97 -0
- backend/inference/catalogs/nvidia.json +40 -0
- backend/inference/catalogs/openai.json +672 -0
- backend/inference/catalogs/opencode-go.json +909 -0
- backend/inference/catalogs/opencode.json +4908 -0
- backend/inference/catalogs/openrouter.json +72 -0
- backend/inference/catalogs/perplexity.json +53 -0
- backend/inference/catalogs/together.json +67 -0
- backend/inference/catalogs/vercel.json +943 -0
- backend/inference/catalogs/xai.json +109 -0
- backend/inference/catalogs/zai.json +40 -0
- backend/inference/clients/__init__.py +74 -0
- backend/inference/clients/anthropic_client.py +90 -0
- backend/inference/clients/base.py +679 -0
- backend/inference/clients/factory.py +322 -0
- backend/inference/clients/openai_client.py +124 -0
- backend/inference/cost_tracker.py +104 -0
- backend/inference/debug_mixin.py +130 -0
- backend/inference/discover_models.py +140 -0
- backend/inference/exceptions.py +213 -0
- backend/inference/fn_call/__init__.py +106 -0
- backend/inference/fn_call/_fn_call_convert.py +246 -0
- backend/inference/fn_call/_fn_call_examples.py +386 -0
- backend/inference/fn_call/_fn_call_to_messages.py +766 -0
- backend/inference/llm/__init__.py +67 -0
- backend/inference/llm/config.py +259 -0
- backend/inference/llm/core.py +787 -0
- backend/inference/llm/exceptions.py +231 -0
- backend/inference/llm/stream.py +93 -0
- backend/inference/llm/utils.py +255 -0
- backend/inference/llm_registry.py +260 -0
- backend/inference/local_model.py +42 -0
- backend/inference/mappers/__init__.py +1 -0
- backend/inference/mappers/anthropic.py +456 -0
- backend/inference/mappers/gemini.py +565 -0
- backend/inference/mappers/openai.py +90 -0
- backend/inference/metrics.py +360 -0
- backend/inference/provider_resolver.py +459 -0
- backend/inference/providers/__init__.py +1 -0
- backend/inference/providers/anthropic_ops.py +417 -0
- backend/inference/providers/gemini_ops.py +596 -0
- backend/inference/providers/openai_ops.py +633 -0
- backend/inference/providers/opencode_gemini_ops.py +165 -0
- backend/inference/providers/opencode_responses_ops.py +213 -0
- backend/inference/rate_limit_parser.py +265 -0
- backend/inference/reasoning.py +678 -0
- backend/inference/reasoning_profiles.py +130 -0
- backend/inference/retry_mixin.py +230 -0
- backend/inference/runtime_profile.py +170 -0
- backend/inference/tool_support/__init__.py +0 -0
- backend/inference/tool_support/tool_history.py +47 -0
- backend/inference/tool_support/tool_result_format.py +50 -0
- backend/inference/tool_support/tool_types.py +73 -0
- backend/inference/transport.py +16 -0
- backend/inference/utils/batching.py +249 -0
- backend/integrations/README.md +32 -0
- backend/integrations/__init__.py +31 -0
- backend/integrations/mcp/README.md +24 -0
- backend/integrations/mcp/__init__.py +65 -0
- backend/integrations/mcp/cache.py +125 -0
- backend/integrations/mcp/client.py +493 -0
- backend/integrations/mcp/config_bus.py +353 -0
- backend/integrations/mcp/error_collector.py +79 -0
- backend/integrations/mcp/mcp_bootstrap_status.py +64 -0
- backend/integrations/mcp/mcp_tool_aliases.py +56 -0
- backend/integrations/mcp/mcp_utils.py +1165 -0
- backend/integrations/mcp/native_backends.py +60 -0
- backend/integrations/mcp/rigour_bootstrap.py +72 -0
- backend/integrations/mcp/tool.py +44 -0
- backend/integrations/mcp/wrappers.py +94 -0
- backend/knowledge/__init__.py +17 -0
- backend/knowledge/knowledge_base_manager.py +537 -0
- backend/knowledge/query_expansion.py +120 -0
- backend/knowledge/smart_chunking.py +559 -0
- backend/ledger/__init__.py +21 -0
- backend/ledger/action/__init__.py +105 -0
- backend/ledger/action/action.py +49 -0
- backend/ledger/action/agent.py +360 -0
- backend/ledger/action/browse.py +33 -0
- backend/ledger/action/browser_tool.py +31 -0
- backend/ledger/action/code_nav.py +41 -0
- backend/ledger/action/commands.py +59 -0
- backend/ledger/action/debugger.py +86 -0
- backend/ledger/action/empty.py +46 -0
- backend/ledger/action/files.py +102 -0
- backend/ledger/action/mcp.py +43 -0
- backend/ledger/action/memory_tools.py +114 -0
- backend/ledger/action/message.py +113 -0
- backend/ledger/action/search.py +91 -0
- backend/ledger/action/terminal.py +167 -0
- backend/ledger/event/__init__.py +26 -0
- backend/ledger/event/_event.py +244 -0
- backend/ledger/event/event_filter.py +146 -0
- backend/ledger/event/event_store.py +561 -0
- backend/ledger/event/event_store_abc.py +119 -0
- backend/ledger/event/event_utils.py +76 -0
- backend/ledger/infra/__init__.py +1 -0
- backend/ledger/infra/adapter.py +98 -0
- backend/ledger/infra/config.py +130 -0
- backend/ledger/infra/integrity.py +118 -0
- backend/ledger/infra/secret_masker.py +129 -0
- backend/ledger/infra/tool.py +64 -0
- backend/ledger/model_response_lite.py +111 -0
- backend/ledger/observation/__init__.py +107 -0
- backend/ledger/observation/acceptance_criteria.py +21 -0
- backend/ledger/observation/agent.py +161 -0
- backend/ledger/observation/browser_screenshot.py +44 -0
- backend/ledger/observation/code_nav.py +40 -0
- backend/ledger/observation/commands.py +266 -0
- backend/ledger/observation/debugger.py +26 -0
- backend/ledger/observation/empty.py +22 -0
- backend/ledger/observation/error.py +64 -0
- backend/ledger/observation/file_download.py +29 -0
- backend/ledger/observation/files.py +302 -0
- backend/ledger/observation/mcp.py +21 -0
- backend/ledger/observation/memory_tools.py +104 -0
- backend/ledger/observation/observation.py +43 -0
- backend/ledger/observation/reject.py +19 -0
- backend/ledger/observation/search.py +94 -0
- backend/ledger/observation/server.py +32 -0
- backend/ledger/observation/status.py +34 -0
- backend/ledger/observation/success.py +19 -0
- backend/ledger/observation/task_state.py +15 -0
- backend/ledger/observation/task_tracking.py +21 -0
- backend/ledger/observation/terminal.py +31 -0
- backend/ledger/observation_cause.py +62 -0
- backend/ledger/serialization/__init__.py +17 -0
- backend/ledger/serialization/action.py +197 -0
- backend/ledger/serialization/common.py +21 -0
- backend/ledger/serialization/event.py +455 -0
- backend/ledger/serialization/observation.py +253 -0
- backend/ledger/serialization/serialization_utils.py +24 -0
- backend/ledger/stream/__init__.py +39 -0
- backend/ledger/stream/async_event_store_wrapper.py +37 -0
- backend/ledger/stream/backpressure.py +264 -0
- backend/ledger/stream/coalescing.py +168 -0
- backend/ledger/stream/compaction.py +176 -0
- backend/ledger/stream/durable_writer.py +358 -0
- backend/ledger/stream/event_stream.py +1132 -0
- backend/ledger/stream/nested_event_store.py +191 -0
- backend/ledger/stream/persistence.py +764 -0
- backend/ledger/stream/stream_stats.py +82 -0
- backend/orchestration/__init__.py +6 -0
- backend/orchestration/action_scheduler.py +199 -0
- backend/orchestration/agent/__init__.py +303 -0
- backend/orchestration/agent/agent_protocol.py +180 -0
- backend/orchestration/agent/autonomy.py +237 -0
- backend/orchestration/agent/circuit_breaker.py +632 -0
- backend/orchestration/agent/tools.py +88 -0
- backend/orchestration/blackboard.py +156 -0
- backend/orchestration/file_edits/__init__.py +1 -0
- backend/orchestration/file_edits/file_edit_transaction.py +418 -0
- backend/orchestration/file_edits/file_state_tracker.py +310 -0
- backend/orchestration/file_edits/pre_exec_diff.py +219 -0
- backend/orchestration/health.py +377 -0
- backend/orchestration/memory_pressure.py +366 -0
- backend/orchestration/middleware/__init__.py +34 -0
- backend/orchestration/middleware/auto_check.py +99 -0
- backend/orchestration/middleware/blackboard.py +103 -0
- backend/orchestration/middleware/circuit_breaker.py +135 -0
- backend/orchestration/middleware/context_window.py +121 -0
- backend/orchestration/middleware/cost_quota.py +65 -0
- backend/orchestration/middleware/destructive_command.py +200 -0
- backend/orchestration/middleware/logging_mw.py +39 -0
- backend/orchestration/middleware/post_edit_diagnostics.py +350 -0
- backend/orchestration/middleware/progress_policy.py +123 -0
- backend/orchestration/middleware/rollback_middleware.py +263 -0
- backend/orchestration/middleware/safety_validator.py +69 -0
- backend/orchestration/middleware/symbol_index_invalidation.py +52 -0
- backend/orchestration/middleware/telemetry.py +31 -0
- backend/orchestration/middleware/tool_result_validator.py +392 -0
- backend/orchestration/mixins/__init__.py +59 -0
- backend/orchestration/mixins/action.py +171 -0
- backend/orchestration/mixins/lifecycle.py +357 -0
- backend/orchestration/mixins/parallel.py +537 -0
- backend/orchestration/mixins/state.py +436 -0
- backend/orchestration/mixins/step.py +253 -0
- backend/orchestration/mixins/watchdog.py +194 -0
- backend/orchestration/orchestration_config.py +107 -0
- backend/orchestration/rate_governor.py +238 -0
- backend/orchestration/replay.py +220 -0
- backend/orchestration/safety_validator.py +368 -0
- backend/orchestration/services/__init__.py +67 -0
- backend/orchestration/services/action_execution_service.py +856 -0
- backend/orchestration/services/action_service.py +239 -0
- backend/orchestration/services/autonomy_service.py +89 -0
- backend/orchestration/services/circuit_breaker_service.py +142 -0
- backend/orchestration/services/confirmation_service.py +174 -0
- backend/orchestration/services/error_formatting.py +214 -0
- backend/orchestration/services/event_router_mixins/__init__.py +33 -0
- backend/orchestration/services/event_router_mixins/_event_router_actions_mixin.py +286 -0
- backend/orchestration/services/event_router_mixins/_event_router_delegate_helpers.py +280 -0
- backend/orchestration/services/event_router_mixins/_event_router_delegate_mixin.py +818 -0
- backend/orchestration/services/event_router_mixins/_event_router_state_mixin.py +85 -0
- backend/orchestration/services/event_router_mixins/_event_router_user_message_mixin.py +201 -0
- backend/orchestration/services/event_router_service.py +52 -0
- backend/orchestration/services/exception_handler_service.py +106 -0
- backend/orchestration/services/guard_bus.py +186 -0
- backend/orchestration/services/iteration_guard_service.py +139 -0
- backend/orchestration/services/iteration_service.py +104 -0
- backend/orchestration/services/lifecycle_service.py +105 -0
- backend/orchestration/services/observation_service.py +508 -0
- backend/orchestration/services/orchestration_context.py +279 -0
- backend/orchestration/services/pending_action_service.py +642 -0
- backend/orchestration/services/recovery_service.py +717 -0
- backend/orchestration/services/retry_queue.py +353 -0
- backend/orchestration/services/retry_service.py +657 -0
- backend/orchestration/services/safety_service.py +157 -0
- backend/orchestration/services/state_transition_service.py +267 -0
- backend/orchestration/services/step_decision_service.py +119 -0
- backend/orchestration/services/step_guard_service.py +580 -0
- backend/orchestration/services/step_prerequisite_service.py +64 -0
- backend/orchestration/services/stuck_detection_service.py +50 -0
- backend/orchestration/services/task_validation_service.py +113 -0
- backend/orchestration/session_orchestrator.py +582 -0
- backend/orchestration/session_orchestrator_accessors.py +121 -0
- backend/orchestration/state/__init__.py +46 -0
- backend/orchestration/state/control_flags.py +118 -0
- backend/orchestration/state/session_checkpoint_manager.py +131 -0
- backend/orchestration/state/state.py +980 -0
- backend/orchestration/state/state_tracker.py +427 -0
- backend/orchestration/stuck/__init__.py +5 -0
- backend/orchestration/stuck/detector.py +772 -0
- backend/orchestration/stuck/patterns.py +187 -0
- backend/orchestration/telemetry/__init__.py +1 -0
- backend/orchestration/telemetry/conversation_stats.py +231 -0
- backend/orchestration/telemetry/progress_tracker.py +281 -0
- backend/orchestration/telemetry/tool_telemetry.py +580 -0
- backend/orchestration/tool_pipeline.py +155 -0
- backend/persistence/README.md +32 -0
- backend/persistence/__init__.py +56 -0
- backend/persistence/auth.py +57 -0
- backend/persistence/conversation/__init__.py +1 -0
- backend/persistence/conversation/conversation_resumer.py +156 -0
- backend/persistence/conversation/conversation_store.py +78 -0
- backend/persistence/conversation/conversation_validator.py +195 -0
- backend/persistence/conversation/file_conversation_store.py +257 -0
- backend/persistence/data_models/__init__.py +1 -0
- backend/persistence/data_models/conversation_metadata.py +52 -0
- backend/persistence/data_models/conversation_metadata_result_set.py +19 -0
- backend/persistence/data_models/conversation_status.py +43 -0
- backend/persistence/data_models/conversation_template.py +96 -0
- backend/persistence/data_models/knowledge_base.py +164 -0
- backend/persistence/data_models/settings.py +354 -0
- backend/persistence/data_models/user_secrets.py +263 -0
- backend/persistence/file_store/__init__.py +0 -0
- backend/persistence/file_store/atomic_write.py +42 -0
- backend/persistence/file_store/files.py +65 -0
- backend/persistence/file_store/in_memory_file_store.py +95 -0
- backend/persistence/file_store/local_file_store.py +241 -0
- backend/persistence/knowledge_base/__init__.py +1 -0
- backend/persistence/knowledge_base/knowledge_base_store.py +302 -0
- backend/persistence/knowledge_base/migrations/001_create_knowledge_base_tables.sql +38 -0
- backend/persistence/knowledge_base/migrations/__init__.py +1 -0
- backend/persistence/knowledge_base/migrations/run_migrations.py +81 -0
- backend/persistence/locations.py +341 -0
- backend/persistence/secrets/__init__.py +1 -0
- backend/persistence/secrets/file_secrets_store.py +101 -0
- backend/persistence/secrets/secrets_store.py +39 -0
- backend/persistence/settings/__init__.py +1 -0
- backend/persistence/settings/file_settings_store.py +150 -0
- backend/persistence/settings/settings_store.py +40 -0
- backend/persistence/sqlite_event_store.py +588 -0
- backend/persistence/user/__init__.py +0 -0
- backend/playbooks/README.md +73 -0
- backend/playbooks/__init__.py +1 -0
- backend/playbooks/add_repo_inst.md +65 -0
- backend/playbooks/address_pr_comments.md +28 -0
- backend/playbooks/agent_memory.md +32 -0
- backend/playbooks/api.md +70 -0
- backend/playbooks/code-review.md +50 -0
- backend/playbooks/database.md +33 -0
- backend/playbooks/debug.md +42 -0
- backend/playbooks/deps.md +67 -0
- backend/playbooks/documentation.md +36 -0
- backend/playbooks/engine/__init__.py +18 -0
- backend/playbooks/engine/playbook.py +673 -0
- backend/playbooks/engine/types.py +97 -0
- backend/playbooks/feature.md +36 -0
- backend/playbooks/git-wizard.md +66 -0
- backend/playbooks/incident.md +51 -0
- backend/playbooks/log-fu.md +86 -0
- backend/playbooks/migration.md +54 -0
- backend/playbooks/net-diag.md +95 -0
- backend/playbooks/perf.md +60 -0
- backend/playbooks/python.md +50 -0
- backend/playbooks/react.md +40 -0
- backend/playbooks/refactoring.md +33 -0
- backend/playbooks/security.md +52 -0
- backend/playbooks/shell.md +41 -0
- backend/playbooks/testing.md +63 -0
- backend/playbooks/tool.md +50 -0
- backend/playbooks/typescript.md +50 -0
- backend/playbooks/update_pr_description.md +33 -0
- backend/playbooks/update_test.md +20 -0
- backend/py.typed +0 -0
- backend/scripts/README.md +30 -0
- backend/scripts/build_tree_sitter_lang.py +89 -0
- backend/scripts/sanitize_trajectories.py +319 -0
- backend/scripts/verify/README.md +31 -0
- backend/scripts/verify/check_fastmcp_import.py +14 -0
- backend/scripts/verify/check_file_size.py +131 -0
- backend/scripts/verify/check_layer_imports.py +214 -0
- backend/scripts/verify/ga_onboarding_gate.py +222 -0
- backend/scripts/verify/reliability_gate.py +238 -0
- backend/scripts/verify/verify_api_versioning.py +175 -0
- backend/scripts/verify/verify_optional_imports.py +75 -0
- backend/security/__init__.py +15 -0
- backend/security/analyzer.py +131 -0
- backend/security/command_analyzer.py +686 -0
- backend/security/options.py +36 -0
- backend/security/safety_config.py +54 -0
- backend/task_state/__init__.py +7 -0
- backend/task_state/models.py +118 -0
- backend/task_state/service.py +262 -0
- backend/task_state/store.py +57 -0
- backend/telemetry/__init__.py +6 -0
- backend/telemetry/audit_logger.py +370 -0
- backend/telemetry/models.py +137 -0
- backend/utils/README.md +18 -0
- backend/utils/__init__.py +5 -0
- backend/utils/async_helpers/__init__.py +1 -0
- backend/utils/async_helpers/async_utils.py +679 -0
- backend/utils/async_helpers/circuit_breaker.py +196 -0
- backend/utils/async_helpers/retry.py +260 -0
- backend/utils/async_helpers/subprocess_bridge.py +56 -0
- backend/utils/async_helpers/tenacity_metrics.py +131 -0
- backend/utils/async_helpers/tenacity_stop.py +35 -0
- backend/utils/conversation_summary.py +250 -0
- backend/utils/core_utils.py +73 -0
- backend/utils/http/__init__.py +1 -0
- backend/utils/http/http_session.py +89 -0
- backend/utils/http/stdio_json_rpc.py +106 -0
- backend/utils/impact_analysis.py +488 -0
- backend/utils/import_utils.py +124 -0
- backend/utils/linux_host_tools.py +213 -0
- backend/utils/lsp/__init__.py +1 -0
- backend/utils/lsp/lsp_capabilities.py +46 -0
- backend/utils/lsp/lsp_client.py +1173 -0
- backend/utils/lsp/lsp_project_routing.py +129 -0
- backend/utils/lsp/lsp_session.py +557 -0
- backend/utils/lsp/lsp_timeouts.py +61 -0
- backend/utils/metrics_labels.py +27 -0
- backend/utils/model_prewarm.py +102 -0
- backend/utils/optional_extras.py +78 -0
- backend/utils/path_normalize.py +156 -0
- backend/utils/prompt.py +388 -0
- backend/utils/regex_limits.py +24 -0
- backend/utils/runtime_detect.py +1028 -0
- backend/utils/search_utils.py +65 -0
- backend/utils/shutdown_listener.py +97 -0
- backend/utils/stdio_restore.py +55 -0
- backend/utils/terminal/__init__.py +1 -0
- backend/utils/terminal/term_color.py +29 -0
- backend/utils/terminal/terminal_contract.py +124 -0
- backend/utils/treesitter/__init__.py +1 -0
- backend/utils/treesitter/_tse_errors.py +165 -0
- backend/utils/treesitter/_tse_languages.py +167 -0
- backend/utils/treesitter/_tse_query.py +328 -0
- backend/utils/treesitter/_tse_runtime.py +57 -0
- backend/utils/treesitter/_tse_types.py +49 -0
- backend/utils/treesitter/chunk_localizer.py +116 -0
- backend/utils/treesitter/syntax_check.py +281 -0
- backend/utils/treesitter/treesitter_editor.py +767 -0
- backend/validation/__init__.py +5 -0
- backend/validation/code_quality/__init__.py +9 -0
- backend/validation/code_quality/linter.py +339 -0
- backend/validation/command_classification.py +272 -0
- backend/validation/task_metadata.py +185 -0
- backend/validation/task_validator.py +925 -0
- grinta-1.0.0.dist-info/METADATA +197 -0
- grinta-1.0.0.dist-info/RECORD +1082 -0
- grinta-1.0.0.dist-info/WHEEL +4 -0
- grinta-1.0.0.dist-info/entry_points.txt +2 -0
- grinta-1.0.0.dist-info/licenses/LICENSE +24 -0
- launch/__init__.py +1 -0
- 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.
|
backend/README_GRINTA.md
ADDED
|
@@ -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__
|
backend/app/__init__.py
ADDED
|
@@ -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
|