iCode-TUI 0.29.1__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.
- chrys/__init__.py +16 -0
- chrys/app/__init__.py +3 -0
- chrys/app/acp/__init__.py +3 -0
- chrys/app/acp/bridge.py +664 -0
- chrys/app/acp/content.py +132 -0
- chrys/app/acp/doc/frontend-api.md +425 -0
- chrys/app/acp/history.py +585 -0
- chrys/app/acp/server.py +1796 -0
- chrys/app/acp/session_manager.py +1815 -0
- chrys/app/acp/tool_status.py +45 -0
- chrys/app/cli/__init__.py +3 -0
- chrys/app/cli/acp.py +178 -0
- chrys/app/cli/app.py +165 -0
- chrys/app/cli/approvals.py +101 -0
- chrys/app/cli/headless.py +223 -0
- chrys/app/cli/launch_cwd.py +42 -0
- chrys/app/cli/profiles.py +298 -0
- chrys/app/cli/progress.py +857 -0
- chrys/app/cli/run.py +425 -0
- chrys/app/cli/serve.py +1593 -0
- chrys/app/cli/tool_summary.py +225 -0
- chrys/app/cli/trajectory.py +201 -0
- chrys/app/cli/workflow.py +601 -0
- chrys/app/features/__init__.py +3 -0
- chrys/app/features/buddy/__init__.py +3 -0
- chrys/app/features/buddy/actions.py +68 -0
- chrys/app/features/buddy/animation.py +76 -0
- chrys/app/features/buddy/commands.py +196 -0
- chrys/app/features/buddy/docs/design.md +187 -0
- chrys/app/features/buddy/hatchery.py +80 -0
- chrys/app/features/buddy/lifecycle.py +41 -0
- chrys/app/features/buddy/model.py +265 -0
- chrys/app/features/buddy/pixel_renderer.py +113 -0
- chrys/app/features/buddy/pixel_sprites.py +279 -0
- chrys/app/features/buddy/portrait.py +76 -0
- chrys/app/features/buddy/progression.py +58 -0
- chrys/app/features/buddy/replies.py +191 -0
- chrys/app/features/buddy/sprites/alien.toml +70 -0
- chrys/app/features/buddy/sprites/axolotl.toml +71 -0
- chrys/app/features/buddy/sprites/bat.toml +69 -0
- chrys/app/features/buddy/sprites/bee.toml +69 -0
- chrys/app/features/buddy/sprites/cactus.toml +73 -0
- chrys/app/features/buddy/sprites/capybara.toml +70 -0
- chrys/app/features/buddy/sprites/cat.toml +69 -0
- chrys/app/features/buddy/sprites/crab.toml +70 -0
- chrys/app/features/buddy/sprites/dragon.toml +71 -0
- chrys/app/features/buddy/sprites/duck.toml +69 -0
- chrys/app/features/buddy/sprites/fox.toml +69 -0
- chrys/app/features/buddy/sprites/frog.toml +70 -0
- chrys/app/features/buddy/sprites/ghost.toml +70 -0
- chrys/app/features/buddy/sprites/goose.toml +69 -0
- chrys/app/features/buddy/sprites/jelly.toml +70 -0
- chrys/app/features/buddy/sprites/llama.toml +70 -0
- chrys/app/features/buddy/sprites/mushroom.toml +69 -0
- chrys/app/features/buddy/sprites/octopus.toml +70 -0
- chrys/app/features/buddy/sprites/owl.toml +70 -0
- chrys/app/features/buddy/sprites/panda.toml +71 -0
- chrys/app/features/buddy/sprites/penguin.toml +69 -0
- chrys/app/features/buddy/sprites/rabbit.toml +70 -0
- chrys/app/features/buddy/sprites/robot.toml +72 -0
- chrys/app/features/buddy/sprites/shark.toml +70 -0
- chrys/app/features/buddy/sprites/snail.toml +69 -0
- chrys/app/features/buddy/sprites/snake.toml +69 -0
- chrys/app/features/buddy/sprites/tabby.toml +69 -0
- chrys/app/features/buddy/sprites/turtle.toml +69 -0
- chrys/app/features/buddy/store.py +143 -0
- chrys/app/features/session_title/__init__.py +7 -0
- chrys/app/features/session_title/updater.py +582 -0
- chrys/app/installer.py +651 -0
- chrys/app/parsing.py +17 -0
- chrys/app/tui/__init__.py +3 -0
- chrys/app/tui/app.py +1287 -0
- chrys/app/tui/behaviors/__init__.py +3 -0
- chrys/app/tui/behaviors/click_outside_dismiss.py +90 -0
- chrys/app/tui/behaviors/insert_clipboard.py +73 -0
- chrys/app/tui/behaviors/right_click_copy.py +146 -0
- chrys/app/tui/binding_display.py +139 -0
- chrys/app/tui/buddy_messages.py +17 -0
- chrys/app/tui/buddy_reply.py +86 -0
- chrys/app/tui/chrys.tcss +549 -0
- chrys/app/tui/clipboard.py +109 -0
- chrys/app/tui/copy_messages.py +10 -0
- chrys/app/tui/i18n.py +230 -0
- chrys/app/tui/language.py +58 -0
- chrys/app/tui/notifications/__init__.py +12 -0
- chrys/app/tui/notifications/drivers.py +180 -0
- chrys/app/tui/notifications/service.py +126 -0
- chrys/app/tui/notifications/settings.py +141 -0
- chrys/app/tui/screens/__init__.py +3 -0
- chrys/app/tui/screens/agents/__init__.py +8 -0
- chrys/app/tui/screens/agents/agent_draft_store.py +937 -0
- chrys/app/tui/screens/agents/config.py +2142 -0
- chrys/app/tui/screens/agents/config.tcss +169 -0
- chrys/app/tui/screens/agents/panels/__init__.py +3 -0
- chrys/app/tui/screens/agents/panels/acp.py +1176 -0
- chrys/app/tui/screens/agents/panels/basic.py +497 -0
- chrys/app/tui/screens/agents/panels/compaction.py +231 -0
- chrys/app/tui/screens/agents/panels/config_card.py +218 -0
- chrys/app/tui/screens/agents/panels/instructions.py +91 -0
- chrys/app/tui/screens/agents/panels/markdown_report.py +76 -0
- chrys/app/tui/screens/agents/panels/mcp.py +2262 -0
- chrys/app/tui/screens/agents/panels/memory.py +684 -0
- chrys/app/tui/screens/agents/panels/path_entry.py +227 -0
- chrys/app/tui/screens/agents/panels/skills.py +806 -0
- chrys/app/tui/screens/agents/panels/subagents.py +652 -0
- chrys/app/tui/screens/agents/panels/tools.py +205 -0
- chrys/app/tui/screens/agents/picker.py +103 -0
- chrys/app/tui/screens/agents/skill_paths.py +38 -0
- chrys/app/tui/screens/agents/validation_messages.py +452 -0
- chrys/app/tui/screens/dialogs/__init__.py +35 -0
- chrys/app/tui/screens/dialogs/agent_load.py +834 -0
- chrys/app/tui/screens/dialogs/agent_load.tcss +78 -0
- chrys/app/tui/screens/dialogs/app_mode.py +55 -0
- chrys/app/tui/screens/dialogs/approval/__init__.py +15 -0
- chrys/app/tui/screens/dialogs/approval/approval.tcss +311 -0
- chrys/app/tui/screens/dialogs/approval/bodies/__init__.py +3 -0
- chrys/app/tui/screens/dialogs/approval/bodies/file_edit.py +210 -0
- chrys/app/tui/screens/dialogs/approval/bodies/sub_agent.py +82 -0
- chrys/app/tui/screens/dialogs/approval/body.py +110 -0
- chrys/app/tui/screens/dialogs/approval/dialog.py +565 -0
- chrys/app/tui/screens/dialogs/approval/mode.py +105 -0
- chrys/app/tui/screens/dialogs/ask_user.py +148 -0
- chrys/app/tui/screens/dialogs/ask_user.tcss +62 -0
- chrys/app/tui/screens/dialogs/base.py +84 -0
- chrys/app/tui/screens/dialogs/confirm.py +184 -0
- chrys/app/tui/screens/dialogs/confirm.tcss +46 -0
- chrys/app/tui/screens/dialogs/connection_test.py +183 -0
- chrys/app/tui/screens/dialogs/connection_test.tcss +92 -0
- chrys/app/tui/screens/dialogs/diagram.py +102 -0
- chrys/app/tui/screens/dialogs/diagram.tcss +24 -0
- chrys/app/tui/screens/dialogs/editor.py +378 -0
- chrys/app/tui/screens/dialogs/editor.tcss +132 -0
- chrys/app/tui/screens/dialogs/file_picker.py +582 -0
- chrys/app/tui/screens/dialogs/file_picker.tcss +78 -0
- chrys/app/tui/screens/dialogs/fork_session.py +219 -0
- chrys/app/tui/screens/dialogs/fork_session.tcss +75 -0
- chrys/app/tui/screens/dialogs/image_compression.py +102 -0
- chrys/app/tui/screens/dialogs/image_compression.tcss +28 -0
- chrys/app/tui/screens/dialogs/man_page.py +172 -0
- chrys/app/tui/screens/dialogs/man_page.tcss +39 -0
- chrys/app/tui/screens/dialogs/new_folder.py +277 -0
- chrys/app/tui/screens/dialogs/new_folder.tcss +51 -0
- chrys/app/tui/screens/dialogs/notice.tcss +14 -0
- chrys/app/tui/screens/dialogs/prompt_cache.py +144 -0
- chrys/app/tui/screens/dialogs/prompt_cache.tcss +38 -0
- chrys/app/tui/screens/dialogs/runtime_details.py +371 -0
- chrys/app/tui/screens/dialogs/runtime_details.tcss +49 -0
- chrys/app/tui/screens/dialogs/session_title.py +110 -0
- chrys/app/tui/screens/dialogs/session_title.tcss +43 -0
- chrys/app/tui/screens/dialogs/tool_view.py +207 -0
- chrys/app/tui/screens/dialogs/tool_view.tcss +43 -0
- chrys/app/tui/screens/dialogs/vision_unsupported.py +122 -0
- chrys/app/tui/screens/dialogs/vision_unsupported.tcss +35 -0
- chrys/app/tui/screens/dialogs/workflow_confirm.py +91 -0
- chrys/app/tui/screens/dialogs/workflow_confirm.tcss +17 -0
- chrys/app/tui/screens/dialogs/workflow_input.py +258 -0
- chrys/app/tui/screens/dialogs/workflow_input.tcss +73 -0
- chrys/app/tui/screens/dialogs/workflow_node.py +462 -0
- chrys/app/tui/screens/dialogs/workflow_node.tcss +41 -0
- chrys/app/tui/screens/dialogs/workflow_picker.py +46 -0
- chrys/app/tui/screens/dialogs/workflow_result.py +136 -0
- chrys/app/tui/screens/dialogs/workflow_result.tcss +14 -0
- chrys/app/tui/screens/diff/__init__.py +22 -0
- chrys/app/tui/screens/diff/rollback_modal.py +1381 -0
- chrys/app/tui/screens/diff/rollback_modal.tcss +248 -0
- chrys/app/tui/screens/diff/screen.py +1532 -0
- chrys/app/tui/screens/diff/screen.tcss +104 -0
- chrys/app/tui/screens/guides/__init__.py +7 -0
- chrys/app/tui/screens/guides/_docs/en/guides/configuration/agents.md +178 -0
- chrys/app/tui/screens/guides/_docs/en/guides/configuration/approval.md +117 -0
- chrys/app/tui/screens/guides/_docs/en/guides/configuration/chat-options.md +276 -0
- chrys/app/tui/screens/guides/_docs/en/guides/configuration/compaction.md +42 -0
- chrys/app/tui/screens/guides/_docs/en/guides/configuration/memory.md +48 -0
- chrys/app/tui/screens/guides/_docs/en/guides/configuration/models.md +158 -0
- chrys/app/tui/screens/guides/_docs/en/guides/configuration/settings.md +210 -0
- chrys/app/tui/screens/guides/_docs/en/guides/configuration/themes.md +61 -0
- chrys/app/tui/screens/guides/_docs/en/guides/configuration/tools.md +60 -0
- chrys/app/tui/screens/guides/_docs/en/guides/configuration/web-tools.md +286 -0
- chrys/app/tui/screens/guides/_docs/en/guides/daily-use/sessions.md +77 -0
- chrys/app/tui/screens/guides/_docs/en/guides/daily-use/workspaces.md +51 -0
- chrys/app/tui/screens/guides/_docs/en/guides/extensions/external-acp-agents.md +126 -0
- chrys/app/tui/screens/guides/_docs/en/guides/extensions/hooks.md +167 -0
- chrys/app/tui/screens/guides/_docs/en/guides/extensions/mcp.md +95 -0
- chrys/app/tui/screens/guides/_docs/en/guides/extensions/skills.md +175 -0
- chrys/app/tui/screens/guides/_docs/en/guides/running/icode-acp.md +61 -0
- chrys/app/tui/screens/guides/_docs/en/guides/running/icode-run.md +190 -0
- chrys/app/tui/screens/guides/_docs/en/guides/running/icode-serve.md +239 -0
- chrys/app/tui/screens/guides/_docs/en/guides/running/workflows.md +664 -0
- chrys/app/tui/screens/guides/_docs/en/reference/agent-profile.md +548 -0
- chrys/app/tui/screens/guides/_docs/en/reference/hooks.md +602 -0
- chrys/app/tui/screens/guides/_docs/en/reference/opentelemetry.md +177 -0
- chrys/app/tui/screens/guides/_docs/en/reference/settings.md +245 -0
- chrys/app/tui/screens/guides/_docs/en/reference/themes.md +149 -0
- chrys/app/tui/screens/guides/_docs/en/reference/tool-kinds-and-names.md +58 -0
- chrys/app/tui/screens/guides/_docs/en/reference/tui-slash-commands.md +76 -0
- chrys/app/tui/screens/guides/_docs/en/reference/workflows.md +1006 -0
- chrys/app/tui/screens/guides/_docs/en/start/getting-started.md +170 -0
- chrys/app/tui/screens/guides/_docs/en/start/what-is-icode.md +34 -0
- chrys/app/tui/screens/guides/_docs/index.yaml +100 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/configuration/agents.md +178 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/configuration/approval.md +117 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/configuration/chat-options.md +276 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/configuration/compaction.md +42 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/configuration/memory.md +48 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/configuration/models.md +158 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/configuration/settings.md +210 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/configuration/themes.md +61 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/configuration/tools.md +60 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/configuration/web-tools.md +286 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/daily-use/sessions.md +77 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/daily-use/workspaces.md +51 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/extensions/external-acp-agents.md +126 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/extensions/hooks.md +167 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/extensions/mcp.md +95 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/extensions/skills.md +175 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/running/icode-acp.md +61 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/running/icode-run.md +190 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/running/icode-serve.md +239 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/running/workflows.md +664 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/reference/agent-profile.md +548 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/reference/hooks.md +602 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/reference/opentelemetry.md +177 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/reference/settings.md +245 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/reference/themes.md +149 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/reference/tool-kinds-and-names.md +58 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/reference/tui-slash-commands.md +76 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/reference/workflows.md +1005 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/start/getting-started.md +170 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/start/what-is-icode.md +34 -0
- chrys/app/tui/screens/guides/index.py +215 -0
- chrys/app/tui/screens/guides/reader.py +173 -0
- chrys/app/tui/screens/guides/screen.py +442 -0
- chrys/app/tui/screens/guides/screen.tcss +52 -0
- chrys/app/tui/screens/logs/__init__.py +7 -0
- chrys/app/tui/screens/logs/screen.py +504 -0
- chrys/app/tui/screens/logs/screen.tcss +45 -0
- chrys/app/tui/screens/main/__init__.py +7 -0
- chrys/app/tui/screens/main/action_availability.py +30 -0
- chrys/app/tui/screens/main/buddy_command.py +143 -0
- chrys/app/tui/screens/main/commands.py +1073 -0
- chrys/app/tui/screens/main/config_actions.py +464 -0
- chrys/app/tui/screens/main/copy_actions.py +117 -0
- chrys/app/tui/screens/main/dialog_controllers.py +826 -0
- chrys/app/tui/screens/main/dialog_gateway.py +166 -0
- chrys/app/tui/screens/main/diff_controller.py +478 -0
- chrys/app/tui/screens/main/engine_read_model.py +184 -0
- chrys/app/tui/screens/main/event_handlers.py +2014 -0
- chrys/app/tui/screens/main/input_flow.py +241 -0
- chrys/app/tui/screens/main/live_diff.py +244 -0
- chrys/app/tui/screens/main/main_screen_presenter.py +295 -0
- chrys/app/tui/screens/main/model_indicator.py +217 -0
- chrys/app/tui/screens/main/navigation.py +343 -0
- chrys/app/tui/screens/main/ports.py +571 -0
- chrys/app/tui/screens/main/recent_dirs.py +123 -0
- chrys/app/tui/screens/main/rollback_controller.py +586 -0
- chrys/app/tui/screens/main/runtime_info.py +71 -0
- chrys/app/tui/screens/main/screen.py +2265 -0
- chrys/app/tui/screens/main/screen.tcss +21 -0
- chrys/app/tui/screens/main/session_handlers.py +1127 -0
- chrys/app/tui/screens/main/session_title.py +239 -0
- chrys/app/tui/screens/main/settings_coordinator.py +365 -0
- chrys/app/tui/screens/main/settings_persistence.py +184 -0
- chrys/app/tui/screens/main/shell_mode.py +112 -0
- chrys/app/tui/screens/main/state.py +289 -0
- chrys/app/tui/screens/main/submit_state.py +11 -0
- chrys/app/tui/screens/main/subscriptions.py +177 -0
- chrys/app/tui/screens/main/suggestions.py +982 -0
- chrys/app/tui/screens/main/tool_action_bridge.py +75 -0
- chrys/app/tui/screens/main/view_adapter.py +1567 -0
- chrys/app/tui/screens/main/workflow_browser.py +747 -0
- chrys/app/tui/screens/main/workflow_content.py +248 -0
- chrys/app/tui/screens/main/workflow_controller.py +240 -0
- chrys/app/tui/screens/main/workflow_feedback.py +137 -0
- chrys/app/tui/screens/main/workflow_flow.py +49 -0
- chrys/app/tui/screens/main/workflow_run_control.py +456 -0
- chrys/app/tui/screens/main/workflow_session_view.py +316 -0
- chrys/app/tui/screens/main/workspace_actions.py +272 -0
- chrys/app/tui/screens/main/workspace_branch.py +194 -0
- chrys/app/tui/screens/menus/__init__.py +8 -0
- chrys/app/tui/screens/menus/languages.py +114 -0
- chrys/app/tui/screens/models/__init__.py +7 -0
- chrys/app/tui/screens/models/picker.py +147 -0
- chrys/app/tui/screens/models/screen.py +2043 -0
- chrys/app/tui/screens/models/screen.tcss +255 -0
- chrys/app/tui/screens/sessions/__init__.py +8 -0
- chrys/app/tui/screens/sessions/presenter.py +586 -0
- chrys/app/tui/screens/sessions/screen.py +779 -0
- chrys/app/tui/screens/sessions/screen.tcss +127 -0
- chrys/app/tui/screens/settings/__init__.py +29 -0
- chrys/app/tui/screens/settings/danger.py +26 -0
- chrys/app/tui/screens/settings/dialog.py +281 -0
- chrys/app/tui/screens/settings/layout.py +519 -0
- chrys/app/tui/screens/settings/migrate_dialog.py +253 -0
- chrys/app/tui/screens/settings/panes/__init__.py +3 -0
- chrys/app/tui/screens/settings/panes/notifications.py +248 -0
- chrys/app/tui/screens/settings/panes/sessions.py +148 -0
- chrys/app/tui/screens/settings/ports.py +55 -0
- chrys/app/tui/screens/settings/provenance.py +102 -0
- chrys/app/tui/screens/settings/rows.py +546 -0
- chrys/app/tui/screens/settings/settings.tcss +406 -0
- chrys/app/tui/screens/themes/__init__.py +8 -0
- chrys/app/tui/screens/themes/dialogs.py +330 -0
- chrys/app/tui/screens/themes/editor.py +632 -0
- chrys/app/tui/screens/themes/editor.tcss +268 -0
- chrys/app/tui/screens/themes/messages.py +95 -0
- chrys/app/tui/screens/themes/palette.py +694 -0
- chrys/app/tui/screens/themes/panel.py +113 -0
- chrys/app/tui/screens/themes/picker.py +203 -0
- chrys/app/tui/screens/themes/save.py +191 -0
- chrys/app/tui/support/__init__.py +3 -0
- chrys/app/tui/support/file_manager.py +64 -0
- chrys/app/tui/support/gc_freeze.py +1114 -0
- chrys/app/tui/support/path_shortcuts.py +50 -0
- chrys/app/tui/support/prompt_history.py +298 -0
- chrys/app/tui/support/workspace_mru.py +476 -0
- chrys/app/tui/terminal/__init__.py +6 -0
- chrys/app/tui/terminal/_pty_backend.py +114 -0
- chrys/app/tui/terminal/emulator/__init__.py +24 -0
- chrys/app/tui/terminal/emulator/buffer.py +456 -0
- chrys/app/tui/terminal/emulator/charsets.py +113 -0
- chrys/app/tui/terminal/emulator/core.py +963 -0
- chrys/app/tui/terminal/emulator/input.py +342 -0
- chrys/app/tui/terminal/emulator/parser.py +227 -0
- chrys/app/tui/terminal/emulator/pen.py +158 -0
- chrys/app/tui/terminal/launcher.py +455 -0
- chrys/app/tui/terminal/leaked_reports.py +44 -0
- chrys/app/tui/terminal/panel.py +323 -0
- chrys/app/tui/terminal/pty_process.py +405 -0
- chrys/app/tui/terminal/rendering.py +151 -0
- chrys/app/tui/terminal/shell.py +273 -0
- chrys/app/tui/terminal/shell_integration.py +199 -0
- chrys/app/tui/terminal/title.py +224 -0
- chrys/app/tui/terminal/widget.py +654 -0
- chrys/app/tui/theme.py +422 -0
- chrys/app/tui/theme_loader.py +201 -0
- chrys/app/tui/theme_stylesheet.py +49 -0
- chrys/app/tui/themes/__init__.py +3 -0
- chrys/app/tui/themes/document.py +120 -0
- chrys/app/tui/themes/preview.py +170 -0
- chrys/app/tui/themes/store.py +176 -0
- chrys/app/tui/toasts.py +69 -0
- chrys/app/tui/util/__init__.py +3 -0
- chrys/app/tui/util/context_pressure.py +146 -0
- chrys/app/tui/util/debug_log.py +292 -0
- chrys/app/tui/util/diff_entries.py +64 -0
- chrys/app/tui/util/formatting.py +53 -0
- chrys/app/tui/util/git_branch.py +326 -0
- chrys/app/tui/util/invocation_progress.py +57 -0
- chrys/app/tui/util/logo.py +32 -0
- chrys/app/tui/util/message_gate.py +35 -0
- chrys/app/tui/util/mutation_sources.py +14 -0
- chrys/app/tui/util/picker_text.py +27 -0
- chrys/app/tui/util/removal.py +47 -0
- chrys/app/tui/util/rich_style.py +36 -0
- chrys/app/tui/util/source_text.py +12 -0
- chrys/app/tui/util/static_update.py +88 -0
- chrys/app/tui/util/todo_format.py +51 -0
- chrys/app/tui/util/visibility.py +214 -0
- chrys/app/tui/widgets/__init__.py +60 -0
- chrys/app/tui/widgets/ask_user_controls.py +652 -0
- chrys/app/tui/widgets/ask_user_markdown.py +17 -0
- chrys/app/tui/widgets/ask_user_prompt.py +606 -0
- chrys/app/tui/widgets/buttons.py +52 -0
- chrys/app/tui/widgets/chat/__init__.py +3 -0
- chrys/app/tui/widgets/chat/agent_transcript_surface.py +818 -0
- chrys/app/tui/widgets/chat/chrome.py +296 -0
- chrys/app/tui/widgets/chat/compaction_card.py +353 -0
- chrys/app/tui/widgets/chat/context_fold.py +77 -0
- chrys/app/tui/widgets/chat/file_snapshot.py +91 -0
- chrys/app/tui/widgets/chat/image_preview.py +214 -0
- chrys/app/tui/widgets/chat/live_renderer.py +383 -0
- chrys/app/tui/widgets/chat/messages.py +1039 -0
- chrys/app/tui/widgets/chat/panel.py +1769 -0
- chrys/app/tui/widgets/chat/ports.py +245 -0
- chrys/app/tui/widgets/chat/renderers/__init__.py +7 -0
- chrys/app/tui/widgets/chat/renderers/ask_user.py +747 -0
- chrys/app/tui/widgets/chat/renderers/execute.py +431 -0
- chrys/app/tui/widgets/chat/renderers/file_edit.py +925 -0
- chrys/app/tui/widgets/chat/renderers/hosted_code.py +83 -0
- chrys/app/tui/widgets/chat/renderers/hosted_generic.py +330 -0
- chrys/app/tui/widgets/chat/renderers/hosted_image.py +107 -0
- chrys/app/tui/widgets/chat/renderers/hosted_mcp.py +43 -0
- chrys/app/tui/widgets/chat/renderers/hosted_search.py +167 -0
- chrys/app/tui/widgets/chat/renderers/hosted_shell.py +132 -0
- chrys/app/tui/widgets/chat/renderers/read_file.py +399 -0
- chrys/app/tui/widgets/chat/renderers/search.py +348 -0
- chrys/app/tui/widgets/chat/renderers/skill.py +564 -0
- chrys/app/tui/widgets/chat/renderers/sleep.py +287 -0
- chrys/app/tui/widgets/chat/renderers/sub_agent.py +1385 -0
- chrys/app/tui/widgets/chat/renderers/todo.py +114 -0
- chrys/app/tui/widgets/chat/renderers/web.py +69 -0
- chrys/app/tui/widgets/chat/replay.py +1605 -0
- chrys/app/tui/widgets/chat/replay_mount.py +322 -0
- chrys/app/tui/widgets/chat/scroll_controller.py +579 -0
- chrys/app/tui/widgets/chat/selection_controller.py +435 -0
- chrys/app/tui/widgets/chat/session_json.py +508 -0
- chrys/app/tui/widgets/chat/toc_model.py +156 -0
- chrys/app/tui/widgets/chat/tool_call.py +2478 -0
- chrys/app/tui/widgets/chat/tool_registry.py +753 -0
- chrys/app/tui/widgets/chat/tool_renderers.py +247 -0
- chrys/app/tui/widgets/chat/tool_view_builders.py +260 -0
- chrys/app/tui/widgets/chat/transcript_reader.py +57 -0
- chrys/app/tui/widgets/checkbox.py +24 -0
- chrys/app/tui/widgets/chrome/__init__.py +3 -0
- chrys/app/tui/widgets/chrome/app_header.py +283 -0
- chrys/app/tui/widgets/chrome/commands.py +95 -0
- chrys/app/tui/widgets/chrome/file_index.py +68 -0
- chrys/app/tui/widgets/chrome/file_scanner.py +670 -0
- chrys/app/tui/widgets/chrome/footer.py +284 -0
- chrys/app/tui/widgets/chrome/image_paste.py +351 -0
- chrys/app/tui/widgets/chrome/input_bar.py +1299 -0
- chrys/app/tui/widgets/chrome/status_bar.py +911 -0
- chrys/app/tui/widgets/chrome/suggestion_list.py +652 -0
- chrys/app/tui/widgets/click_affordance.py +24 -0
- chrys/app/tui/widgets/color_picker/__init__.py +254 -0
- chrys/app/tui/widgets/color_picker/controls.py +171 -0
- chrys/app/tui/widgets/color_picker/model.py +89 -0
- chrys/app/tui/widgets/dialog_buttons.py +58 -0
- chrys/app/tui/widgets/dialog_scroll.py +24 -0
- chrys/app/tui/widgets/diff_view/__init__.py +20 -0
- chrys/app/tui/widgets/diff_view/cells.py +59 -0
- chrys/app/tui/widgets/diff_view/code.py +280 -0
- chrys/app/tui/widgets/diff_view/compute.py +286 -0
- chrys/app/tui/widgets/diff_view/gutter.py +161 -0
- chrys/app/tui/widgets/diff_view/inline.py +77 -0
- chrys/app/tui/widgets/diff_view/palette.py +87 -0
- chrys/app/tui/widgets/diff_view/protocols.py +24 -0
- chrys/app/tui/widgets/diff_view/rows.py +138 -0
- chrys/app/tui/widgets/diff_view/unified.py +267 -0
- chrys/app/tui/widgets/diff_view/widget.py +209 -0
- chrys/app/tui/widgets/editor/__init__.py +79 -0
- chrys/app/tui/widgets/editor/coordinates.py +30 -0
- chrys/app/tui/widgets/editor/highlighter.py +139 -0
- chrys/app/tui/widgets/editor/keymaps.py +357 -0
- chrys/app/tui/widgets/editor/types.py +216 -0
- chrys/app/tui/widgets/editor/vim.py +1195 -0
- chrys/app/tui/widgets/editor/widget.py +401 -0
- chrys/app/tui/widgets/file_preview.py +58 -0
- chrys/app/tui/widgets/hatch.py +138 -0
- chrys/app/tui/widgets/input.py +66 -0
- chrys/app/tui/widgets/loading.py +125 -0
- chrys/app/tui/widgets/markdown/__init__.py +25 -0
- chrys/app/tui/widgets/markdown/_utils.py +21 -0
- chrys/app/tui/widgets/markdown/anchors.py +71 -0
- chrys/app/tui/widgets/markdown/blocks.py +115 -0
- chrys/app/tui/widgets/markdown/copyable.py +163 -0
- chrys/app/tui/widgets/markdown/diagram/__init__.py +35 -0
- chrys/app/tui/widgets/markdown/diagram/canvas.py +409 -0
- chrys/app/tui/widgets/markdown/diagram/charts.py +52 -0
- chrys/app/tui/widgets/markdown/diagram/diagnostics.py +101 -0
- chrys/app/tui/widgets/markdown/diagram/geometry.py +46 -0
- chrys/app/tui/widgets/markdown/diagram/layout.py +494 -0
- chrys/app/tui/widgets/markdown/diagram/messages.py +18 -0
- chrys/app/tui/widgets/markdown/diagram/model.py +275 -0
- chrys/app/tui/widgets/markdown/diagram/parser.py +173 -0
- chrys/app/tui/widgets/markdown/diagram/parsers/__init__.py +3 -0
- chrys/app/tui/widgets/markdown/diagram/parsers/charts.py +349 -0
- chrys/app/tui/widgets/markdown/diagram/parsers/common.py +403 -0
- chrys/app/tui/widgets/markdown/diagram/parsers/graphs.py +1072 -0
- chrys/app/tui/widgets/markdown/diagram/parsers/planning.py +317 -0
- chrys/app/tui/widgets/markdown/diagram/parsers/schedule.py +298 -0
- chrys/app/tui/widgets/markdown/diagram/parsers/schemas.py +241 -0
- chrys/app/tui/widgets/markdown/diagram/parsers/structure.py +221 -0
- chrys/app/tui/widgets/markdown/diagram/presentation.py +32 -0
- chrys/app/tui/widgets/markdown/diagram/renderers/__init__.py +3 -0
- chrys/app/tui/widgets/markdown/diagram/renderers/charts.py +275 -0
- chrys/app/tui/widgets/markdown/diagram/renderers/common.py +73 -0
- chrys/app/tui/widgets/markdown/diagram/renderers/planning.py +157 -0
- chrys/app/tui/widgets/markdown/diagram/renderers/schedule.py +202 -0
- chrys/app/tui/widgets/markdown/diagram/renderers/structure.py +77 -0
- chrys/app/tui/widgets/markdown/diagram/renderers/xy.py +385 -0
- chrys/app/tui/widgets/markdown/diagram/router.py +651 -0
- chrys/app/tui/widgets/markdown/diagram/specs/__init__.py +3 -0
- chrys/app/tui/widgets/markdown/diagram/specs/charts.py +94 -0
- chrys/app/tui/widgets/markdown/diagram/specs/planning.py +68 -0
- chrys/app/tui/widgets/markdown/diagram/specs/schedule.py +65 -0
- chrys/app/tui/widgets/markdown/diagram/specs/structure.py +23 -0
- chrys/app/tui/widgets/markdown/diagram/viewer.py +92 -0
- chrys/app/tui/widgets/markdown/links.py +47 -0
- chrys/app/tui/widgets/markdown/math/__init__.py +36 -0
- chrys/app/tui/widgets/markdown/math/layout.py +739 -0
- chrys/app/tui/widgets/markdown/math/markdown.py +291 -0
- chrys/app/tui/widgets/markdown/math/parser.py +325 -0
- chrys/app/tui/widgets/markdown/math/symbols.py +325 -0
- chrys/app/tui/widgets/markdown/navigator.py +80 -0
- chrys/app/tui/widgets/markdown/parser.py +1057 -0
- chrys/app/tui/widgets/markdown/stream.py +73 -0
- chrys/app/tui/widgets/markdown/toc.py +98 -0
- chrys/app/tui/widgets/markdown/viewer.py +146 -0
- chrys/app/tui/widgets/markdown/widget.py +2046 -0
- chrys/app/tui/widgets/marquee.py +101 -0
- chrys/app/tui/widgets/option_menu.py +82 -0
- chrys/app/tui/widgets/page_navigator.py +118 -0
- chrys/app/tui/widgets/select.py +196 -0
- chrys/app/tui/widgets/selection.py +59 -0
- chrys/app/tui/widgets/sidebar/__init__.py +3 -0
- chrys/app/tui/widgets/sidebar/buddy.py +367 -0
- chrys/app/tui/widgets/sidebar/context.py +482 -0
- chrys/app/tui/widgets/sidebar/debug.py +195 -0
- chrys/app/tui/widgets/sidebar/empty_state.py +11 -0
- chrys/app/tui/widgets/sidebar/panel.py +198 -0
- chrys/app/tui/widgets/sidebar/tasks.py +198 -0
- chrys/app/tui/widgets/sidebar/toc.py +166 -0
- chrys/app/tui/widgets/sidebar/toc_types.py +30 -0
- chrys/app/tui/widgets/syntax_theme.py +85 -0
- chrys/app/tui/widgets/text_area.py +258 -0
- chrys/app/tui/widgets/trajectory/__init__.py +8 -0
- chrys/app/tui/widgets/trajectory/chartkit.py +264 -0
- chrys/app/tui/widgets/trajectory/insights.py +1266 -0
- chrys/app/tui/widgets/trajectory/overview.py +1101 -0
- chrys/app/tui/widgets/trajectory/panel.py +983 -0
- chrys/app/tui/widgets/trajectory/presentation.py +311 -0
- chrys/app/tui/widgets/trajectory/session_info.py +124 -0
- chrys/app/tui/widgets/trajectory/text_view.py +124 -0
- chrys/app/tui/widgets/trajectory/timeline.py +380 -0
- chrys/app/tui/widgets/welcome.py +126 -0
- chrys/app/tui/widgets/workflow/__init__.py +5 -0
- chrys/app/tui/widgets/workflow/edges.py +89 -0
- chrys/app/tui/widgets/workflow/graph.py +869 -0
- chrys/app/tui/widgets/workflow/info.py +310 -0
- chrys/app/tui/widgets/workflow/node_view.py +27 -0
- chrys/app/tui/widgets/workflow/output.py +225 -0
- chrys/app/tui/widgets/workflow/panel.py +658 -0
- chrys/app/tui/widgets/workflow/projector.py +324 -0
- chrys/app/tui/widgets/workflow/records.py +69 -0
- chrys/app/tui/widgets/workflow/scrollbar.py +82 -0
- chrys/app/tui/widgets/workflow/selection.py +151 -0
- chrys/app/tui/widgets/workflow/source.py +65 -0
- chrys/app/tui/widgets/workflow/text.py +257 -0
- chrys/app/tui/widgets/workflow/values.py +317 -0
- chrys/foundation/__init__.py +0 -0
- chrys/foundation/branding.py +15 -0
- chrys/foundation/config/__init__.py +7 -0
- chrys/foundation/config/coercion.py +374 -0
- chrys/foundation/config/context.py +34 -0
- chrys/foundation/config/env_file.py +141 -0
- chrys/foundation/config/env_layers.py +370 -0
- chrys/foundation/config/migrations.py +521 -0
- chrys/foundation/config/notification_events.py +22 -0
- chrys/foundation/config/process_settings.py +332 -0
- chrys/foundation/config/runtime_pointer.py +133 -0
- chrys/foundation/config/settings.py +1952 -0
- chrys/foundation/config/settings_store.py +996 -0
- chrys/foundation/config/spec.py +396 -0
- chrys/foundation/config/user_settings.py +140 -0
- chrys/foundation/config/warnings.py +262 -0
- chrys/foundation/config/web_values.py +135 -0
- chrys/foundation/config/yaml_store.py +487 -0
- chrys/foundation/errors/__init__.py +68 -0
- chrys/foundation/errors/_legacy.py +117 -0
- chrys/foundation/errors/_text.py +13 -0
- chrys/foundation/errors/_walk.py +85 -0
- chrys/foundation/errors/classify.py +278 -0
- chrys/foundation/errors/display.py +274 -0
- chrys/foundation/errors/formatting.py +283 -0
- chrys/foundation/errors/kinds.py +67 -0
- chrys/foundation/errors/network.py +497 -0
- chrys/foundation/errors/provider.py +445 -0
- chrys/foundation/errors/route.py +85 -0
- chrys/foundation/events/__init__.py +8 -0
- chrys/foundation/events/bus.py +143 -0
- chrys/foundation/events/types.py +1629 -0
- chrys/foundation/events/workflow.py +38 -0
- chrys/foundation/hosted_tools.py +142 -0
- chrys/foundation/i18n/__init__.py +32 -0
- chrys/foundation/i18n/_catalogs/zh-Hans/LC_MESSAGES/chrys.mo +0 -0
- chrys/foundation/i18n/catalogs.py +42 -0
- chrys/foundation/i18n/formatting.py +202 -0
- chrys/foundation/i18n/locale.py +92 -0
- chrys/foundation/i18n/localizer.py +187 -0
- chrys/foundation/i18n/messages.py +268 -0
- chrys/foundation/io/__init__.py +3 -0
- chrys/foundation/io/result_content.py +237 -0
- chrys/foundation/models/__init__.py +3 -0
- chrys/foundation/models/approval_reuse.py +23 -0
- chrys/foundation/models/ask_user.py +468 -0
- chrys/foundation/models/execution.py +18 -0
- chrys/foundation/models/history_markers.py +115 -0
- chrys/foundation/models/invocations.py +63 -0
- chrys/foundation/models/mutation_scope.py +28 -0
- chrys/foundation/models/session_env.py +87 -0
- chrys/foundation/models/session_surface.py +29 -0
- chrys/foundation/models/todos.py +74 -0
- chrys/foundation/models/turns.py +125 -0
- chrys/foundation/models/workflow_session.py +89 -0
- chrys/foundation/models/workspace.py +59 -0
- chrys/foundation/net/__init__.py +3 -0
- chrys/foundation/net/address_class.py +57 -0
- chrys/foundation/net/route_probe.py +94 -0
- chrys/foundation/net/url.py +107 -0
- chrys/foundation/observability/__init__.py +3 -0
- chrys/foundation/observability/exporters.py +174 -0
- chrys/foundation/observability/gate.py +31 -0
- chrys/foundation/observability/setup.py +497 -0
- chrys/foundation/observability/sink.py +228 -0
- chrys/foundation/patches/__init__.py +19 -0
- chrys/foundation/patches/mdurl_cache.py +59 -0
- chrys/foundation/patches/patcher.py +287 -0
- chrys/foundation/patches/staged_members.py +205 -0
- chrys/foundation/patches/textual_block_border.py +105 -0
- chrys/foundation/patches/textual_button_ansi.py +65 -0
- chrys/foundation/patches/textual_button_ansi_old.txt +68 -0
- chrys/foundation/patches/textual_callback_cache.py +248 -0
- chrys/foundation/patches/textual_callback_dispatch.py +109 -0
- chrys/foundation/patches/textual_compositor_cjk.py +566 -0
- chrys/foundation/patches/textual_dispatch_cache.py +150 -0
- chrys/foundation/patches/textual_ime_cursor_anchor.py +92 -0
- chrys/foundation/patches/textual_kitty_keyboard.py +268 -0
- chrys/foundation/patches/textual_lru_acyclic.py +241 -0
- chrys/foundation/patches/textual_message_pump.py +136 -0
- chrys/foundation/patches/textual_node_diet.py +875 -0
- chrys/foundation/patches/textual_one_shot_timer.py +48 -0
- chrys/foundation/patches/textual_option_list.py +90 -0
- chrys/foundation/patches/textual_precompose.py +89 -0
- chrys/foundation/patches/textual_pruned_tabs.py +69 -0
- chrys/foundation/patches/textual_reflow_reuse.py +1753 -0
- chrys/foundation/patches/textual_removed_node_caches.py +86 -0
- chrys/foundation/patches/textual_removed_screen_callbacks.py +55 -0
- chrys/foundation/patches/textual_selection_extract.py +48 -0
- chrys/foundation/patches/textual_strip_cycles.py +119 -0
- chrys/foundation/patches/textual_tab_selection.py +1611 -0
- chrys/foundation/patches/textual_timer_skip.py +70 -0
- chrys/foundation/patches/textual_utf8_decoder.py +106 -0
- chrys/foundation/patches/textual_win_sleep.py +167 -0
- chrys/foundation/patches/watchdog_fsevents.py +70 -0
- chrys/foundation/patches/watchdog_windows.py +52 -0
- chrys/foundation/platform/__init__.py +556 -0
- chrys/foundation/platform/c_api.py +32 -0
- chrys/foundation/platform/child_reap.py +107 -0
- chrys/foundation/platform/command_line.py +95 -0
- chrys/foundation/platform/files.py +1470 -0
- chrys/foundation/platform/output_capture.py +113 -0
- chrys/foundation/platform/paths.py +193 -0
- chrys/foundation/platform/process.py +1468 -0
- chrys/foundation/platform/pty_output.py +19 -0
- chrys/foundation/platform/runtime_paths.py +281 -0
- chrys/foundation/platform/win_console.py +129 -0
- chrys/foundation/reasoning_origin.py +67 -0
- chrys/foundation/recovery.py +16 -0
- chrys/foundation/retry.py +278 -0
- chrys/foundation/text/__init__.py +3 -0
- chrys/foundation/text/encoding.py +603 -0
- chrys/foundation/text/images.py +304 -0
- chrys/foundation/text/lines.py +24 -0
- chrys/foundation/text/mentions.py +90 -0
- chrys/foundation/text/model_json.py +25 -0
- chrys/foundation/text/reading_order.py +20 -0
- chrys/foundation/text/tokenizer.py +25 -0
- chrys/foundation/text/tool_output.py +287 -0
- chrys/foundation/text/yaml_io.py +62 -0
- chrys/foundation/tool_call_context.py +202 -0
- chrys/foundation/tool_execution_stamp.py +184 -0
- chrys/foundation/tool_invocation_order.py +48 -0
- chrys/foundation/tool_kinds.py +102 -0
- chrys/foundation/tool_result_metadata.py +287 -0
- chrys/foundation/trajectory/__init__.py +10 -0
- chrys/foundation/trajectory/context.py +481 -0
- chrys/foundation/trajectory/envelope.py +571 -0
- chrys/foundation/trajectory/event_types.py +294 -0
- chrys/foundation/trajectory/finalizers.py +46 -0
- chrys/foundation/trajectory/fingerprint.py +62 -0
- chrys/foundation/trajectory/ids.py +155 -0
- chrys/foundation/trajectory/keys.py +99 -0
- chrys/foundation/trajectory/lease.py +173 -0
- chrys/foundation/trajectory/metadata.py +72 -0
- chrys/foundation/trajectory/reader.py +271 -0
- chrys/foundation/trajectory/recovery.py +225 -0
- chrys/foundation/trajectory/revisions.py +152 -0
- chrys/foundation/trajectory/segments.py +225 -0
- chrys/foundation/trajectory/tools.py +117 -0
- chrys/foundation/trajectory/usage.py +151 -0
- chrys/foundation/trajectory/writer.py +972 -0
- chrys/foundation/trajectory_timing.py +97 -0
- chrys/foundation/util/__init__.py +3 -0
- chrys/foundation/util/async_tasks.py +29 -0
- chrys/foundation/util/chrys_headers.py +23 -0
- chrys/foundation/util/env_templates.py +104 -0
- chrys/foundation/util/filenames.py +96 -0
- chrys/foundation/util/header_charset.py +138 -0
- chrys/foundation/util/httpx_helpers.py +12 -0
- chrys/foundation/util/lock.py +236 -0
- chrys/foundation/util/once_close.py +46 -0
- chrys/foundation/util/session_ids.py +29 -0
- chrys/foundation/util/shell_tokens.py +88 -0
- chrys/foundation/util/sub_agent_context.py +38 -0
- chrys/foundation/util/time.py +35 -0
- chrys/foundation/util/unicode_scalars.py +36 -0
- chrys/foundation/vendor/__init__.py +43 -0
- chrys/foundation/vendor/ripgrep/rg-aarch64-apple-darwin +0 -0
- chrys/foundation/vendor/ripgrep/rg-aarch64-pc-windows-msvc.exe +0 -0
- chrys/foundation/vendor/ripgrep/rg-aarch64-unknown-linux-gnu +0 -0
- chrys/foundation/vendor/ripgrep/rg-x86_64-apple-darwin +0 -0
- chrys/foundation/vendor/ripgrep/rg-x86_64-pc-windows-msvc.exe +0 -0
- chrys/foundation/vendor/ripgrep/rg-x86_64-unknown-linux-musl +0 -0
- chrys/kernel/__init__.py +256 -0
- chrys/kernel/_content.py +1866 -0
- chrys/kernel/_loop_recorder.py +631 -0
- chrys/kernel/_null_overlay.py +1026 -0
- chrys/kernel/_result_ceiling.py +216 -0
- chrys/kernel/_serialization.py +431 -0
- chrys/kernel/_tool_arg_errors.py +1629 -0
- chrys/kernel/_tool_execution.py +1172 -0
- chrys/kernel/_tool_expansion.py +26 -0
- chrys/kernel/_types.py +2598 -0
- chrys/kernel/agent.py +994 -0
- chrys/kernel/client.py +1084 -0
- chrys/kernel/compaction.py +1315 -0
- chrys/kernel/exceptions.py +211 -0
- chrys/kernel/exchanges.py +683 -0
- chrys/kernel/identity.py +95 -0
- chrys/kernel/images.py +36 -0
- chrys/kernel/instrumentation.py +1618 -0
- chrys/kernel/loop.py +2308 -0
- chrys/kernel/middleware.py +616 -0
- chrys/kernel/sessions.py +604 -0
- chrys/kernel/tools.py +1061 -0
- chrys/kernel/types.py +126 -0
- chrys/orchestration/__init__.py +3 -0
- chrys/orchestration/engine/__init__.py +3 -0
- chrys/orchestration/engine/assembly.py +236 -0
- chrys/orchestration/engine/build/__init__.py +3 -0
- chrys/orchestration/engine/build/builder.py +1061 -0
- chrys/orchestration/engine/build/construction.py +408 -0
- chrys/orchestration/engine/build/loaded.py +139 -0
- chrys/orchestration/engine/engine.py +789 -0
- chrys/orchestration/engine/execution.py +771 -0
- chrys/orchestration/engine/loader.py +865 -0
- chrys/orchestration/engine/rollback.py +918 -0
- chrys/orchestration/engine/run/__init__.py +3 -0
- chrys/orchestration/engine/run/active_injection.py +419 -0
- chrys/orchestration/engine/run/attachments.py +519 -0
- chrys/orchestration/engine/run/bindings.py +1095 -0
- chrys/orchestration/engine/run/coordinator.py +1062 -0
- chrys/orchestration/engine/run/finalizer.py +417 -0
- chrys/orchestration/engine/run/input_refs.py +60 -0
- chrys/orchestration/engine/run/prompt_content.py +457 -0
- chrys/orchestration/engine/run/resume.py +299 -0
- chrys/orchestration/engine/run/retry.py +948 -0
- chrys/orchestration/engine/run/runner.py +625 -0
- chrys/orchestration/engine/run/runtime_skills.py +146 -0
- chrys/orchestration/engine/run/sub_agent_coordination.py +126 -0
- chrys/orchestration/engine/run/turn_hooks.py +258 -0
- chrys/orchestration/engine/run/turn_state.py +149 -0
- chrys/orchestration/engine/run/working_dir.py +50 -0
- chrys/orchestration/engine/session_lifecycle.py +2013 -0
- chrys/orchestration/engine/state/__init__.py +3 -0
- chrys/orchestration/engine/state/active_session.py +183 -0
- chrys/orchestration/engine/state/controls.py +639 -0
- chrys/orchestration/engine/state/current_agent.py +26 -0
- chrys/orchestration/engine/state/lifecycle_permits.py +395 -0
- chrys/orchestration/engine/state/machine.py +193 -0
- chrys/orchestration/engine/state/session_writer.py +434 -0
- chrys/orchestration/engine/trajectory.py +714 -0
- chrys/orchestration/engine/usage.py +118 -0
- chrys/orchestration/invoker/__init__.py +3 -0
- chrys/orchestration/invoker/acp.py +727 -0
- chrys/orchestration/invoker/acp_protocol.py +1115 -0
- chrys/orchestration/invoker/acp_spec.py +79 -0
- chrys/orchestration/invoker/attempts.py +994 -0
- chrys/orchestration/invoker/child_compaction.py +131 -0
- chrys/orchestration/invoker/child_history.py +99 -0
- chrys/orchestration/invoker/contracts.py +253 -0
- chrys/orchestration/invoker/evidence.py +94 -0
- chrys/orchestration/invoker/kernel.py +343 -0
- chrys/orchestration/invoker/origin.py +79 -0
- chrys/orchestration/invoker/resources.py +343 -0
- chrys/orchestration/invoker/runtime.py +299 -0
- chrys/orchestration/invoker/usage.py +80 -0
- chrys/orchestration/session_hooks.py +117 -0
- chrys/orchestration/session_host.py +1023 -0
- chrys/orchestration/session_resources.py +95 -0
- chrys/orchestration/session_usage.py +219 -0
- chrys/orchestration/startup.py +255 -0
- chrys/orchestration/sub_agents/__init__.py +3 -0
- chrys/orchestration/sub_agents/acp_policy.py +269 -0
- chrys/orchestration/sub_agents/kernel_policy.py +848 -0
- chrys/orchestration/sub_agents/registration.py +44 -0
- chrys/orchestration/sub_agents/shell.py +337 -0
- chrys/orchestration/sub_agents/tools.py +2228 -0
- chrys/orchestration/workflows/__init__.py +3 -0
- chrys/orchestration/workflows/agent_archive.py +156 -0
- chrys/orchestration/workflows/agent_node.py +894 -0
- chrys/orchestration/workflows/agent_node_build.py +687 -0
- chrys/orchestration/workflows/catalog.py +332 -0
- chrys/orchestration/workflows/coordinator.py +771 -0
- chrys/orchestration/workflows/hooks.py +176 -0
- chrys/orchestration/workflows/preview.py +322 -0
- chrys/orchestration/workflows/rollback.py +151 -0
- chrys/orchestration/workflows/runner.py +986 -0
- chrys/orchestration/workflows/session.py +390 -0
- chrys/orchestration/workflows/settings.py +97 -0
- chrys/orchestration/workflows/validation.py +674 -0
- chrys/orchestration/workflows/worker_client.py +1002 -0
- chrys/service/__init__.py +3 -0
- chrys/service/acp_client/__init__.py +65 -0
- chrys/service/acp_client/_transport.py +922 -0
- chrys/service/acp_client/client.py +1311 -0
- chrys/service/acp_client/errors.py +224 -0
- chrys/service/acp_client/protocol.py +220 -0
- chrys/service/acp_client/spawn.py +239 -0
- chrys/service/acp_client/spec.py +100 -0
- chrys/service/agent_middleware/__init__.py +60 -0
- chrys/service/agent_middleware/_metadata_keys.py +52 -0
- chrys/service/agent_middleware/control/__init__.py +3 -0
- chrys/service/agent_middleware/control/approval.py +769 -0
- chrys/service/agent_middleware/control/approval_hooks.py +62 -0
- chrys/service/agent_middleware/control/ask_user.py +207 -0
- chrys/service/agent_middleware/control/interrupt.py +50 -0
- chrys/service/agent_middleware/control/sleep.py +118 -0
- chrys/service/agent_middleware/control/todo.py +117 -0
- chrys/service/agent_middleware/events/__init__.py +3 -0
- chrys/service/agent_middleware/events/hook_dispatch.py +250 -0
- chrys/service/agent_middleware/events/hosted_tools.py +1762 -0
- chrys/service/agent_middleware/events/intermediate_text.py +128 -0
- chrys/service/agent_middleware/events/rejection_metadata.py +50 -0
- chrys/service/agent_middleware/events/result_persistence.py +98 -0
- chrys/service/agent_middleware/events/sub_agent_events.py +951 -0
- chrys/service/agent_middleware/events/tool_error_text.py +22 -0
- chrys/service/agent_middleware/events/tool_events.py +779 -0
- chrys/service/agent_middleware/injection.py +510 -0
- chrys/service/agent_middleware/reminders/__init__.py +91 -0
- chrys/service/agent_middleware/reminders/archive_pointer.py +154 -0
- chrys/service/agent_middleware/reminders/base.py +25 -0
- chrys/service/agent_middleware/reminders/context_usage.py +74 -0
- chrys/service/agent_middleware/reminders/file_change.py +63 -0
- chrys/service/agent_middleware/reminders/mcp.py +39 -0
- chrys/service/agent_middleware/reminders/profile_switch.py +106 -0
- chrys/service/agent_middleware/reminders/runtime_env.py +190 -0
- chrys/service/agent_middleware/reminders/skills.py +44 -0
- chrys/service/agent_middleware/reminders/sub_agents.py +35 -0
- chrys/service/agent_middleware/reminders/todo.py +35 -0
- chrys/service/agent_middleware/reminders/turn_line.py +48 -0
- chrys/service/agent_middleware/response_validation.py +1380 -0
- chrys/service/agent_middleware/system_reminder.py +1107 -0
- chrys/service/agent_middleware/validators.py +396 -0
- chrys/service/analytics/__init__.py +124 -0
- chrys/service/analytics/_actions.py +896 -0
- chrys/service/analytics/_context_evidence.py +357 -0
- chrys/service/analytics/_critical_path.py +179 -0
- chrys/service/analytics/_facts.py +919 -0
- chrys/service/analytics/_insights.py +769 -0
- chrys/service/analytics/_metric_ops.py +83 -0
- chrys/service/analytics/_session_projection.py +460 -0
- chrys/service/analytics/_timeline.py +434 -0
- chrys/service/analytics/_turn_graph.py +1237 -0
- chrys/service/analytics/_turns.py +1377 -0
- chrys/service/analytics/_workflows.py +171 -0
- chrys/service/analytics/aggregation.py +1474 -0
- chrys/service/analytics/classification.py +128 -0
- chrys/service/analytics/export.py +803 -0
- chrys/service/analytics/findings.py +282 -0
- chrys/service/analytics/math.py +79 -0
- chrys/service/analytics/model.py +886 -0
- chrys/service/analytics/reader.py +321 -0
- chrys/service/approval/__init__.py +3 -0
- chrys/service/approval/arbitration.py +102 -0
- chrys/service/approval/command_identity.py +109 -0
- chrys/service/approval/correlation.py +57 -0
- chrys/service/approval/grant_store.py +108 -0
- chrys/service/approval/judge.py +589 -0
- chrys/service/approval/level.py +15 -0
- chrys/service/approval/policy.py +209 -0
- chrys/service/approval/reuse.py +223 -0
- chrys/service/approval/reuse_binding.py +133 -0
- chrys/service/approval/safety_classifier.py +536 -0
- chrys/service/approval/turn_context.py +49 -0
- chrys/service/context/__init__.py +3 -0
- chrys/service/context/compaction/__init__.py +38 -0
- chrys/service/context/compaction/breaker.py +156 -0
- chrys/service/context/compaction/budgets.py +93 -0
- chrys/service/context/compaction/calibration.py +77 -0
- chrys/service/context/compaction/compression.py +690 -0
- chrys/service/context/compaction/current_turn_drop.py +458 -0
- chrys/service/context/compaction/events.py +201 -0
- chrys/service/context/compaction/exclusions.py +261 -0
- chrys/service/context/compaction/groups.py +361 -0
- chrys/service/context/compaction/last_words.py +1996 -0
- chrys/service/context/compaction/last_words_state.py +752 -0
- chrys/service/context/compaction/scoped.py +472 -0
- chrys/service/context/compaction/spill.py +1947 -0
- chrys/service/context/compaction/strategy.py +1116 -0
- chrys/service/context/compaction/summaries.py +319 -0
- chrys/service/context/compaction/turns.py +375 -0
- chrys/service/context/manager.py +174 -0
- chrys/service/context/memory_loader.py +792 -0
- chrys/service/context/middleware/__init__.py +3 -0
- chrys/service/context/middleware/usage.py +332 -0
- chrys/service/context/providers/__init__.py +3 -0
- chrys/service/context/providers/context_management.py +432 -0
- chrys/service/context/providers/history.py +647 -0
- chrys/service/context/providers/memory.py +50 -0
- chrys/service/context/tool_content.py +22 -0
- chrys/service/hooks/__init__.py +37 -0
- chrys/service/hooks/detached_worker.py +118 -0
- chrys/service/hooks/docs/README.md +14 -0
- chrys/service/hooks/docs/authoring.md +684 -0
- chrys/service/hooks/docs/configuration.md +499 -0
- chrys/service/hooks/docs/design.md +359 -0
- chrys/service/hooks/docs/project-hooks.md +348 -0
- chrys/service/hooks/events.py +157 -0
- chrys/service/hooks/loader.py +665 -0
- chrys/service/hooks/manager.py +807 -0
- chrys/service/hooks/matcher.py +111 -0
- chrys/service/hooks/outbox.py +294 -0
- chrys/service/hooks/runner.py +572 -0
- chrys/service/hooks/schema.py +407 -0
- chrys/service/llm/__init__.py +7 -0
- chrys/service/llm/_structured_outputs.py +192 -0
- chrys/service/llm/anthropic_messages/__init__.py +9 -0
- chrys/service/llm/anthropic_messages/client.py +254 -0
- chrys/service/llm/anthropic_messages/decode.py +331 -0
- chrys/service/llm/anthropic_messages/history.py +279 -0
- chrys/service/llm/anthropic_messages/request.py +323 -0
- chrys/service/llm/anthropic_messages/server_tools.py +319 -0
- chrys/service/llm/anthropic_messages/stream.py +297 -0
- chrys/service/llm/anthropic_messages/thinking_binding.py +156 -0
- chrys/service/llm/chat_completions/__init__.py +9 -0
- chrys/service/llm/chat_completions/client.py +369 -0
- chrys/service/llm/chat_completions/decode.py +338 -0
- chrys/service/llm/chat_completions/history.py +657 -0
- chrys/service/llm/chat_completions/reasoning.py +244 -0
- chrys/service/llm/chat_completions/request.py +192 -0
- chrys/service/llm/chat_completions/stream.py +546 -0
- chrys/service/llm/chat_completions/validation.py +308 -0
- chrys/service/llm/clients.py +613 -0
- chrys/service/llm/images.py +65 -0
- chrys/service/llm/mock.py +413 -0
- chrys/service/llm/observer.py +446 -0
- chrys/service/llm/one_shot.py +106 -0
- chrys/service/llm/openai_exceptions.py +93 -0
- chrys/service/llm/openai_responses/__init__.py +10 -0
- chrys/service/llm/openai_responses/client.py +323 -0
- chrys/service/llm/openai_responses/decode.py +432 -0
- chrys/service/llm/openai_responses/history.py +519 -0
- chrys/service/llm/openai_responses/hosted.py +625 -0
- chrys/service/llm/openai_responses/replay.py +629 -0
- chrys/service/llm/openai_responses/request.py +342 -0
- chrys/service/llm/openai_responses/stream.py +847 -0
- chrys/service/llm/openai_timestamps.py +57 -0
- chrys/service/llm/providers.py +107 -0
- chrys/service/llm/proxy_route.py +54 -0
- chrys/service/llm/raw_http_log.py +309 -0
- chrys/service/llm/route_facts.py +63 -0
- chrys/service/llm/route_sessions.py +49 -0
- chrys/service/llm/sdk_anthropic.py +18 -0
- chrys/service/llm/sdk_headers.py +47 -0
- chrys/service/llm/sdk_openai.py +18 -0
- chrys/service/llm/sdk_retry.py +59 -0
- chrys/service/llm/wire_client.py +246 -0
- chrys/service/mcp/__init__.py +3 -0
- chrys/service/mcp/_connection.py +235 -0
- chrys/service/mcp/_http_transport.py +350 -0
- chrys/service/mcp/_progressive.py +459 -0
- chrys/service/mcp/_stdio_transport.py +614 -0
- chrys/service/mcp/_tool_mixins.py +96 -0
- chrys/service/mcp/adapter.py +1031 -0
- chrys/service/mcp/cache.py +476 -0
- chrys/service/mcp/content.py +32 -0
- chrys/service/mcp/errors.py +169 -0
- chrys/service/mcp/owned.py +1330 -0
- chrys/service/mcp/result_limits.py +168 -0
- chrys/service/mcp/thinking_warning.py +95 -0
- chrys/service/mcp/validation.py +74 -0
- chrys/service/mutations/__init__.py +84 -0
- chrys/service/mutations/coordination.py +894 -0
- chrys/service/mutations/detector.py +458 -0
- chrys/service/mutations/git_calibrator.py +397 -0
- chrys/service/mutations/git_state.py +647 -0
- chrys/service/mutations/pipeline.py +779 -0
- chrys/service/mutations/scanner.py +466 -0
- chrys/service/mutations/snapshot_files.py +233 -0
- chrys/service/mutations/store.py +625 -0
- chrys/service/mutations/tool_names.py +15 -0
- chrys/service/mutations/trace.py +246 -0
- chrys/service/mutations/tracker.py +1289 -0
- chrys/service/mutations/types.py +559 -0
- chrys/service/mutations/workspace_changes.py +1583 -0
- chrys/service/profiles/__init__.py +2 -0
- chrys/service/profiles/agents/__init__.py +3 -0
- chrys/service/profiles/agents/builtins/Code.yaml +199 -0
- chrys/service/profiles/agents/builtins/Explore.yaml +62 -0
- chrys/service/profiles/agents/builtins/General.yaml +114 -0
- chrys/service/profiles/agents/builtins/QA.yaml +128 -0
- chrys/service/profiles/agents/loader.py +808 -0
- chrys/service/profiles/agents/registry.py +727 -0
- chrys/service/profiles/agents/schema.py +371 -0
- chrys/service/profiles/agents/serializer.py +196 -0
- chrys/service/profiles/coercion.py +22 -0
- chrys/service/profiles/models/__init__.py +3 -0
- chrys/service/profiles/models/env_bridge.py +157 -0
- chrys/service/profiles/models/loader.py +282 -0
- chrys/service/profiles/models/options.py +438 -0
- chrys/service/profiles/models/registry.py +104 -0
- chrys/service/profiles/models/resolver.py +286 -0
- chrys/service/profiles/models/schema.py +91 -0
- chrys/service/profiles/models/serializer.py +76 -0
- chrys/service/session/__init__.py +3 -0
- chrys/service/session/checkpoint.py +156 -0
- chrys/service/session/history.py +1616 -0
- chrys/service/session/message_metadata.py +151 -0
- chrys/service/session/persistence.py +435 -0
- chrys/service/session/runtime_metadata.py +210 -0
- chrys/service/session/sub_agent_logs.py +1069 -0
- chrys/service/session/sub_agent_transcript.py +654 -0
- chrys/service/skills/__init__.py +3 -0
- chrys/service/skills/adapter.py +408 -0
- chrys/service/skills/constants.py +8 -0
- chrys/service/skills/loader.py +575 -0
- chrys/service/skills/model.py +130 -0
- chrys/service/skills/provider.py +841 -0
- chrys/service/skills/runner.py +390 -0
- chrys/service/state/__init__.py +3 -0
- chrys/service/state/_fork.py +710 -0
- chrys/service/state/_session_files.py +175 -0
- chrys/service/state/_session_meta.py +552 -0
- chrys/service/state/locks.py +154 -0
- chrys/service/state/serializers.py +156 -0
- chrys/service/state/session_catalog.py +361 -0
- chrys/service/state/session_listing.py +84 -0
- chrys/service/state/session_migration.py +446 -0
- chrys/service/state/session_mru.py +315 -0
- chrys/service/state/store.py +2132 -0
- chrys/service/state/workflow.py +158 -0
- chrys/service/text_blocks.py +47 -0
- chrys/service/todos/__init__.py +3 -0
- chrys/service/todos/reminder.py +31 -0
- chrys/service/todos/tracker.py +58 -0
- chrys/service/tools/__init__.py +3 -0
- chrys/service/tools/approval_targets.py +92 -0
- chrys/service/tools/builtins/__init__.py +3 -0
- chrys/service/tools/builtins/ask_user.py +326 -0
- chrys/service/tools/builtins/doc_converter/__init__.py +494 -0
- chrys/service/tools/builtins/doc_converter/artifacts.py +392 -0
- chrys/service/tools/builtins/doc_converter/parsers/__init__.py +3 -0
- chrys/service/tools/builtins/doc_converter/parsers/_table.py +34 -0
- chrys/service/tools/builtins/doc_converter/parsers/base.py +101 -0
- chrys/service/tools/builtins/doc_converter/parsers/docx.py +88 -0
- chrys/service/tools/builtins/doc_converter/parsers/pdf.py +144 -0
- chrys/service/tools/builtins/doc_converter/parsers/pptx.py +103 -0
- chrys/service/tools/builtins/doc_converter/parsers/xls.py +32 -0
- chrys/service/tools/builtins/doc_converter/parsers/xlsx.py +51 -0
- chrys/service/tools/builtins/doc_converter/registry.py +55 -0
- chrys/service/tools/builtins/filesystem.py +1071 -0
- chrys/service/tools/builtins/search.py +1265 -0
- chrys/service/tools/builtins/shell.py +967 -0
- chrys/service/tools/builtins/shell_command_filtering/__init__.py +5 -0
- chrys/service/tools/builtins/shell_command_filtering/policy.py +60 -0
- chrys/service/tools/builtins/shell_command_filtering/presets.py +152 -0
- chrys/service/tools/builtins/shell_command_filtering/readonly/__init__.py +358 -0
- chrys/service/tools/builtins/shell_command_filtering/readonly/commands.py +416 -0
- chrys/service/tools/builtins/shell_command_filtering/readonly/git.py +408 -0
- chrys/service/tools/builtins/shell_command_filtering/readonly/syntax.py +87 -0
- chrys/service/tools/builtins/shell_command_filtering/tokenizer.py +214 -0
- chrys/service/tools/builtins/shell_filter.py +24 -0
- chrys/service/tools/builtins/sleep.py +91 -0
- chrys/service/tools/builtins/todo.py +64 -0
- chrys/service/tools/builtins/web/__init__.py +6 -0
- chrys/service/tools/builtins/web/build.py +268 -0
- chrys/service/tools/builtins/web/config.py +338 -0
- chrys/service/tools/builtins/web/credentials.py +37 -0
- chrys/service/tools/builtins/web/fetch/__init__.py +3 -0
- chrys/service/tools/builtins/web/fetch/cache.py +68 -0
- chrys/service/tools/builtins/web/fetch/convert.py +56 -0
- chrys/service/tools/builtins/web/fetch/tool.py +223 -0
- chrys/service/tools/builtins/web/hosted.py +61 -0
- chrys/service/tools/builtins/web/http.py +330 -0
- chrys/service/tools/builtins/web/progress.py +18 -0
- chrys/service/tools/builtins/web/search/__init__.py +3 -0
- chrys/service/tools/builtins/web/search/exa_mcp.py +146 -0
- chrys/service/tools/builtins/web/search/html.py +152 -0
- chrys/service/tools/builtins/web/search/json_api.py +227 -0
- chrys/service/tools/builtins/web/search/providers.py +77 -0
- chrys/service/tools/builtins/web/search/tool.py +218 -0
- chrys/service/tools/builtins/web/search/types.py +28 -0
- chrys/service/tools/builtins/web/tls_identity.py +66 -0
- chrys/service/tools/kinds.py +115 -0
- chrys/service/tools/names.py +47 -0
- chrys/service/tools/registry.py +242 -0
- chrys/service/tools/result_metadata.py +103 -0
- chrys/service/tools/session_artifacts.py +196 -0
- chrys/service/tools/spill.py +218 -0
- chrys/service/tools/workspace_paths.py +81 -0
- chrys/service/trajectory/__init__.py +11 -0
- chrys/service/trajectory/approvals.py +201 -0
- chrys/service/trajectory/compaction.py +420 -0
- chrys/service/trajectory/fork.py +75 -0
- chrys/service/trajectory/hooks.py +217 -0
- chrys/service/trajectory/items.py +41 -0
- chrys/service/trajectory/preparation.py +374 -0
- chrys/service/trajectory/retries.py +95 -0
- chrys/service/trajectory/revisions.py +129 -0
- chrys/service/trajectory/segmented.py +163 -0
- chrys/service/trajectory/session.py +762 -0
- chrys/service/trajectory/state.py +83 -0
- chrys/service/trajectory/sub_agents.py +169 -0
- chrys/service/trajectory/tombstone.py +262 -0
- chrys/service/trajectory/tools.py +323 -0
- chrys/service/trajectory/validation.py +130 -0
- chrys/service/trajectory/waits.py +161 -0
- chrys/service/trajectory/workflow.py +148 -0
- chrys/service/vision.py +128 -0
- chrys/service/workflows/__init__.py +3 -0
- chrys/service/workflows/admission.py +151 -0
- chrys/service/workflows/artifacts.py +109 -0
- chrys/service/workflows/asks.py +130 -0
- chrys/service/workflows/builtins/__init__.py +12 -0
- chrys/service/workflows/builtins/demo-workflow.manifest.json +635 -0
- chrys/service/workflows/builtins/demo-workflow.py +756 -0
- chrys/service/workflows/discovery.py +554 -0
- chrys/service/workflows/environment.py +284 -0
- chrys/service/workflows/graph.py +430 -0
- chrys/service/workflows/history.py +82 -0
- chrys/service/workflows/interpreter.py +107 -0
- chrys/service/workflows/journal.py +334 -0
- chrys/service/workflows/layout.py +56 -0
- chrys/service/workflows/ledger.py +149 -0
- chrys/service/workflows/model_selection.py +18 -0
- chrys/service/workflows/orphans.py +209 -0
- chrys/service/workflows/outcomes.py +46 -0
- chrys/service/workflows/protocol.py +210 -0
- chrys/service/workflows/records.py +142 -0
- chrys/service/workflows/scheduler.py +770 -0
- chrys/service/workflows/sdk/__init__.py +51 -0
- chrys/service/workflows/sdk/_ask.py +167 -0
- chrys/service/workflows/sdk/_builder.py +781 -0
- chrys/service/workflows/sdk/_values.py +92 -0
- chrys/service/workflows/sdk_artifact.py +74 -0
- chrys/service/workflows/store.py +494 -0
- chrys/service/workflows/transcript.py +102 -0
- chrys/service/workflows/values.py +73 -0
- chrys/service/workflows/worker_host.py +1820 -0
- chrys/workflows.py +38 -0
- icode_tui-0.29.1.dist-info/METADATA +104 -0
- icode_tui-0.29.1.dist-info/RECORD +1138 -0
- icode_tui-0.29.1.dist-info/WHEEL +4 -0
- icode_tui-0.29.1.dist-info/entry_points.txt +2 -0
- icode_tui-0.29.1.dist-info/licenses/LICENSE +202 -0
- icode_tui-0.29.1.dist-info/licenses/NOTICE +1955 -0
|
@@ -0,0 +1,789 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Agent engine entry point, event subscriptions, and component facades.
|
|
4
|
+
|
|
5
|
+
Assembly supplies ten long-lived components: session, permits, current, writer,
|
|
6
|
+
usage_publisher, loader, lifecycle, rollback, turns, and controls. The coordinator
|
|
7
|
+
owns turn state and its execution lease; assembly shares hook dispatch between
|
|
8
|
+
the loader and coordinator. current.loaded owns one installed build, changes on
|
|
9
|
+
install or release, and is None after shutdown. current.manifest describes the
|
|
10
|
+
most recently installed build and retains its values after the resources close.
|
|
11
|
+
|
|
12
|
+
The engine subscribes to frontend events, routes them to its collaborators,
|
|
13
|
+
and exposes facades for session state, build details, and runtime controls.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import asyncio
|
|
19
|
+
import copy
|
|
20
|
+
import logging
|
|
21
|
+
from collections.abc import Awaitable, Callable
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
from typing import TYPE_CHECKING
|
|
24
|
+
|
|
25
|
+
from chrys.foundation.config.settings import Settings, persist_approval_mode
|
|
26
|
+
from chrys.foundation.config.settings_store import LoadedSettings, SettingsHandle
|
|
27
|
+
from chrys.foundation.events.types import (
|
|
28
|
+
AgentProfileSwitch,
|
|
29
|
+
AgentRuntimeDetails,
|
|
30
|
+
Error,
|
|
31
|
+
InvocationAborted,
|
|
32
|
+
InvocationAbortRequested,
|
|
33
|
+
InvocationCascadeAborted,
|
|
34
|
+
InvocationPaused,
|
|
35
|
+
InvocationResumed,
|
|
36
|
+
InvocationRetryRequested,
|
|
37
|
+
ProfileSwitched,
|
|
38
|
+
SessionClear,
|
|
39
|
+
SessionDelete,
|
|
40
|
+
SessionFork,
|
|
41
|
+
SessionNew,
|
|
42
|
+
SessionRestore,
|
|
43
|
+
SetApprovalMode,
|
|
44
|
+
SetModelProfile,
|
|
45
|
+
SettingsReload,
|
|
46
|
+
UserInject,
|
|
47
|
+
UserInjectCancel,
|
|
48
|
+
UserInterrupt,
|
|
49
|
+
UserMessage,
|
|
50
|
+
UserRetry,
|
|
51
|
+
UserRollback,
|
|
52
|
+
WorkspaceChange,
|
|
53
|
+
)
|
|
54
|
+
from chrys.foundation.models.workspace import Workspace
|
|
55
|
+
from chrys.foundation.tool_kinds import KIND_SUB_AGENT
|
|
56
|
+
from chrys.foundation.trajectory.context import TrajectoryContext
|
|
57
|
+
from chrys.orchestration.engine import trajectory as trajectory_recorder
|
|
58
|
+
from chrys.orchestration.engine.loader import AgentLoader
|
|
59
|
+
from chrys.orchestration.engine.rollback import RollbackController
|
|
60
|
+
from chrys.orchestration.engine.run.coordinator import TurnCoordinator
|
|
61
|
+
from chrys.orchestration.engine.session_lifecycle import SessionLifecycle
|
|
62
|
+
from chrys.orchestration.engine.state.active_session import ActiveSession
|
|
63
|
+
from chrys.orchestration.engine.state.controls import RuntimeControls
|
|
64
|
+
from chrys.orchestration.engine.state.current_agent import CurrentAgent
|
|
65
|
+
from chrys.orchestration.engine.state.lifecycle_permits import LifecyclePermits
|
|
66
|
+
from chrys.orchestration.engine.state.machine import EngineState, EngineStateMachine
|
|
67
|
+
from chrys.orchestration.engine.state.session_writer import SessionWriter
|
|
68
|
+
from chrys.orchestration.engine.usage import UsagePublisher
|
|
69
|
+
from chrys.orchestration.workflows.coordinator import WorkflowCoordinator
|
|
70
|
+
from chrys.service.approval.policy import ApprovalMode
|
|
71
|
+
from chrys.service.mutations.coordination import MutationCoordinator
|
|
72
|
+
from chrys.service.mutations.tracker import MutationTracker
|
|
73
|
+
from chrys.service.session.history import SessionHistoryManager
|
|
74
|
+
from chrys.service.state.store import (
|
|
75
|
+
SESSION_WRITE_LOCK_TIMEOUT_SECONDS,
|
|
76
|
+
atomic_copy_file,
|
|
77
|
+
)
|
|
78
|
+
from chrys.service.todos.tracker import TodoTracker
|
|
79
|
+
|
|
80
|
+
if TYPE_CHECKING:
|
|
81
|
+
from chrys.foundation.events.bus import EventBus
|
|
82
|
+
from chrys.foundation.models.execution import ExecutionSnapshot
|
|
83
|
+
from chrys.service.profiles.agents.schema import AgentProfile
|
|
84
|
+
from chrys.service.profiles.models.registry import ModelProfileRegistry
|
|
85
|
+
from chrys.service.profiles.models.schema import ModelProfile
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
# Session-keyed registry of live engines, for app features that run beside the session (the buddy).
|
|
89
|
+
_current_engines: dict[str, AgentEngine] = {}
|
|
90
|
+
_foreground_engine_session_id: str | None = None
|
|
91
|
+
logger = logging.getLogger(__name__)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def get_current_engine(session_id: str | None = None) -> AgentEngine | None:
|
|
95
|
+
"""Get an active AgentEngine instance.
|
|
96
|
+
|
|
97
|
+
Used by buddy module to access conversation history. A session id
|
|
98
|
+
selects a specific engine; no id preserves the legacy "foreground"
|
|
99
|
+
behavior for single-instance integrations.
|
|
100
|
+
"""
|
|
101
|
+
if session_id:
|
|
102
|
+
return _current_engines.get(session_id)
|
|
103
|
+
if _foreground_engine_session_id is not None:
|
|
104
|
+
engine = _current_engines.get(_foreground_engine_session_id)
|
|
105
|
+
if engine is not None:
|
|
106
|
+
return engine
|
|
107
|
+
if len(_current_engines) == 1:
|
|
108
|
+
return next(iter(_current_engines.values()))
|
|
109
|
+
return None
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _set_current_engine(engine: AgentEngine) -> None:
|
|
113
|
+
"""Make an active engine findable by features that run beside its session."""
|
|
114
|
+
global _foreground_engine_session_id
|
|
115
|
+
if engine.session_id is None:
|
|
116
|
+
return
|
|
117
|
+
_current_engines[engine.session_id] = engine
|
|
118
|
+
_foreground_engine_session_id = engine.session_id
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _unset_current_engine(engine: AgentEngine) -> None:
|
|
122
|
+
"""Take an engine out of the registry when it shuts down."""
|
|
123
|
+
global _foreground_engine_session_id
|
|
124
|
+
removed = [session_id for session_id, registered in _current_engines.items() if registered is engine]
|
|
125
|
+
for session_id in removed:
|
|
126
|
+
_current_engines.pop(session_id, None)
|
|
127
|
+
if _foreground_engine_session_id in removed:
|
|
128
|
+
_foreground_engine_session_id = next(reversed(_current_engines), None)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class AgentEngine:
|
|
132
|
+
"""Top-level orchestrator for the Chrys agent.
|
|
133
|
+
|
|
134
|
+
Usage::
|
|
135
|
+
|
|
136
|
+
bus = EventBus()
|
|
137
|
+
engine = assemble_agent_engine(bus, settings)
|
|
138
|
+
await engine.start(profile)
|
|
139
|
+
# Frontend publishes UserMessage events → engine handles them
|
|
140
|
+
await engine.shutdown()
|
|
141
|
+
"""
|
|
142
|
+
|
|
143
|
+
def __init__(
|
|
144
|
+
self,
|
|
145
|
+
*,
|
|
146
|
+
bus: EventBus,
|
|
147
|
+
session: ActiveSession,
|
|
148
|
+
permits: LifecyclePermits,
|
|
149
|
+
current: CurrentAgent,
|
|
150
|
+
writer: SessionWriter,
|
|
151
|
+
usage_publisher: UsagePublisher,
|
|
152
|
+
loader: AgentLoader,
|
|
153
|
+
lifecycle: SessionLifecycle,
|
|
154
|
+
rollback: RollbackController,
|
|
155
|
+
turns: TurnCoordinator,
|
|
156
|
+
controls: RuntimeControls,
|
|
157
|
+
settings_handle: SettingsHandle,
|
|
158
|
+
model_registry: ModelProfileRegistry | None,
|
|
159
|
+
fsm: EngineStateMachine,
|
|
160
|
+
history: SessionHistoryManager,
|
|
161
|
+
trajectory_recorder: trajectory_recorder.TrajectoryRecorder,
|
|
162
|
+
workflows: WorkflowCoordinator,
|
|
163
|
+
) -> None:
|
|
164
|
+
self._bus = bus
|
|
165
|
+
self._session = session
|
|
166
|
+
self._permits = permits
|
|
167
|
+
self._current = current
|
|
168
|
+
self._writer = writer
|
|
169
|
+
self._usage_publisher = usage_publisher
|
|
170
|
+
self._loader = loader
|
|
171
|
+
self._lifecycle = lifecycle
|
|
172
|
+
self._rollback = rollback
|
|
173
|
+
self._turns = turns
|
|
174
|
+
self._controls = controls
|
|
175
|
+
self._settings_handle = settings_handle
|
|
176
|
+
self._model_registry = model_registry
|
|
177
|
+
self._fsm = fsm
|
|
178
|
+
self._history = history
|
|
179
|
+
self._trajectory_recorder = trajectory_recorder
|
|
180
|
+
self._workflows = workflows
|
|
181
|
+
self._subscribed = False
|
|
182
|
+
self._release_task: asyncio.Task[None] | None = None
|
|
183
|
+
|
|
184
|
+
@property
|
|
185
|
+
def turns(self) -> TurnCoordinator:
|
|
186
|
+
"""Turn orchestration and runtime state."""
|
|
187
|
+
return self._turns
|
|
188
|
+
|
|
189
|
+
@property
|
|
190
|
+
def workflows(self) -> WorkflowCoordinator:
|
|
191
|
+
"""Workflow run admission and routing."""
|
|
192
|
+
return self._workflows
|
|
193
|
+
|
|
194
|
+
@property
|
|
195
|
+
def lifecycle(self) -> SessionLifecycle:
|
|
196
|
+
"""Session orchestration and resource shutdown."""
|
|
197
|
+
return self._lifecycle
|
|
198
|
+
|
|
199
|
+
@property
|
|
200
|
+
def rollback(self) -> RollbackController:
|
|
201
|
+
"""Session and workspace rollback operations."""
|
|
202
|
+
return self._rollback
|
|
203
|
+
|
|
204
|
+
@property
|
|
205
|
+
def controls(self) -> RuntimeControls:
|
|
206
|
+
"""Profile, model, settings, and workspace controls."""
|
|
207
|
+
return self._controls
|
|
208
|
+
|
|
209
|
+
@property
|
|
210
|
+
def loader(self) -> AgentLoader:
|
|
211
|
+
"""Candidate construction, installation, and build resource release."""
|
|
212
|
+
return self._loader
|
|
213
|
+
|
|
214
|
+
@property
|
|
215
|
+
def usage_publisher(self) -> UsagePublisher:
|
|
216
|
+
"""Session usage accounting and ordered publication."""
|
|
217
|
+
return self._usage_publisher
|
|
218
|
+
|
|
219
|
+
@property
|
|
220
|
+
def writer(self) -> SessionWriter:
|
|
221
|
+
"""Session saves and recovery checkpoint persistence."""
|
|
222
|
+
return self._writer
|
|
223
|
+
|
|
224
|
+
@property
|
|
225
|
+
def current(self) -> CurrentAgent:
|
|
226
|
+
"""The current resources and last installed manifest."""
|
|
227
|
+
return self._current
|
|
228
|
+
|
|
229
|
+
@property
|
|
230
|
+
def permits(self) -> LifecyclePermits:
|
|
231
|
+
"""Lifecycle admission and owner clocks."""
|
|
232
|
+
return self._permits
|
|
233
|
+
|
|
234
|
+
@property
|
|
235
|
+
def session(self) -> ActiveSession:
|
|
236
|
+
"""The active session record."""
|
|
237
|
+
return self._session
|
|
238
|
+
|
|
239
|
+
@property
|
|
240
|
+
def session_generation(self) -> int:
|
|
241
|
+
"""Engine-owned session generation for stale-owner detection."""
|
|
242
|
+
return self._permits.session_generation
|
|
243
|
+
|
|
244
|
+
@property
|
|
245
|
+
def conversation_revision(self) -> int:
|
|
246
|
+
"""Monotonic fresh/retry lifecycle revision for stale projections."""
|
|
247
|
+
return self._turns.conversation_revision
|
|
248
|
+
|
|
249
|
+
@property
|
|
250
|
+
def build_generation(self) -> int:
|
|
251
|
+
"""Engine-owned successful-build generation."""
|
|
252
|
+
return self._permits.build_generation
|
|
253
|
+
|
|
254
|
+
@property
|
|
255
|
+
def workspace_primary_cwd(self) -> str:
|
|
256
|
+
"""Current normalized primary cwd for stale projection detection."""
|
|
257
|
+
return self._session.workspace_cwd()
|
|
258
|
+
|
|
259
|
+
@property
|
|
260
|
+
def load_generation(self) -> int:
|
|
261
|
+
"""Engine-owned agent-load attempt generation."""
|
|
262
|
+
return self._permits.load_generation
|
|
263
|
+
|
|
264
|
+
@property
|
|
265
|
+
def is_running(self) -> bool:
|
|
266
|
+
return self._current.loaded is not None and self._current.loaded.bindings.state.running
|
|
267
|
+
|
|
268
|
+
def execution_busy(self) -> bool:
|
|
269
|
+
"""Existing lifecycle busy predicate, including preparation and final save."""
|
|
270
|
+
return self._turns.execution_busy()
|
|
271
|
+
|
|
272
|
+
def execution(self) -> ExecutionSnapshot:
|
|
273
|
+
"""What the execution lease is running right now: nothing, a turn, or a workflow run."""
|
|
274
|
+
return self._turns.execution()
|
|
275
|
+
|
|
276
|
+
def turn_accepts_injection(self) -> bool:
|
|
277
|
+
"""Existing FSM is_running predicate, including pending retry and child waits."""
|
|
278
|
+
return self._turns.turn_accepts_injection()
|
|
279
|
+
|
|
280
|
+
@property
|
|
281
|
+
def is_turn_active(self) -> bool:
|
|
282
|
+
"""True when a turn is in-flight and can accept an injection.
|
|
283
|
+
|
|
284
|
+
Uses the FSM rather than the executor flag so it also covers
|
|
285
|
+
``PENDING_RETRY`` / ``AWAITING_SUB_AGENTS`` — the same predicate
|
|
286
|
+
``on_user_message`` uses to inject instead of starting a turn.
|
|
287
|
+
"""
|
|
288
|
+
return self.turn_accepts_injection()
|
|
289
|
+
|
|
290
|
+
@property
|
|
291
|
+
def is_turn_lifecycle_active(self) -> bool:
|
|
292
|
+
"""True through execution, session persistence, and after-turn hooks.
|
|
293
|
+
|
|
294
|
+
Unlike :attr:`is_turn_active`, this follows the owned run task rather
|
|
295
|
+
than the FSM. Finalization intentionally transitions the FSM to idle
|
|
296
|
+
before it saves the session and drains hooks.
|
|
297
|
+
"""
|
|
298
|
+
return self.execution_busy()
|
|
299
|
+
|
|
300
|
+
@property
|
|
301
|
+
def turn_lifecycle_task(self) -> asyncio.Task[None] | None:
|
|
302
|
+
"""Return the currently owned execution/finalization task.
|
|
303
|
+
|
|
304
|
+
Callers that need a boundary for one captured turn should retain this
|
|
305
|
+
exact task instead of later awaiting the replaceable run-task chain.
|
|
306
|
+
"""
|
|
307
|
+
return self._turns.turn_lifecycle_task
|
|
308
|
+
|
|
309
|
+
def was_turn_lifecycle_saved(self, task: asyncio.Task[None]) -> bool:
|
|
310
|
+
"""Return whether *task* completed its final session save successfully."""
|
|
311
|
+
return self._turns.was_turn_lifecycle_saved(task)
|
|
312
|
+
|
|
313
|
+
@property
|
|
314
|
+
def session_id(self) -> str | None:
|
|
315
|
+
"""Current canonical session id, or ``None`` before session start."""
|
|
316
|
+
return self._session.session_id
|
|
317
|
+
|
|
318
|
+
@property
|
|
319
|
+
def runtime_details(self) -> AgentRuntimeDetails:
|
|
320
|
+
"""Runtime details for the currently built agent."""
|
|
321
|
+
return copy.deepcopy(self._current.manifest.runtime_details)
|
|
322
|
+
|
|
323
|
+
# Public read accessors for engine collaborators (buddy, session-title
|
|
324
|
+
# updater, other app-layer features) so they don't reach into privates.
|
|
325
|
+
|
|
326
|
+
@property
|
|
327
|
+
def event_bus(self) -> EventBus:
|
|
328
|
+
"""Event bus the engine publishes on (constructor-injected)."""
|
|
329
|
+
return self._bus
|
|
330
|
+
|
|
331
|
+
@property
|
|
332
|
+
def state(self) -> EngineState:
|
|
333
|
+
"""Current lifecycle state of the engine state machine.
|
|
334
|
+
|
|
335
|
+
Read-only view; transitions stay engine-internal.
|
|
336
|
+
"""
|
|
337
|
+
return self._fsm.state
|
|
338
|
+
|
|
339
|
+
@property
|
|
340
|
+
def workspace(self) -> Workspace | None:
|
|
341
|
+
"""Active workspace (primary cwd + working dirs), or ``None`` before start.
|
|
342
|
+
|
|
343
|
+
Read-only view: rebinding stays with the session-lifecycle host
|
|
344
|
+
contract.
|
|
345
|
+
"""
|
|
346
|
+
return self._session.workspace
|
|
347
|
+
|
|
348
|
+
@property
|
|
349
|
+
def settings(self) -> Settings:
|
|
350
|
+
"""Live settings object the engine was built with."""
|
|
351
|
+
return self._settings_handle.settings
|
|
352
|
+
|
|
353
|
+
@property
|
|
354
|
+
def loaded_settings(self) -> LoadedSettings:
|
|
355
|
+
"""Live settings together with where each value came from.
|
|
356
|
+
|
|
357
|
+
Anything that answers "why does this session use this value" — the
|
|
358
|
+
panel, ``settings/options``, the explanation for a key that was sealed
|
|
359
|
+
at its default — needs the provenance that used to be discarded the
|
|
360
|
+
moment a root unpacked ``.settings``.
|
|
361
|
+
"""
|
|
362
|
+
return self._settings_handle.loaded
|
|
363
|
+
|
|
364
|
+
@property
|
|
365
|
+
def settings_handle(self) -> SettingsHandle:
|
|
366
|
+
"""The cell a frontend shares to stay on the same settings as this engine."""
|
|
367
|
+
return self._settings_handle
|
|
368
|
+
|
|
369
|
+
@property
|
|
370
|
+
def agent_profile(self) -> AgentProfile | None:
|
|
371
|
+
"""Agent profile of the currently built runtime, or ``None`` before build."""
|
|
372
|
+
return self._session.agent_profile
|
|
373
|
+
|
|
374
|
+
@property
|
|
375
|
+
def active_model_profile(self) -> ModelProfile | None:
|
|
376
|
+
"""Model profile of the currently built runtime, or ``None`` before build."""
|
|
377
|
+
return copy.deepcopy(self._current.manifest.active_profile)
|
|
378
|
+
|
|
379
|
+
@property
|
|
380
|
+
def model_registry(self) -> ModelProfileRegistry | None:
|
|
381
|
+
"""Model profile registry the engine resolves profiles from, if any."""
|
|
382
|
+
return self._model_registry
|
|
383
|
+
|
|
384
|
+
@property
|
|
385
|
+
def session_dir(self) -> Path | None:
|
|
386
|
+
"""Session directory path, or ``None`` if no session is active."""
|
|
387
|
+
return self._session.session_dir
|
|
388
|
+
|
|
389
|
+
def trajectory_context(self) -> TrajectoryContext | None:
|
|
390
|
+
"""The session's trajectory recording scope (current turn), or ``None`` when unrecorded.
|
|
391
|
+
|
|
392
|
+
Side calls made outside a model run (title generation) bind this with
|
|
393
|
+
:func:`chrys.foundation.trajectory.context.side_call_scope` so their
|
|
394
|
+
exchanges are attributed to the session.
|
|
395
|
+
"""
|
|
396
|
+
return self._trajectory_recorder.context()
|
|
397
|
+
|
|
398
|
+
@property
|
|
399
|
+
def history_messages(self) -> list:
|
|
400
|
+
"""Live message list of the bound session history.
|
|
401
|
+
|
|
402
|
+
Raises if no history is bound yet (before session start) — callers
|
|
403
|
+
that can run that early should guard accordingly.
|
|
404
|
+
"""
|
|
405
|
+
return self._history.messages
|
|
406
|
+
|
|
407
|
+
def tool_kind_for_name(self, name: str) -> str:
|
|
408
|
+
"""Return the live tool kind for *name*, or an empty string when unknown."""
|
|
409
|
+
kind = self._current.manifest.tool_kinds.get(name, "")
|
|
410
|
+
if kind:
|
|
411
|
+
return kind
|
|
412
|
+
if (
|
|
413
|
+
self._current.loaded is not None and self._current.loaded.sub_agent_tools is not None
|
|
414
|
+
) and name in self._current.loaded.sub_agent_tools.tool_names():
|
|
415
|
+
return KIND_SUB_AGENT
|
|
416
|
+
return ""
|
|
417
|
+
|
|
418
|
+
def current_profile_snapshot(self) -> ProfileSwitched:
|
|
419
|
+
"""Build a no-op ``ProfileSwitched`` reflecting the live runtime.
|
|
420
|
+
|
|
421
|
+
A frontend reselecting the already-active agent performs no backend
|
|
422
|
+
switch and emits no event, so callers that still owe the client the
|
|
423
|
+
standard runtime envelope read it here instead of fabricating blank
|
|
424
|
+
fields. ``from``/``to`` are identical because nothing changed. Field
|
|
425
|
+
sourcing mirrors the real switch event so the two cannot drift.
|
|
426
|
+
"""
|
|
427
|
+
return self._controls.current_profile_snapshot()
|
|
428
|
+
|
|
429
|
+
@property
|
|
430
|
+
def approval_mode(self) -> ApprovalMode:
|
|
431
|
+
"""Live approval mode (updated by ``SetApprovalMode``)."""
|
|
432
|
+
return self._session.approval_mode
|
|
433
|
+
|
|
434
|
+
@property
|
|
435
|
+
def recovered_from_sidecar(self) -> bool:
|
|
436
|
+
"""Whether the current session restore selected the crash-recovery sidecar."""
|
|
437
|
+
return self._session.recovered_from_sidecar
|
|
438
|
+
|
|
439
|
+
async def wait_for_run_task(self) -> None:
|
|
440
|
+
"""Wait for the active run task to finish post-run cleanup and saving."""
|
|
441
|
+
await self._turns.wait_for_run_task()
|
|
442
|
+
|
|
443
|
+
async def begin_rollback_projection(
|
|
444
|
+
self,
|
|
445
|
+
*,
|
|
446
|
+
session_id: str | None,
|
|
447
|
+
session_generation: int,
|
|
448
|
+
) -> str | None:
|
|
449
|
+
return await self._rollback.begin_rollback_projection(
|
|
450
|
+
session_id=session_id, session_generation=session_generation
|
|
451
|
+
)
|
|
452
|
+
|
|
453
|
+
def finish_rollback_projection(self, owner: str) -> None:
|
|
454
|
+
self._rollback.finish_rollback_projection(owner)
|
|
455
|
+
|
|
456
|
+
async def start(
|
|
457
|
+
self,
|
|
458
|
+
profile: AgentProfile,
|
|
459
|
+
*,
|
|
460
|
+
operation: str = "startup",
|
|
461
|
+
staged_loaded: LoadedSettings | None = None,
|
|
462
|
+
workspace: Workspace | None = None,
|
|
463
|
+
) -> None:
|
|
464
|
+
await self._subscribe_event_handlers()
|
|
465
|
+
await self._lifecycle.start(profile, operation=operation, staged_loaded=staged_loaded, workspace=workspace)
|
|
466
|
+
|
|
467
|
+
async def prepare(self, fallback_profile: AgentProfile | None = None) -> None:
|
|
468
|
+
"""Subscribe handlers and optionally seed the profile used by legacy restores."""
|
|
469
|
+
await self._subscribe_event_handlers()
|
|
470
|
+
self._lifecycle.prepare(fallback_profile)
|
|
471
|
+
|
|
472
|
+
async def _subscribe_event_handlers(self) -> None:
|
|
473
|
+
"""Subscribe frontend event handlers once, even if the first build fails.
|
|
474
|
+
|
|
475
|
+
Handlers are intentionally available before the initial build completes
|
|
476
|
+
so settings/profile changes can recover from startup failure. The TUI
|
|
477
|
+
blocks user actions while agent loading is active; if an external caller
|
|
478
|
+
publishes recovery events during a still-running first build, those
|
|
479
|
+
events may re-enter ``start()`` before ``_turn_bindings`` exists.
|
|
480
|
+
"""
|
|
481
|
+
if self._subscribed:
|
|
482
|
+
return
|
|
483
|
+
self._subscribed = True
|
|
484
|
+
await self._bus.subscribe(UserMessage, self._on_user_message)
|
|
485
|
+
await self._bus.subscribe(UserInterrupt, self._on_user_interrupt)
|
|
486
|
+
await self._bus.subscribe(UserRetry, self._on_user_retry)
|
|
487
|
+
await self._bus.subscribe(UserInject, self._on_user_inject)
|
|
488
|
+
await self._bus.subscribe(UserInjectCancel, self._on_user_inject_cancel)
|
|
489
|
+
await self._bus.subscribe(UserRollback, self._on_user_rollback)
|
|
490
|
+
await self._bus.subscribe(AgentProfileSwitch, self._on_profile_switch)
|
|
491
|
+
await self._bus.subscribe(SessionNew, self._on_new_session)
|
|
492
|
+
await self._bus.subscribe(SessionRestore, self.on_session_restore)
|
|
493
|
+
await self._bus.subscribe(SessionDelete, self._on_session_delete)
|
|
494
|
+
await self._bus.subscribe(SessionClear, self._on_session_clear)
|
|
495
|
+
await self._bus.subscribe(SessionFork, self._on_session_fork)
|
|
496
|
+
await self._bus.subscribe(WorkspaceChange, self._on_workspace_change)
|
|
497
|
+
await self._bus.subscribe(SettingsReload, self._on_settings_reload)
|
|
498
|
+
await self._bus.subscribe(SetApprovalMode, self._on_set_approval_mode)
|
|
499
|
+
await self._bus.subscribe(SetModelProfile, self._on_set_model_profile)
|
|
500
|
+
await self._bus.subscribe(InvocationRetryRequested, self._on_sub_agent_retry)
|
|
501
|
+
await self._bus.subscribe(InvocationAbortRequested, self._on_sub_agent_abort)
|
|
502
|
+
await self._bus.subscribe(InvocationPaused, self._on_sub_agent_paused)
|
|
503
|
+
await self._bus.subscribe(InvocationResumed, self._on_sub_agent_unpaused)
|
|
504
|
+
await self._bus.subscribe(InvocationAborted, self._on_sub_agent_unpaused)
|
|
505
|
+
await self._bus.subscribe(InvocationCascadeAborted, self._on_sub_agent_unpaused)
|
|
506
|
+
await self._workflows.subscribe()
|
|
507
|
+
|
|
508
|
+
async def shutdown(self) -> None:
|
|
509
|
+
# Closing is declared before the active workflow run is drained: a requester queued behind that
|
|
510
|
+
# run is refused as shutting down instead of being admitted into a session that is going away.
|
|
511
|
+
self._session.mark_closing()
|
|
512
|
+
await self._workflows.shutdown()
|
|
513
|
+
await self._release()
|
|
514
|
+
|
|
515
|
+
async def _release(self) -> None:
|
|
516
|
+
"""Release the session's resources and lock on a task of the engine's own.
|
|
517
|
+
|
|
518
|
+
A shutdown awaited from inside a workflow run's agent pass (a subscriber to one of its tool events)
|
|
519
|
+
returns from the drain at once, and the cancel it queued then cancels the subscriber's task under
|
|
520
|
+
it: the release runs on its own task so the session is released either way. A shutdown awaited
|
|
521
|
+
while a release is in flight waits for that one.
|
|
522
|
+
"""
|
|
523
|
+
task = self._release_task
|
|
524
|
+
if task is None or task.done():
|
|
525
|
+
task = asyncio.create_task(self._lifecycle.shutdown(), name="chrys.engine.release")
|
|
526
|
+
self._release_task = task
|
|
527
|
+
# Shutdown drains usage publications. An inline UsageUpdate handler must return before that
|
|
528
|
+
# drain can finish; the release task retains ownership after the handler gives up its wait.
|
|
529
|
+
if asyncio.current_task() in self._usage_publisher.tasks:
|
|
530
|
+
return
|
|
531
|
+
await asyncio.shield(task)
|
|
532
|
+
|
|
533
|
+
async def _session_operation(
|
|
534
|
+
self, operation: str, run: Callable[[], Awaitable[None]], *, target_session_id: str | None = None
|
|
535
|
+
) -> None:
|
|
536
|
+
"""Session-family operations and workflow runs exclude each other, in both directions.
|
|
537
|
+
|
|
538
|
+
The operation is refused, not queued, while a run owns the lease; and while it is in flight (its
|
|
539
|
+
reads and fences included) a run request is refused, so no run is admitted into a session that is
|
|
540
|
+
being restored, replaced, forked, deleted or rolled back under it.
|
|
541
|
+
|
|
542
|
+
The refusal is addressed to *target_session_id* when the operation names another session (a
|
|
543
|
+
restore): the requester waiting for that session's answer hears it, where a refusal addressed to
|
|
544
|
+
the active session would never reach it.
|
|
545
|
+
"""
|
|
546
|
+
lease = self._turns.turn_state.lease
|
|
547
|
+
if lease.workflow is not None:
|
|
548
|
+
await self._bus.publish(
|
|
549
|
+
Error(
|
|
550
|
+
code="workflow_active",
|
|
551
|
+
message=f"Cannot {operation} while a workflow run is active. Cancel the workflow run first.",
|
|
552
|
+
session_id=target_session_id or self._session.session_id,
|
|
553
|
+
)
|
|
554
|
+
)
|
|
555
|
+
return
|
|
556
|
+
with lease.session_operation():
|
|
557
|
+
await run()
|
|
558
|
+
|
|
559
|
+
# --- Event handlers ---
|
|
560
|
+
|
|
561
|
+
@property
|
|
562
|
+
def mutation_tracker(self) -> MutationTracker | None:
|
|
563
|
+
"""Live mutation tracker, or ``None`` if no session is active.
|
|
564
|
+
|
|
565
|
+
Exposed read-only so the TUI (e.g. the rollback modal) can build
|
|
566
|
+
per-turn diff views directly from in-memory state without a JSON
|
|
567
|
+
round-trip through ``session.json``. This matters during
|
|
568
|
+
interrupted / failed runs where the tracker has up-to-date turn
|
|
569
|
+
info that hasn't been persisted yet.
|
|
570
|
+
"""
|
|
571
|
+
return self._session.mutation_tracker
|
|
572
|
+
|
|
573
|
+
@property
|
|
574
|
+
def mutation_coordinator(self) -> MutationCoordinator | None:
|
|
575
|
+
"""Cross-session mutation coordinator, or ``None`` when disabled."""
|
|
576
|
+
return self._session.mutation_coordinator
|
|
577
|
+
|
|
578
|
+
@property
|
|
579
|
+
def todo_tracker(self) -> TodoTracker | None:
|
|
580
|
+
"""Live session todo tracker, or ``None`` if no session is active.
|
|
581
|
+
|
|
582
|
+
Exposed read-only so hosts (e.g. the ACP plan-update sender) can read
|
|
583
|
+
the current list via the sync ``snapshot()`` without touching the
|
|
584
|
+
private attribute.
|
|
585
|
+
"""
|
|
586
|
+
return self._session.todo_tracker
|
|
587
|
+
|
|
588
|
+
async def refresh_mutation_attribution(self, *, force: bool = False) -> bool:
|
|
589
|
+
return await self._lifecycle.refresh_mutation_attribution(force=force)
|
|
590
|
+
|
|
591
|
+
# --- Rollback snapshots -------------------------------------------------
|
|
592
|
+
#
|
|
593
|
+
# Before each new user turn begins, the engine copies the current
|
|
594
|
+
# ``session.json`` to ``{session_dir}/snapshots/turn_{N}.json`` where
|
|
595
|
+
# ``N`` is the turn about to start. Rolling back to keep turn K means
|
|
596
|
+
# swapping the snapshot whose payload has ``turn_counter == K`` back in
|
|
597
|
+
# as ``session.json`` and reloading. ``K == 0`` is the pre-session
|
|
598
|
+
# welcome state, so it deletes the session file instead of swapping.
|
|
599
|
+
|
|
600
|
+
def turn_prompt_previews(self) -> dict[int, str]:
|
|
601
|
+
"""Return ``{turn_number: first_user_prompt}`` for every known turn."""
|
|
602
|
+
return self._rollback.turn_prompt_previews()
|
|
603
|
+
|
|
604
|
+
def first_rolled_back_user_text(self, target_turn: int) -> str:
|
|
605
|
+
"""Return the first user prompt discarded by rollback to ``target_turn``."""
|
|
606
|
+
return self._rollback.first_rolled_back_user_text(target_turn)
|
|
607
|
+
|
|
608
|
+
def available_rollback_turns(self) -> list[int]:
|
|
609
|
+
"""Public accessor for :meth:`_available_rollback_turns`.
|
|
610
|
+
|
|
611
|
+
Used by the TUI to decide whether ``/rollback`` should show the
|
|
612
|
+
modal at all, and to populate the turn picker.
|
|
613
|
+
"""
|
|
614
|
+
return self._rollback.available_turns()
|
|
615
|
+
|
|
616
|
+
@property
|
|
617
|
+
def current_turn_number(self) -> int:
|
|
618
|
+
"""Current engine turn counter.
|
|
619
|
+
|
|
620
|
+
Tracks the most-recently-started turn (incremented by the turn
|
|
621
|
+
runner at the start of each run, restored from ``turn_counter``
|
|
622
|
+
on session reload). Equal to the last
|
|
623
|
+
completed turn index while the engine is idle between turns.
|
|
624
|
+
|
|
625
|
+
Exposed so the TUI can label the "you are here" entry in the
|
|
626
|
+
rollback picker independently of which snapshots happen to
|
|
627
|
+
exist on disk — otherwise a session with all snapshots
|
|
628
|
+
deleted would show ``Turn 1 (Current)`` instead of the real
|
|
629
|
+
current-turn index.
|
|
630
|
+
"""
|
|
631
|
+
return self._session.turn_number
|
|
632
|
+
|
|
633
|
+
async def _on_user_rollback(self, event: UserRollback) -> None:
|
|
634
|
+
"""Handle a rollback request."""
|
|
635
|
+
await self._session_operation(
|
|
636
|
+
"roll back",
|
|
637
|
+
lambda: self._rollback.on_user_rollback(
|
|
638
|
+
event,
|
|
639
|
+
atomic_copy_file=atomic_copy_file,
|
|
640
|
+
lock_timeout_seconds=SESSION_WRITE_LOCK_TIMEOUT_SECONDS,
|
|
641
|
+
),
|
|
642
|
+
)
|
|
643
|
+
|
|
644
|
+
async def reset_after_failed_startup_restore(self) -> None:
|
|
645
|
+
"""Return a partial startup restore to a clean, unlocked baseline."""
|
|
646
|
+
await self._lifecycle.reset_after_failed_startup_restore()
|
|
647
|
+
|
|
648
|
+
async def _on_user_message(self, event: UserMessage) -> None:
|
|
649
|
+
"""Handle a user message by running the executor as an async task."""
|
|
650
|
+
await self._turns.on_user_message(event)
|
|
651
|
+
|
|
652
|
+
async def _on_user_interrupt(self, _event: UserInterrupt) -> None:
|
|
653
|
+
"""Handle user interrupt.
|
|
654
|
+
|
|
655
|
+
Cascades to every live sub-agent controller first so paused
|
|
656
|
+
sub-agents resolve via the cascade-abort branch (otherwise their
|
|
657
|
+
``pending_decision`` future would keep their ``_invoke``
|
|
658
|
+
coroutine pinned forever and the subsequent task cancel below
|
|
659
|
+
would leak). Then sets the interrupt flag / cancels the parent
|
|
660
|
+
task. It then binds cancellation to the exact pre-executor run task
|
|
661
|
+
or interrupts the active executor; ``run_and_save`` detects
|
|
662
|
+
``was_interrupted`` and rolls back history.
|
|
663
|
+
"""
|
|
664
|
+
await self._turns.on_user_interrupt(_event)
|
|
665
|
+
|
|
666
|
+
async def _on_sub_agent_retry(self, event: InvocationRetryRequested) -> None:
|
|
667
|
+
"""Route a user's per-card Retry click to the owning controller."""
|
|
668
|
+
await self._turns.on_sub_agent_retry(event)
|
|
669
|
+
|
|
670
|
+
async def _on_sub_agent_abort(self, event: InvocationAbortRequested) -> None:
|
|
671
|
+
"""Route a user's per-card Abort click to the owning controller."""
|
|
672
|
+
await self._turns.on_sub_agent_abort(event)
|
|
673
|
+
|
|
674
|
+
async def _on_sub_agent_paused(self, event: InvocationPaused) -> None:
|
|
675
|
+
"""Track a newly paused sub-agent and drive FSM / marker.
|
|
676
|
+
|
|
677
|
+
Idempotent on the paused set — if the same id arrives twice
|
|
678
|
+
(controller re-publishes after retry exhaustion, for example)
|
|
679
|
+
the FSM transition only fires on the 0→1 edge.
|
|
680
|
+
|
|
681
|
+
Defensive FSM guard: if the parent run has already terminated
|
|
682
|
+
(e.g. the bus is dispatching a stale pause event that was queued
|
|
683
|
+
before the parent's task was cancelled and ``_post_run`` ran),
|
|
684
|
+
drop the event silently rather than re-inserting a marker on top
|
|
685
|
+
of an already-terminal ``interrupted``/``error`` marker. The
|
|
686
|
+
parent invariant ("parent run ends only after all sub-agents
|
|
687
|
+
resolve") should make this unreachable, but defense in depth
|
|
688
|
+
keeps history well-formed if that invariant ever breaks.
|
|
689
|
+
"""
|
|
690
|
+
await self._turns.on_sub_agent_paused(event)
|
|
691
|
+
|
|
692
|
+
async def _on_sub_agent_unpaused(
|
|
693
|
+
self,
|
|
694
|
+
event: InvocationResumed | InvocationAborted | InvocationCascadeAborted,
|
|
695
|
+
) -> None:
|
|
696
|
+
"""Common handler — retry/abort/cascade all remove the invocation from the paused set.
|
|
697
|
+
|
|
698
|
+
FSM transitions only on the N→0 edge (last paused sub-agent
|
|
699
|
+
resolved). Marker is updated or stripped accordingly.
|
|
700
|
+
"""
|
|
701
|
+
await self._turns.on_sub_agent_unpaused(event)
|
|
702
|
+
|
|
703
|
+
async def _on_user_retry(self, event: UserRetry) -> None:
|
|
704
|
+
"""Handle retry — resume from current state.
|
|
705
|
+
|
|
706
|
+
When ``event.text`` is non-empty, it is forwarded to
|
|
707
|
+
``retry_and_save`` (or stashed for the pending-retry path) and
|
|
708
|
+
becomes the mid-turn continuation prompt, replacing the
|
|
709
|
+
executor's default ``"continue"`` placeholder.
|
|
710
|
+
"""
|
|
711
|
+
await self._turns.on_user_retry(event)
|
|
712
|
+
|
|
713
|
+
async def _on_user_inject(self, event: UserInject) -> None:
|
|
714
|
+
"""Handle user injection (prompt inserted before next model call)."""
|
|
715
|
+
await self._turns.on_user_inject(event)
|
|
716
|
+
|
|
717
|
+
async def _on_user_inject_cancel(self, event: UserInjectCancel) -> None:
|
|
718
|
+
"""Handle user cancellation of a still-pending mid-run injection."""
|
|
719
|
+
await self._turns.on_user_inject_cancel(event)
|
|
720
|
+
|
|
721
|
+
async def _on_set_approval_mode(self, event: SetApprovalMode) -> None:
|
|
722
|
+
"""Update the active approval mode on the running middleware."""
|
|
723
|
+
if event.session_id is not None and event.session_id != self._session.session_id:
|
|
724
|
+
return
|
|
725
|
+
await self._controls.on_set_approval_mode(
|
|
726
|
+
event,
|
|
727
|
+
persist_approval_mode_fn=persist_approval_mode,
|
|
728
|
+
)
|
|
729
|
+
|
|
730
|
+
async def _on_set_model_profile(self, event: SetModelProfile) -> None:
|
|
731
|
+
"""Switch the active model profile for this session only."""
|
|
732
|
+
await self._controls.on_set_model_profile(event)
|
|
733
|
+
|
|
734
|
+
async def _on_profile_switch(self, event: AgentProfileSwitch) -> None:
|
|
735
|
+
"""Handle agent profile switch — preserves conversation history."""
|
|
736
|
+
await self._controls.on_profile_switch(event)
|
|
737
|
+
|
|
738
|
+
def pin_ask_user_timeout(self) -> None:
|
|
739
|
+
"""Mark ``ask_user_timeout_seconds`` as caller-owned across reloads.
|
|
740
|
+
|
|
741
|
+
Callers that inject the timeout out-of-band (ACP sets it to ``None`` at
|
|
742
|
+
launch via ``dataclasses.replace``) call this so a later ``SettingsReload``
|
|
743
|
+
keeps the live value instead of reverting to the env default.
|
|
744
|
+
"""
|
|
745
|
+
self._session.ask_user_timeout_pinned = True
|
|
746
|
+
|
|
747
|
+
def pin_model_profile(self) -> None:
|
|
748
|
+
"""Mark the model selection as caller-owned across reloads.
|
|
749
|
+
|
|
750
|
+
Headless ``--model`` lives only in this host's settings — it never
|
|
751
|
+
parks the choice in the process pointer the way the TUI does — so
|
|
752
|
+
without the pin one ``SettingsReload`` would silently revert the run
|
|
753
|
+
to the global default.
|
|
754
|
+
"""
|
|
755
|
+
self._session.model_profile_pinned = True
|
|
756
|
+
|
|
757
|
+
async def _on_settings_reload(self, _event: SettingsReload) -> None:
|
|
758
|
+
"""Handle settings reload — recreate Settings from env and rebuild agent."""
|
|
759
|
+
await self._controls.on_settings_reload(_event)
|
|
760
|
+
|
|
761
|
+
async def _on_workspace_change(self, event: WorkspaceChange) -> None:
|
|
762
|
+
"""Handle workspace/cwd change — rebuild agent with new workspace."""
|
|
763
|
+
await self._controls.on_workspace_change(event)
|
|
764
|
+
|
|
765
|
+
async def _on_new_session(self, _event: SessionNew) -> None:
|
|
766
|
+
"""Handle new session request — save current, then start fresh."""
|
|
767
|
+
await self._session_operation("start a new session", lambda: self._lifecycle.on_new_session(_event))
|
|
768
|
+
|
|
769
|
+
async def on_session_restore(self, event: SessionRestore) -> None:
|
|
770
|
+
"""Handle session restore — load saved session state."""
|
|
771
|
+
await self._session_operation(
|
|
772
|
+
"restore a session",
|
|
773
|
+
lambda: self._lifecycle.on_session_restore(event),
|
|
774
|
+
target_session_id=event.session_id,
|
|
775
|
+
)
|
|
776
|
+
|
|
777
|
+
async def _on_session_delete(self, event: SessionDelete) -> None:
|
|
778
|
+
"""Handle session deletion; the active session is the one whose lock we hold, by its full or short id."""
|
|
779
|
+
if not self._session.guard.owns(event.session_id):
|
|
780
|
+
await self._lifecycle.on_session_delete(event)
|
|
781
|
+
return
|
|
782
|
+
await self._session_operation("delete the active session", lambda: self._lifecycle.on_session_delete(event))
|
|
783
|
+
|
|
784
|
+
async def _on_session_clear(self, event: SessionClear) -> None:
|
|
785
|
+
"""Handle clear: delete the active session and start fresh as one fenced transition."""
|
|
786
|
+
await self._session_operation("clear the session", lambda: self._lifecycle.on_session_clear(event))
|
|
787
|
+
|
|
788
|
+
async def _on_session_fork(self, event: SessionFork) -> None:
|
|
789
|
+
await self._session_operation("fork the session", lambda: self._lifecycle.on_session_fork(event))
|