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,779 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Tool event middleware — publishes InvocationToolCallStart/InvocationToolCallResult for each invocation."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import time
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from datetime import UTC, datetime
|
|
10
|
+
from typing import TYPE_CHECKING, Any
|
|
11
|
+
from uuid import uuid4
|
|
12
|
+
|
|
13
|
+
from chrys.foundation.events.types import (
|
|
14
|
+
InvocationMessage,
|
|
15
|
+
InvocationToolCallProgress,
|
|
16
|
+
InvocationToolCallResult,
|
|
17
|
+
InvocationToolCallStart,
|
|
18
|
+
)
|
|
19
|
+
from chrys.foundation.io.result_content import extract_result_images, extract_result_text
|
|
20
|
+
from chrys.foundation.models.invocations import InvocationOrigin
|
|
21
|
+
from chrys.foundation.platform.paths import resolve_workspace_path
|
|
22
|
+
from chrys.foundation.tool_call_context import resolve_tool_call_context
|
|
23
|
+
from chrys.foundation.tool_execution_stamp import write_execution_stamp
|
|
24
|
+
from chrys.foundation.tool_kinds import KIND_SHELL, KIND_SUB_AGENT, KIND_WEB_FETCH, KIND_WEB_SEARCH, get_tool_kind
|
|
25
|
+
from chrys.foundation.tool_result_metadata import (
|
|
26
|
+
TOOL_ERROR_KIND_METADATA_KEY,
|
|
27
|
+
TOOL_ERRORED_METADATA_KEY,
|
|
28
|
+
tool_payload_observation,
|
|
29
|
+
tool_result_metadata_failure_state,
|
|
30
|
+
)
|
|
31
|
+
from chrys.foundation.trajectory.context import bind_tool_operation, reset_tool_operation
|
|
32
|
+
from chrys.foundation.trajectory.event_types import ToolOutcome
|
|
33
|
+
from chrys.foundation.trajectory_timing import build_trajectory_timing, stamp_trajectory_timing
|
|
34
|
+
from chrys.kernel._result_ceiling import preview_result_ceiling
|
|
35
|
+
from chrys.kernel.middleware import FunctionMiddleware
|
|
36
|
+
from chrys.service.agent_middleware._metadata_keys import (
|
|
37
|
+
_APPROVAL_MODIFIED_ARGS_KEY,
|
|
38
|
+
_APPROVAL_REJECTED_KEY,
|
|
39
|
+
_SHORT_ID_LEN,
|
|
40
|
+
_SLEEP_INTERRUPTED_KEY,
|
|
41
|
+
_SLEEP_SKIPPED_KEY,
|
|
42
|
+
)
|
|
43
|
+
from chrys.service.agent_middleware.events.hook_dispatch import (
|
|
44
|
+
append_extra_context_to_result,
|
|
45
|
+
apply_before_tool_hooks,
|
|
46
|
+
final_tool_args,
|
|
47
|
+
fire_after_tool_hooks,
|
|
48
|
+
get_call_id,
|
|
49
|
+
get_provider_call_id,
|
|
50
|
+
get_tool_invocation_order,
|
|
51
|
+
is_mutable_tool_args,
|
|
52
|
+
set_call_id,
|
|
53
|
+
set_tool_invocation_order,
|
|
54
|
+
)
|
|
55
|
+
from chrys.service.agent_middleware.events.intermediate_text import IntermediateTextBuffer
|
|
56
|
+
from chrys.service.agent_middleware.events.rejection_metadata import rejection_result_metadata, rejection_source
|
|
57
|
+
from chrys.service.agent_middleware.events.result_persistence import (
|
|
58
|
+
RESULT_SLEEP_INTERRUPTED_METADATA_KEY,
|
|
59
|
+
RESULT_SLEEP_SKIPPED_METADATA_KEY,
|
|
60
|
+
RESULT_SUB_AGENT_AUDIT_COMPLETE_METADATA_KEY,
|
|
61
|
+
RESULT_SUB_AGENT_INVOCATION_ID_METADATA_KEY,
|
|
62
|
+
RESULT_SUB_AGENT_LOG_FILE_METADATA_KEY,
|
|
63
|
+
write_result_carriage,
|
|
64
|
+
)
|
|
65
|
+
from chrys.service.agent_middleware.events.tool_error_text import tool_card_error_text
|
|
66
|
+
from chrys.service.mutations.pipeline import (
|
|
67
|
+
abort_mutation_tracking,
|
|
68
|
+
finalize_mutation_tracking,
|
|
69
|
+
prepare_mutation_tracking,
|
|
70
|
+
)
|
|
71
|
+
from chrys.service.mutations.tool_names import _FILE_TOOLS, _IMPLICIT_WRITE_TOOLS
|
|
72
|
+
from chrys.service.tools.builtins.web.progress import web_progress_callback
|
|
73
|
+
from chrys.service.tools.result_metadata import tool_result_metadata
|
|
74
|
+
from chrys.service.trajectory.preparation import (
|
|
75
|
+
PreparationOutcome,
|
|
76
|
+
PreparationScope,
|
|
77
|
+
PreparationTrace,
|
|
78
|
+
preparation_lock,
|
|
79
|
+
)
|
|
80
|
+
from chrys.service.trajectory.tools import ToolOperationTrace, tool_operation_id, tool_outcome
|
|
81
|
+
|
|
82
|
+
if TYPE_CHECKING:
|
|
83
|
+
from collections.abc import Awaitable, Callable
|
|
84
|
+
|
|
85
|
+
from chrys.foundation.events.bus import EventBus
|
|
86
|
+
from chrys.kernel.middleware import FunctionInvocationContext
|
|
87
|
+
from chrys.service.hooks.manager import HookManager
|
|
88
|
+
from chrys.service.mutations.coordination import MutationCoordinator
|
|
89
|
+
from chrys.service.mutations.tracker import MutationTracker
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@dataclass(frozen=True, slots=True)
|
|
93
|
+
class ToolBatchRecord:
|
|
94
|
+
"""Batch attribution for one dispatched tool invocation, recorded PRE-execution.
|
|
95
|
+
|
|
96
|
+
``provider_call_id`` + ``tool_name`` are the ONLY matching keys for
|
|
97
|
+
``persist_batch_ids`` — the persisted ``function_call.call_id`` is the
|
|
98
|
+
raw provider id, so identity matching works across interruption and
|
|
99
|
+
mid-pass compression where positional pairing misattributes.
|
|
100
|
+
``tool_order`` (a per-run ordinal) and ``batch_id`` context ride along
|
|
101
|
+
for diagnostics/assignment; ``tool_order`` is never a match key.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
provider_call_id: str
|
|
105
|
+
tool_name: str
|
|
106
|
+
tool_order: int
|
|
107
|
+
batch_id: int
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
@dataclass(frozen=True, slots=True)
|
|
111
|
+
class ToolEventRetrySnapshot:
|
|
112
|
+
"""Append-only tool-event state that must survive an outer retry.
|
|
113
|
+
|
|
114
|
+
Result metadata needs no snapshot slot: it rides each invocation's
|
|
115
|
+
context into the result Content at construction, so a rolled-back
|
|
116
|
+
attempt's metadata leaves with its messages.
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
batch_records: tuple[ToolBatchRecord, ...]
|
|
120
|
+
invocation_order: int
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class ToolEventMiddleware(FunctionMiddleware):
|
|
124
|
+
"""Publishes InvocationToolCallStart and InvocationToolCallResult events for each tool invocation.
|
|
125
|
+
|
|
126
|
+
Wraps each function call in the agent's tool loop, firing events before
|
|
127
|
+
and after execution. This lets the frontend display real-time tool activity.
|
|
128
|
+
|
|
129
|
+
When an ``IntermediateTextBuffer`` is attached, drains pending intermediate
|
|
130
|
+
text and publishes it as ``InvocationMessage(is_intermediate=True)`` **before**
|
|
131
|
+
``InvocationToolCallStart``. This ensures correct event ordering (text → tool call).
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
def __init__(
|
|
135
|
+
self,
|
|
136
|
+
event_bus: EventBus,
|
|
137
|
+
session_id: str | None = None,
|
|
138
|
+
intermediate_buffer: IntermediateTextBuffer | None = None,
|
|
139
|
+
mutation_tracker: MutationTracker | None = None,
|
|
140
|
+
hook_manager: HookManager | None = None,
|
|
141
|
+
profile_name: str = "",
|
|
142
|
+
workspace_cwd: str = "",
|
|
143
|
+
serialize_implicit_windows: bool = False,
|
|
144
|
+
mutation_coordinator: MutationCoordinator | None = None,
|
|
145
|
+
on_start_published: Callable[[str], Awaitable[None]] | None = None,
|
|
146
|
+
tool_result_ceiling_tokens: int | None = None,
|
|
147
|
+
*,
|
|
148
|
+
origin: InvocationOrigin,
|
|
149
|
+
) -> None:
|
|
150
|
+
self._origin = origin
|
|
151
|
+
self._bus = event_bus
|
|
152
|
+
self._session_id = session_id
|
|
153
|
+
self._intermediate_buffer = intermediate_buffer
|
|
154
|
+
self._mutation_tracker = mutation_tracker
|
|
155
|
+
self._mutation_coordinator = mutation_coordinator
|
|
156
|
+
self._hook_manager = hook_manager
|
|
157
|
+
self._profile_name = profile_name
|
|
158
|
+
self._workspace_cwd = workspace_cwd
|
|
159
|
+
self._serialize_implicit_windows = serialize_implicit_windows
|
|
160
|
+
self._on_start_published = on_start_published
|
|
161
|
+
self._tool_result_ceiling_tokens = tool_result_ceiling_tokens
|
|
162
|
+
self._tool_batch_records: list[ToolBatchRecord] = []
|
|
163
|
+
self._tool_invocation_order = 0
|
|
164
|
+
|
|
165
|
+
def bind_origin(self, origin: InvocationOrigin) -> None:
|
|
166
|
+
"""Bind the next pass; each dispatched callback captures its own origin."""
|
|
167
|
+
self._origin = origin
|
|
168
|
+
|
|
169
|
+
async def release_intermediate_text(self) -> None:
|
|
170
|
+
"""Publish intermediate text that no tool start has released yet.
|
|
171
|
+
|
|
172
|
+
A call that never enters the tool pipeline (unknown tool, pre-pipeline
|
|
173
|
+
argument rejection) starts no tool, so the text streamed with it stays
|
|
174
|
+
buffered until the next response starts or the pass ends.
|
|
175
|
+
"""
|
|
176
|
+
await self._release_intermediate_text(self._origin, None)
|
|
177
|
+
|
|
178
|
+
async def finish_intermediate_text(self) -> None:
|
|
179
|
+
"""Release what is still buffered as the pass ends; see ``IntermediateTextBuffer.finish``."""
|
|
180
|
+
if self._intermediate_buffer is not None:
|
|
181
|
+
await self._intermediate_buffer.finish(self._intermediate_publisher(self._origin))
|
|
182
|
+
|
|
183
|
+
async def _release_intermediate_text(self, origin: InvocationOrigin, preamble: PreparationTrace | None) -> None:
|
|
184
|
+
if self._intermediate_buffer is not None:
|
|
185
|
+
await self._intermediate_buffer.release(self._intermediate_publisher(origin), preamble)
|
|
186
|
+
|
|
187
|
+
def _intermediate_publisher(self, origin: InvocationOrigin) -> Callable[[str], Awaitable[None]]:
|
|
188
|
+
async def publish(text: str) -> None:
|
|
189
|
+
await self._bus.publish(
|
|
190
|
+
InvocationMessage(
|
|
191
|
+
origin=origin, text=text, is_final=False, is_intermediate=True, session_id=self._session_id
|
|
192
|
+
)
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
return publish
|
|
196
|
+
|
|
197
|
+
async def process(
|
|
198
|
+
self,
|
|
199
|
+
context: FunctionInvocationContext,
|
|
200
|
+
call_next: Callable[[], Awaitable[None]],
|
|
201
|
+
) -> None:
|
|
202
|
+
origin = self._origin
|
|
203
|
+
# The trace is bound before the first await because the kernel hands
|
|
204
|
+
# the operation over the moment it dispatches the batch: from here on
|
|
205
|
+
# nothing else accounts for it, and everything below — the
|
|
206
|
+
# intermediate-text publish, before-tool hooks, the mutation lock —
|
|
207
|
+
# can be cancelled. Binding writes nothing; the start marker is still
|
|
208
|
+
# written where the call is dispatched.
|
|
209
|
+
trajectory = ToolOperationTrace.open(context.metadata if isinstance(context.metadata, dict) else {})
|
|
210
|
+
preamble = (
|
|
211
|
+
PreparationTrace.open(
|
|
212
|
+
scope=PreparationScope.TOOL_PREAMBLE,
|
|
213
|
+
phase="tool_dispatch",
|
|
214
|
+
parent_operation_id=trajectory.context.innermost_model_operation_id,
|
|
215
|
+
target_operation_id=trajectory.operation_id,
|
|
216
|
+
context=trajectory.context,
|
|
217
|
+
)
|
|
218
|
+
if trajectory is not None
|
|
219
|
+
else None
|
|
220
|
+
)
|
|
221
|
+
try:
|
|
222
|
+
if preamble is not None:
|
|
223
|
+
await preamble.started()
|
|
224
|
+
await self._process(context, call_next, trajectory, preamble, origin)
|
|
225
|
+
except Exception:
|
|
226
|
+
if preamble is not None:
|
|
227
|
+
preamble.finished_soon(outcome=PreparationOutcome.FAILED)
|
|
228
|
+
self._abandon_operation(context, trajectory, preamble, ToolOutcome.ERRORED)
|
|
229
|
+
raise
|
|
230
|
+
except BaseException:
|
|
231
|
+
if preamble is not None:
|
|
232
|
+
preamble.finished_soon(outcome=PreparationOutcome.INTERRUPTED)
|
|
233
|
+
self._abandon_operation(context, trajectory, preamble, ToolOutcome.INTERRUPTED)
|
|
234
|
+
raise
|
|
235
|
+
|
|
236
|
+
def _abandon_operation(
|
|
237
|
+
self,
|
|
238
|
+
context: FunctionInvocationContext,
|
|
239
|
+
trajectory: ToolOperationTrace | None,
|
|
240
|
+
preamble: PreparationTrace | None,
|
|
241
|
+
outcome: str,
|
|
242
|
+
) -> None:
|
|
243
|
+
"""Close an operation that never reached its own start marker (a no-op once it has)."""
|
|
244
|
+
if trajectory is None:
|
|
245
|
+
return
|
|
246
|
+
metadata = context.metadata if isinstance(context.metadata, dict) else {}
|
|
247
|
+
args = context.arguments if is_mutable_tool_args(context.arguments) else {}
|
|
248
|
+
trajectory.abandoned_soon(
|
|
249
|
+
tool_name=context.function.name,
|
|
250
|
+
tool_kind=get_tool_kind(context.function) or "",
|
|
251
|
+
batch_index=self._intermediate_buffer.batch_id if self._intermediate_buffer is not None else None,
|
|
252
|
+
invocation_order=get_tool_invocation_order(context),
|
|
253
|
+
arguments=args,
|
|
254
|
+
invocation_metadata=metadata,
|
|
255
|
+
tool_context=resolve_tool_call_context(context.function, args) or None,
|
|
256
|
+
outcome=outcome,
|
|
257
|
+
preamble_operation_id=(
|
|
258
|
+
preamble.operation_id if preamble is not None and preamble.start_committed else None
|
|
259
|
+
),
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
async def _process(
|
|
263
|
+
self,
|
|
264
|
+
context: FunctionInvocationContext,
|
|
265
|
+
call_next: Callable[[], Awaitable[None]],
|
|
266
|
+
trajectory: ToolOperationTrace | None,
|
|
267
|
+
preamble: PreparationTrace | None,
|
|
268
|
+
origin: InvocationOrigin,
|
|
269
|
+
) -> None:
|
|
270
|
+
tool_order = get_tool_invocation_order(context)
|
|
271
|
+
if tool_order is None:
|
|
272
|
+
tool_order = self._tool_invocation_order
|
|
273
|
+
self._tool_invocation_order = max(self._tool_invocation_order, tool_order + 1)
|
|
274
|
+
set_tool_invocation_order(context, tool_order)
|
|
275
|
+
|
|
276
|
+
# Publish the intermediate text accumulated by the result_hook BEFORE
|
|
277
|
+
# InvocationToolCallStart so the TUI renders it first. Parallel tool
|
|
278
|
+
# calls run this middleware concurrently (the kernel loop dispatches
|
|
279
|
+
# the batch via asyncio.gather); the release holds every sibling until
|
|
280
|
+
# the text is fully delivered (including stream consumers), because a
|
|
281
|
+
# start that overtakes it lands the text mid-batch and the TUI splits
|
|
282
|
+
# the tool group, orphaning already-rendered cards.
|
|
283
|
+
await self._release_intermediate_text(origin, preamble)
|
|
284
|
+
|
|
285
|
+
provider_call_id = get_provider_call_id(context)
|
|
286
|
+
call_id = get_call_id(context) or uuid4().hex[:_SHORT_ID_LEN]
|
|
287
|
+
tool_name = context.function.name
|
|
288
|
+
args = context.arguments if is_mutable_tool_args(context.arguments) else {}
|
|
289
|
+
|
|
290
|
+
# Record batch attribution for this tool call PRE-execution and
|
|
291
|
+
# unconditionally — an interrupted, cancelled, or metadata-less call
|
|
292
|
+
# must not lose its ``_batch_id``. The batch_id increments once per
|
|
293
|
+
# LLM response (intermediate-text boundary). The engine drains the
|
|
294
|
+
# records (``drain_batch_records``) to assign ``_batch_id`` to
|
|
295
|
+
# session messages in post-processing, keyed by
|
|
296
|
+
# (provider_call_id, tool_name) — never by position.
|
|
297
|
+
if self._intermediate_buffer is not None:
|
|
298
|
+
self._tool_batch_records.append(
|
|
299
|
+
ToolBatchRecord(
|
|
300
|
+
provider_call_id=provider_call_id,
|
|
301
|
+
tool_name=tool_name,
|
|
302
|
+
tool_order=tool_order,
|
|
303
|
+
batch_id=self._intermediate_buffer.batch_id,
|
|
304
|
+
)
|
|
305
|
+
)
|
|
306
|
+
# Stash the Chrys call_id in metadata so downstream middleware
|
|
307
|
+
# (approval, sub-agent correlation) references the same id as the
|
|
308
|
+
# published InvocationToolCallStart/InvocationToolCallResult events.
|
|
309
|
+
set_call_id(context, call_id)
|
|
310
|
+
|
|
311
|
+
tool_kind = get_tool_kind(context.function) or ""
|
|
312
|
+
blocked = await apply_before_tool_hooks(
|
|
313
|
+
manager=self._hook_manager,
|
|
314
|
+
context=context,
|
|
315
|
+
session_id=self._session_id,
|
|
316
|
+
profile_name=self._profile_name,
|
|
317
|
+
tool_name=tool_name,
|
|
318
|
+
kind=tool_kind,
|
|
319
|
+
call_id=call_id,
|
|
320
|
+
args=args,
|
|
321
|
+
workspace_cwd=self._workspace_cwd,
|
|
322
|
+
target_operation_id=trajectory.operation_id if trajectory is not None else None,
|
|
323
|
+
)
|
|
324
|
+
args = context.arguments if is_mutable_tool_args(context.arguments) else {}
|
|
325
|
+
|
|
326
|
+
async def _blocked_call_next() -> None:
|
|
327
|
+
return None
|
|
328
|
+
|
|
329
|
+
# Serialize concurrent mutations to the same file. FunctionInvocationLayer
|
|
330
|
+
# dispatches parallel tool calls via asyncio.gather(); without this
|
|
331
|
+
# lock, record() for a later edit runs before record_after() for an
|
|
332
|
+
# earlier one, breaking the _last_known_hash chain.
|
|
333
|
+
file_lock_path = _file_lock_path(tool_name, args, self._workspace_cwd)
|
|
334
|
+
implicit_window = _uses_implicit_window(tool_name, tool_kind)
|
|
335
|
+
if blocked:
|
|
336
|
+
await self._process_tool_call(
|
|
337
|
+
context, _blocked_call_next, call_id, provider_call_id, tool_name, args, trajectory, preamble, origin
|
|
338
|
+
)
|
|
339
|
+
elif self._serialize_implicit_windows and implicit_window and self._mutation_tracker is not None:
|
|
340
|
+
async with preparation_lock(self._mutation_tracker.get_implicit_window_lock(), preamble):
|
|
341
|
+
await self._process_tool_call(
|
|
342
|
+
context, call_next, call_id, provider_call_id, tool_name, args, trajectory, preamble, origin
|
|
343
|
+
)
|
|
344
|
+
elif file_lock_path and self._mutation_tracker is not None:
|
|
345
|
+
async with preparation_lock(self._mutation_tracker.get_file_lock(file_lock_path), preamble):
|
|
346
|
+
await self._process_tool_call(
|
|
347
|
+
context, call_next, call_id, provider_call_id, tool_name, args, trajectory, preamble, origin
|
|
348
|
+
)
|
|
349
|
+
else:
|
|
350
|
+
await self._process_tool_call(
|
|
351
|
+
context, call_next, call_id, provider_call_id, tool_name, args, trajectory, preamble, origin
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
async def _process_tool_call(
|
|
355
|
+
self,
|
|
356
|
+
context: FunctionInvocationContext,
|
|
357
|
+
call_next: Callable[[], Awaitable[None]],
|
|
358
|
+
call_id: str,
|
|
359
|
+
provider_call_id: str,
|
|
360
|
+
tool_name: str,
|
|
361
|
+
args: dict,
|
|
362
|
+
trajectory: ToolOperationTrace | None,
|
|
363
|
+
preamble: PreparationTrace | None,
|
|
364
|
+
origin: InvocationOrigin,
|
|
365
|
+
) -> None:
|
|
366
|
+
"""Core tool-call processing: mutation tracking, execution, event publishing."""
|
|
367
|
+
is_shell = get_tool_kind(context.function) == KIND_SHELL
|
|
368
|
+
is_sub_agent = get_tool_kind(context.function) == KIND_SUB_AGENT
|
|
369
|
+
modified_args = (
|
|
370
|
+
context.metadata.get(_APPROVAL_MODIFIED_ARGS_KEY) if isinstance(context.metadata, dict) else None
|
|
371
|
+
)
|
|
372
|
+
if isinstance(modified_args, dict):
|
|
373
|
+
args = modified_args
|
|
374
|
+
|
|
375
|
+
# Pre-execution mutation tracking
|
|
376
|
+
_meta = context.metadata if isinstance(context.metadata, dict) else {}
|
|
377
|
+
pre_rejected = bool(_meta.get(_APPROVAL_REJECTED_KEY))
|
|
378
|
+
mut_ctx = None
|
|
379
|
+
if not pre_rejected:
|
|
380
|
+
mut_ctx = await prepare_mutation_tracking(
|
|
381
|
+
self._mutation_tracker,
|
|
382
|
+
tool_name,
|
|
383
|
+
args,
|
|
384
|
+
call_id,
|
|
385
|
+
is_shell,
|
|
386
|
+
workspace_cwd=self._workspace_cwd,
|
|
387
|
+
coordinator=self._mutation_coordinator,
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
tool_kind = get_tool_kind(context.function) or ""
|
|
391
|
+
await self._bus.publish(
|
|
392
|
+
InvocationToolCallStart(
|
|
393
|
+
origin=origin,
|
|
394
|
+
tool_name=tool_name,
|
|
395
|
+
tool_kind=tool_kind,
|
|
396
|
+
args=args,
|
|
397
|
+
call_id=call_id,
|
|
398
|
+
session_id=self._session_id,
|
|
399
|
+
)
|
|
400
|
+
)
|
|
401
|
+
if self._on_start_published is not None:
|
|
402
|
+
await self._on_start_published(provider_call_id)
|
|
403
|
+
|
|
404
|
+
# Propagate parent call_id into the sub-agent's ``_invoke`` via
|
|
405
|
+
# ContextVar so it can bind invocation_id ↔ parent call_id for the
|
|
406
|
+
# TUI. Reset on the way out — parallel sub-agent siblings each get
|
|
407
|
+
# their own asyncio-task context, so the token would be auto-released
|
|
408
|
+
# anyway, but explicit reset keeps non-task call sites clean.
|
|
409
|
+
sub_agent_token = None
|
|
410
|
+
sub_agent_metadata_token = None
|
|
411
|
+
sub_agent_metadata = None
|
|
412
|
+
if is_sub_agent:
|
|
413
|
+
from chrys.foundation.util.sub_agent_context import (
|
|
414
|
+
SUB_AGENT_RESULT_COMMIT_CALLBACK_KEY,
|
|
415
|
+
SUB_AGENT_TRANSCRIPT_FINAL_TEXT_METADATA_KEY,
|
|
416
|
+
SubAgentParentResultMetadata,
|
|
417
|
+
sub_agent_parent_call_id,
|
|
418
|
+
sub_agent_parent_result_metadata,
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
raw_commit = context.metadata.get(SUB_AGENT_RESULT_COMMIT_CALLBACK_KEY)
|
|
422
|
+
sub_agent_token = sub_agent_parent_call_id.set(call_id)
|
|
423
|
+
sub_agent_metadata = SubAgentParentResultMetadata(
|
|
424
|
+
parent_provider_call_id=provider_call_id,
|
|
425
|
+
parent_event_call_id=call_id,
|
|
426
|
+
commit_interrupted_result=raw_commit if callable(raw_commit) else None,
|
|
427
|
+
)
|
|
428
|
+
sub_agent_metadata_token = sub_agent_parent_result_metadata.set(sub_agent_metadata)
|
|
429
|
+
|
|
430
|
+
web_progress_token = None
|
|
431
|
+
if get_tool_kind(context.function) in {KIND_WEB_SEARCH, KIND_WEB_FETCH}:
|
|
432
|
+
|
|
433
|
+
async def _emit_web_progress(lines: list[str]) -> None:
|
|
434
|
+
await self._bus.publish(
|
|
435
|
+
InvocationToolCallProgress(
|
|
436
|
+
origin=origin, tool_name=tool_name, call_id=call_id, session_id=self._session_id, lines=lines
|
|
437
|
+
)
|
|
438
|
+
)
|
|
439
|
+
|
|
440
|
+
web_progress_token = web_progress_callback.set(_emit_web_progress)
|
|
441
|
+
|
|
442
|
+
# Set up progress streaming for shell tools
|
|
443
|
+
progress_token = None
|
|
444
|
+
shell_metadata_token = None
|
|
445
|
+
shell_metadata: dict[str, object] | None = None
|
|
446
|
+
generic_metadata: dict[str, object] = {}
|
|
447
|
+
generic_metadata_token = tool_result_metadata.set(generic_metadata)
|
|
448
|
+
payload_observation: dict[str, object] = {}
|
|
449
|
+
payload_observation_token = tool_payload_observation.set(payload_observation)
|
|
450
|
+
if is_shell:
|
|
451
|
+
from chrys.service.tools.builtins.shell import shell_progress_callback, shell_result_metadata
|
|
452
|
+
|
|
453
|
+
bus = self._bus
|
|
454
|
+
sid = self._session_id
|
|
455
|
+
|
|
456
|
+
async def _emit_progress(lines: list[str]) -> None:
|
|
457
|
+
await bus.publish(
|
|
458
|
+
InvocationToolCallProgress(
|
|
459
|
+
origin=origin,
|
|
460
|
+
tool_name=tool_name,
|
|
461
|
+
call_id=call_id,
|
|
462
|
+
lines=lines,
|
|
463
|
+
session_id=sid,
|
|
464
|
+
)
|
|
465
|
+
)
|
|
466
|
+
|
|
467
|
+
progress_token = shell_progress_callback.set(_emit_progress)
|
|
468
|
+
shell_metadata = {}
|
|
469
|
+
shell_metadata_token = shell_result_metadata.set(shell_metadata)
|
|
470
|
+
|
|
471
|
+
started_at = datetime.now(UTC)
|
|
472
|
+
start = time.monotonic()
|
|
473
|
+
error_text = ""
|
|
474
|
+
errored = False
|
|
475
|
+
raised_error_kind: str | None = None
|
|
476
|
+
cancelled = False
|
|
477
|
+
tool_operation_token = bind_tool_operation(
|
|
478
|
+
trajectory.operation_id if trajectory is not None else tool_operation_id(_meta)
|
|
479
|
+
)
|
|
480
|
+
try:
|
|
481
|
+
if preamble is not None:
|
|
482
|
+
await preamble.finished(outcome=PreparationOutcome.HANDOFF)
|
|
483
|
+
# Inside the block that closes the operation: the start marker
|
|
484
|
+
# awaits its write ack, and an interrupt landing there would
|
|
485
|
+
# otherwise leave the operation open forever. Nothing between the
|
|
486
|
+
# trace and here awaits, so the marker still precedes the call.
|
|
487
|
+
if trajectory is not None:
|
|
488
|
+
await trajectory.started(
|
|
489
|
+
tool_name=tool_name,
|
|
490
|
+
tool_kind=tool_kind,
|
|
491
|
+
batch_index=self._intermediate_buffer.batch_id if self._intermediate_buffer is not None else None,
|
|
492
|
+
invocation_order=get_tool_invocation_order(context),
|
|
493
|
+
arguments=args,
|
|
494
|
+
invocation_metadata=_meta,
|
|
495
|
+
# Resolved again after the call for the persisted carriage;
|
|
496
|
+
# here it describes the call as dispatched, alongside the
|
|
497
|
+
# argument fingerprint of those same arguments.
|
|
498
|
+
tool_context=resolve_tool_call_context(context.function, args) or None,
|
|
499
|
+
preamble_operation_id=(
|
|
500
|
+
preamble.operation_id if preamble is not None and preamble.start_committed else None
|
|
501
|
+
),
|
|
502
|
+
)
|
|
503
|
+
await call_next()
|
|
504
|
+
except Exception as exc:
|
|
505
|
+
errored = True
|
|
506
|
+
raised_error_kind = type(exc).__name__
|
|
507
|
+
error_text = tool_card_error_text(exc)
|
|
508
|
+
raise
|
|
509
|
+
except BaseException:
|
|
510
|
+
# CancelledError (BaseException) — the agent task was cancelled by
|
|
511
|
+
# interrupt(). Don't publish InvocationToolCallResult; the TUI's
|
|
512
|
+
# cancel_running_tools() already marks all running widgets.
|
|
513
|
+
cancelled = True
|
|
514
|
+
raise
|
|
515
|
+
finally:
|
|
516
|
+
reset_tool_operation(tool_operation_token)
|
|
517
|
+
if web_progress_token is not None:
|
|
518
|
+
web_progress_callback.reset(web_progress_token)
|
|
519
|
+
if progress_token is not None:
|
|
520
|
+
from chrys.service.tools.builtins.shell import shell_progress_callback
|
|
521
|
+
|
|
522
|
+
shell_progress_callback.reset(progress_token)
|
|
523
|
+
if shell_metadata_token is not None:
|
|
524
|
+
from chrys.service.tools.builtins.shell import shell_result_metadata
|
|
525
|
+
|
|
526
|
+
shell_result_metadata.reset(shell_metadata_token)
|
|
527
|
+
tool_result_metadata.reset(generic_metadata_token)
|
|
528
|
+
tool_payload_observation.reset(payload_observation_token)
|
|
529
|
+
|
|
530
|
+
if sub_agent_token is not None:
|
|
531
|
+
from chrys.foundation.util.sub_agent_context import sub_agent_parent_call_id
|
|
532
|
+
|
|
533
|
+
sub_agent_parent_call_id.reset(sub_agent_token)
|
|
534
|
+
if sub_agent_metadata_token is not None:
|
|
535
|
+
from chrys.foundation.util.sub_agent_context import sub_agent_parent_result_metadata
|
|
536
|
+
|
|
537
|
+
sub_agent_parent_result_metadata.reset(sub_agent_metadata_token)
|
|
538
|
+
|
|
539
|
+
if not isinstance(context.metadata, dict):
|
|
540
|
+
context.metadata = {}
|
|
541
|
+
rejected = bool(context.metadata.get(_APPROVAL_REJECTED_KEY, False))
|
|
542
|
+
finished_at = datetime.now(UTC)
|
|
543
|
+
elapsed_ms = int((time.monotonic() - start) * 1000)
|
|
544
|
+
# A rejected call reports no duration to the UI — it never ran —
|
|
545
|
+
# but the operation was open for the whole approval wait, and
|
|
546
|
+
# that wait is the only thing that happened inside it.
|
|
547
|
+
duration_ms = 0 if rejected else elapsed_ms
|
|
548
|
+
stamp_trajectory_timing(
|
|
549
|
+
context.metadata,
|
|
550
|
+
build_trajectory_timing(
|
|
551
|
+
started_at=finished_at if rejected else started_at,
|
|
552
|
+
finished_at=finished_at,
|
|
553
|
+
duration_ms=duration_ms,
|
|
554
|
+
),
|
|
555
|
+
overwrite=True,
|
|
556
|
+
)
|
|
557
|
+
|
|
558
|
+
if cancelled and trajectory is not None:
|
|
559
|
+
# The task is unwinding from CancelledError: no further
|
|
560
|
+
# await is safe, so the operation closes without its ack.
|
|
561
|
+
trajectory.finished_soon(outcome=ToolOutcome.INTERRUPTED, duration_ms=elapsed_ms)
|
|
562
|
+
if cancelled and mut_ctx is not None:
|
|
563
|
+
# Cancelled tasks raise CancelledError at their next await,
|
|
564
|
+
# so the async finalize below is unreachable — release the
|
|
565
|
+
# trace wrapper and close the coordination window
|
|
566
|
+
# synchronously or the registry advertises a live command
|
|
567
|
+
# to peers until shutdown. The command may have written
|
|
568
|
+
# before the interrupt, so implicit detection is truncated.
|
|
569
|
+
abort_mutation_tracking(mut_ctx, self._mutation_coordinator, tracker=self._mutation_tracker)
|
|
570
|
+
if not cancelled:
|
|
571
|
+
try:
|
|
572
|
+
result_text = error_text or extract_result_text(context.result)
|
|
573
|
+
_meta = context.metadata
|
|
574
|
+
args = final_tool_args(context, args)
|
|
575
|
+
if rejected and mut_ctx is not None:
|
|
576
|
+
# Rejected at approval, post-prepare: finalize is
|
|
577
|
+
# deliberately skipped (the tool never executed), so
|
|
578
|
+
# release the trace wrapper and close the observation
|
|
579
|
+
# window here.
|
|
580
|
+
abort_mutation_tracking(mut_ctx, self._mutation_coordinator)
|
|
581
|
+
|
|
582
|
+
# Post-execution mutation tracking
|
|
583
|
+
metadata: dict[str, Any] = {}
|
|
584
|
+
metadata.update(generic_metadata)
|
|
585
|
+
if shell_metadata:
|
|
586
|
+
metadata.update(shell_metadata)
|
|
587
|
+
if not rejected and mut_ctx is not None:
|
|
588
|
+
# Authorship gate for coordination claims: structured
|
|
589
|
+
# "Error: ..." results (tool_error / record_tool_failure)
|
|
590
|
+
# mean the write may not have happened — the observed
|
|
591
|
+
# delta could be a peer racing our window. ``errored``
|
|
592
|
+
# only covers raised exceptions; the metadata failure
|
|
593
|
+
# state covers the no-raise failure paths.
|
|
594
|
+
tool_failed = errored or tool_result_metadata_failure_state(metadata) is True
|
|
595
|
+
try:
|
|
596
|
+
mut_result = await finalize_mutation_tracking(
|
|
597
|
+
self._mutation_tracker,
|
|
598
|
+
mut_ctx,
|
|
599
|
+
call_id,
|
|
600
|
+
coordinator=self._mutation_coordinator,
|
|
601
|
+
tool_errored=tool_failed,
|
|
602
|
+
)
|
|
603
|
+
except BaseException:
|
|
604
|
+
# An interrupt landing DURING finalize (git
|
|
605
|
+
# calibration, scans, and trace parsing are executor
|
|
606
|
+
# hops) bypasses both the cancel-path abort above
|
|
607
|
+
# (``cancelled`` only covers call_next) and
|
|
608
|
+
# finalize's own release — clean up synchronously.
|
|
609
|
+
# Idempotent after a partial finalize. The command
|
|
610
|
+
# ran; its aborted detection is truncated.
|
|
611
|
+
abort_mutation_tracking(mut_ctx, self._mutation_coordinator, tracker=self._mutation_tracker)
|
|
612
|
+
raise
|
|
613
|
+
if mut_result.file_snapshot is not None:
|
|
614
|
+
metadata["file_snapshot"] = mut_result.file_snapshot
|
|
615
|
+
if mut_result.file_operation is not None:
|
|
616
|
+
metadata["file_mutation_op"] = mut_result.file_operation
|
|
617
|
+
if mut_result.file_bytes_changed is not None:
|
|
618
|
+
metadata["file_bytes_changed"] = mut_result.file_bytes_changed
|
|
619
|
+
if mut_result.file_hashes is not None:
|
|
620
|
+
metadata["file_mutation_hashes"] = mut_result.file_hashes
|
|
621
|
+
if mut_result.shell_snapshots:
|
|
622
|
+
metadata["shell_file_snapshots"] = mut_result.shell_snapshots
|
|
623
|
+
if rejected:
|
|
624
|
+
metadata.update(rejection_result_metadata(_meta))
|
|
625
|
+
if isinstance(_meta, dict) and _meta.get(_SLEEP_SKIPPED_KEY, False):
|
|
626
|
+
metadata[RESULT_SLEEP_SKIPPED_METADATA_KEY] = True
|
|
627
|
+
if isinstance(_meta, dict) and _meta.get(_SLEEP_INTERRUPTED_KEY, False):
|
|
628
|
+
metadata[RESULT_SLEEP_INTERRUPTED_METADATA_KEY] = True
|
|
629
|
+
if sub_agent_metadata is not None:
|
|
630
|
+
if sub_agent_metadata.sub_agent_invocation_id:
|
|
631
|
+
metadata[RESULT_SUB_AGENT_INVOCATION_ID_METADATA_KEY] = (
|
|
632
|
+
sub_agent_metadata.sub_agent_invocation_id
|
|
633
|
+
)
|
|
634
|
+
if sub_agent_metadata.sub_agent_log_file:
|
|
635
|
+
metadata[RESULT_SUB_AGENT_LOG_FILE_METADATA_KEY] = sub_agent_metadata.sub_agent_log_file
|
|
636
|
+
if sub_agent_metadata.sub_agent_audit_complete:
|
|
637
|
+
metadata[RESULT_SUB_AGENT_AUDIT_COMPLETE_METADATA_KEY] = True
|
|
638
|
+
if sub_agent_metadata.transcript_final_text is not None:
|
|
639
|
+
metadata[SUB_AGENT_TRANSCRIPT_FINAL_TEXT_METADATA_KEY] = (
|
|
640
|
+
sub_agent_metadata.transcript_final_text
|
|
641
|
+
)
|
|
642
|
+
if errored:
|
|
643
|
+
metadata[TOOL_ERRORED_METADATA_KEY] = True
|
|
644
|
+
structured_failed = tool_result_metadata_failure_state(metadata) is True
|
|
645
|
+
source = rejection_source(_meta) if rejected else ""
|
|
646
|
+
# Carry result metadata and per-call provenance (resolved from
|
|
647
|
+
# the final args, so rejected/blocked calls whose tool body
|
|
648
|
+
# never ran still get it) on this invocation's context. The
|
|
649
|
+
# kernel folds both onto the right Contents at construction —
|
|
650
|
+
# no post-run positional re-association.
|
|
651
|
+
tool_context = resolve_tool_call_context(context.function, args)
|
|
652
|
+
write_result_carriage(context, metadata=metadata, tool_context=tool_context or None)
|
|
653
|
+
|
|
654
|
+
hook_decision = await fire_after_tool_hooks(
|
|
655
|
+
manager=self._hook_manager,
|
|
656
|
+
session_id=self._session_id,
|
|
657
|
+
profile_name=self._profile_name,
|
|
658
|
+
tool_name=tool_name,
|
|
659
|
+
kind=tool_kind,
|
|
660
|
+
call_id=call_id,
|
|
661
|
+
args=args,
|
|
662
|
+
result_text=result_text,
|
|
663
|
+
duration_ms=duration_ms,
|
|
664
|
+
errored=errored,
|
|
665
|
+
failed=structured_failed,
|
|
666
|
+
approval_rejected=rejected,
|
|
667
|
+
rejection_source=source,
|
|
668
|
+
workspace_cwd=self._workspace_cwd,
|
|
669
|
+
target_operation_id=trajectory.operation_id if trajectory is not None else None,
|
|
670
|
+
)
|
|
671
|
+
context.result, result_text = append_extra_context_to_result(
|
|
672
|
+
context.result,
|
|
673
|
+
result_text,
|
|
674
|
+
hook_decision.extra_context,
|
|
675
|
+
)
|
|
676
|
+
structured_error_kind = metadata.get(TOOL_ERROR_KIND_METADATA_KEY)
|
|
677
|
+
if not isinstance(context.metadata, dict):
|
|
678
|
+
context.metadata = {}
|
|
679
|
+
write_execution_stamp(
|
|
680
|
+
context.metadata,
|
|
681
|
+
context.arguments,
|
|
682
|
+
outcome="error" if errored or structured_failed else "ok",
|
|
683
|
+
error_kind=(
|
|
684
|
+
raised_error_kind
|
|
685
|
+
or (structured_error_kind if isinstance(structured_error_kind, str) else None)
|
|
686
|
+
),
|
|
687
|
+
)
|
|
688
|
+
result_images = extract_result_images(context.result)
|
|
689
|
+
await self._bus.publish(
|
|
690
|
+
InvocationToolCallResult(
|
|
691
|
+
origin=origin,
|
|
692
|
+
tool_name=tool_name,
|
|
693
|
+
call_id=call_id,
|
|
694
|
+
result=result_text,
|
|
695
|
+
image_contents=result_images,
|
|
696
|
+
duration_ms=duration_ms,
|
|
697
|
+
session_id=self._session_id,
|
|
698
|
+
metadata=metadata,
|
|
699
|
+
)
|
|
700
|
+
)
|
|
701
|
+
if trajectory is not None:
|
|
702
|
+
# The kernel's ceiling bounds the result after this
|
|
703
|
+
# middleware returns — including whatever the hooks
|
|
704
|
+
# just appended — so measure what it will leave, or
|
|
705
|
+
# the record describes text the model never saw. The
|
|
706
|
+
# same call is what tells the observation it was cut.
|
|
707
|
+
await trajectory.payload_observed(
|
|
708
|
+
result_text=preview_result_ceiling(
|
|
709
|
+
result_text,
|
|
710
|
+
self._tool_result_ceiling_tokens,
|
|
711
|
+
observation=payload_observation,
|
|
712
|
+
),
|
|
713
|
+
image_count=len(result_images),
|
|
714
|
+
observation=payload_observation,
|
|
715
|
+
)
|
|
716
|
+
await trajectory.finished(
|
|
717
|
+
outcome=tool_outcome(
|
|
718
|
+
cancelled=False,
|
|
719
|
+
rejected=rejected,
|
|
720
|
+
errored=errored,
|
|
721
|
+
result_metadata=metadata,
|
|
722
|
+
),
|
|
723
|
+
duration_ms=elapsed_ms,
|
|
724
|
+
result_metadata=metadata,
|
|
725
|
+
error_kind=raised_error_kind,
|
|
726
|
+
)
|
|
727
|
+
except BaseException:
|
|
728
|
+
# Interrupted while closing out a call that already ran:
|
|
729
|
+
# the operation is open, and only this path can close it.
|
|
730
|
+
if trajectory is not None:
|
|
731
|
+
trajectory.finished_soon(outcome=ToolOutcome.INTERRUPTED, duration_ms=elapsed_ms)
|
|
732
|
+
raise
|
|
733
|
+
|
|
734
|
+
def drain_batch_records(self) -> list[ToolBatchRecord]:
|
|
735
|
+
"""Return and clear batch records (one per tool invocation, in dispatch order)."""
|
|
736
|
+
records = list(self._tool_batch_records)
|
|
737
|
+
self._tool_batch_records.clear()
|
|
738
|
+
return records
|
|
739
|
+
|
|
740
|
+
def snapshot_retry_state(self) -> ToolEventRetrySnapshot:
|
|
741
|
+
"""Capture records that predate the retrying Agent.run."""
|
|
742
|
+
return ToolEventRetrySnapshot(
|
|
743
|
+
batch_records=tuple(self._tool_batch_records),
|
|
744
|
+
invocation_order=self._tool_invocation_order,
|
|
745
|
+
)
|
|
746
|
+
|
|
747
|
+
def restore_retry_state(self, snapshot: ToolEventRetrySnapshot) -> None:
|
|
748
|
+
"""Drop failed-attempt records while preserving the completed baseline."""
|
|
749
|
+
self._tool_batch_records = list(snapshot.batch_records)
|
|
750
|
+
self._tool_invocation_order = snapshot.invocation_order
|
|
751
|
+
|
|
752
|
+
def clear_batch_records(self) -> None:
|
|
753
|
+
"""Clear recorded batch records (called on history rollback).
|
|
754
|
+
|
|
755
|
+
A stale record surviving rollback carries a provider id that can
|
|
756
|
+
collide with the retried attempt's calls (sequential providers
|
|
757
|
+
reuse call_0-style ids per response) and would stamp wrong
|
|
758
|
+
``_batch_id``s after the retry.
|
|
759
|
+
"""
|
|
760
|
+
self._tool_batch_records.clear()
|
|
761
|
+
|
|
762
|
+
def reset_invocation_order(self) -> None:
|
|
763
|
+
"""Reset the per-run tool invocation order counter."""
|
|
764
|
+
self._tool_invocation_order = 0
|
|
765
|
+
|
|
766
|
+
|
|
767
|
+
def _file_lock_path(tool_name: str, args: dict[str, Any], workspace_cwd: str = "") -> str:
|
|
768
|
+
"""Return a file path for write/edit serialization, or empty when absent."""
|
|
769
|
+
if tool_name not in _FILE_TOOLS:
|
|
770
|
+
return ""
|
|
771
|
+
path = args.get("path")
|
|
772
|
+
if not isinstance(path, str) or not path:
|
|
773
|
+
return ""
|
|
774
|
+
return resolve_workspace_path(path, base_cwd=workspace_cwd or None)
|
|
775
|
+
|
|
776
|
+
|
|
777
|
+
def _uses_implicit_window(tool_name: str, tool_kind: str) -> bool:
|
|
778
|
+
"""Return whether a tool needs serialized implicit mutation observation."""
|
|
779
|
+
return tool_kind == KIND_SHELL or tool_name in _IMPLICIT_WRITE_TOOLS
|