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,771 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Owner of the execution lifetime: the Turn run task, or the one workflow run, from admission to release.
|
|
4
|
+
|
|
5
|
+
Multiple preparations and a single promoted task are preserved for turns.
|
|
6
|
+
Pending retry remains the existing Turn policy; a Conversation is a borrowed
|
|
7
|
+
resource and its lifetime never acquires this lease. A workflow run holds the
|
|
8
|
+
lease exclusively through :attr:`ExecutionLease.workflow`: at most one run
|
|
9
|
+
globally, admitted only while no turn is live, and every turn admission and
|
|
10
|
+
rebuild is refused while it is held. :meth:`ExecutionLease.execution` is the
|
|
11
|
+
snapshot frontends read to tell the two apart.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import asyncio
|
|
17
|
+
import contextlib
|
|
18
|
+
import time
|
|
19
|
+
from collections.abc import Callable, Iterator
|
|
20
|
+
from dataclasses import dataclass, field
|
|
21
|
+
from datetime import datetime
|
|
22
|
+
from typing import TYPE_CHECKING, Any, Literal
|
|
23
|
+
from weakref import WeakSet
|
|
24
|
+
|
|
25
|
+
from chrys.foundation.events.types import Error, ExecutionChanged
|
|
26
|
+
from chrys.foundation.models.execution import ExecutionSnapshot
|
|
27
|
+
from chrys.service.trajectory.preparation import PreparationOutcome, PreparationTrace
|
|
28
|
+
from chrys.service.trajectory.waits import WaitOutcome, WaitTrace
|
|
29
|
+
|
|
30
|
+
if TYPE_CHECKING:
|
|
31
|
+
from chrys.foundation.events.bus import EventBus
|
|
32
|
+
from chrys.orchestration.engine.run.turn_state import ActiveInjectionTarget
|
|
33
|
+
from chrys.service.agent_middleware.system_reminder import CurrentRunReminderScope
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass
|
|
37
|
+
class WorkflowExecution:
|
|
38
|
+
"""The one workflow run the lease admits at a time; ``task`` is installed once the run is spawned."""
|
|
39
|
+
|
|
40
|
+
run_id: str
|
|
41
|
+
request_id: str
|
|
42
|
+
task: asyncio.Task[None] | None = None
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@dataclass(frozen=True)
|
|
46
|
+
class RunTaskDrainOutcome:
|
|
47
|
+
"""Outcome from observing a run-task chain for a rebuild/session boundary."""
|
|
48
|
+
|
|
49
|
+
cancelled: bool = False
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@dataclass
|
|
53
|
+
class PreAdmissionPreparationEntry:
|
|
54
|
+
"""Registered pre-turn preparation that has not reached an admission record."""
|
|
55
|
+
|
|
56
|
+
preparation: PreparationTrace
|
|
57
|
+
current_wait: WaitTrace | None = field(default=None, repr=False, compare=False)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@dataclass
|
|
61
|
+
class PreAdmissionPreparationTracker:
|
|
62
|
+
"""Mutable worker-local pointer to the current pre-admission preparation."""
|
|
63
|
+
|
|
64
|
+
current: PreAdmissionPreparationEntry | None = None
|
|
65
|
+
preparation_handed_off: bool = False
|
|
66
|
+
"""Whether the current trace moved to a longer-lived owner."""
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def preparation(self) -> PreparationTrace | None:
|
|
70
|
+
"""Return the worker's current preparation trace, if recording is enabled."""
|
|
71
|
+
return self.current.preparation if self.current is not None else None
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@dataclass(frozen=True)
|
|
75
|
+
class PromptAdmissionRecord:
|
|
76
|
+
"""Visible prompt/retry admission while awaited validation is in progress."""
|
|
77
|
+
|
|
78
|
+
admission_id: int
|
|
79
|
+
kind: Literal["fresh", "retry"]
|
|
80
|
+
session_generation: int
|
|
81
|
+
build_generation: int
|
|
82
|
+
created_at_monotonic: float
|
|
83
|
+
preparation_trace: PreparationTrace | None = field(default=None, repr=False, compare=False)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@dataclass
|
|
87
|
+
class PendingRetry:
|
|
88
|
+
"""Retry request queued to run after the current executor call returns."""
|
|
89
|
+
|
|
90
|
+
text: str = ""
|
|
91
|
+
created_at: datetime | str | None = None
|
|
92
|
+
session_generation: int = 0
|
|
93
|
+
run_generation: int = 0
|
|
94
|
+
updated_by_admission_id: int | None = None
|
|
95
|
+
owner_admission_id: int | None = None
|
|
96
|
+
dispatch_disabled: bool = False
|
|
97
|
+
preparation_trace: PreparationTrace | None = field(default=None, repr=False, compare=False)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
@dataclass(frozen=True)
|
|
101
|
+
class PromptAdmissionScope:
|
|
102
|
+
"""Exact prompt/retry admission token."""
|
|
103
|
+
|
|
104
|
+
admission_id: int
|
|
105
|
+
kind: Literal["fresh", "retry"]
|
|
106
|
+
session_generation: int
|
|
107
|
+
build_generation: int
|
|
108
|
+
preparation_trace: PreparationTrace | None = field(default=None, repr=False, compare=False)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@dataclass(frozen=True)
|
|
112
|
+
class CurrentRunScope:
|
|
113
|
+
"""Orchestration-owned identity for one logical main-agent run."""
|
|
114
|
+
|
|
115
|
+
run_generation: int
|
|
116
|
+
session_generation: int
|
|
117
|
+
build_generation: int
|
|
118
|
+
owner_admission_id: int
|
|
119
|
+
reminder_scope: CurrentRunReminderScope
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@dataclass(frozen=True)
|
|
123
|
+
class CurrentRunInjectionWindow:
|
|
124
|
+
"""Injectable executor-pass window for a current run."""
|
|
125
|
+
|
|
126
|
+
run_generation: int
|
|
127
|
+
window_generation: int
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
@dataclass(frozen=True)
|
|
131
|
+
class PromptPromotionResult:
|
|
132
|
+
"""Result from promoting a fresh prompt admission into a run task."""
|
|
133
|
+
|
|
134
|
+
promoted: bool
|
|
135
|
+
conflict: bool = False
|
|
136
|
+
stale: bool = False
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
@dataclass(frozen=True)
|
|
140
|
+
class RetryPromotionResult:
|
|
141
|
+
"""Result from promoting a retry admission into a task or pending retry."""
|
|
142
|
+
|
|
143
|
+
outcome: Literal["task", "pending_installed", "pending_updated", "stale", "invalid"]
|
|
144
|
+
task: asyncio.Task[None] | None = None
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
@dataclass
|
|
148
|
+
class ExecutionLease:
|
|
149
|
+
"""One top-level task truth, its generation fences, admission and save evidence."""
|
|
150
|
+
|
|
151
|
+
bus: EventBus | None = field(default=None, repr=False, compare=False)
|
|
152
|
+
_last_execution: ExecutionSnapshot = field(default_factory=lambda: ExecutionSnapshot("idle"), init=False)
|
|
153
|
+
_notification_task: asyncio.Task[None] | None = field(default=None, init=False, repr=False, compare=False)
|
|
154
|
+
|
|
155
|
+
next_admission_id: int = 1
|
|
156
|
+
|
|
157
|
+
active_admissions: dict[int, PromptAdmissionRecord] = field(default_factory=dict)
|
|
158
|
+
|
|
159
|
+
pre_admission_preparations: dict[str, PreAdmissionPreparationEntry] = field(
|
|
160
|
+
default_factory=dict,
|
|
161
|
+
repr=False,
|
|
162
|
+
compare=False,
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
active_admissions_idle: asyncio.Event = field(default_factory=asyncio.Event, repr=False, compare=False)
|
|
166
|
+
|
|
167
|
+
prompt_admission_closed: bool = False
|
|
168
|
+
|
|
169
|
+
prompt_admission_close_owner: str | None = None
|
|
170
|
+
|
|
171
|
+
prompt_admission_open: asyncio.Event = field(default_factory=asyncio.Event, repr=False, compare=False)
|
|
172
|
+
|
|
173
|
+
_run_task: asyncio.Task[None] | None = field(default=None, init=False, repr=False)
|
|
174
|
+
|
|
175
|
+
workflow: WorkflowExecution | None = None
|
|
176
|
+
|
|
177
|
+
# Session-family operations in flight (new, clear, fork, restore, delete, rollback), reads and fences
|
|
178
|
+
# included: a workflow run is not admitted under one, or it would run inside a session being replaced.
|
|
179
|
+
session_operations: int = 0
|
|
180
|
+
|
|
181
|
+
current_run_scope: CurrentRunScope | None = None
|
|
182
|
+
|
|
183
|
+
next_run_generation: int = 1
|
|
184
|
+
|
|
185
|
+
conversation_revision: int = 0
|
|
186
|
+
|
|
187
|
+
injection_window_generation: int = 0
|
|
188
|
+
|
|
189
|
+
injection_admission_open: bool = False
|
|
190
|
+
|
|
191
|
+
active_injection_commits: int = 0
|
|
192
|
+
|
|
193
|
+
active_injection_commits_idle: asyncio.Event = field(default_factory=asyncio.Event, repr=False, compare=False)
|
|
194
|
+
|
|
195
|
+
pending_retry: PendingRetry = field(default_factory=PendingRetry)
|
|
196
|
+
|
|
197
|
+
pending_retry_dispatch_disabled_for_session_generation: int | None = None
|
|
198
|
+
|
|
199
|
+
_successfully_saved_run_tasks: WeakSet[asyncio.Task[Any]] = field(
|
|
200
|
+
default_factory=WeakSet,
|
|
201
|
+
repr=False,
|
|
202
|
+
compare=False,
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
_pre_executor_interrupt_tasks: WeakSet[asyncio.Task[Any]] = field(
|
|
206
|
+
default_factory=WeakSet,
|
|
207
|
+
repr=False,
|
|
208
|
+
compare=False,
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
def __post_init__(self) -> None:
|
|
212
|
+
"""Initialize waitable idle markers for freshly constructed state."""
|
|
213
|
+
if not self.active_admissions:
|
|
214
|
+
self.active_admissions_idle.set()
|
|
215
|
+
if not self.prompt_admission_closed:
|
|
216
|
+
self.prompt_admission_open.set()
|
|
217
|
+
if self.active_injection_commits == 0:
|
|
218
|
+
self.active_injection_commits_idle.set()
|
|
219
|
+
|
|
220
|
+
@property
|
|
221
|
+
def run_task(self) -> asyncio.Task[None] | None:
|
|
222
|
+
return self._run_task
|
|
223
|
+
|
|
224
|
+
@run_task.setter
|
|
225
|
+
def run_task(self, task: asyncio.Task[None] | None) -> None:
|
|
226
|
+
if self._run_task is task:
|
|
227
|
+
return
|
|
228
|
+
if self._run_task is not None:
|
|
229
|
+
self._run_task.remove_done_callback(self._run_task_finished)
|
|
230
|
+
self._run_task = task
|
|
231
|
+
if task is not None:
|
|
232
|
+
task.add_done_callback(self._run_task_finished)
|
|
233
|
+
self._notify_execution()
|
|
234
|
+
|
|
235
|
+
def _run_task_finished(self, task: asyncio.Task[None]) -> None:
|
|
236
|
+
if task is self._run_task:
|
|
237
|
+
self._notify_execution()
|
|
238
|
+
|
|
239
|
+
def _notify_execution(self) -> None:
|
|
240
|
+
snapshot = self.execution()
|
|
241
|
+
if snapshot == self._last_execution:
|
|
242
|
+
return
|
|
243
|
+
self._last_execution = snapshot
|
|
244
|
+
bus = self.bus
|
|
245
|
+
if bus is None:
|
|
246
|
+
return
|
|
247
|
+
previous = self._notification_task
|
|
248
|
+
|
|
249
|
+
async def publish() -> None:
|
|
250
|
+
if previous is not None:
|
|
251
|
+
await previous
|
|
252
|
+
await bus.publish(ExecutionChanged(snapshot=snapshot))
|
|
253
|
+
|
|
254
|
+
self._notification_task = asyncio.create_task(publish(), name="chrys.execution.changed")
|
|
255
|
+
|
|
256
|
+
async def settle_notifications(self) -> None:
|
|
257
|
+
"""Drain ordered snapshots before the execution owner releases its resources."""
|
|
258
|
+
while (task := self._notification_task) is not None:
|
|
259
|
+
if task is asyncio.current_task():
|
|
260
|
+
return
|
|
261
|
+
await asyncio.shield(task)
|
|
262
|
+
if self._notification_task is task:
|
|
263
|
+
self._notification_task = None
|
|
264
|
+
|
|
265
|
+
def record_current_run_final_save(self) -> None:
|
|
266
|
+
"""Record that the current lifecycle task completed its final save."""
|
|
267
|
+
task = asyncio.current_task()
|
|
268
|
+
if task is not None:
|
|
269
|
+
self._successfully_saved_run_tasks.add(task)
|
|
270
|
+
|
|
271
|
+
def was_run_task_finally_saved(self, task: asyncio.Task[Any]) -> bool:
|
|
272
|
+
"""Return whether *task* completed a successful final session save."""
|
|
273
|
+
return task in self._successfully_saved_run_tasks
|
|
274
|
+
|
|
275
|
+
def request_pre_executor_interrupt(self, task: asyncio.Task[Any] | None) -> bool:
|
|
276
|
+
"""Bind a pre-executor interrupt to an exact captured run task."""
|
|
277
|
+
if task is None or task.done():
|
|
278
|
+
return False
|
|
279
|
+
self._pre_executor_interrupt_tasks.add(task)
|
|
280
|
+
return True
|
|
281
|
+
|
|
282
|
+
def consume_pre_executor_interrupt(self) -> bool:
|
|
283
|
+
"""Consume an interrupt only when it belongs to the calling run task."""
|
|
284
|
+
task = asyncio.current_task()
|
|
285
|
+
if task is None or task not in self._pre_executor_interrupt_tasks:
|
|
286
|
+
return False
|
|
287
|
+
self._pre_executor_interrupt_tasks.discard(task)
|
|
288
|
+
return True
|
|
289
|
+
|
|
290
|
+
def discard_pre_executor_interrupt(self, task: asyncio.Task[Any] | None) -> None:
|
|
291
|
+
"""Drop a task-scoped interrupt at that task's terminal boundary."""
|
|
292
|
+
if task is not None:
|
|
293
|
+
self._pre_executor_interrupt_tasks.discard(task)
|
|
294
|
+
|
|
295
|
+
def advance_conversation_revision(self) -> int:
|
|
296
|
+
"""Advance the monotonic revision for one fresh or retry lifecycle."""
|
|
297
|
+
self.conversation_revision += 1
|
|
298
|
+
return self.conversation_revision
|
|
299
|
+
|
|
300
|
+
def register_pre_admission_preparation(self, entry: PreAdmissionPreparationEntry) -> None:
|
|
301
|
+
"""Expose a started preparation until it reaches durable admission state."""
|
|
302
|
+
self.pre_admission_preparations[entry.preparation.operation_id] = entry
|
|
303
|
+
|
|
304
|
+
def deregister_pre_admission_preparation(self, entry: PreAdmissionPreparationEntry | None) -> None:
|
|
305
|
+
"""Remove *entry* when it is still the registered owner."""
|
|
306
|
+
if entry is None:
|
|
307
|
+
return
|
|
308
|
+
operation_id = entry.preparation.operation_id
|
|
309
|
+
if self.pre_admission_preparations.get(operation_id) is entry:
|
|
310
|
+
del self.pre_admission_preparations[operation_id]
|
|
311
|
+
|
|
312
|
+
def clear_pre_admission_preparations(self) -> None:
|
|
313
|
+
"""Settle preparations and straddling waits that have not reached admission."""
|
|
314
|
+
entries = tuple(self.pre_admission_preparations.values())
|
|
315
|
+
self.pre_admission_preparations.clear()
|
|
316
|
+
for entry in entries:
|
|
317
|
+
wait = entry.current_wait
|
|
318
|
+
if wait is not None:
|
|
319
|
+
wait.finished_soon(outcome=WaitOutcome.CANCELLED)
|
|
320
|
+
entry.current_wait = None
|
|
321
|
+
entry.preparation.finished_soon(outcome=PreparationOutcome.OWNER_CHANGED)
|
|
322
|
+
|
|
323
|
+
def reserve_prompt_admission(
|
|
324
|
+
self,
|
|
325
|
+
*,
|
|
326
|
+
kind: Literal["fresh", "retry"],
|
|
327
|
+
session_generation: int,
|
|
328
|
+
build_generation: int,
|
|
329
|
+
preparation_trace: PreparationTrace | None = None,
|
|
330
|
+
) -> PromptAdmissionScope | None:
|
|
331
|
+
"""Reserve an exact prompt/retry admission unless admission is closed."""
|
|
332
|
+
if self.prompt_admission_closed:
|
|
333
|
+
return None
|
|
334
|
+
admission_id = self.next_admission_id
|
|
335
|
+
self.next_admission_id += 1
|
|
336
|
+
self.active_admissions_idle.clear()
|
|
337
|
+
self.active_admissions[admission_id] = PromptAdmissionRecord(
|
|
338
|
+
admission_id=admission_id,
|
|
339
|
+
kind=kind,
|
|
340
|
+
session_generation=session_generation,
|
|
341
|
+
build_generation=build_generation,
|
|
342
|
+
preparation_trace=preparation_trace,
|
|
343
|
+
created_at_monotonic=time.monotonic(),
|
|
344
|
+
)
|
|
345
|
+
return PromptAdmissionScope(
|
|
346
|
+
admission_id=admission_id,
|
|
347
|
+
kind=kind,
|
|
348
|
+
session_generation=session_generation,
|
|
349
|
+
build_generation=build_generation,
|
|
350
|
+
preparation_trace=preparation_trace,
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
def active_admission_count(self) -> int:
|
|
354
|
+
"""Return the number of exact active admissions."""
|
|
355
|
+
return len(self.active_admissions)
|
|
356
|
+
|
|
357
|
+
def has_active_admission_kind(self, kind: Literal["fresh", "retry"]) -> bool:
|
|
358
|
+
"""Return whether an active admission of *kind* is currently preparing."""
|
|
359
|
+
return any(record.kind == kind for record in self.active_admissions.values())
|
|
360
|
+
|
|
361
|
+
def release_prompt_admission(self, admission: PromptAdmissionScope) -> bool:
|
|
362
|
+
"""Release an exact admission; duplicate releases are no-ops."""
|
|
363
|
+
record = self.active_admissions.get(admission.admission_id)
|
|
364
|
+
if record is None:
|
|
365
|
+
return False
|
|
366
|
+
if (
|
|
367
|
+
record.kind != admission.kind
|
|
368
|
+
or record.session_generation != admission.session_generation
|
|
369
|
+
or record.build_generation != admission.build_generation
|
|
370
|
+
):
|
|
371
|
+
return False
|
|
372
|
+
del self.active_admissions[admission.admission_id]
|
|
373
|
+
if not self.active_admissions:
|
|
374
|
+
self.active_admissions_idle.set()
|
|
375
|
+
return True
|
|
376
|
+
|
|
377
|
+
async def wait_for_active_admissions_idle(self) -> None:
|
|
378
|
+
"""Wait until no exact prompt/retry admission is active."""
|
|
379
|
+
while self.active_admissions:
|
|
380
|
+
await self.active_admissions_idle.wait()
|
|
381
|
+
|
|
382
|
+
def begin_current_run_scope(
|
|
383
|
+
self,
|
|
384
|
+
*,
|
|
385
|
+
owner_admission_id: int,
|
|
386
|
+
session_generation: int,
|
|
387
|
+
build_generation: int,
|
|
388
|
+
reminder_scope: CurrentRunReminderScope,
|
|
389
|
+
) -> CurrentRunScope:
|
|
390
|
+
"""Create and install a current-run scope."""
|
|
391
|
+
scope = CurrentRunScope(
|
|
392
|
+
run_generation=self.next_run_generation,
|
|
393
|
+
session_generation=session_generation,
|
|
394
|
+
build_generation=build_generation,
|
|
395
|
+
owner_admission_id=owner_admission_id,
|
|
396
|
+
reminder_scope=reminder_scope,
|
|
397
|
+
)
|
|
398
|
+
self.next_run_generation += 1
|
|
399
|
+
self.current_run_scope = scope
|
|
400
|
+
return scope
|
|
401
|
+
|
|
402
|
+
def open_injection_admission(self, scope: CurrentRunScope) -> CurrentRunInjectionWindow:
|
|
403
|
+
"""Open injection admission for the current executor pass."""
|
|
404
|
+
self.injection_window_generation += 1
|
|
405
|
+
self.injection_admission_open = self.current_run_scope == scope
|
|
406
|
+
return CurrentRunInjectionWindow(
|
|
407
|
+
run_generation=scope.run_generation,
|
|
408
|
+
window_generation=self.injection_window_generation,
|
|
409
|
+
)
|
|
410
|
+
|
|
411
|
+
def close_injection_admission(self, scope: CurrentRunScope) -> None:
|
|
412
|
+
"""Close injection admission for *scope* if it is current."""
|
|
413
|
+
if self.current_run_scope == scope:
|
|
414
|
+
self.injection_admission_open = False
|
|
415
|
+
|
|
416
|
+
def capture_current_injection_window(self, scope: CurrentRunScope) -> CurrentRunInjectionWindow | None:
|
|
417
|
+
"""Capture the currently open injection window for *scope*, if any."""
|
|
418
|
+
if self.current_run_scope != scope or not self.injection_admission_open:
|
|
419
|
+
return None
|
|
420
|
+
return CurrentRunInjectionWindow(
|
|
421
|
+
run_generation=scope.run_generation,
|
|
422
|
+
window_generation=self.injection_window_generation,
|
|
423
|
+
)
|
|
424
|
+
|
|
425
|
+
def is_injection_admission_current(self, window: CurrentRunInjectionWindow) -> bool:
|
|
426
|
+
"""Return whether *window* still admits active-turn injection."""
|
|
427
|
+
scope = self.current_run_scope
|
|
428
|
+
return (
|
|
429
|
+
self.injection_admission_open
|
|
430
|
+
and scope is not None
|
|
431
|
+
and scope.run_generation == window.run_generation
|
|
432
|
+
and self.injection_window_generation == window.window_generation
|
|
433
|
+
)
|
|
434
|
+
|
|
435
|
+
def begin_active_injection_commit(self, target: ActiveInjectionTarget) -> bool:
|
|
436
|
+
"""Begin a commit guard when the captured active-injection target is current."""
|
|
437
|
+
if target.current_run_scope != self.current_run_scope:
|
|
438
|
+
return False
|
|
439
|
+
if not self.is_injection_admission_current(target.injection_window):
|
|
440
|
+
return False
|
|
441
|
+
self.active_injection_commits += 1
|
|
442
|
+
self.active_injection_commits_idle.clear()
|
|
443
|
+
return True
|
|
444
|
+
|
|
445
|
+
def finish_active_injection_commit(self) -> None:
|
|
446
|
+
"""Release one active-injection commit guard."""
|
|
447
|
+
if self.active_injection_commits > 0:
|
|
448
|
+
self.active_injection_commits -= 1
|
|
449
|
+
if self.active_injection_commits == 0:
|
|
450
|
+
self.active_injection_commits_idle.set()
|
|
451
|
+
|
|
452
|
+
async def wait_for_active_injection_commits_idle(self) -> None:
|
|
453
|
+
"""Wait until active-injection commit guards have drained."""
|
|
454
|
+
while self.active_injection_commits > 0:
|
|
455
|
+
await self.active_injection_commits_idle.wait()
|
|
456
|
+
|
|
457
|
+
def promote_fresh_admission_to_run(
|
|
458
|
+
self,
|
|
459
|
+
admission: PromptAdmissionScope,
|
|
460
|
+
*,
|
|
461
|
+
reminder_scope: CurrentRunReminderScope,
|
|
462
|
+
make_task: Callable[[CurrentRunScope, CurrentRunInjectionWindow], asyncio.Task[None]],
|
|
463
|
+
) -> PromptPromotionResult:
|
|
464
|
+
"""Promote an exact fresh admission into a visible run task."""
|
|
465
|
+
if not self._admission_matches(admission, expected_kind="fresh"):
|
|
466
|
+
return PromptPromotionResult(promoted=False, stale=True)
|
|
467
|
+
if self.current_run_scope is not None or (self.run_task is not None and not self.run_task.done()):
|
|
468
|
+
return PromptPromotionResult(promoted=False, conflict=True)
|
|
469
|
+
scope = self.begin_current_run_scope(
|
|
470
|
+
owner_admission_id=admission.admission_id,
|
|
471
|
+
session_generation=admission.session_generation,
|
|
472
|
+
build_generation=admission.build_generation,
|
|
473
|
+
reminder_scope=reminder_scope,
|
|
474
|
+
)
|
|
475
|
+
window = self.open_injection_admission(scope)
|
|
476
|
+
self.run_task = make_task(scope, window)
|
|
477
|
+
self.release_prompt_admission(admission)
|
|
478
|
+
return PromptPromotionResult(promoted=True)
|
|
479
|
+
|
|
480
|
+
def promote_retry_admission(
|
|
481
|
+
self,
|
|
482
|
+
admission: PromptAdmissionScope,
|
|
483
|
+
*,
|
|
484
|
+
reminder_scope: CurrentRunReminderScope,
|
|
485
|
+
make_task: Callable[[CurrentRunScope, CurrentRunInjectionWindow], asyncio.Task[None]],
|
|
486
|
+
text: str,
|
|
487
|
+
created_at: datetime | str | None,
|
|
488
|
+
pending: bool = False,
|
|
489
|
+
) -> RetryPromotionResult:
|
|
490
|
+
"""Promote an exact retry admission into a task or pending retry."""
|
|
491
|
+
if not self._admission_matches(admission, expected_kind="retry"):
|
|
492
|
+
return RetryPromotionResult(outcome="stale")
|
|
493
|
+
if pending:
|
|
494
|
+
updated = self.upsert_pending_retry_from_admission(admission, text, created_at)
|
|
495
|
+
self.release_prompt_admission(admission)
|
|
496
|
+
return RetryPromotionResult(outcome="pending_updated" if updated else "pending_installed")
|
|
497
|
+
if self.run_task is not None and not self.run_task.done():
|
|
498
|
+
return RetryPromotionResult(outcome="invalid")
|
|
499
|
+
scope = self._retry_scope_for_admission(admission, reminder_scope=reminder_scope)
|
|
500
|
+
window = self.open_injection_admission(scope)
|
|
501
|
+
task = make_task(scope, window)
|
|
502
|
+
self.run_task = task
|
|
503
|
+
self.release_prompt_admission(admission)
|
|
504
|
+
return RetryPromotionResult(outcome="task", task=task)
|
|
505
|
+
|
|
506
|
+
def close_prompt_admission_for_rebuild(self, owner: str = "rebuild") -> None:
|
|
507
|
+
"""Close fresh prompt/retry admission for a future rebuild fence."""
|
|
508
|
+
self.prompt_admission_closed = True
|
|
509
|
+
self.prompt_admission_close_owner = owner
|
|
510
|
+
self.prompt_admission_open.clear()
|
|
511
|
+
|
|
512
|
+
def reopen_prompt_admission_after_rebuild(self, owner: str = "rebuild") -> None:
|
|
513
|
+
"""Reopen prompt/retry admission if *owner* owns the close."""
|
|
514
|
+
if self.prompt_admission_close_owner in (None, owner):
|
|
515
|
+
self.prompt_admission_closed = False
|
|
516
|
+
self.prompt_admission_close_owner = None
|
|
517
|
+
self.prompt_admission_open.set()
|
|
518
|
+
|
|
519
|
+
async def wait_for_prompt_admission_open(self) -> None:
|
|
520
|
+
"""Wait until fresh prompt/retry admission is open."""
|
|
521
|
+
while self.prompt_admission_closed:
|
|
522
|
+
await self.prompt_admission_open.wait()
|
|
523
|
+
|
|
524
|
+
def clear_current_run_scope(self, scope: CurrentRunScope) -> None:
|
|
525
|
+
"""Clear the current-run scope if *scope* is still installed."""
|
|
526
|
+
if self.current_run_scope == scope:
|
|
527
|
+
self.current_run_scope = None
|
|
528
|
+
self.injection_admission_open = False
|
|
529
|
+
|
|
530
|
+
def clear_pending_retry(self, *, outcome: Literal["dropped", "retry_turn"]) -> PendingRetry:
|
|
531
|
+
"""Clear pending retry state and terminalize its preparation scope."""
|
|
532
|
+
pending = self.pending_retry
|
|
533
|
+
if pending.preparation_trace is not None:
|
|
534
|
+
pending.preparation_trace.finished_soon(outcome=outcome)
|
|
535
|
+
self.pending_retry = PendingRetry()
|
|
536
|
+
return pending
|
|
537
|
+
|
|
538
|
+
def clear_active_admissions(self, *, outcome: str) -> None:
|
|
539
|
+
"""Clear active admissions and terminalize their preparation scopes."""
|
|
540
|
+
for admission in self.active_admissions.values():
|
|
541
|
+
if admission.preparation_trace is not None:
|
|
542
|
+
admission.preparation_trace.finished_soon(outcome=outcome)
|
|
543
|
+
self.active_admissions.clear()
|
|
544
|
+
self.active_admissions_idle.set()
|
|
545
|
+
|
|
546
|
+
def upsert_pending_retry_from_admission(
|
|
547
|
+
self,
|
|
548
|
+
admission: PromptAdmissionScope,
|
|
549
|
+
text: str,
|
|
550
|
+
created_at: datetime | str | None,
|
|
551
|
+
) -> bool:
|
|
552
|
+
"""Install or update pending retry for the current run from *admission*."""
|
|
553
|
+
run_generation = self.current_run_scope.run_generation if self.current_run_scope is not None else 0
|
|
554
|
+
existing_same_run = (
|
|
555
|
+
self.pending_retry.owner_admission_id is not None
|
|
556
|
+
and self.pending_retry.session_generation == admission.session_generation
|
|
557
|
+
and self.pending_retry.run_generation == run_generation
|
|
558
|
+
)
|
|
559
|
+
if (
|
|
560
|
+
existing_same_run
|
|
561
|
+
and self.pending_retry.updated_by_admission_id is not None
|
|
562
|
+
and admission.admission_id < self.pending_retry.updated_by_admission_id
|
|
563
|
+
):
|
|
564
|
+
if admission.preparation_trace is not None:
|
|
565
|
+
admission.preparation_trace.finished_soon(outcome=PreparationOutcome.SUPERSEDED)
|
|
566
|
+
return True
|
|
567
|
+
if existing_same_run and self.pending_retry.preparation_trace is not None:
|
|
568
|
+
self.pending_retry.preparation_trace.finished_soon(outcome=PreparationOutcome.SUPERSEDED)
|
|
569
|
+
if admission.preparation_trace is not None:
|
|
570
|
+
admission.preparation_trace.state_soon("requeued" if existing_same_run else "queued")
|
|
571
|
+
self.pending_retry = PendingRetry(
|
|
572
|
+
text=text,
|
|
573
|
+
created_at=created_at,
|
|
574
|
+
session_generation=admission.session_generation,
|
|
575
|
+
run_generation=run_generation,
|
|
576
|
+
updated_by_admission_id=admission.admission_id,
|
|
577
|
+
owner_admission_id=self.pending_retry.owner_admission_id if existing_same_run else admission.admission_id,
|
|
578
|
+
dispatch_disabled=False,
|
|
579
|
+
preparation_trace=admission.preparation_trace,
|
|
580
|
+
)
|
|
581
|
+
return existing_same_run
|
|
582
|
+
|
|
583
|
+
def disable_pending_retry_dispatch_for_session_transition(self, session_generation: int) -> None:
|
|
584
|
+
"""Disable pending retry dispatch for an abandoned session generation."""
|
|
585
|
+
self.pending_retry_dispatch_disabled_for_session_generation = session_generation
|
|
586
|
+
if self.pending_retry.session_generation == session_generation:
|
|
587
|
+
self.pending_retry.dispatch_disabled = True
|
|
588
|
+
|
|
589
|
+
def invalidate_for_session_transition_pre_shutdown(
|
|
590
|
+
self,
|
|
591
|
+
*,
|
|
592
|
+
old_session_generation: int,
|
|
593
|
+
prompt_admission_owner: str | None = None,
|
|
594
|
+
) -> None:
|
|
595
|
+
"""Invalidate old-session admission/injection/pending-retry state before shutdown."""
|
|
596
|
+
if prompt_admission_owner is not None:
|
|
597
|
+
self.close_prompt_admission_for_rebuild(prompt_admission_owner)
|
|
598
|
+
self.clear_active_admissions(outcome=PreparationOutcome.OWNER_CHANGED)
|
|
599
|
+
self.clear_pre_admission_preparations()
|
|
600
|
+
self.injection_admission_open = False
|
|
601
|
+
self.disable_pending_retry_dispatch_for_session_transition(old_session_generation)
|
|
602
|
+
|
|
603
|
+
def reset_after_session_shutdown(
|
|
604
|
+
self,
|
|
605
|
+
*,
|
|
606
|
+
prompt_admission_owner: str | None = None,
|
|
607
|
+
) -> CurrentRunScope | None:
|
|
608
|
+
"""Clear turn-owned state after shutdown has observed the old task."""
|
|
609
|
+
old_scope = self.current_run_scope
|
|
610
|
+
self.run_task = None
|
|
611
|
+
self.current_run_scope = None
|
|
612
|
+
self.injection_admission_open = False
|
|
613
|
+
# ``AgentEngine.shutdown()`` terminalizes pending-retry and admission
|
|
614
|
+
# preparations before it closes the trajectory recorder. This reset
|
|
615
|
+
# runs after shutdown and must never try to emit against the closed writer.
|
|
616
|
+
self.pending_retry = PendingRetry()
|
|
617
|
+
self._pre_executor_interrupt_tasks.clear()
|
|
618
|
+
self.active_admissions.clear()
|
|
619
|
+
self.pre_admission_preparations.clear()
|
|
620
|
+
self.active_admissions_idle.set()
|
|
621
|
+
self.active_injection_commits = 0
|
|
622
|
+
self.active_injection_commits_idle.set()
|
|
623
|
+
if prompt_admission_owner is None:
|
|
624
|
+
self.prompt_admission_closed = False
|
|
625
|
+
self.prompt_admission_close_owner = None
|
|
626
|
+
self.prompt_admission_open.set()
|
|
627
|
+
else:
|
|
628
|
+
self.prompt_admission_closed = True
|
|
629
|
+
self.prompt_admission_close_owner = prompt_admission_owner
|
|
630
|
+
self.prompt_admission_open.clear()
|
|
631
|
+
return old_scope
|
|
632
|
+
|
|
633
|
+
def _admission_matches(
|
|
634
|
+
self,
|
|
635
|
+
admission: PromptAdmissionScope,
|
|
636
|
+
*,
|
|
637
|
+
expected_kind: Literal["fresh", "retry"],
|
|
638
|
+
) -> bool:
|
|
639
|
+
record = self.active_admissions.get(admission.admission_id)
|
|
640
|
+
return (
|
|
641
|
+
record is not None
|
|
642
|
+
and admission.kind == expected_kind
|
|
643
|
+
and record.kind == expected_kind
|
|
644
|
+
and record.session_generation == admission.session_generation
|
|
645
|
+
and record.build_generation == admission.build_generation
|
|
646
|
+
)
|
|
647
|
+
|
|
648
|
+
def _retry_scope_for_admission(
|
|
649
|
+
self,
|
|
650
|
+
admission: PromptAdmissionScope,
|
|
651
|
+
*,
|
|
652
|
+
reminder_scope: CurrentRunReminderScope,
|
|
653
|
+
) -> CurrentRunScope:
|
|
654
|
+
"""Return the retry scope for *admission*, rebinding an existing logical retry scope."""
|
|
655
|
+
current = self.current_run_scope
|
|
656
|
+
if (
|
|
657
|
+
current is not None
|
|
658
|
+
and current.session_generation == admission.session_generation
|
|
659
|
+
and current.build_generation == admission.build_generation
|
|
660
|
+
):
|
|
661
|
+
scope = CurrentRunScope(
|
|
662
|
+
run_generation=current.run_generation,
|
|
663
|
+
session_generation=current.session_generation,
|
|
664
|
+
build_generation=current.build_generation,
|
|
665
|
+
owner_admission_id=admission.admission_id,
|
|
666
|
+
reminder_scope=current.reminder_scope,
|
|
667
|
+
)
|
|
668
|
+
self.current_run_scope = scope
|
|
669
|
+
return scope
|
|
670
|
+
return self.begin_current_run_scope(
|
|
671
|
+
owner_admission_id=admission.admission_id,
|
|
672
|
+
session_generation=admission.session_generation,
|
|
673
|
+
build_generation=admission.build_generation,
|
|
674
|
+
reminder_scope=reminder_scope,
|
|
675
|
+
)
|
|
676
|
+
|
|
677
|
+
async def observe_run_task_chain(self, *, propagate_inner_cancel: bool) -> RunTaskDrainOutcome:
|
|
678
|
+
"""Observe each installed run task, including tasks installed during finalization."""
|
|
679
|
+
outcome = RunTaskDrainOutcome()
|
|
680
|
+
observed: set[asyncio.Task[None]] = set()
|
|
681
|
+
while True:
|
|
682
|
+
task = self.run_task
|
|
683
|
+
if task is None or task in observed:
|
|
684
|
+
return outcome
|
|
685
|
+
try:
|
|
686
|
+
await asyncio.shield(task)
|
|
687
|
+
except asyncio.CancelledError:
|
|
688
|
+
waiter = asyncio.current_task()
|
|
689
|
+
caller_cancelled = waiter is not None and waiter.cancelling() > 0
|
|
690
|
+
if task.cancelled() and not caller_cancelled:
|
|
691
|
+
outcome = RunTaskDrainOutcome(cancelled=True)
|
|
692
|
+
observed.add(task)
|
|
693
|
+
if propagate_inner_cancel:
|
|
694
|
+
raise
|
|
695
|
+
else:
|
|
696
|
+
raise
|
|
697
|
+
else:
|
|
698
|
+
observed.add(task)
|
|
699
|
+
|
|
700
|
+
def execution_busy(self) -> bool:
|
|
701
|
+
"""Lifecycle-busy predicate: a live turn task (prepare through save) or a held workflow run."""
|
|
702
|
+
return self.turn_busy() or self.workflow is not None
|
|
703
|
+
|
|
704
|
+
def turn_busy(self) -> bool:
|
|
705
|
+
"""The turn half of :meth:`execution_busy`: the top-level task includes prepare and save."""
|
|
706
|
+
return self.run_task is not None and not self.run_task.done()
|
|
707
|
+
|
|
708
|
+
def release_run_task(self) -> None:
|
|
709
|
+
"""Clear the installed task after the caller has drained the task chain."""
|
|
710
|
+
self.run_task = None
|
|
711
|
+
|
|
712
|
+
def execution(self) -> ExecutionSnapshot:
|
|
713
|
+
"""The frontend view of the lease; a workflow run is always cancellable, a turn while its task lives."""
|
|
714
|
+
if self.workflow is not None:
|
|
715
|
+
return ExecutionSnapshot(
|
|
716
|
+
"workflow", run_id=self.workflow.run_id, cancellable=True, request_id=self.workflow.request_id
|
|
717
|
+
)
|
|
718
|
+
if self.turn_busy():
|
|
719
|
+
return ExecutionSnapshot("turn", cancellable=True)
|
|
720
|
+
return ExecutionSnapshot("idle")
|
|
721
|
+
|
|
722
|
+
def workflow_start_allowed(self) -> bool:
|
|
723
|
+
"""Whether the lease is free for workflow admission."""
|
|
724
|
+
return self.workflow_start_refusal() is None
|
|
725
|
+
|
|
726
|
+
def workflow_start_refusal(self) -> Literal["workflow_active", "turn_active", "engine_busy"] | None:
|
|
727
|
+
"""The first execution boundary that prevents workflow admission."""
|
|
728
|
+
if self.workflow is not None:
|
|
729
|
+
return "workflow_active"
|
|
730
|
+
if self.turn_busy() or self.active_admission_count() > 0 or self.pre_admission_preparations:
|
|
731
|
+
return "turn_active"
|
|
732
|
+
if self.prompt_admission_closed or self.session_operations:
|
|
733
|
+
return "engine_busy"
|
|
734
|
+
return None
|
|
735
|
+
|
|
736
|
+
async def refuse_while_workflow_active(self, bus: EventBus, session_id: str | None) -> bool:
|
|
737
|
+
"""Answer a turn/retry request while a workflow owns the lease."""
|
|
738
|
+
if self.workflow is None:
|
|
739
|
+
return False
|
|
740
|
+
await bus.publish(
|
|
741
|
+
Error(
|
|
742
|
+
code="workflow_active",
|
|
743
|
+
message="A workflow run is active. Cancel the workflow run first.",
|
|
744
|
+
session_id=session_id,
|
|
745
|
+
)
|
|
746
|
+
)
|
|
747
|
+
return True
|
|
748
|
+
|
|
749
|
+
@contextlib.contextmanager
|
|
750
|
+
def session_operation(self) -> Iterator[None]:
|
|
751
|
+
"""Hold the lease against workflow admission for one session-family operation, its awaits included."""
|
|
752
|
+
self.session_operations += 1
|
|
753
|
+
try:
|
|
754
|
+
yield
|
|
755
|
+
finally:
|
|
756
|
+
self.session_operations -= 1
|
|
757
|
+
|
|
758
|
+
def begin_workflow(self, run_id: str, request_id: str) -> WorkflowExecution:
|
|
759
|
+
"""Reserve the lease for one workflow run; the caller checked :meth:`workflow_start_allowed` first."""
|
|
760
|
+
if not self.workflow_start_allowed():
|
|
761
|
+
raise RuntimeError("The execution lease is not free for a workflow run")
|
|
762
|
+
execution = WorkflowExecution(run_id=run_id, request_id=request_id)
|
|
763
|
+
self.workflow = execution
|
|
764
|
+
self._notify_execution()
|
|
765
|
+
return execution
|
|
766
|
+
|
|
767
|
+
def end_workflow(self, execution: WorkflowExecution) -> None:
|
|
768
|
+
"""Release the lease held by *execution*; a stale release (another run installed since) is ignored."""
|
|
769
|
+
if self.workflow is execution:
|
|
770
|
+
self.workflow = None
|
|
771
|
+
self._notify_execution()
|