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,639 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Engine-internal profile, settings, workspace, and approval controls."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import asyncio
|
|
8
|
+
import copy
|
|
9
|
+
import dataclasses
|
|
10
|
+
import logging
|
|
11
|
+
from collections.abc import Callable
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from typing import TYPE_CHECKING, Any
|
|
14
|
+
|
|
15
|
+
from chrys.foundation.config.context import EvalContext
|
|
16
|
+
from chrys.foundation.config.process_settings import reattribute_command_line, route_restart_settings
|
|
17
|
+
from chrys.foundation.config.settings_store import LoadedSettings, SettingsHandle, load_settings
|
|
18
|
+
from chrys.foundation.config.spec import Source
|
|
19
|
+
from chrys.foundation.config.warnings import settings_warning_events
|
|
20
|
+
from chrys.foundation.events.types import (
|
|
21
|
+
AgentProfileSwitch,
|
|
22
|
+
ApprovalModeUpdated,
|
|
23
|
+
Error,
|
|
24
|
+
ModelProfileSwitched,
|
|
25
|
+
ProfileSwitched,
|
|
26
|
+
SetApprovalMode,
|
|
27
|
+
SetModelProfile,
|
|
28
|
+
SettingsReload,
|
|
29
|
+
SettingsReloaded,
|
|
30
|
+
Warning,
|
|
31
|
+
WorkspaceChange,
|
|
32
|
+
WorkspaceUpdated,
|
|
33
|
+
)
|
|
34
|
+
from chrys.foundation.i18n import DisplayPath, DisplaySequence, msg
|
|
35
|
+
from chrys.foundation.i18n.formatting import format_message
|
|
36
|
+
from chrys.foundation.models.workspace import Workspace
|
|
37
|
+
from chrys.foundation.platform import safe_getcwd
|
|
38
|
+
from chrys.foundation.platform.files import surrogate_safe_text
|
|
39
|
+
from chrys.orchestration.engine.state.lifecycle_permits import RebuildControlToken, RebuildPermit, RebuildPermitDenied
|
|
40
|
+
from chrys.service.approval.policy import ApprovalMode
|
|
41
|
+
|
|
42
|
+
if TYPE_CHECKING:
|
|
43
|
+
from chrys.foundation.events.bus import EventBus
|
|
44
|
+
from chrys.orchestration.engine.session_lifecycle import SessionLifecycle
|
|
45
|
+
from chrys.orchestration.engine.state.active_session import ActiveSession
|
|
46
|
+
from chrys.orchestration.engine.state.current_agent import CurrentAgent
|
|
47
|
+
from chrys.orchestration.engine.state.lifecycle_permits import LifecyclePermits
|
|
48
|
+
from chrys.orchestration.workflows.coordinator import WorkflowCoordinator
|
|
49
|
+
from chrys.service.mutations.workspace_changes import WorkspaceChangeTracker
|
|
50
|
+
from chrys.service.profiles.agents.registry import AgentProfileRegistry
|
|
51
|
+
from chrys.service.profiles.agents.schema import AgentProfile
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
logger = logging.getLogger(__name__)
|
|
55
|
+
|
|
56
|
+
_CONTROLS_NO_REGISTRY = msg(
|
|
57
|
+
"controls.no_registry",
|
|
58
|
+
fallback="No profile registry configured — cannot switch profiles",
|
|
59
|
+
)
|
|
60
|
+
_CONTROLS_PROFILE_NOT_FOUND = msg(
|
|
61
|
+
"controls.profile_not_found",
|
|
62
|
+
fallback="Profile '{profile_name}' not found",
|
|
63
|
+
)
|
|
64
|
+
_CONTROLS_MODEL_SWITCH_NOT_READY = msg(
|
|
65
|
+
"controls.model_switch_not_ready",
|
|
66
|
+
fallback="No active agent — cannot switch model",
|
|
67
|
+
)
|
|
68
|
+
_CONTROLS_WORKSPACE_SWITCH_NOT_READY = msg(
|
|
69
|
+
"controls.workspace_switch_not_ready",
|
|
70
|
+
fallback="No active agent — cannot change workspace",
|
|
71
|
+
)
|
|
72
|
+
_CONTROLS_WORKSPACE_MISSING = msg(
|
|
73
|
+
"controls.workspace_missing",
|
|
74
|
+
fallback="Cannot change the working directory: {path} does not exist.",
|
|
75
|
+
)
|
|
76
|
+
_CONTROLS_SETTINGS_RESTART_REQUIRED = msg(
|
|
77
|
+
"controls.settings_restart_required",
|
|
78
|
+
fallback="Saved; takes effect after restart: {keys}.",
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
PersistApprovalModeFn = Callable[[str], None]
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def _denial_allows_already_satisfied_success(denied: RebuildPermitDenied) -> bool:
|
|
85
|
+
"""Return whether a denial can be converted to an already-satisfied success."""
|
|
86
|
+
return denied.reason == "superseded"
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _workspace_primary_matches(workspace: Workspace | None, primary_cwd: str) -> bool:
|
|
90
|
+
"""Return whether *primary_cwd* names the live workspace primary cwd."""
|
|
91
|
+
if workspace is None:
|
|
92
|
+
return False
|
|
93
|
+
if workspace.primary_cwd == primary_cwd:
|
|
94
|
+
return True
|
|
95
|
+
return workspace.primary_cwd == Workspace.from_cwd(primary_cwd).primary_cwd
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class RuntimeControls:
|
|
99
|
+
"""Applies profile, model, settings, workspace, and approval changes."""
|
|
100
|
+
|
|
101
|
+
def __init__(
|
|
102
|
+
self,
|
|
103
|
+
*,
|
|
104
|
+
session: ActiveSession,
|
|
105
|
+
current: CurrentAgent,
|
|
106
|
+
permits: LifecyclePermits,
|
|
107
|
+
lifecycle: SessionLifecycle,
|
|
108
|
+
bus: EventBus,
|
|
109
|
+
settings_handle: SettingsHandle,
|
|
110
|
+
agent_registry: AgentProfileRegistry | None,
|
|
111
|
+
workspace_change_tracker: WorkspaceChangeTracker,
|
|
112
|
+
workflows: WorkflowCoordinator,
|
|
113
|
+
) -> None:
|
|
114
|
+
self._session = session
|
|
115
|
+
self._current = current
|
|
116
|
+
self._permits = permits
|
|
117
|
+
self._lifecycle = lifecycle
|
|
118
|
+
self._bus = bus
|
|
119
|
+
self._settings_handle = settings_handle
|
|
120
|
+
self._agent_registry = agent_registry
|
|
121
|
+
self._workspace_change_tracker = workspace_change_tracker
|
|
122
|
+
self._workflows = workflows
|
|
123
|
+
|
|
124
|
+
def current_profile_snapshot(self) -> ProfileSwitched:
|
|
125
|
+
"""Build a no-op ``ProfileSwitched`` reflecting the live runtime.
|
|
126
|
+
|
|
127
|
+
A frontend reselecting the already-active agent performs no backend
|
|
128
|
+
switch and emits no event, so callers that still owe the client the
|
|
129
|
+
standard runtime envelope read it here instead of fabricating blank
|
|
130
|
+
fields. ``from``/``to`` are identical because nothing changed. Field
|
|
131
|
+
sourcing mirrors the real switch event so the two cannot drift.
|
|
132
|
+
"""
|
|
133
|
+
profile = self._session.agent_profile
|
|
134
|
+
name = profile.name if profile else ""
|
|
135
|
+
display = (profile.display_name or profile.name) if profile else ""
|
|
136
|
+
messages = (
|
|
137
|
+
self._current.loaded.bindings.backend.history_state.get("messages", [])
|
|
138
|
+
if self._current.loaded is not None
|
|
139
|
+
else []
|
|
140
|
+
)
|
|
141
|
+
return ProfileSwitched(
|
|
142
|
+
from_profile=name,
|
|
143
|
+
to_profile=name,
|
|
144
|
+
from_display_name=display,
|
|
145
|
+
to_display_name=display,
|
|
146
|
+
message_count=len(messages),
|
|
147
|
+
model_profile_id=self._current.manifest.active_profile.id if self._current.manifest.active_profile else "",
|
|
148
|
+
max_context_tokens=self._current.manifest.active_profile.max_context_tokens
|
|
149
|
+
if self._current.manifest.active_profile
|
|
150
|
+
else 0,
|
|
151
|
+
session_id=self._session.session_id,
|
|
152
|
+
tool_names=list(self._current.manifest.tool_names),
|
|
153
|
+
skill_names=list(self._current.manifest.skill_names),
|
|
154
|
+
sub_agent_tool_names=self._current.loaded.sub_agent_tools.tool_names()
|
|
155
|
+
if self._current.loaded is not None and self._current.loaded.sub_agent_tools
|
|
156
|
+
else [],
|
|
157
|
+
memory_files=list(self._current.manifest.memory_files),
|
|
158
|
+
runtime_details=copy.deepcopy(self._current.manifest.runtime_details),
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
async def on_set_approval_mode(
|
|
162
|
+
self,
|
|
163
|
+
event: SetApprovalMode,
|
|
164
|
+
*,
|
|
165
|
+
persist_approval_mode_fn: PersistApprovalModeFn,
|
|
166
|
+
) -> None:
|
|
167
|
+
"""Update the active approval mode on the running middleware."""
|
|
168
|
+
try:
|
|
169
|
+
mode = ApprovalMode(event.mode)
|
|
170
|
+
except ValueError:
|
|
171
|
+
logger.warning("Unknown approval mode: %r", event.mode)
|
|
172
|
+
return
|
|
173
|
+
self._session.approval_mode = mode
|
|
174
|
+
if self._current.loaded is not None:
|
|
175
|
+
self._current.loaded.bindings.approval.set_approval_mode(mode)
|
|
176
|
+
# Propagate to sub-agent tools so each fresh sub-agent invocation
|
|
177
|
+
# constructs its ApprovalMiddleware with the live mode.
|
|
178
|
+
if self._current.loaded is not None and self._current.loaded.sub_agent_tools is not None:
|
|
179
|
+
self._current.loaded.sub_agent_tools.set_approval_mode(mode)
|
|
180
|
+
self._workflows.set_approval_mode(mode)
|
|
181
|
+
if event.persist:
|
|
182
|
+
# Persist the user's choice so it survives restart. BYPASS is
|
|
183
|
+
# downgraded to AUTO inside ``persist_approval_mode`` to avoid
|
|
184
|
+
# booting into unattended auto-approval on next launch — mirror
|
|
185
|
+
# that same downgrade onto the in-memory Settings so a later
|
|
186
|
+
# ``SettingsReload`` stays consistent with what's on disk.
|
|
187
|
+
#
|
|
188
|
+
# Through the overlay rather than onto the field: this key is
|
|
189
|
+
# ``Risk.DANGEROUS``, so a rejected value seals it at ``manual``, and
|
|
190
|
+
# an in-place write would leave that seal on top of the mode the user
|
|
191
|
+
# just chose.
|
|
192
|
+
self._settings_handle.persist_approval_default(mode.value, persist=persist_approval_mode_fn)
|
|
193
|
+
await self._bus.publish(ApprovalModeUpdated(mode=mode.value, session_id=self._session.session_id))
|
|
194
|
+
|
|
195
|
+
async def on_profile_switch(self, event: AgentProfileSwitch) -> None:
|
|
196
|
+
"""Handle agent profile switch — preserves conversation history."""
|
|
197
|
+
token = self._permits.capture_control_token()
|
|
198
|
+
if self._agent_registry is None:
|
|
199
|
+
await self._bus.publish(
|
|
200
|
+
Error(
|
|
201
|
+
code="no_registry",
|
|
202
|
+
message="No profile registry configured — cannot switch profiles",
|
|
203
|
+
display_message=_CONTROLS_NO_REGISTRY.bind(),
|
|
204
|
+
session_id=self._session.session_id,
|
|
205
|
+
)
|
|
206
|
+
)
|
|
207
|
+
return
|
|
208
|
+
|
|
209
|
+
new_profile = self._agent_registry.get(event.profile_name)
|
|
210
|
+
if new_profile is None:
|
|
211
|
+
await self._bus.publish(
|
|
212
|
+
Error(
|
|
213
|
+
code="profile_not_found",
|
|
214
|
+
message=f"Profile '{event.profile_name}' not found",
|
|
215
|
+
display_message=_CONTROLS_PROFILE_NOT_FOUND.bind(profile_name=event.profile_name),
|
|
216
|
+
session_id=self._session.session_id,
|
|
217
|
+
)
|
|
218
|
+
)
|
|
219
|
+
return
|
|
220
|
+
|
|
221
|
+
permit = await self._permits.acquire_rebuild_permit(token)
|
|
222
|
+
if isinstance(permit, RebuildPermitDenied):
|
|
223
|
+
if await self._publish_profile_satisfied_or_denied(event.profile_name, permit, token.session_id):
|
|
224
|
+
return
|
|
225
|
+
return
|
|
226
|
+
try:
|
|
227
|
+
if (
|
|
228
|
+
self._current.loaded is not None
|
|
229
|
+
and self._session.agent_profile
|
|
230
|
+
and new_profile.name == self._session.agent_profile.name
|
|
231
|
+
):
|
|
232
|
+
await self._bus.publish(self._profile_switched_snapshot(permit.token.session_id))
|
|
233
|
+
return
|
|
234
|
+
if self._current.loaded is None:
|
|
235
|
+
await self._lifecycle.start_with_rebuild_permit(permit, new_profile, operation="switch")
|
|
236
|
+
await self._bus.publish(self._profile_switched_snapshot(permit.token.session_id))
|
|
237
|
+
return
|
|
238
|
+
await self._lifecycle.reload_with_rebuild_permit(permit, new_profile, operation="switch")
|
|
239
|
+
finally:
|
|
240
|
+
self._permits.release_rebuild_permit(permit)
|
|
241
|
+
|
|
242
|
+
async def _publish_profile_satisfied_or_denied(
|
|
243
|
+
self,
|
|
244
|
+
profile_name: str,
|
|
245
|
+
denied: RebuildPermitDenied,
|
|
246
|
+
session_id: str | None,
|
|
247
|
+
) -> bool:
|
|
248
|
+
if _denial_allows_already_satisfied_success(denied) and (
|
|
249
|
+
self._session.agent_profile is not None and self._session.agent_profile.name == profile_name
|
|
250
|
+
):
|
|
251
|
+
await self._bus.publish(self._profile_switched_snapshot(session_id))
|
|
252
|
+
return True
|
|
253
|
+
await self._publish_rebuild_denied(denied, session_id)
|
|
254
|
+
return False
|
|
255
|
+
|
|
256
|
+
def _profile_switched_snapshot(self, session_id: str | None) -> ProfileSwitched:
|
|
257
|
+
return dataclasses.replace(self.current_profile_snapshot(), session_id=session_id)
|
|
258
|
+
|
|
259
|
+
async def _publish_rebuild_denied(
|
|
260
|
+
self,
|
|
261
|
+
denied: RebuildPermitDenied,
|
|
262
|
+
session_id: str | None,
|
|
263
|
+
) -> None:
|
|
264
|
+
await self._bus.publish(Error(code=denied.code, message=denied.message, session_id=session_id))
|
|
265
|
+
|
|
266
|
+
async def _publish_model_switched_snapshot(
|
|
267
|
+
self,
|
|
268
|
+
profile_id: str,
|
|
269
|
+
session_id: str | None,
|
|
270
|
+
) -> None:
|
|
271
|
+
active = self._current.manifest.active_profile
|
|
272
|
+
await self._bus.publish(
|
|
273
|
+
ModelProfileSwitched(
|
|
274
|
+
model_profile_id=active.id if active else profile_id,
|
|
275
|
+
max_context_tokens=active.max_context_tokens if active else 0,
|
|
276
|
+
runtime_details=copy.deepcopy(self._current.manifest.runtime_details),
|
|
277
|
+
session_id=session_id,
|
|
278
|
+
)
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
def _pin_session_model_profile(self, profile_id: str) -> None:
|
|
282
|
+
self._settings_handle.install(
|
|
283
|
+
self._settings_handle.loaded.overlay(
|
|
284
|
+
Source.SESSION,
|
|
285
|
+
model_profile=profile_id,
|
|
286
|
+
model_profile_override=profile_id,
|
|
287
|
+
model_profile_override_sub_agents=False,
|
|
288
|
+
),
|
|
289
|
+
)
|
|
290
|
+
self._session.model_profile_pinned = True
|
|
291
|
+
|
|
292
|
+
async def _publish_workspace_updated_snapshot(
|
|
293
|
+
self,
|
|
294
|
+
session_id: str | None,
|
|
295
|
+
*,
|
|
296
|
+
primary_cwd: str | None = None,
|
|
297
|
+
) -> None:
|
|
298
|
+
workspace = self._session.workspace
|
|
299
|
+
resolved_primary_cwd = primary_cwd if primary_cwd is not None else (workspace.primary_cwd if workspace else "")
|
|
300
|
+
await self._bus.publish(
|
|
301
|
+
WorkspaceUpdated(
|
|
302
|
+
primary_cwd=resolved_primary_cwd,
|
|
303
|
+
working_dirs=[d.path for d in workspace.working_dirs] if workspace is not None else [],
|
|
304
|
+
reference_files=list(workspace.reference_files) if workspace is not None else [],
|
|
305
|
+
session_id=session_id,
|
|
306
|
+
)
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
async def _publish_model_satisfied_or_denied(
|
|
310
|
+
self,
|
|
311
|
+
profile_id: str,
|
|
312
|
+
denied: RebuildPermitDenied,
|
|
313
|
+
session_id: str | None,
|
|
314
|
+
) -> None:
|
|
315
|
+
if _denial_allows_already_satisfied_success(denied) and (
|
|
316
|
+
self._current.manifest.active_profile is not None and self._current.manifest.active_profile.id == profile_id
|
|
317
|
+
):
|
|
318
|
+
self._pin_session_model_profile(profile_id)
|
|
319
|
+
await self._publish_model_switched_snapshot(profile_id, session_id)
|
|
320
|
+
return
|
|
321
|
+
await self._publish_rebuild_denied(denied, session_id)
|
|
322
|
+
|
|
323
|
+
async def _publish_workspace_satisfied_or_denied(
|
|
324
|
+
self,
|
|
325
|
+
primary_cwd: str,
|
|
326
|
+
denied: RebuildPermitDenied,
|
|
327
|
+
session_id: str | None,
|
|
328
|
+
) -> None:
|
|
329
|
+
if _denial_allows_already_satisfied_success(denied) and _workspace_primary_matches(
|
|
330
|
+
self._session.workspace, primary_cwd
|
|
331
|
+
):
|
|
332
|
+
await self._publish_workspace_updated_snapshot(session_id, primary_cwd=primary_cwd)
|
|
333
|
+
return
|
|
334
|
+
await self._publish_rebuild_denied(denied, session_id)
|
|
335
|
+
|
|
336
|
+
async def _acquire_rebuild_permit_or_publish_error(
|
|
337
|
+
self,
|
|
338
|
+
token: RebuildControlToken,
|
|
339
|
+
) -> RebuildPermit | None:
|
|
340
|
+
permit = await self._permits.acquire_rebuild_permit(token)
|
|
341
|
+
if isinstance(permit, RebuildPermitDenied):
|
|
342
|
+
await self._publish_rebuild_denied(permit, token.session_id)
|
|
343
|
+
return None
|
|
344
|
+
return permit
|
|
345
|
+
|
|
346
|
+
async def _start_or_restart_with_permit(
|
|
347
|
+
self,
|
|
348
|
+
permit: RebuildPermit,
|
|
349
|
+
profile: AgentProfile,
|
|
350
|
+
*,
|
|
351
|
+
operation: str,
|
|
352
|
+
workspace: Workspace | None = None,
|
|
353
|
+
staged_loaded: LoadedSettings | None = None,
|
|
354
|
+
) -> None:
|
|
355
|
+
if self._current.loaded is None:
|
|
356
|
+
# The workspace rides as staged input, exactly like the settings: a
|
|
357
|
+
# build that fails before committing must leave the live root — the
|
|
358
|
+
# one the live settings and hooks were derived from — untouched.
|
|
359
|
+
await self._lifecycle.start_with_rebuild_permit(
|
|
360
|
+
permit, profile, operation=operation, staged_loaded=staged_loaded, workspace=workspace
|
|
361
|
+
)
|
|
362
|
+
return
|
|
363
|
+
await self._lifecycle.reload_with_rebuild_permit(
|
|
364
|
+
permit, profile, workspace=workspace, operation=operation, staged_loaded=staged_loaded
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
async def on_set_model_profile(self, event: SetModelProfile) -> None:
|
|
368
|
+
"""Switch the active model profile for this session only (no global .env write).
|
|
369
|
+
|
|
370
|
+
Swaps the in-memory model selector and explicit override, then rebuilds;
|
|
371
|
+
the build path resolves the model from ``settings`` against the registry,
|
|
372
|
+
and credentials come from the profile itself, so sessions stay isolated.
|
|
373
|
+
"""
|
|
374
|
+
if self._session.agent_profile is None:
|
|
375
|
+
await self._bus.publish(
|
|
376
|
+
Error(
|
|
377
|
+
code="runtime_mutation_not_ready",
|
|
378
|
+
message="No active agent — cannot switch model",
|
|
379
|
+
display_message=_CONTROLS_MODEL_SWITCH_NOT_READY.bind(),
|
|
380
|
+
session_id=self._session.session_id,
|
|
381
|
+
)
|
|
382
|
+
)
|
|
383
|
+
return
|
|
384
|
+
token = self._permits.capture_control_token()
|
|
385
|
+
permit = await self._permits.acquire_rebuild_permit(token)
|
|
386
|
+
if isinstance(permit, RebuildPermitDenied):
|
|
387
|
+
await self._publish_model_satisfied_or_denied(event.profile_id, permit, token.session_id)
|
|
388
|
+
return
|
|
389
|
+
|
|
390
|
+
old_loaded = self._settings_handle.loaded
|
|
391
|
+
old_pinned = self._session.model_profile_pinned
|
|
392
|
+
|
|
393
|
+
try:
|
|
394
|
+
try:
|
|
395
|
+
self._pin_session_model_profile(event.profile_id)
|
|
396
|
+
await self._start_or_restart_with_permit(permit, self._session.agent_profile, operation="model_switch")
|
|
397
|
+
except Exception:
|
|
398
|
+
# Rebuild failed (AgentLoadFailed already published). Restore the pin/settings
|
|
399
|
+
# so the still-running executor stays consistent with session state.
|
|
400
|
+
self._settings_handle.install(old_loaded)
|
|
401
|
+
self._session.model_profile_pinned = old_pinned
|
|
402
|
+
raise
|
|
403
|
+
await self._publish_model_switched_snapshot(event.profile_id, token.session_id)
|
|
404
|
+
finally:
|
|
405
|
+
self._permits.release_rebuild_permit(permit)
|
|
406
|
+
|
|
407
|
+
def _session_pin_overrides(self) -> dict[str, Any]:
|
|
408
|
+
"""Snapshot the per-session pins every re-load must carry.
|
|
409
|
+
|
|
410
|
+
Per-session overrides injected into ``Settings`` (not the environment) are
|
|
411
|
+
carried across only when pinned, so unpinned sessions still pick up a
|
|
412
|
+
changed env value on the next load:
|
|
413
|
+
|
|
414
|
+
* ``model_profile`` / ``model_profile_override`` — pinned by a per-session
|
|
415
|
+
model switch.
|
|
416
|
+
* ``ask_user_timeout_seconds`` — pinned when ACP owns the ask_user
|
|
417
|
+
lifetime (set via dataclasses.replace at launch — see app/cli/acp.py).
|
|
418
|
+
* ``frontend_default_max_transient_retries`` — launch-mode policy; travels
|
|
419
|
+
as the :func:`_reload_eval_context` instead, and the separate
|
|
420
|
+
env-derived override is deliberately re-read.
|
|
421
|
+
"""
|
|
422
|
+
overrides: dict[str, Any] = {}
|
|
423
|
+
if self._session.ask_user_timeout_pinned:
|
|
424
|
+
overrides["ask_user_timeout_seconds"] = self._settings_handle.settings.ask_user_timeout_seconds
|
|
425
|
+
if self._session.model_profile_pinned:
|
|
426
|
+
overrides["model_profile"] = self._settings_handle.settings.model_profile
|
|
427
|
+
overrides["model_profile_override"] = self._settings_handle.settings.model_profile_override
|
|
428
|
+
overrides["model_profile_override_sub_agents"] = (
|
|
429
|
+
self._settings_handle.settings.model_profile_override_sub_agents
|
|
430
|
+
)
|
|
431
|
+
return overrides
|
|
432
|
+
|
|
433
|
+
def _reload_eval_context(self) -> EvalContext:
|
|
434
|
+
"""The launch mode's retry policy, passed *into* the load.
|
|
435
|
+
|
|
436
|
+
An input to the load rather than an override: the project layer's
|
|
437
|
+
tighten/loosen verdicts are evaluated against it, and every re-load must
|
|
438
|
+
use the same one the initial load did.
|
|
439
|
+
"""
|
|
440
|
+
return EvalContext(
|
|
441
|
+
frontend_default_max_transient_retries=self._settings_handle.settings.frontend_default_max_transient_retries
|
|
442
|
+
)
|
|
443
|
+
|
|
444
|
+
def _session_project_root(self) -> Path:
|
|
445
|
+
"""The workspace root whose project trust domain this session lives under."""
|
|
446
|
+
workspace = self._session.workspace
|
|
447
|
+
return Path(workspace.primary_cwd) if workspace is not None else Path(safe_getcwd())
|
|
448
|
+
|
|
449
|
+
async def on_settings_reload(self, _event: SettingsReload) -> None:
|
|
450
|
+
"""Handle settings reload — reload Settings from disk and env, then rebuild."""
|
|
451
|
+
token = self._permits.capture_control_token()
|
|
452
|
+
# Taken even with nothing built yet. A host that has not built — startup
|
|
453
|
+
# before the first build, a first build that failed, a host that only
|
|
454
|
+
# subscribed — must still genuinely reload; echoing completion without
|
|
455
|
+
# reloading would report success and then hand the first build the old
|
|
456
|
+
# configuration. The permit is also what serializes the load against a
|
|
457
|
+
# build, since ``start`` takes this same boundary: the values installed
|
|
458
|
+
# below cannot land halfway through one.
|
|
459
|
+
permit = await self._acquire_rebuild_permit_or_publish_error(token)
|
|
460
|
+
if permit is None:
|
|
461
|
+
return
|
|
462
|
+
|
|
463
|
+
old_loaded = self._settings_handle.loaded
|
|
464
|
+
try:
|
|
465
|
+
try:
|
|
466
|
+
# Re-read settings from env (matches TUI behavior, which persists
|
|
467
|
+
# changes before triggering reload), for this session's workspace
|
|
468
|
+
# root — the project trust domain is root-derived, so the reload
|
|
469
|
+
# must re-derive it from where the session actually lives.
|
|
470
|
+
#
|
|
471
|
+
# Off-thread because the load reads config files and waits on their
|
|
472
|
+
# lock, and this handler runs inline on the bus: a synchronous load
|
|
473
|
+
# here would stall every other event for as long as the disk takes.
|
|
474
|
+
# The pins are snapshotted before the hand-off, so the load works
|
|
475
|
+
# from the state that asked for it.
|
|
476
|
+
candidate = await asyncio.to_thread(
|
|
477
|
+
load_settings,
|
|
478
|
+
project_root=self._session_project_root(),
|
|
479
|
+
eval_context=self._reload_eval_context(),
|
|
480
|
+
**self._session_pin_overrides(),
|
|
481
|
+
)
|
|
482
|
+
# Routed after the load, not excluded from it: the reload still has
|
|
483
|
+
# to report a RESTART value the user typed wrong, it just must not
|
|
484
|
+
# claim the good ones took effect. The snapshot fields keep the
|
|
485
|
+
# bootstrap values their readers hold; the rest of the RESTART tier
|
|
486
|
+
# is held at the values already in force, so the rebuild below
|
|
487
|
+
# cannot apply what only a restart may.
|
|
488
|
+
loaded, deferred_keys = route_restart_settings(
|
|
489
|
+
reattribute_command_line(candidate, old_loaded),
|
|
490
|
+
old_loaded,
|
|
491
|
+
)
|
|
492
|
+
# A reload is the moment a user finds out their edit did not take.
|
|
493
|
+
# Startup already reports these; dropping them here would make the
|
|
494
|
+
# same bad value silent from the second read onwards.
|
|
495
|
+
for warning in settings_warning_events(loaded):
|
|
496
|
+
await self._bus.publish(dataclasses.replace(warning, session_id=self._session.session_id))
|
|
497
|
+
if deferred_keys:
|
|
498
|
+
display_message = _CONTROLS_SETTINGS_RESTART_REQUIRED.bind(keys=DisplaySequence(deferred_keys))
|
|
499
|
+
await self._bus.publish(
|
|
500
|
+
Warning(
|
|
501
|
+
code="settings_restart_required",
|
|
502
|
+
message=format_message(display_message),
|
|
503
|
+
display_message=display_message,
|
|
504
|
+
session_id=self._session.session_id,
|
|
505
|
+
)
|
|
506
|
+
)
|
|
507
|
+
|
|
508
|
+
# Pull the latest active profile instance from the registry so edits
|
|
509
|
+
# saved to user YAML (e.g. MCP enabled/disabled) take effect immediately.
|
|
510
|
+
profile_for_restart = self._session.agent_profile
|
|
511
|
+
if profile_for_restart is not None and self._agent_registry is not None:
|
|
512
|
+
refreshed = self._agent_registry.get(profile_for_restart.name)
|
|
513
|
+
if refreshed is not None:
|
|
514
|
+
profile_for_restart = refreshed
|
|
515
|
+
else:
|
|
516
|
+
logger.warning(
|
|
517
|
+
"Active profile '%s' missing from registry during settings reload; reusing current profile.",
|
|
518
|
+
profile_for_restart.name,
|
|
519
|
+
)
|
|
520
|
+
except Exception as exc:
|
|
521
|
+
# A failing load (an unreadable settings file, say) aborts *before*
|
|
522
|
+
# the rebuild publishes any completion event. The bus swallows
|
|
523
|
+
# handler exceptions, so without an explicit failure here a caller
|
|
524
|
+
# awaiting the reload would hang until its timeout. Nothing was
|
|
525
|
+
# installed yet — the candidate stays staged until the rebuild
|
|
526
|
+
# commits it — so surfacing the error is all there is to do.
|
|
527
|
+
#
|
|
528
|
+
# Individually invalid values no longer land here: they are rejected
|
|
529
|
+
# by their coercer and reported as warnings, so one bad variable can
|
|
530
|
+
# no longer take a whole reload down.
|
|
531
|
+
await self._bus.publish(
|
|
532
|
+
Error(code="settings_reload_failed", message=str(exc), session_id=self._session.session_id)
|
|
533
|
+
)
|
|
534
|
+
raise
|
|
535
|
+
|
|
536
|
+
# Only the rebuild is conditional: with nothing built there is no
|
|
537
|
+
# runtime to replace, so the candidate is installed directly and the
|
|
538
|
+
# first build will read it. With a runtime, the candidate travels as
|
|
539
|
+
# the rebuild's staged input and is committed by the build itself,
|
|
540
|
+
# together with the executor it configured: a rebuild that fails
|
|
541
|
+
# before installing leaves the live settings untouched, and one that
|
|
542
|
+
# fails after keeps the settings its executor was actually built from
|
|
543
|
+
# — restoring the old ones there would desynchronize the two.
|
|
544
|
+
if profile_for_restart is not None:
|
|
545
|
+
await self._start_or_restart_with_permit(
|
|
546
|
+
permit, profile_for_restart, operation="settings_reload", staged_loaded=loaded
|
|
547
|
+
)
|
|
548
|
+
if (
|
|
549
|
+
old_loaded.settings.workspace_change_notice
|
|
550
|
+
and not self._settings_handle.settings.workspace_change_notice
|
|
551
|
+
):
|
|
552
|
+
# Drop the baseline only once the off-state rebuild has committed —
|
|
553
|
+
# a failed rebuild keeps the old enabled settings AND the baseline.
|
|
554
|
+
self._workspace_change_tracker.invalidate()
|
|
555
|
+
else:
|
|
556
|
+
self._settings_handle.install(loaded)
|
|
557
|
+
await self._publish_settings_reloaded()
|
|
558
|
+
finally:
|
|
559
|
+
self._permits.release_rebuild_permit(permit)
|
|
560
|
+
|
|
561
|
+
async def _publish_settings_reloaded(self) -> None:
|
|
562
|
+
await self._bus.publish(
|
|
563
|
+
SettingsReloaded(
|
|
564
|
+
runtime_details=copy.deepcopy(self._current.manifest.runtime_details),
|
|
565
|
+
session_id=self._session.session_id,
|
|
566
|
+
)
|
|
567
|
+
)
|
|
568
|
+
|
|
569
|
+
async def on_workspace_change(self, event: WorkspaceChange) -> None:
|
|
570
|
+
"""Handle workspace/cwd change — rebuild agent with new workspace."""
|
|
571
|
+
if self._session.agent_profile is None:
|
|
572
|
+
await self._bus.publish(
|
|
573
|
+
Error(
|
|
574
|
+
code="runtime_mutation_not_ready",
|
|
575
|
+
message="No active agent — cannot change workspace",
|
|
576
|
+
display_message=_CONTROLS_WORKSPACE_SWITCH_NOT_READY.bind(),
|
|
577
|
+
session_id=self._session.session_id,
|
|
578
|
+
)
|
|
579
|
+
)
|
|
580
|
+
return
|
|
581
|
+
if event.primary_cwd and (missing := Workspace.from_cwd(event.primary_cwd).missing_primary()) is not None:
|
|
582
|
+
await self._bus.publish(
|
|
583
|
+
Error(
|
|
584
|
+
code="workspace_change_failed",
|
|
585
|
+
message=f"Working directory does not exist: {surrogate_safe_text(missing)}",
|
|
586
|
+
display_message=_CONTROLS_WORKSPACE_MISSING.bind(path=DisplayPath(missing)),
|
|
587
|
+
session_id=self._session.session_id,
|
|
588
|
+
)
|
|
589
|
+
)
|
|
590
|
+
return
|
|
591
|
+
token = self._permits.capture_control_token()
|
|
592
|
+
permit = await self._permits.acquire_rebuild_permit(token)
|
|
593
|
+
if isinstance(permit, RebuildPermitDenied):
|
|
594
|
+
await self._publish_workspace_satisfied_or_denied(event.primary_cwd, permit, token.session_id)
|
|
595
|
+
return
|
|
596
|
+
|
|
597
|
+
new_workspace = Workspace.from_cwd(event.primary_cwd)
|
|
598
|
+
starting_without_executor = self._current.loaded is None
|
|
599
|
+
try:
|
|
600
|
+
# A workspace change is a settings reload in disguise: the project
|
|
601
|
+
# trust domain is root-derived, so the new root's layers must be
|
|
602
|
+
# audited and applied — and the old root's dropped — by the same
|
|
603
|
+
# rebuild that installs the new workspace. Same routing as a reload
|
|
604
|
+
# (RESTART values stay in force, the command line keeps its credit),
|
|
605
|
+
# minus the restart-required warning: nothing was edited here, so any
|
|
606
|
+
# deferred value was already reported by the reload that deferred it.
|
|
607
|
+
try:
|
|
608
|
+
old_loaded = self._settings_handle.loaded
|
|
609
|
+
candidate = await asyncio.to_thread(
|
|
610
|
+
load_settings,
|
|
611
|
+
project_root=Path(new_workspace.primary_cwd),
|
|
612
|
+
eval_context=self._reload_eval_context(),
|
|
613
|
+
**self._session_pin_overrides(),
|
|
614
|
+
)
|
|
615
|
+
staged_loaded, _ = route_restart_settings(reattribute_command_line(candidate, old_loaded), old_loaded)
|
|
616
|
+
except Exception as exc:
|
|
617
|
+
# Same shape as a reload's load failure: it aborts before the
|
|
618
|
+
# rebuild publishes any completion event, and the bus swallows
|
|
619
|
+
# handler exceptions — without an explicit terminal event here a
|
|
620
|
+
# caller awaiting the change would hang until its timeout.
|
|
621
|
+
await self._bus.publish(
|
|
622
|
+
Error(code="workspace_change_failed", message=str(exc), session_id=self._session.session_id)
|
|
623
|
+
)
|
|
624
|
+
raise
|
|
625
|
+
await self._start_or_restart_with_permit(
|
|
626
|
+
permit,
|
|
627
|
+
self._session.agent_profile,
|
|
628
|
+
operation="workspace_change",
|
|
629
|
+
workspace=new_workspace,
|
|
630
|
+
staged_loaded=staged_loaded,
|
|
631
|
+
)
|
|
632
|
+
# After the commit, not before: these verdicts describe the new
|
|
633
|
+
# root's files, and a failed rebuild keeps the old root's settings.
|
|
634
|
+
for warning in settings_warning_events(staged_loaded):
|
|
635
|
+
await self._bus.publish(dataclasses.replace(warning, session_id=self._session.session_id))
|
|
636
|
+
if starting_without_executor:
|
|
637
|
+
await self._publish_workspace_updated_snapshot(token.session_id)
|
|
638
|
+
finally:
|
|
639
|
+
self._permits.release_rebuild_permit(permit)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""The current build resources and the last installed configuration."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from chrys.orchestration.engine.build.loaded import AgentManifest, LoadedAgent
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CurrentAgent:
|
|
11
|
+
"""Keep resource lifetime separate from manifest lifetime."""
|
|
12
|
+
|
|
13
|
+
__slots__ = ("loaded", "manifest")
|
|
14
|
+
|
|
15
|
+
loaded: LoadedAgent | None
|
|
16
|
+
manifest: AgentManifest
|
|
17
|
+
|
|
18
|
+
def __init__(self) -> None:
|
|
19
|
+
self.loaded = None
|
|
20
|
+
self.manifest = AgentManifest.empty()
|
|
21
|
+
|
|
22
|
+
def require_loaded(self) -> LoadedAgent:
|
|
23
|
+
"""Read the current build at use time; do not retain it across rebuilds."""
|
|
24
|
+
if self.loaded is None:
|
|
25
|
+
raise RuntimeError("The current agent has not been loaded.")
|
|
26
|
+
return self.loaded
|