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,85 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Exception-graph walks shared by the error classifier and formatter.
|
|
4
|
+
|
|
5
|
+
Two walks with different trust:
|
|
6
|
+
|
|
7
|
+
* :func:`iter_full_chain` follows ``__cause__`` and unsuppressed
|
|
8
|
+
``__context__``. Implicit context can be stale — an exception that was
|
|
9
|
+
being handled when a fresh request failed — so only the legacy retry layers
|
|
10
|
+
and the owner-terminal veto read it.
|
|
11
|
+
* :func:`iter_explicit_graph` follows only edges a raiser set on purpose:
|
|
12
|
+
``__cause__``, exceptions held in ``args`` (httpcore keeps its root cause in
|
|
13
|
+
``args[0]`` after ``raise ... from None``; ``ChatClientException`` keeps its
|
|
14
|
+
inner exception in ``args[1]``) and exception-group members. It never
|
|
15
|
+
follows ``__context__`` and does not descend below a node whose request got
|
|
16
|
+
an HTTP response: anything deeper belongs to response processing, not to
|
|
17
|
+
this request's failure. Every classification rule other than the legacy
|
|
18
|
+
layers reads this walk.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
from collections.abc import Iterator
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def iter_full_chain(exc: BaseException, *, unwrap_single_groups: bool = False) -> Iterator[BaseException]:
|
|
27
|
+
"""Yield an exception and its explicit/implicit cause chain."""
|
|
28
|
+
seen: set[int] = set()
|
|
29
|
+
cur: BaseException | None = exc
|
|
30
|
+
while cur is not None and id(cur) not in seen:
|
|
31
|
+
yield cur
|
|
32
|
+
seen.add(id(cur))
|
|
33
|
+
if unwrap_single_groups and isinstance(cur, BaseExceptionGroup) and len(cur.exceptions) == 1:
|
|
34
|
+
cur = cur.exceptions[0]
|
|
35
|
+
else:
|
|
36
|
+
cur = (
|
|
37
|
+
cur.__cause__ if cur.__cause__ is not None else (None if cur.__suppress_context__ else cur.__context__)
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def has_response_status(exc: BaseException) -> bool:
|
|
42
|
+
"""Return whether *exc* proves that its request received an HTTP response."""
|
|
43
|
+
if getattr(exc, "status_code", None) is not None:
|
|
44
|
+
return True
|
|
45
|
+
response = getattr(exc, "response", None)
|
|
46
|
+
return response is not None and getattr(response, "status_code", None) is not None
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def explicit_children(exc: BaseException) -> list[BaseException]:
|
|
50
|
+
"""Return *exc*'s explicit children: cause, exceptions in ``args``, group members."""
|
|
51
|
+
children: list[BaseException] = []
|
|
52
|
+
if exc.__cause__ is not None:
|
|
53
|
+
children.append(exc.__cause__)
|
|
54
|
+
children.extend(arg for arg in exc.args if isinstance(arg, BaseException))
|
|
55
|
+
if isinstance(exc, BaseExceptionGroup):
|
|
56
|
+
children.extend(exc.exceptions)
|
|
57
|
+
return children
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def iter_explicit_graph(exc: BaseException) -> Iterator[BaseException]:
|
|
61
|
+
"""Yield *exc* and its explicit causes depth-first, pre-order.
|
|
62
|
+
|
|
63
|
+
Children are visited cause first, then exceptions in ``args``, then group
|
|
64
|
+
members. Each exception is yielded once, so cycles terminate.
|
|
65
|
+
"""
|
|
66
|
+
seen: set[int] = set()
|
|
67
|
+
stack: list[BaseException] = [exc]
|
|
68
|
+
while stack:
|
|
69
|
+
node = stack.pop()
|
|
70
|
+
if id(node) in seen:
|
|
71
|
+
continue
|
|
72
|
+
seen.add(id(node))
|
|
73
|
+
yield node
|
|
74
|
+
if has_response_status(node):
|
|
75
|
+
continue
|
|
76
|
+
stack.extend(reversed(explicit_children(node)))
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def request_of(exc: BaseException) -> object | None:
|
|
80
|
+
"""Return the HTTP request an SDK or httpx exception carries, if any."""
|
|
81
|
+
try:
|
|
82
|
+
# httpx raises RuntimeError from ``.request`` when none was attached.
|
|
83
|
+
return getattr(exc, "request", None)
|
|
84
|
+
except RuntimeError:
|
|
85
|
+
return None
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""The one error classifier: kind and retry decision from one pass.
|
|
4
|
+
|
|
5
|
+
Invariant: apart from the two legacy rules (the owner-terminal veto and the
|
|
6
|
+
transient layers), everything that sets ``kind`` or overrides ``retryable``
|
|
7
|
+
reads only the explicit graph (:func:`iter_explicit_graph`). An exception
|
|
8
|
+
left in ``__context__`` from an earlier request — a stale 413 or quota error
|
|
9
|
+
being handled when a fresh request failed — can neither steer the retry
|
|
10
|
+
decision nor the kind shown to the user.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from dataclasses import dataclass
|
|
16
|
+
|
|
17
|
+
from . import _legacy
|
|
18
|
+
from ._text import _clean_exception_text
|
|
19
|
+
from ._walk import iter_explicit_graph, iter_full_chain
|
|
20
|
+
from .kinds import ErrorKind, TimeoutPhase
|
|
21
|
+
from .network import NetworkFailure, classify_connection_failure
|
|
22
|
+
from .provider import (
|
|
23
|
+
ContinuationVerdictError,
|
|
24
|
+
ProviderResponseError,
|
|
25
|
+
ProviderSignal,
|
|
26
|
+
in_band_failure_retryable,
|
|
27
|
+
is_2xx,
|
|
28
|
+
named_context_limit,
|
|
29
|
+
names_context_overflow,
|
|
30
|
+
names_server_error_overflow,
|
|
31
|
+
provider_signal,
|
|
32
|
+
signal_kind,
|
|
33
|
+
status_kind,
|
|
34
|
+
stream_error_retryable,
|
|
35
|
+
)
|
|
36
|
+
from .route import RouteFacts, route_of
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass(frozen=True, slots=True)
|
|
40
|
+
class ErrorClassification:
|
|
41
|
+
"""What an exception means for retry policy and for the user."""
|
|
42
|
+
|
|
43
|
+
kind: ErrorKind
|
|
44
|
+
retryable: bool
|
|
45
|
+
signal: ProviderSignal | None = None
|
|
46
|
+
timeout_phase: TimeoutPhase | None = None
|
|
47
|
+
# The failed request's route snapshot, when its client stamped one.
|
|
48
|
+
route: RouteFacts | None = None
|
|
49
|
+
# A TCP or DNS answer shows the first hop (the proxy, or the target when
|
|
50
|
+
# direct) itself failed.
|
|
51
|
+
failed_at_first_hop: bool = False
|
|
52
|
+
# The model service itself answered: only the LLM client stamps a route,
|
|
53
|
+
# and model-response types are raised only for its responses. Another
|
|
54
|
+
# client's HTTP status (an MCP server's 401) classifies the same way but
|
|
55
|
+
# says nothing about the model service.
|
|
56
|
+
from_model_service: bool = False
|
|
57
|
+
invalidates_continuation_token: bool = False
|
|
58
|
+
# Log-only trace of the deciding evidence, e.g. ``"http 429"``.
|
|
59
|
+
evidence: str = ""
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# Matched by class name anywhere in the MRO: the owning classes live in
|
|
63
|
+
# higher tiers than foundation.
|
|
64
|
+
_TYPE_KINDS = (
|
|
65
|
+
(frozenset({"StreamStall", "StreamStallExhausted"}), ErrorKind.STREAM_STALLED),
|
|
66
|
+
(frozenset({"ChatClientContentFilterException", "AgentContentFilterException"}), ErrorKind.CONTENT_FILTERED),
|
|
67
|
+
(
|
|
68
|
+
frozenset({"ChatClientInvalidResponseException", "AgentInvalidResponseException", "ResponseValidationError"}),
|
|
69
|
+
ErrorKind.INVALID_RESPONSE,
|
|
70
|
+
),
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# httpx and httpcore timeouts, by class name.
|
|
74
|
+
_TIMEOUT_PHASES: dict[str, TimeoutPhase] = {
|
|
75
|
+
"ConnectTimeout": "connect",
|
|
76
|
+
"WriteTimeout": "write",
|
|
77
|
+
"ReadTimeout": "read",
|
|
78
|
+
"PoolTimeout": "pool",
|
|
79
|
+
}
|
|
80
|
+
_TIMEOUT_MODULES = frozenset({"httpx", "httpcore"})
|
|
81
|
+
|
|
82
|
+
# What Anthropic says when replayed thinking no longer matches the conversation before it.
|
|
83
|
+
_THINKING_BINDING_PHRASE = "bound to a different conversation"
|
|
84
|
+
|
|
85
|
+
# Kinds no retry can fix, whatever the transient layers say.
|
|
86
|
+
_NON_RETRYABLE_KINDS = frozenset({ErrorKind.QUOTA_EXHAUSTED, ErrorKind.CONTEXT_OVERFLOW, ErrorKind.PAYLOAD_TOO_LARGE})
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _status_code(exc: BaseException) -> int | None:
|
|
90
|
+
status = getattr(exc, "status_code", None)
|
|
91
|
+
if isinstance(status, int):
|
|
92
|
+
return status
|
|
93
|
+
response = getattr(exc, "response", None)
|
|
94
|
+
status = getattr(response, "status_code", None) if response is not None else None
|
|
95
|
+
return status if isinstance(status, int) else None
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _type_kind(exc: BaseException) -> ErrorKind | None:
|
|
99
|
+
names = {cls.__name__ for cls in type(exc).__mro__}
|
|
100
|
+
return next((kind for type_names, kind in _TYPE_KINDS if names & type_names), None)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _timeout_phase(exc: BaseException) -> TimeoutPhase | None:
|
|
104
|
+
for cls in type(exc).__mro__:
|
|
105
|
+
if cls.__module__.partition(".")[0] in _TIMEOUT_MODULES and cls.__name__ in _TIMEOUT_PHASES:
|
|
106
|
+
return _TIMEOUT_PHASES[cls.__name__]
|
|
107
|
+
return None
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _first_timeout_phase(explicit: tuple[BaseException, ...]) -> TimeoutPhase | None:
|
|
111
|
+
return next((phase for node in explicit if (phase := _timeout_phase(node)) is not None), None)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def _explicit_kind(
|
|
115
|
+
explicit: tuple[BaseException, ...],
|
|
116
|
+
signal: ProviderSignal | None,
|
|
117
|
+
network: NetworkFailure | None,
|
|
118
|
+
overflow: bool,
|
|
119
|
+
) -> tuple[ErrorKind, str]:
|
|
120
|
+
"""Return the kind explicit evidence names: provider signal, then network leaf, then node types."""
|
|
121
|
+
if overflow:
|
|
122
|
+
return ErrorKind.CONTEXT_OVERFLOW, "context overflow"
|
|
123
|
+
if signal is not None:
|
|
124
|
+
kind, evidence = signal_kind(signal)
|
|
125
|
+
if kind is not ErrorKind.UNKNOWN:
|
|
126
|
+
return kind, evidence
|
|
127
|
+
if network is not None and network.kind is not ErrorKind.UNKNOWN:
|
|
128
|
+
return network.kind, network.evidence
|
|
129
|
+
for node in explicit:
|
|
130
|
+
if node is not (signal.source if signal is not None else None) and (status := _status_code(node)) is not None:
|
|
131
|
+
return status_kind(status), f"http {status}"
|
|
132
|
+
if (kind := _type_kind(node)) is not None:
|
|
133
|
+
return kind, f"type {type(node).__name__}"
|
|
134
|
+
return ErrorKind.UNKNOWN, ""
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def _from_model_service(explicit: tuple[BaseException, ...], route: RouteFacts | None) -> bool:
|
|
138
|
+
return route is not None or any(
|
|
139
|
+
isinstance(node, ProviderResponseError) or _type_kind(node) is not None for node in explicit
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def _invalidates_continuation_token(explicit: tuple[BaseException, ...]) -> bool:
|
|
144
|
+
return any(isinstance(node, ContinuationVerdictError) and node.invalidates_continuation_token for node in explicit)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def classify_error(exc: BaseException) -> ErrorClassification:
|
|
148
|
+
"""Classify *exc* for retry policy and display."""
|
|
149
|
+
explicit = tuple(iter_explicit_graph(exc))
|
|
150
|
+
route = route_of(explicit)
|
|
151
|
+
signal = provider_signal(explicit)
|
|
152
|
+
network = classify_connection_failure(exc, route)
|
|
153
|
+
overflow = names_context_overflow(
|
|
154
|
+
signal, (_clean_exception_text(node) for node in explicit if _type_kind(node) is None)
|
|
155
|
+
)
|
|
156
|
+
kind, evidence = _explicit_kind(explicit, signal, network, overflow)
|
|
157
|
+
# The full chain feeds only the frozen legacy layers.
|
|
158
|
+
full = tuple(iter_full_chain(exc))
|
|
159
|
+
if _legacy.is_owner_terminal(full):
|
|
160
|
+
retryable = False
|
|
161
|
+
elif signal is not None and signal.explicit_retryable is not None:
|
|
162
|
+
retryable = signal.explicit_retryable
|
|
163
|
+
elif (
|
|
164
|
+
(network is not None and network.deterministic)
|
|
165
|
+
or kind in _NON_RETRYABLE_KINDS
|
|
166
|
+
or _names_a_final_in_band_failure(signal)
|
|
167
|
+
):
|
|
168
|
+
retryable = False
|
|
169
|
+
elif signal is not None and is_2xx(signal.status_code):
|
|
170
|
+
retryable = stream_error_retryable(signal)
|
|
171
|
+
else:
|
|
172
|
+
# The legacy owner and deterministic vetoes were both decided above.
|
|
173
|
+
retryable = _legacy.is_transient(full)
|
|
174
|
+
return ErrorClassification(
|
|
175
|
+
kind=kind,
|
|
176
|
+
retryable=retryable,
|
|
177
|
+
signal=signal,
|
|
178
|
+
timeout_phase=(network.timeout_phase if network is not None else None) or _first_timeout_phase(explicit),
|
|
179
|
+
route=route,
|
|
180
|
+
failed_at_first_hop=network is not None and network.first_hop_evidence,
|
|
181
|
+
from_model_service=_from_model_service(explicit, route),
|
|
182
|
+
invalidates_continuation_token=_invalidates_continuation_token(explicit),
|
|
183
|
+
evidence=evidence,
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def _names_a_final_in_band_failure(signal: ProviderSignal | None) -> bool:
|
|
188
|
+
"""Whether *signal* is an error a stream reported in-band whose code a retry meets again.
|
|
189
|
+
|
|
190
|
+
The OpenAI SDK raises an error event inside a stream as a bare
|
|
191
|
+
``APIError`` with no status: its code gets the verdict an adapter gives
|
|
192
|
+
the same failure (:func:`in_band_failure_retryable`). A veto only: an
|
|
193
|
+
unknown code keeps the retry it had.
|
|
194
|
+
"""
|
|
195
|
+
return (
|
|
196
|
+
signal is not None
|
|
197
|
+
and signal.status_code is None
|
|
198
|
+
and signal.code is not None
|
|
199
|
+
and not in_band_failure_retryable(signal.code)
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def is_retryable(e: BaseException) -> bool:
|
|
204
|
+
"""Check if an exception is a transient error worth retrying."""
|
|
205
|
+
return classify_error(e).retryable
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def is_context_overflow(exc: BaseException) -> bool:
|
|
209
|
+
"""Return whether the provider rejected the request for exceeding the context window.
|
|
210
|
+
|
|
211
|
+
``request_too_large`` / 413 is an oversized payload, not an overflow.
|
|
212
|
+
"""
|
|
213
|
+
return classify_error(exc).kind is ErrorKind.CONTEXT_OVERFLOW
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def is_thinking_binding_rejection(exc: BaseException) -> bool:
|
|
217
|
+
"""Return whether Anthropic refused replayed thinking as bound to a different conversation.
|
|
218
|
+
|
|
219
|
+
The service binds each signed thinking block to the request before it and
|
|
220
|
+
answers a changed one with a 400 ``invalid_request_error`` saying so. All
|
|
221
|
+
three are read from the one provider signal: a gateway that rewrites the
|
|
222
|
+
text is missed rather than every invalid request caught. The text may
|
|
223
|
+
also name the context window, so *exc* can be an overflow as well.
|
|
224
|
+
"""
|
|
225
|
+
signal = classify_error(exc).signal
|
|
226
|
+
return (
|
|
227
|
+
signal is not None
|
|
228
|
+
and signal.status_code == 400
|
|
229
|
+
and signal.error_type == "invalid_request_error"
|
|
230
|
+
and signal.message is not None
|
|
231
|
+
and _THINKING_BINDING_PHRASE in signal.message
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def context_overflow_limit(exc: BaseException) -> int | None:
|
|
236
|
+
"""Return the window limit, in tokens, the provider named when it rejected the request as too long.
|
|
237
|
+
|
|
238
|
+
Read only from the text that made *exc* an overflow: the provider
|
|
239
|
+
signal's own, or without one the explicit nodes' (never ``__context__``).
|
|
240
|
+
None when *exc* is no overflow or names no single positive limit.
|
|
241
|
+
"""
|
|
242
|
+
result = classify_error(exc)
|
|
243
|
+
if result.kind is not ErrorKind.CONTEXT_OVERFLOW:
|
|
244
|
+
return None
|
|
245
|
+
if (signal := result.signal) is not None:
|
|
246
|
+
return named_context_limit((signal.message or "", _clean_exception_text(signal.source)))
|
|
247
|
+
return named_context_limit(
|
|
248
|
+
_clean_exception_text(node) for node in iter_explicit_graph(exc) if _type_kind(node) is None
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def may_be_context_overflow(exc: BaseException) -> bool:
|
|
253
|
+
"""Return whether *exc* is, or may be, a context-window rejection.
|
|
254
|
+
|
|
255
|
+
Only for a caller whose false positive merely shrinks its input, such as
|
|
256
|
+
compaction's last-words shrink sequence: beyond :func:`is_context_overflow`,
|
|
257
|
+
a 5xx whose text names the context window counts, since a gateway may wrap
|
|
258
|
+
an overflow in one. Retry policy, display and the main turn use
|
|
259
|
+
:func:`is_context_overflow`, which leaves that 5xx retryable.
|
|
260
|
+
"""
|
|
261
|
+
classification = classify_error(exc)
|
|
262
|
+
if classification.kind is ErrorKind.CONTEXT_OVERFLOW:
|
|
263
|
+
return True
|
|
264
|
+
return classification.signal is not None and names_server_error_overflow(classification.signal)
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def invalidates_continuation_token(exc: BaseException) -> bool:
|
|
268
|
+
"""Return whether *exc* judged a terminal response, so a retry must not re-poll it.
|
|
269
|
+
|
|
270
|
+
A type check over the explicit graph alone: every failed wire call asks,
|
|
271
|
+
and the retry policy classifies separately.
|
|
272
|
+
"""
|
|
273
|
+
return _invalidates_continuation_token(tuple(iter_explicit_graph(exc)))
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def is_read_timeout(exc: BaseException) -> bool:
|
|
277
|
+
"""Return whether *exc* is a read timeout (connect, write and pool timeouts aren't)."""
|
|
278
|
+
return classify_error(exc).timeout_phase == "read"
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""What a classified error means to the user, as locale-neutral display messages.
|
|
4
|
+
|
|
5
|
+
Producers attach :func:`display_fields` to failure events; frontends render
|
|
6
|
+
the message and hint in the current locale and join them with
|
|
7
|
+
:data:`DISPLAY_WITH_HINT`. The raw English text (``clean_error_message``)
|
|
8
|
+
stays on the event for the model, logs, ACP and the detail line. Kinds with
|
|
9
|
+
nothing more useful to say than the raw text (a rejected request, an invalid
|
|
10
|
+
response, an unknown failure) describe as None, and so does any failure the
|
|
11
|
+
model service didn't answer: a network failure without a route snapshot (only
|
|
12
|
+
the LLM client stamps one) or another client's HTTP status.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import logging
|
|
18
|
+
from collections.abc import Callable
|
|
19
|
+
from dataclasses import dataclass
|
|
20
|
+
|
|
21
|
+
from chrys.foundation.branding import APP_DISPLAY_NAME
|
|
22
|
+
from chrys.foundation.i18n import MessageDef, MessageRef, msg
|
|
23
|
+
from chrys.foundation.net.route_probe import default_route_available, is_local_target
|
|
24
|
+
|
|
25
|
+
from .classify import ErrorClassification, classify_error, context_overflow_limit
|
|
26
|
+
from .kinds import NETWORK_KINDS, ErrorKind
|
|
27
|
+
from .route import Origin
|
|
28
|
+
|
|
29
|
+
logger = logging.getLogger(__name__)
|
|
30
|
+
|
|
31
|
+
_NO_ROUTE = msg(
|
|
32
|
+
"error.kind.no_route",
|
|
33
|
+
fallback="Can't reach the network: there is no route to {host}. Check your network connection or VPN.",
|
|
34
|
+
)
|
|
35
|
+
_DNS_FAILED = msg(
|
|
36
|
+
"error.kind.dns_failed",
|
|
37
|
+
fallback=(
|
|
38
|
+
"Can't resolve {host}. Check your network connection and DNS; "
|
|
39
|
+
"if the address is wrong, fix the base URL in the model profile."
|
|
40
|
+
),
|
|
41
|
+
)
|
|
42
|
+
_HOST_UNREACHABLE = msg(
|
|
43
|
+
"error.kind.host_unreachable",
|
|
44
|
+
fallback="Can't reach {host}: the host is unreachable. Check your network, VPN, or firewall.",
|
|
45
|
+
)
|
|
46
|
+
_CONNECTION_REFUSED = msg(
|
|
47
|
+
"error.kind.connection_refused",
|
|
48
|
+
fallback="{host} refused the connection. Check the address and port, and that the service is running.",
|
|
49
|
+
)
|
|
50
|
+
_CONNECT_TIMEOUT = msg(
|
|
51
|
+
"error.kind.connect_timeout", fallback="Connecting to {host} timed out. Check your network and firewall."
|
|
52
|
+
)
|
|
53
|
+
_CONNECTION_FAILED = msg(
|
|
54
|
+
"error.kind.connection_failed", fallback="Couldn't connect to {host}. Check your network connection."
|
|
55
|
+
)
|
|
56
|
+
_CONNECTION_LOST = msg("error.kind.connection_lost", fallback="The connection to {host} was interrupted.")
|
|
57
|
+
_READ_TIMEOUT = msg("error.kind.read_timeout", fallback="Timed out waiting for a response from {host}.")
|
|
58
|
+
_WRITE_TIMEOUT = msg("error.kind.write_timeout", fallback="Timed out sending the request to {host}.")
|
|
59
|
+
_NETWORK_GENERIC = msg(
|
|
60
|
+
"error.kind.network_generic",
|
|
61
|
+
fallback="Couldn't connect to the model service. Check your network and proxy settings.",
|
|
62
|
+
)
|
|
63
|
+
_PROXY_UNREACHABLE = msg(
|
|
64
|
+
"error.kind.proxy_unreachable",
|
|
65
|
+
fallback=(
|
|
66
|
+
"Can't connect to the proxy {proxy}. Check that the proxy is running and configured correctly, "
|
|
67
|
+
'or turn on "Bypass proxy" in the model profile.'
|
|
68
|
+
),
|
|
69
|
+
)
|
|
70
|
+
_PROXY_REJECTED = msg("error.kind.proxy_rejected", fallback="The proxy {proxy} couldn't connect to {host}.")
|
|
71
|
+
_VIA_PROXY_FAILED = msg(
|
|
72
|
+
"error.kind.via_proxy_failed",
|
|
73
|
+
fallback="Connecting to {host} through the proxy {proxy} failed. Check the proxy and your network connection.",
|
|
74
|
+
)
|
|
75
|
+
_PROXY_AUTH_FAILED = msg(
|
|
76
|
+
"error.kind.proxy_auth_failed",
|
|
77
|
+
fallback="The proxy {proxy} requires authentication or rejected the credentials.",
|
|
78
|
+
)
|
|
79
|
+
_TLS_FAILED = msg(
|
|
80
|
+
"error.kind.tls_failed",
|
|
81
|
+
fallback=(
|
|
82
|
+
"Couldn't establish a secure connection to {host}: the certificate isn't trusted or the protocol "
|
|
83
|
+
"doesn't match. On a corporate network, check the proxy certificate setup."
|
|
84
|
+
),
|
|
85
|
+
)
|
|
86
|
+
_INVALID_ENDPOINT = msg(
|
|
87
|
+
"error.kind.invalid_endpoint",
|
|
88
|
+
fallback="The service address is invalid. Check the base URL in the model profile.",
|
|
89
|
+
)
|
|
90
|
+
_RATE_LIMITED = msg("error.kind.rate_limited", fallback="The model service is rate limiting requests.")
|
|
91
|
+
_QUOTA_EXHAUSTED = msg(
|
|
92
|
+
"error.kind.quota_exhausted",
|
|
93
|
+
fallback="The model service account is out of quota or credit. Check the account and try again.",
|
|
94
|
+
)
|
|
95
|
+
_OVERLOADED = msg("error.kind.overloaded", fallback="The model service is overloaded.")
|
|
96
|
+
_SERVER_ERROR = msg("error.kind.server_error", fallback="The model service returned an internal error.")
|
|
97
|
+
_CONTEXT_OVERFLOW = msg(
|
|
98
|
+
"error.kind.context_overflow",
|
|
99
|
+
fallback=(
|
|
100
|
+
"The request exceeds the model's context window. "
|
|
101
|
+
"Check that the profile's context window matches the model's real one."
|
|
102
|
+
),
|
|
103
|
+
)
|
|
104
|
+
_CONTEXT_OVERFLOW_CONFIG_MISMATCH = msg(
|
|
105
|
+
"error.kind.context_overflow_config_mismatch",
|
|
106
|
+
fallback=(
|
|
107
|
+
"The model profile's maximum context window ({configured_max_context_tokens}) is larger than the server's "
|
|
108
|
+
'limit ({server_max_context_tokens}). Set "Max Context Window" in the model profile '
|
|
109
|
+
"to {server_max_context_tokens} or less."
|
|
110
|
+
),
|
|
111
|
+
)
|
|
112
|
+
_PAYLOAD_TOO_LARGE = msg(
|
|
113
|
+
"error.kind.payload_too_large",
|
|
114
|
+
fallback="The request is too large (for example, an image or attachment). Make it smaller and try again.",
|
|
115
|
+
)
|
|
116
|
+
_AUTH_FAILED = msg(
|
|
117
|
+
"error.kind.auth_failed",
|
|
118
|
+
fallback="The API key is invalid or lacks access. Check the API key in the model profile.",
|
|
119
|
+
)
|
|
120
|
+
_CONTENT_FILTERED = msg(
|
|
121
|
+
"error.kind.content_filtered", fallback="The model service's content filter blocked this request."
|
|
122
|
+
)
|
|
123
|
+
_STREAM_TRUNCATED = msg("error.kind.stream_truncated", fallback="The model's response was cut off.")
|
|
124
|
+
_STREAM_STALLED = msg("retry.stream_stalled", fallback="Stream stalled")
|
|
125
|
+
_CONTEXT_OVERFLOW_RESEND = msg(
|
|
126
|
+
"retry.context_overflow", fallback="The context window is full. Compacting the context before one retry."
|
|
127
|
+
)
|
|
128
|
+
# The probe checks the device {app} runs on: under ``icode serve`` that is the
|
|
129
|
+
# server, not the device showing the browser.
|
|
130
|
+
_MAYBE_OFFLINE = msg(
|
|
131
|
+
"error.hint.maybe_offline",
|
|
132
|
+
fallback="The device running {app} doesn't seem to have a network connection. Check it first.",
|
|
133
|
+
)
|
|
134
|
+
DISPLAY_WITH_HINT = msg("error.display.with_hint", fallback="{message} {hint}")
|
|
135
|
+
"""Joins a rendered message and its rendered hint; zh-Hans joins without a space."""
|
|
136
|
+
|
|
137
|
+
# Messages that name the target host. TLS keeps its own wording through a
|
|
138
|
+
# proxy: an untrusted certificate is usually the proxy's own.
|
|
139
|
+
_HOST_MESSAGES: dict[ErrorKind, MessageDef] = {
|
|
140
|
+
ErrorKind.NO_ROUTE: _NO_ROUTE,
|
|
141
|
+
ErrorKind.DNS_FAILED: _DNS_FAILED,
|
|
142
|
+
ErrorKind.HOST_UNREACHABLE: _HOST_UNREACHABLE,
|
|
143
|
+
ErrorKind.CONNECTION_REFUSED: _CONNECTION_REFUSED,
|
|
144
|
+
ErrorKind.CONNECT_TIMEOUT: _CONNECT_TIMEOUT,
|
|
145
|
+
ErrorKind.CONNECTION_FAILED: _CONNECTION_FAILED,
|
|
146
|
+
ErrorKind.CONNECTION_LOST: _CONNECTION_LOST,
|
|
147
|
+
ErrorKind.READ_TIMEOUT: _READ_TIMEOUT,
|
|
148
|
+
ErrorKind.WRITE_TIMEOUT: _WRITE_TIMEOUT,
|
|
149
|
+
ErrorKind.TLS_FAILED: _TLS_FAILED,
|
|
150
|
+
}
|
|
151
|
+
# The model service's own answers, shown only when it answered.
|
|
152
|
+
_HOSTLESS_MESSAGES: dict[ErrorKind, MessageDef] = {
|
|
153
|
+
ErrorKind.RATE_LIMITED: _RATE_LIMITED,
|
|
154
|
+
ErrorKind.QUOTA_EXHAUSTED: _QUOTA_EXHAUSTED,
|
|
155
|
+
ErrorKind.OVERLOADED: _OVERLOADED,
|
|
156
|
+
ErrorKind.SERVER_ERROR: _SERVER_ERROR,
|
|
157
|
+
ErrorKind.CONTEXT_OVERFLOW: _CONTEXT_OVERFLOW,
|
|
158
|
+
ErrorKind.PAYLOAD_TOO_LARGE: _PAYLOAD_TOO_LARGE,
|
|
159
|
+
ErrorKind.AUTH_FAILED: _AUTH_FAILED,
|
|
160
|
+
ErrorKind.CONTENT_FILTERED: _CONTENT_FILTERED,
|
|
161
|
+
ErrorKind.STREAM_TRUNCATED: _STREAM_TRUNCATED,
|
|
162
|
+
}
|
|
163
|
+
# Failures an offline machine produces; refused, unreachable and no-route
|
|
164
|
+
# already name their cause.
|
|
165
|
+
_PROBED_KINDS = frozenset({ErrorKind.DNS_FAILED, ErrorKind.CONNECT_TIMEOUT, ErrorKind.CONNECTION_FAILED})
|
|
166
|
+
_DEFAULT_PORTS = {"http": 80, "https": 443}
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
@dataclass(frozen=True, slots=True)
|
|
170
|
+
class ErrorDescription:
|
|
171
|
+
"""A classified error's display message, plus an optional hint shown after it."""
|
|
172
|
+
|
|
173
|
+
kind: ErrorKind
|
|
174
|
+
message: MessageRef
|
|
175
|
+
hint: MessageRef | None = None
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def _label(origin: Origin, *, with_port: bool) -> str:
|
|
179
|
+
host = f"[{origin.host}]" if ":" in origin.host else origin.host
|
|
180
|
+
return f"{host}:{origin.port}" if with_port else host
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def _host(origin: Origin) -> str:
|
|
184
|
+
"""The target as the user wrote it: the port only when it isn't the scheme's default."""
|
|
185
|
+
return _label(origin, with_port=_DEFAULT_PORTS.get(origin.scheme) != origin.port)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def _proxy(origin: Origin) -> str:
|
|
189
|
+
return _label(origin, with_port=True)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def _describe_network(result: ErrorClassification, route_probe: Callable[[], bool | None]) -> ErrorDescription | None:
|
|
193
|
+
kind = result.kind
|
|
194
|
+
route = result.route
|
|
195
|
+
if route is None:
|
|
196
|
+
return None
|
|
197
|
+
if kind is ErrorKind.INVALID_ENDPOINT:
|
|
198
|
+
return ErrorDescription(kind, _INVALID_ENDPOINT.bind())
|
|
199
|
+
host = _host(route.target)
|
|
200
|
+
if route.proxy is not None:
|
|
201
|
+
proxy = _proxy(route.proxy)
|
|
202
|
+
if kind is ErrorKind.PROXY_AUTH_FAILED:
|
|
203
|
+
return ErrorDescription(kind, _PROXY_AUTH_FAILED.bind(proxy=proxy))
|
|
204
|
+
if kind is ErrorKind.PROXY_REJECTED:
|
|
205
|
+
return ErrorDescription(kind, _PROXY_REJECTED.bind(host=host, proxy=proxy))
|
|
206
|
+
if result.failed_at_first_hop:
|
|
207
|
+
return ErrorDescription(kind, _PROXY_UNREACHABLE.bind(proxy=proxy))
|
|
208
|
+
if kind is ErrorKind.TLS_FAILED:
|
|
209
|
+
return ErrorDescription(kind, _TLS_FAILED.bind(host=host))
|
|
210
|
+
# Timeouts, a dropped tunnel, a lost connection: which hop failed is unknown.
|
|
211
|
+
return ErrorDescription(kind, _VIA_PROXY_FAILED.bind(host=host, proxy=proxy))
|
|
212
|
+
definition = _HOST_MESSAGES.get(kind)
|
|
213
|
+
if definition is None:
|
|
214
|
+
# A proxy verdict with no proxy on the route.
|
|
215
|
+
return ErrorDescription(kind, _NETWORK_GENERIC.bind())
|
|
216
|
+
hint = None
|
|
217
|
+
if kind in _PROBED_KINDS and not is_local_target(route.target.host) and route_probe() is False:
|
|
218
|
+
hint = _MAYBE_OFFLINE.bind(app=APP_DISPLAY_NAME)
|
|
219
|
+
return ErrorDescription(kind, definition.bind(host=host), hint)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def describe_error(
|
|
223
|
+
exc: BaseException,
|
|
224
|
+
*,
|
|
225
|
+
route_probe: Callable[[], bool | None] = default_route_available,
|
|
226
|
+
retry_notice: bool = False,
|
|
227
|
+
max_context_tokens: int | None = None,
|
|
228
|
+
) -> ErrorDescription | None:
|
|
229
|
+
"""Describe *exc* for the user, or None when the raw text is the best description.
|
|
230
|
+
|
|
231
|
+
*route_probe* runs only for a direct request to a public host that
|
|
232
|
+
failed to resolve or connect; it adds a hint and never changes the
|
|
233
|
+
message. A *retry_notice* also names a stalled stream; a paused
|
|
234
|
+
sub-agent's card already labels a stall by its pause reason. A retry
|
|
235
|
+
notice for a context overflow is the one resend after compacting.
|
|
236
|
+
*max_context_tokens*, the failed request's configured window, lets an
|
|
237
|
+
overflow whose provider names a smaller limit say which value to set.
|
|
238
|
+
"""
|
|
239
|
+
result = classify_error(exc)
|
|
240
|
+
kind = result.kind
|
|
241
|
+
if kind is ErrorKind.STREAM_STALLED and retry_notice:
|
|
242
|
+
return ErrorDescription(kind, _STREAM_STALLED.bind())
|
|
243
|
+
if kind is ErrorKind.CONTEXT_OVERFLOW and retry_notice:
|
|
244
|
+
return ErrorDescription(kind, _CONTEXT_OVERFLOW_RESEND.bind())
|
|
245
|
+
if (definition := _HOSTLESS_MESSAGES.get(kind)) is not None:
|
|
246
|
+
if not result.from_model_service:
|
|
247
|
+
return None
|
|
248
|
+
if kind is ErrorKind.CONTEXT_OVERFLOW and max_context_tokens is not None:
|
|
249
|
+
limit = context_overflow_limit(exc)
|
|
250
|
+
if limit is not None and limit < max_context_tokens:
|
|
251
|
+
return ErrorDescription(
|
|
252
|
+
kind,
|
|
253
|
+
_CONTEXT_OVERFLOW_CONFIG_MISMATCH.bind(
|
|
254
|
+
configured_max_context_tokens=max_context_tokens, server_max_context_tokens=limit
|
|
255
|
+
),
|
|
256
|
+
)
|
|
257
|
+
return ErrorDescription(kind, definition.bind())
|
|
258
|
+
if kind in NETWORK_KINDS:
|
|
259
|
+
return _describe_network(result, route_probe)
|
|
260
|
+
return None
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def display_fields(
|
|
264
|
+
exc: BaseException, *, retry_notice: bool = False, max_context_tokens: int | None = None
|
|
265
|
+
) -> tuple[MessageRef | None, MessageRef | None]:
|
|
266
|
+
"""Return ``(display_message, display_hint)`` for a failure event; ``(None, None)`` on any internal error."""
|
|
267
|
+
try:
|
|
268
|
+
description = describe_error(exc, retry_notice=retry_notice, max_context_tokens=max_context_tokens)
|
|
269
|
+
except Exception:
|
|
270
|
+
logger.debug("Describing an error for display failed", exc_info=True)
|
|
271
|
+
return None, None
|
|
272
|
+
if description is None:
|
|
273
|
+
return None, None
|
|
274
|
+
return description.message, description.hint
|