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,753 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Live tool group and sub-agent routing for chat transcripts.
|
|
4
|
+
|
|
5
|
+
Concurrency contract: in the live pipeline a tool's InvocationToolCallStart and
|
|
6
|
+
InvocationToolCallResult are published from the tool's own invocation task
|
|
7
|
+
(``service.agent_middleware.events.tool_events``), and ``EventBus.publish``
|
|
8
|
+
awaits the subscribed TUI handler chain inline — so a start's publish does
|
|
9
|
+
not return until the card exists and its ownership is registered, and the
|
|
10
|
+
tool only executes after that. A result therefore cannot overtake its own
|
|
11
|
+
start today, even for provider-reused call_ids across turns. The
|
|
12
|
+
interleaving hardening in this module (group-open lock, call-id
|
|
13
|
+
pre-registration before the mount await, generation gates) guards what CAN
|
|
14
|
+
interleave now — parallel tool invocation tasks with distinct call_ids —
|
|
15
|
+
plus anything that would de-serialize same-id delivery in the future:
|
|
16
|
+
stream()-based TUI consumption, out-of-band synthetic results, or a
|
|
17
|
+
fire-and-forget ``publish``. See the residual-window note on
|
|
18
|
+
``_open_tool_group`` before relying on that serialization elsewhere.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import asyncio
|
|
24
|
+
from collections.abc import Callable
|
|
25
|
+
from typing import TYPE_CHECKING, Any
|
|
26
|
+
|
|
27
|
+
from textual.widget import Widget
|
|
28
|
+
|
|
29
|
+
from chrys.app.tui.widgets.chat.file_snapshot import FileSnapshotPayload
|
|
30
|
+
from chrys.app.tui.widgets.chat.ports import ChatMountPort, StatusCleanupPort, TranscriptUiPort
|
|
31
|
+
from chrys.app.tui.widgets.chat.renderers.ask_user import AskUserToolCall
|
|
32
|
+
from chrys.app.tui.widgets.chat.renderers.sub_agent import SubAgentToolCall
|
|
33
|
+
from chrys.app.tui.widgets.chat.tool_call import ToolGroup
|
|
34
|
+
from chrys.foundation.events.types import ProvisionalPresentation
|
|
35
|
+
|
|
36
|
+
if TYPE_CHECKING:
|
|
37
|
+
from chrys.app.tui.widgets import PromptDraft
|
|
38
|
+
from chrys.foundation.models.ask_user import AskUserQuestion
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _expanded_by_default() -> bool:
|
|
42
|
+
return True
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class ToolGroupRegistry:
|
|
46
|
+
"""Own live tool groups, call-id routing, sub-agent links, and tool kinds."""
|
|
47
|
+
|
|
48
|
+
def __init__(
|
|
49
|
+
self,
|
|
50
|
+
mount: ChatMountPort,
|
|
51
|
+
ui: TranscriptUiPort,
|
|
52
|
+
status: StatusCleanupPort,
|
|
53
|
+
finalize_agent_message: Callable[[], None] | None = None,
|
|
54
|
+
tool_groups_expanded: Callable[[], bool] | None = None,
|
|
55
|
+
tool_widget_configurator: Callable[[Widget], None] | None = None,
|
|
56
|
+
) -> None:
|
|
57
|
+
self._mount = mount
|
|
58
|
+
self._ui = ui
|
|
59
|
+
self._status = status
|
|
60
|
+
self._finalize_agent_message = finalize_agent_message
|
|
61
|
+
self._tool_groups_expanded = tool_groups_expanded or _expanded_by_default
|
|
62
|
+
self._tool_widget_configurator = tool_widget_configurator
|
|
63
|
+
self._current_tool_group: ToolGroup | None = None
|
|
64
|
+
self._sub_agent_widgets: dict[str, SubAgentToolCall] = {}
|
|
65
|
+
self._retired_sub_agent_widgets: dict[str, SubAgentToolCall] = {}
|
|
66
|
+
self._sub_agent_owning_groups: dict[SubAgentToolCall, ToolGroup] = {}
|
|
67
|
+
self._unlinked_sub_agents: dict[str, list[SubAgentToolCall]] = {}
|
|
68
|
+
self._tool_groups_by_call_id: dict[str, ToolGroup] = {}
|
|
69
|
+
self._tool_kinds: dict[str, str] = {}
|
|
70
|
+
self._group_generation = 0
|
|
71
|
+
self._group_open_lock = asyncio.Lock()
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def current_tool_group(self) -> ToolGroup | None:
|
|
75
|
+
"""Current live tool group, if one is open."""
|
|
76
|
+
return self._current_tool_group
|
|
77
|
+
|
|
78
|
+
@current_tool_group.setter
|
|
79
|
+
def current_tool_group(self, group: ToolGroup | None) -> None:
|
|
80
|
+
self._current_tool_group = group
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def tool_groups_by_call_id(self) -> dict[str, ToolGroup]:
|
|
84
|
+
"""Live call-id to tool-group map."""
|
|
85
|
+
return self._tool_groups_by_call_id
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
def sub_agent_widgets(self) -> dict[str, SubAgentToolCall]:
|
|
89
|
+
"""Live invocation-id to sub-agent widget map."""
|
|
90
|
+
return self._sub_agent_widgets
|
|
91
|
+
|
|
92
|
+
@property
|
|
93
|
+
def unlinked_sub_agents(self) -> dict[str, list[SubAgentToolCall]]:
|
|
94
|
+
"""FIFO fallback queues for not-yet-linked sub-agent widgets."""
|
|
95
|
+
return self._unlinked_sub_agents
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def tool_kinds(self) -> dict[str, str]:
|
|
99
|
+
"""Runtime tool-name to kind catalog used by replay rendering."""
|
|
100
|
+
return self._tool_kinds
|
|
101
|
+
|
|
102
|
+
@tool_kinds.setter
|
|
103
|
+
def tool_kinds(self, tool_kinds: dict[str, str]) -> None:
|
|
104
|
+
self._tool_kinds = tool_kinds
|
|
105
|
+
|
|
106
|
+
def set_tool_kinds(self, tool_kinds: dict[str, str]) -> None:
|
|
107
|
+
"""Set the runtime tool-name to kind catalog."""
|
|
108
|
+
self._tool_kinds = tool_kinds
|
|
109
|
+
|
|
110
|
+
def _sub_agent_owning_group(self, widget: SubAgentToolCall) -> ToolGroup | None:
|
|
111
|
+
"""Resolve stable ownership, accepting only identity-verified fallback."""
|
|
112
|
+
group = self._sub_agent_owning_groups.get(widget)
|
|
113
|
+
if group is not None:
|
|
114
|
+
return group
|
|
115
|
+
candidate = self._tool_groups_by_call_id.get(widget.call_id)
|
|
116
|
+
if candidate is not None and candidate.get_tool(widget.call_id) is widget:
|
|
117
|
+
self._sub_agent_owning_groups[widget] = candidate
|
|
118
|
+
return candidate
|
|
119
|
+
return None
|
|
120
|
+
|
|
121
|
+
def _set_sub_agent_action_required(self, widget: SubAgentToolCall, *, required: bool) -> None:
|
|
122
|
+
"""Expose paused controls until the invocation resumes or terminates."""
|
|
123
|
+
group = self._sub_agent_owning_group(widget)
|
|
124
|
+
if group is None:
|
|
125
|
+
return
|
|
126
|
+
if required:
|
|
127
|
+
group.lock_collapse_for(widget.call_id)
|
|
128
|
+
self._ui.schedule_anchor_sync()
|
|
129
|
+
else:
|
|
130
|
+
group.unlock_collapse_for(widget.call_id)
|
|
131
|
+
|
|
132
|
+
def resolve_tool_kind(self, tool_name: str) -> str:
|
|
133
|
+
"""Resolve a tool kind by name for replay rendering."""
|
|
134
|
+
return self._tool_kinds.get(tool_name, "")
|
|
135
|
+
|
|
136
|
+
def reset_for_clear(self) -> None:
|
|
137
|
+
"""Clear live per-transcript routing state while preserving tool kinds."""
|
|
138
|
+
self._group_generation += 1
|
|
139
|
+
self._current_tool_group = None
|
|
140
|
+
self._sub_agent_widgets.clear()
|
|
141
|
+
self._retired_sub_agent_widgets.clear()
|
|
142
|
+
self._sub_agent_owning_groups.clear()
|
|
143
|
+
self._unlinked_sub_agents.clear()
|
|
144
|
+
self._tool_groups_by_call_id.clear()
|
|
145
|
+
|
|
146
|
+
def end_group(self) -> None:
|
|
147
|
+
"""Close the current tool group so the next tool starts a new group."""
|
|
148
|
+
if self._current_tool_group is not None:
|
|
149
|
+
self._current_tool_group.finalize_activity_header()
|
|
150
|
+
self._group_generation += 1
|
|
151
|
+
self._current_tool_group = None
|
|
152
|
+
# Committed-compaction signals are delivered on detached tasks and can
|
|
153
|
+
# arrive after an interrupt closes the group; the cards stay in the
|
|
154
|
+
# transcript, so retire their routing entries instead of dropping
|
|
155
|
+
# them (cleared with the transcript in reset_for_clear).
|
|
156
|
+
# Invocations whose parent tool call is still running stay live:
|
|
157
|
+
# closing the group (intermediate prose between tool batches) must
|
|
158
|
+
# not orphan an in-flight sub-agent card — its progress and inner
|
|
159
|
+
# tool events still route by invocation_id. The interrupt path marks
|
|
160
|
+
# records cancelled before calling here (cancel_running_and_end_group),
|
|
161
|
+
# so cancelled invocations retire as before.
|
|
162
|
+
for invocation_id, widget in list(self._sub_agent_widgets.items()):
|
|
163
|
+
group = self._sub_agent_owning_group(widget)
|
|
164
|
+
if group is not None and group.is_tool_running(widget.call_id):
|
|
165
|
+
continue
|
|
166
|
+
self._retired_sub_agent_widgets[invocation_id] = widget
|
|
167
|
+
del self._sub_agent_widgets[invocation_id]
|
|
168
|
+
self._sub_agent_owning_groups.pop(widget, None)
|
|
169
|
+
for queue in self._unlinked_sub_agents.values():
|
|
170
|
+
for widget in queue:
|
|
171
|
+
self._sub_agent_owning_groups.pop(widget, None)
|
|
172
|
+
self._unlinked_sub_agents.clear()
|
|
173
|
+
|
|
174
|
+
def cancel_running_and_end_group(self) -> None:
|
|
175
|
+
"""Cancel in-progress tools in every open group and close them.
|
|
176
|
+
|
|
177
|
+
Besides the current group, older groups can still hold running
|
|
178
|
+
records: ``end_group`` retains sub-agent invocations whose parent
|
|
179
|
+
call is in flight, so after a mid-batch group split those parents
|
|
180
|
+
live in an already-closed group. Stable discovery starts with the
|
|
181
|
+
widget-identity ownership map. The call-id map is a secondary scan
|
|
182
|
+
for tools that have not linked an invocation yet; skipping either
|
|
183
|
+
source could leave a record visually running forever.
|
|
184
|
+
"""
|
|
185
|
+
groups: list[ToolGroup] = []
|
|
186
|
+
seen: set[int] = set()
|
|
187
|
+
if self._current_tool_group is not None:
|
|
188
|
+
groups.append(self._current_tool_group)
|
|
189
|
+
seen.add(id(self._current_tool_group))
|
|
190
|
+
for group in self._sub_agent_owning_groups.values():
|
|
191
|
+
if id(group) not in seen:
|
|
192
|
+
groups.append(group)
|
|
193
|
+
seen.add(id(group))
|
|
194
|
+
for call_id, group in self._tool_groups_by_call_id.items():
|
|
195
|
+
if id(group) not in seen and group.is_tool_running(call_id):
|
|
196
|
+
groups.append(group)
|
|
197
|
+
seen.add(id(group))
|
|
198
|
+
for group in groups:
|
|
199
|
+
group.cancel_running()
|
|
200
|
+
group.collapsed = True
|
|
201
|
+
# Always advance the lifecycle, even when a InvocationToolCallStart is still
|
|
202
|
+
# awaiting status cleanup and has not installed its group yet.
|
|
203
|
+
self.end_group()
|
|
204
|
+
|
|
205
|
+
async def add_tool_start(
|
|
206
|
+
self,
|
|
207
|
+
call_id: str,
|
|
208
|
+
tool_name: str,
|
|
209
|
+
tool_kind: str,
|
|
210
|
+
args_summary: str = "",
|
|
211
|
+
*,
|
|
212
|
+
args: dict[str, Any] | None = None,
|
|
213
|
+
provider_hosted: bool = False,
|
|
214
|
+
hosted_family: str = "",
|
|
215
|
+
provider: str = "",
|
|
216
|
+
provider_item_type: str = "",
|
|
217
|
+
provider_status: str = "",
|
|
218
|
+
provider_call_id: str = "",
|
|
219
|
+
canonical_status: str = "running",
|
|
220
|
+
) -> None:
|
|
221
|
+
"""Add a running tool call, creating a group if needed."""
|
|
222
|
+
group_generation = self._group_generation
|
|
223
|
+
group = self._current_tool_group
|
|
224
|
+
if group is None:
|
|
225
|
+
group = await self._open_tool_group(group_generation)
|
|
226
|
+
if group is None:
|
|
227
|
+
return
|
|
228
|
+
|
|
229
|
+
# Publish ownership BEFORE the mount await. ``add_tool`` creates the
|
|
230
|
+
# logical tool record synchronously, so a fast result racing the
|
|
231
|
+
# widget mount already routes here and is absorbed into the record
|
|
232
|
+
# (the widget picks it up after mounting) — routing through a stale
|
|
233
|
+
# owner of a provider-reused call_id would complete the old card and
|
|
234
|
+
# strand this one as running forever. The continuation below never
|
|
235
|
+
# writes the map again: whatever invalidated this entry during the
|
|
236
|
+
# await (reset_for_clear emptying the map, a newer reused-id start
|
|
237
|
+
# pre-registering itself) is newer and must win. Only the sub-agent
|
|
238
|
+
# fallback queue is generation-gated — end_group/clear emptied it,
|
|
239
|
+
# and a later invocation must not claim this stale card.
|
|
240
|
+
self._tool_groups_by_call_id[call_id] = group
|
|
241
|
+
if provider_hosted:
|
|
242
|
+
await group.add_tool(
|
|
243
|
+
call_id,
|
|
244
|
+
tool_name,
|
|
245
|
+
tool_kind,
|
|
246
|
+
args_summary,
|
|
247
|
+
args=args,
|
|
248
|
+
provider_hosted=True,
|
|
249
|
+
hosted_family=hosted_family,
|
|
250
|
+
provider=provider,
|
|
251
|
+
provider_item_type=provider_item_type,
|
|
252
|
+
provider_status=provider_status,
|
|
253
|
+
provider_call_id=provider_call_id,
|
|
254
|
+
canonical_status=canonical_status,
|
|
255
|
+
)
|
|
256
|
+
else:
|
|
257
|
+
await group.add_tool(call_id, tool_name, tool_kind, args_summary, args=args)
|
|
258
|
+
widget = group.get_tool(call_id)
|
|
259
|
+
if self._group_generation == group_generation and isinstance(widget, SubAgentToolCall):
|
|
260
|
+
self._sub_agent_owning_groups[widget] = group
|
|
261
|
+
self._unlinked_sub_agents.setdefault(tool_name, []).append(widget)
|
|
262
|
+
self._ui.schedule_anchor_sync()
|
|
263
|
+
|
|
264
|
+
async def _open_tool_group(self, group_generation: int) -> ToolGroup | None:
|
|
265
|
+
"""Resolve or create the current tool group, returned fully mounted.
|
|
266
|
+
|
|
267
|
+
Group creation is serialized, and ``_current_tool_group`` is
|
|
268
|
+
published only after the mount await completes: ``add_tool`` queries
|
|
269
|
+
the group's composed content container, so a concurrent
|
|
270
|
+
InvocationToolCallStart that observed a published-but-unmounted group would
|
|
271
|
+
crash on it (NoMatches). Lock waiters re-read the published group
|
|
272
|
+
and reuse it instead of mounting a duplicate. Returns None when the
|
|
273
|
+
group lifecycle advanced (interrupt/clear) while this call awaited.
|
|
274
|
+
|
|
275
|
+
Residual window: a result for a provider-reused call_id landing
|
|
276
|
+
while this method awaits would still route to the stale owner — no
|
|
277
|
+
record exists anywhere for the new occurrence yet, so the
|
|
278
|
+
pre-registration in ``add_tool_start`` (which runs only after this
|
|
279
|
+
returns) cannot cover it. Unreachable while the pipeline serializes
|
|
280
|
+
same-id start/result (see module docstring); if that serialization
|
|
281
|
+
is ever removed, close this with a pending-result stash keyed by
|
|
282
|
+
call_id and consumed by ``add_tool``.
|
|
283
|
+
"""
|
|
284
|
+
async with self._group_open_lock:
|
|
285
|
+
if self._group_generation != group_generation:
|
|
286
|
+
return None
|
|
287
|
+
group = self._current_tool_group
|
|
288
|
+
if group is not None:
|
|
289
|
+
return group
|
|
290
|
+
await self._status.remove_trailing_status()
|
|
291
|
+
if self._group_generation != group_generation:
|
|
292
|
+
return None
|
|
293
|
+
if self._finalize_agent_message is not None:
|
|
294
|
+
self._finalize_agent_message()
|
|
295
|
+
if self._tool_widget_configurator is None:
|
|
296
|
+
group = ToolGroup()
|
|
297
|
+
else:
|
|
298
|
+
group = ToolGroup(tool_widget_configurator=self._tool_widget_configurator)
|
|
299
|
+
group.collapsed = not self._tool_groups_expanded()
|
|
300
|
+
mounted = await self._mount.mount_transcript_widget(group)
|
|
301
|
+
if not mounted or self._group_generation != group_generation:
|
|
302
|
+
await self._mount.remove_transcript_widget(group)
|
|
303
|
+
return None
|
|
304
|
+
self._current_tool_group = group
|
|
305
|
+
return group
|
|
306
|
+
|
|
307
|
+
async def add_tool_result(
|
|
308
|
+
self,
|
|
309
|
+
call_id: str,
|
|
310
|
+
tool_name: str,
|
|
311
|
+
result: str,
|
|
312
|
+
duration_ms: int = 0,
|
|
313
|
+
*,
|
|
314
|
+
image_contents: list[Any] | None = None,
|
|
315
|
+
file_snapshot: FileSnapshotPayload | None = None,
|
|
316
|
+
approval: str | None = None,
|
|
317
|
+
metadata: dict[str, Any] | None = None,
|
|
318
|
+
artifacts: list[dict[str, Any]] | None = None,
|
|
319
|
+
provider_status: str = "",
|
|
320
|
+
canonical_status: str = "completed",
|
|
321
|
+
) -> None:
|
|
322
|
+
"""Update a live tool call as complete."""
|
|
323
|
+
# The owning group wins: a call whose group closed (end_group) while a
|
|
324
|
+
# newer group is already open must not send its result to the newer
|
|
325
|
+
# group, where it would be silently dropped. The current group is only
|
|
326
|
+
# a fallback for results racing in before add_tool_start registered.
|
|
327
|
+
group = self._tool_groups_by_call_id.get(call_id) or self._current_tool_group
|
|
328
|
+
if group is not None:
|
|
329
|
+
group.complete_tool(
|
|
330
|
+
call_id,
|
|
331
|
+
result,
|
|
332
|
+
duration_ms,
|
|
333
|
+
image_contents=image_contents,
|
|
334
|
+
file_snapshot=file_snapshot,
|
|
335
|
+
approval=approval,
|
|
336
|
+
metadata=metadata,
|
|
337
|
+
artifacts=artifacts,
|
|
338
|
+
provider_status=provider_status,
|
|
339
|
+
canonical_status=canonical_status,
|
|
340
|
+
)
|
|
341
|
+
self._ui.schedule_anchor_sync()
|
|
342
|
+
|
|
343
|
+
def update_tool_progress(
|
|
344
|
+
self,
|
|
345
|
+
call_id: str,
|
|
346
|
+
lines: list[str],
|
|
347
|
+
*,
|
|
348
|
+
image_contents: list[Any] | None = None,
|
|
349
|
+
snapshot_metadata: dict[str, Any] | None = None,
|
|
350
|
+
provider_status: str = "",
|
|
351
|
+
) -> None:
|
|
352
|
+
"""Forward streaming progress lines to a running tool widget."""
|
|
353
|
+
group = self._tool_groups_by_call_id.get(call_id)
|
|
354
|
+
if group is not None:
|
|
355
|
+
if image_contents is not None or snapshot_metadata is not None or provider_status:
|
|
356
|
+
group.update_tool_progress(
|
|
357
|
+
call_id,
|
|
358
|
+
lines,
|
|
359
|
+
image_contents=image_contents,
|
|
360
|
+
snapshot_metadata=snapshot_metadata,
|
|
361
|
+
provider_status=provider_status,
|
|
362
|
+
)
|
|
363
|
+
else:
|
|
364
|
+
group.update_tool_progress(call_id, lines)
|
|
365
|
+
self._ui.schedule_anchor_sync()
|
|
366
|
+
|
|
367
|
+
def update_tool_args(self, call_id: str, args: dict[str, Any]) -> None:
|
|
368
|
+
"""Refresh a running tool widget after approval edits its arguments."""
|
|
369
|
+
group = self._tool_groups_by_call_id.get(call_id)
|
|
370
|
+
if group is not None:
|
|
371
|
+
group.update_tool_args(call_id, args)
|
|
372
|
+
self._ui.schedule_anchor_sync()
|
|
373
|
+
|
|
374
|
+
def update_tool_status(
|
|
375
|
+
self,
|
|
376
|
+
call_id: str,
|
|
377
|
+
status: str,
|
|
378
|
+
*,
|
|
379
|
+
provider_status: str = "",
|
|
380
|
+
metadata: dict[str, Any] | None = None,
|
|
381
|
+
) -> None:
|
|
382
|
+
"""Apply a canonical hosted lifecycle transition."""
|
|
383
|
+
group = self._tool_groups_by_call_id.get(call_id)
|
|
384
|
+
if group is not None:
|
|
385
|
+
group.update_tool_status(
|
|
386
|
+
call_id,
|
|
387
|
+
status,
|
|
388
|
+
provider_status=provider_status,
|
|
389
|
+
metadata=metadata,
|
|
390
|
+
)
|
|
391
|
+
self._ui.schedule_anchor_sync()
|
|
392
|
+
|
|
393
|
+
def show_ask_user_inline(
|
|
394
|
+
self,
|
|
395
|
+
call_id: str,
|
|
396
|
+
request_id: str,
|
|
397
|
+
questions: tuple[AskUserQuestion, ...],
|
|
398
|
+
*,
|
|
399
|
+
draft: PromptDraft | None = None,
|
|
400
|
+
) -> bool:
|
|
401
|
+
"""Show a live ask_user response form inside the matching tool renderer."""
|
|
402
|
+
if not call_id or not request_id:
|
|
403
|
+
return False
|
|
404
|
+
group = self._tool_groups_by_call_id.get(call_id)
|
|
405
|
+
if group is None:
|
|
406
|
+
return False
|
|
407
|
+
widget = group.get_tool(call_id)
|
|
408
|
+
if not isinstance(widget, AskUserToolCall):
|
|
409
|
+
return False
|
|
410
|
+
if not widget.show_inline_prompt(request_id, questions, draft=draft):
|
|
411
|
+
return False
|
|
412
|
+
group.lock_collapse_for(call_id)
|
|
413
|
+
self._ui.scroll_inline_prompt_to_top_after_refresh(widget)
|
|
414
|
+
return True
|
|
415
|
+
|
|
416
|
+
def handle_ask_user_inline_resized(self, call_id: str) -> None:
|
|
417
|
+
"""Delegate inline ask_user resize relayout for the matching live group."""
|
|
418
|
+
self._ui.on_inline_prompt_resized(self._tool_groups_by_call_id.get(call_id))
|
|
419
|
+
|
|
420
|
+
def is_tool_running(self, call_id: str) -> bool:
|
|
421
|
+
"""Return whether the tool record for ``call_id`` is still running."""
|
|
422
|
+
group = self._tool_groups_by_call_id.get(call_id)
|
|
423
|
+
return group is not None and group.is_tool_running(call_id)
|
|
424
|
+
|
|
425
|
+
def clear_ask_user_inline_prompts(self) -> None:
|
|
426
|
+
"""Clear live inline ask_user prompts from every known tool group."""
|
|
427
|
+
seen_group_ids: set[int] = set()
|
|
428
|
+
for group in self._tool_groups_by_call_id.values():
|
|
429
|
+
group_id = id(group)
|
|
430
|
+
if group_id in seen_group_ids:
|
|
431
|
+
continue
|
|
432
|
+
seen_group_ids.add(group_id)
|
|
433
|
+
group.clear_ask_user_inline_prompts()
|
|
434
|
+
|
|
435
|
+
def clear_ask_user_inline(self, call_id: str, request_id: str) -> bool:
|
|
436
|
+
"""Clear one timed-out inline prompt without disturbing a newer request."""
|
|
437
|
+
group = self._tool_groups_by_call_id.get(call_id)
|
|
438
|
+
if group is None:
|
|
439
|
+
return False
|
|
440
|
+
widget = group.get_tool(call_id)
|
|
441
|
+
if not isinstance(widget, AskUserToolCall) or not widget.clear_inline_prompt_for(request_id):
|
|
442
|
+
return False
|
|
443
|
+
group.unlock_collapse_for(call_id)
|
|
444
|
+
return True
|
|
445
|
+
|
|
446
|
+
def link_sub_agent_invocation(
|
|
447
|
+
self,
|
|
448
|
+
parent_call_id: str,
|
|
449
|
+
invocation_id: str,
|
|
450
|
+
agent_name: str,
|
|
451
|
+
sub_agent_log_file: str = "",
|
|
452
|
+
*,
|
|
453
|
+
tool_name: str = "",
|
|
454
|
+
) -> None:
|
|
455
|
+
"""Bind an invocation id by exact parent ownership or tool-name FIFO."""
|
|
456
|
+
if not invocation_id:
|
|
457
|
+
return
|
|
458
|
+
if invocation_id in self._sub_agent_widgets:
|
|
459
|
+
return
|
|
460
|
+
group = self._tool_groups_by_call_id.get(parent_call_id)
|
|
461
|
+
widget = group.get_tool(parent_call_id) if group is not None else None
|
|
462
|
+
if not isinstance(widget, SubAgentToolCall) and tool_name:
|
|
463
|
+
unlinked = self._unlinked_sub_agents.get(tool_name)
|
|
464
|
+
if unlinked:
|
|
465
|
+
widget = unlinked.pop(0)
|
|
466
|
+
if not unlinked:
|
|
467
|
+
del self._unlinked_sub_agents[tool_name]
|
|
468
|
+
group = self._sub_agent_owning_group(widget)
|
|
469
|
+
if not isinstance(widget, SubAgentToolCall):
|
|
470
|
+
return
|
|
471
|
+
widget.claim_invocation(invocation_id, agent_name, sub_agent_log_file)
|
|
472
|
+
self._sub_agent_widgets[invocation_id] = widget
|
|
473
|
+
if group is not None:
|
|
474
|
+
self._sub_agent_owning_groups[widget] = group
|
|
475
|
+
group.update_sub_agent_display_name(widget.call_id, agent_name)
|
|
476
|
+
for name, queue in list(self._unlinked_sub_agents.items()):
|
|
477
|
+
if widget in queue:
|
|
478
|
+
queue.remove(widget)
|
|
479
|
+
if not queue:
|
|
480
|
+
del self._unlinked_sub_agents[name]
|
|
481
|
+
|
|
482
|
+
def _resolve_sub_agent(self, invocation_id: str) -> SubAgentToolCall | None:
|
|
483
|
+
"""Resolve a widget after invocation-start established its route."""
|
|
484
|
+
return self._sub_agent_widgets.get(invocation_id)
|
|
485
|
+
|
|
486
|
+
def add_sub_agent_message(
|
|
487
|
+
self,
|
|
488
|
+
agent_name: str,
|
|
489
|
+
invocation_id: str,
|
|
490
|
+
text: str,
|
|
491
|
+
*,
|
|
492
|
+
presentation: ProvisionalPresentation | None = None,
|
|
493
|
+
) -> None:
|
|
494
|
+
"""Route intermediate assistant prose to one sub-agent transcript."""
|
|
495
|
+
widget = self._resolve_sub_agent(invocation_id)
|
|
496
|
+
if widget is not None:
|
|
497
|
+
activity = widget.add_assistant_message(text, presentation=presentation, profile_name=agent_name)
|
|
498
|
+
group = self._sub_agent_owning_group(widget)
|
|
499
|
+
if group is not None:
|
|
500
|
+
group.update_sub_agent_activity(widget.call_id, activity)
|
|
501
|
+
|
|
502
|
+
def accept_sub_agent_presentation(
|
|
503
|
+
self,
|
|
504
|
+
invocation_id: str,
|
|
505
|
+
attempt_id: str,
|
|
506
|
+
segment_ids: tuple[str, ...],
|
|
507
|
+
) -> None:
|
|
508
|
+
"""Commit provisional transcript messages for one sub-agent attempt."""
|
|
509
|
+
widget = self._sub_agent_widgets.get(invocation_id)
|
|
510
|
+
if widget is not None:
|
|
511
|
+
activity = widget.accept_presentation_attempt(attempt_id, segment_ids)
|
|
512
|
+
group = self._sub_agent_owning_group(widget)
|
|
513
|
+
if group is not None:
|
|
514
|
+
group.update_sub_agent_activity(widget.call_id, activity)
|
|
515
|
+
|
|
516
|
+
def reject_sub_agent_presentation(self, invocation_id: str, attempt_id: str) -> None:
|
|
517
|
+
"""Retract provisional transcript messages for one sub-agent attempt."""
|
|
518
|
+
widget = self._sub_agent_widgets.get(invocation_id)
|
|
519
|
+
if widget is not None:
|
|
520
|
+
activity = widget.reject_presentation_attempt(attempt_id)
|
|
521
|
+
group = self._sub_agent_owning_group(widget)
|
|
522
|
+
if group is not None:
|
|
523
|
+
group.update_sub_agent_activity(widget.call_id, activity)
|
|
524
|
+
|
|
525
|
+
async def add_sub_agent_tool_start(
|
|
526
|
+
self,
|
|
527
|
+
agent_name: str,
|
|
528
|
+
invocation_id: str,
|
|
529
|
+
tool_name: str,
|
|
530
|
+
args: dict[str, Any],
|
|
531
|
+
call_id: str,
|
|
532
|
+
*,
|
|
533
|
+
tool_kind: str = "",
|
|
534
|
+
provider_hosted: bool = False,
|
|
535
|
+
hosted_family: str = "",
|
|
536
|
+
provider: str = "",
|
|
537
|
+
provider_item_type: str = "",
|
|
538
|
+
provider_status: str = "",
|
|
539
|
+
provider_call_id: str = "",
|
|
540
|
+
) -> None:
|
|
541
|
+
"""Route an inner tool call start to the correct SubAgentToolCall widget."""
|
|
542
|
+
widget = self._resolve_sub_agent(invocation_id)
|
|
543
|
+
if widget is not None:
|
|
544
|
+
await widget.add_inner_tool_start(
|
|
545
|
+
call_id,
|
|
546
|
+
tool_name,
|
|
547
|
+
args,
|
|
548
|
+
tool_kind=tool_kind,
|
|
549
|
+
provider_hosted=provider_hosted,
|
|
550
|
+
hosted_family=hosted_family,
|
|
551
|
+
provider=provider,
|
|
552
|
+
provider_item_type=provider_item_type,
|
|
553
|
+
provider_status=provider_status,
|
|
554
|
+
provider_call_id=provider_call_id,
|
|
555
|
+
)
|
|
556
|
+
group = self._sub_agent_owning_group(widget)
|
|
557
|
+
if group is not None:
|
|
558
|
+
group.update_nested_tool_activity(
|
|
559
|
+
widget.call_id,
|
|
560
|
+
call_id,
|
|
561
|
+
tool_name=tool_name,
|
|
562
|
+
tool_kind=tool_kind,
|
|
563
|
+
args=args,
|
|
564
|
+
)
|
|
565
|
+
|
|
566
|
+
def update_sub_agent_tool_args(self, invocation_id: str, call_id: str, args: dict[str, Any]) -> None:
|
|
567
|
+
"""Route nested argument snapshots to the owning sub-agent card."""
|
|
568
|
+
widget = self._sub_agent_widgets.get(invocation_id)
|
|
569
|
+
if widget is not None:
|
|
570
|
+
widget.update_inner_tool_args(call_id, args)
|
|
571
|
+
group = self._sub_agent_owning_group(widget)
|
|
572
|
+
if group is not None:
|
|
573
|
+
group.update_nested_tool_activity(widget.call_id, call_id, args=args)
|
|
574
|
+
|
|
575
|
+
def update_sub_agent_tool_status(
|
|
576
|
+
self,
|
|
577
|
+
invocation_id: str,
|
|
578
|
+
call_id: str,
|
|
579
|
+
status: str,
|
|
580
|
+
*,
|
|
581
|
+
metadata: dict[str, Any] | None = None,
|
|
582
|
+
provider_status: str = "",
|
|
583
|
+
) -> None:
|
|
584
|
+
"""Route nested lifecycle status to the owning sub-agent card."""
|
|
585
|
+
widget = self._sub_agent_widgets.get(invocation_id)
|
|
586
|
+
if widget is not None:
|
|
587
|
+
widget.update_inner_tool_status(
|
|
588
|
+
call_id,
|
|
589
|
+
status,
|
|
590
|
+
metadata=metadata,
|
|
591
|
+
provider_status=provider_status,
|
|
592
|
+
)
|
|
593
|
+
group = self._sub_agent_owning_group(widget)
|
|
594
|
+
if group is not None:
|
|
595
|
+
group.update_nested_tool_activity(widget.call_id, call_id, status=status)
|
|
596
|
+
|
|
597
|
+
def update_sub_agent_tool_progress(
|
|
598
|
+
self,
|
|
599
|
+
invocation_id: str,
|
|
600
|
+
call_id: str,
|
|
601
|
+
lines: list[str],
|
|
602
|
+
*,
|
|
603
|
+
image_contents: list[Any] | None = None,
|
|
604
|
+
snapshot_metadata: dict[str, Any] | None = None,
|
|
605
|
+
provider_status: str = "",
|
|
606
|
+
) -> None:
|
|
607
|
+
"""Route nested progress snapshots to the owning sub-agent card."""
|
|
608
|
+
widget = self._sub_agent_widgets.get(invocation_id)
|
|
609
|
+
if widget is not None:
|
|
610
|
+
widget.update_inner_tool_progress(
|
|
611
|
+
call_id,
|
|
612
|
+
lines,
|
|
613
|
+
image_contents=image_contents,
|
|
614
|
+
snapshot_metadata=snapshot_metadata,
|
|
615
|
+
provider_status=provider_status,
|
|
616
|
+
)
|
|
617
|
+
|
|
618
|
+
def add_sub_agent_compaction_start(self, agent_name: str, invocation_id: str, compaction_id: str) -> None:
|
|
619
|
+
"""Route a Phase-4 compaction start line to the correct sub-agent card."""
|
|
620
|
+
widget = self._resolve_sub_agent(invocation_id)
|
|
621
|
+
if widget is not None:
|
|
622
|
+
widget.add_compaction_start(compaction_id)
|
|
623
|
+
|
|
624
|
+
def complete_sub_agent_compaction(
|
|
625
|
+
self,
|
|
626
|
+
invocation_id: str,
|
|
627
|
+
compaction_id: str,
|
|
628
|
+
*,
|
|
629
|
+
outcome: str,
|
|
630
|
+
duration_ms: int = 0,
|
|
631
|
+
format_violation: str = "",
|
|
632
|
+
failure_reason: str = "",
|
|
633
|
+
) -> None:
|
|
634
|
+
"""Flip the compaction line on the matching sub-agent card."""
|
|
635
|
+
widget = self._sub_agent_widgets.get(invocation_id)
|
|
636
|
+
if widget is not None:
|
|
637
|
+
widget.complete_compaction(
|
|
638
|
+
compaction_id,
|
|
639
|
+
outcome=outcome,
|
|
640
|
+
duration_ms=duration_ms,
|
|
641
|
+
format_violation=format_violation,
|
|
642
|
+
failure_reason=failure_reason,
|
|
643
|
+
)
|
|
644
|
+
|
|
645
|
+
def record_sub_agent_compaction_committed(self, invocation_id: str, compaction_id: str) -> None:
|
|
646
|
+
"""Bump the compaction counter on the matching sub-agent card.
|
|
647
|
+
|
|
648
|
+
Falls back to retired routing entries: the committed signal rides a
|
|
649
|
+
detached task, so an interrupt can close the group before it lands
|
|
650
|
+
while the card — and the durable round it must count — remain.
|
|
651
|
+
"""
|
|
652
|
+
widget = self._sub_agent_widgets.get(invocation_id) or self._retired_sub_agent_widgets.get(invocation_id)
|
|
653
|
+
if widget is not None:
|
|
654
|
+
widget.record_compaction_committed(compaction_id)
|
|
655
|
+
|
|
656
|
+
def complete_sub_agent_tool(
|
|
657
|
+
self,
|
|
658
|
+
agent_name: str,
|
|
659
|
+
invocation_id: str,
|
|
660
|
+
call_id: str,
|
|
661
|
+
result: str,
|
|
662
|
+
duration_ms: int,
|
|
663
|
+
image_contents: list[Any] | None = None,
|
|
664
|
+
artifacts: list[dict[str, Any]] | None = None,
|
|
665
|
+
approval: str | None = None,
|
|
666
|
+
metadata: dict[str, Any] | None = None,
|
|
667
|
+
provider_status: str = "",
|
|
668
|
+
canonical_status: str = "completed",
|
|
669
|
+
) -> None:
|
|
670
|
+
"""Route an inner tool call result to the correct SubAgentToolCall widget."""
|
|
671
|
+
widget = self._sub_agent_widgets.get(invocation_id)
|
|
672
|
+
if widget is not None:
|
|
673
|
+
widget.complete_inner_tool(
|
|
674
|
+
call_id,
|
|
675
|
+
result,
|
|
676
|
+
duration_ms,
|
|
677
|
+
image_contents=image_contents,
|
|
678
|
+
artifacts=artifacts,
|
|
679
|
+
approval=approval,
|
|
680
|
+
metadata=metadata,
|
|
681
|
+
provider_status=provider_status,
|
|
682
|
+
canonical_status=canonical_status,
|
|
683
|
+
)
|
|
684
|
+
group = self._sub_agent_owning_group(widget)
|
|
685
|
+
if group is not None:
|
|
686
|
+
group.update_nested_tool_activity(widget.call_id, call_id, status="completed")
|
|
687
|
+
|
|
688
|
+
def update_sub_agent_progress(
|
|
689
|
+
self,
|
|
690
|
+
invocation_id: str,
|
|
691
|
+
tool_call_count: int,
|
|
692
|
+
total_tokens: int,
|
|
693
|
+
total_usage_tokens: int = 0,
|
|
694
|
+
usage_unreported_attempts: int = 0,
|
|
695
|
+
) -> None:
|
|
696
|
+
"""Update progress stats on a running SubAgentToolCall widget."""
|
|
697
|
+
widget = self._sub_agent_widgets.get(invocation_id)
|
|
698
|
+
if widget is not None:
|
|
699
|
+
widget.update_progress(
|
|
700
|
+
tool_call_count,
|
|
701
|
+
total_tokens,
|
|
702
|
+
total_usage_tokens,
|
|
703
|
+
usage_unreported_attempts,
|
|
704
|
+
)
|
|
705
|
+
|
|
706
|
+
def sub_agent_retry_attempt(
|
|
707
|
+
self,
|
|
708
|
+
invocation_id: str,
|
|
709
|
+
message: str,
|
|
710
|
+
attempt: int,
|
|
711
|
+
max_attempts: int,
|
|
712
|
+
delay_seconds: int,
|
|
713
|
+
) -> None:
|
|
714
|
+
"""Dispatch a sub-agent auto-retry banner to the correct card."""
|
|
715
|
+
widget = self._sub_agent_widgets.get(invocation_id)
|
|
716
|
+
if widget is not None:
|
|
717
|
+
widget.set_retry_attempt(message, attempt, max_attempts, delay_seconds)
|
|
718
|
+
|
|
719
|
+
def sub_agent_paused(
|
|
720
|
+
self,
|
|
721
|
+
invocation_id: str,
|
|
722
|
+
reason: str,
|
|
723
|
+
last_error: str,
|
|
724
|
+
retry_attempts: int,
|
|
725
|
+
diagnostic_path: str | None = None,
|
|
726
|
+
last_error_display: str | None = None,
|
|
727
|
+
) -> None:
|
|
728
|
+
"""Dispatch a pause transition to the correct card."""
|
|
729
|
+
widget = self._sub_agent_widgets.get(invocation_id)
|
|
730
|
+
if widget is not None:
|
|
731
|
+
widget.set_paused(reason, last_error, retry_attempts, diagnostic_path, last_error_display)
|
|
732
|
+
self._set_sub_agent_action_required(widget, required=True)
|
|
733
|
+
|
|
734
|
+
def sub_agent_resumed_after_pause(self, invocation_id: str) -> None:
|
|
735
|
+
"""Dispatch a resume-after-pause transition to the correct card."""
|
|
736
|
+
widget = self._sub_agent_widgets.get(invocation_id)
|
|
737
|
+
if widget is not None:
|
|
738
|
+
widget.set_resumed_after_pause()
|
|
739
|
+
self._set_sub_agent_action_required(widget, required=False)
|
|
740
|
+
|
|
741
|
+
def sub_agent_cascade_aborted(self, invocation_id: str) -> None:
|
|
742
|
+
"""Dispatch a cascade-abort transition from global interrupt."""
|
|
743
|
+
widget = self._sub_agent_widgets.get(invocation_id)
|
|
744
|
+
if widget is not None:
|
|
745
|
+
widget.set_cascade_aborted()
|
|
746
|
+
self._set_sub_agent_action_required(widget, required=False)
|
|
747
|
+
|
|
748
|
+
def sub_agent_aborted(self, invocation_id: str, last_error: str) -> None:
|
|
749
|
+
"""Dispatch a user-abort transition to the correct card."""
|
|
750
|
+
widget = self._sub_agent_widgets.get(invocation_id)
|
|
751
|
+
if widget is not None:
|
|
752
|
+
widget.set_aborted(last_error)
|
|
753
|
+
self._set_sub_agent_action_required(widget, required=False)
|