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,23 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Typed approval choices and presentation data; neither supplies authorization keys."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from typing import Literal
|
|
9
|
+
|
|
10
|
+
ReuseChoice = Literal["", "EXACT_SESSION", "EXACT_PROJECT", "PREFIX_SESSION", "PREFIX_PROJECT"]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True)
|
|
14
|
+
class ApprovalReuseOffer:
|
|
15
|
+
"""What a dialog may offer to remember.
|
|
16
|
+
|
|
17
|
+
``targets`` are the command or files shown; ``prefix`` says whether appended
|
|
18
|
+
arguments can also be allowed (literal simple commands only).
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
kind: Literal["command", "files"]
|
|
22
|
+
targets: tuple[str, ...]
|
|
23
|
+
prefix: bool = False
|
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Ask-user data model shared by service, orchestration, TUI and ACP layers."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from typing import TYPE_CHECKING, Final, cast
|
|
10
|
+
|
|
11
|
+
from chrys.foundation.util.unicode_scalars import find_unpaired_surrogate, replace_unpaired_surrogates
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from collections.abc import Sequence
|
|
15
|
+
|
|
16
|
+
MAX_ASK_USER_QUESTIONS: Final[int] = 5
|
|
17
|
+
MAX_ASK_USER_OPTIONS: Final[int] = 8
|
|
18
|
+
MAX_ASK_USER_QUESTION_CHARS: Final[int] = 10_000
|
|
19
|
+
MAX_ASK_USER_LABEL_CHARS: Final[int] = 200
|
|
20
|
+
MAX_ASK_USER_DESCRIPTION_CHARS: Final[int] = 500
|
|
21
|
+
MAX_ASK_USER_HEADER_CHARS: Final[int] = 64
|
|
22
|
+
|
|
23
|
+
_MAX_WIRE_PAYLOAD_BYTES = 1024 * 1024
|
|
24
|
+
_MAX_WIRE_PAYLOAD_DEPTH = 32
|
|
25
|
+
_MAX_WIRE_COLLECTION_ITEMS = 4_096
|
|
26
|
+
_MAX_WIRE_STRING_CHARS = 256 * 1024
|
|
27
|
+
_ASK_USER_INVISIBLE_OPTION_CHARS = dict.fromkeys((0x200B, 0x200C, 0x200D, 0x2060, 0xFEFF))
|
|
28
|
+
_REQUEST_INPUT_KEYS = frozenset({"sessionId", "requestId", "questions", "callerName", "_meta"})
|
|
29
|
+
_QUESTION_KEYS = frozenset({"question", "header", "options", "multiSelect"})
|
|
30
|
+
_OPTION_KEYS = frozenset({"label", "description"})
|
|
31
|
+
_RESPONSE_KEYS = frozenset({"answers", "cancelled", "_meta"})
|
|
32
|
+
_ANSWER_KEYS = frozenset({"values", "note"})
|
|
33
|
+
ASK_USER_META_COLLISION_KEYS: Final[frozenset[str]] = frozenset(
|
|
34
|
+
{
|
|
35
|
+
"answers",
|
|
36
|
+
"cancelled",
|
|
37
|
+
"callerName",
|
|
38
|
+
"questions",
|
|
39
|
+
"requestId",
|
|
40
|
+
"sessionId",
|
|
41
|
+
"session_id",
|
|
42
|
+
"toolCall",
|
|
43
|
+
"tool_call",
|
|
44
|
+
"kwargs",
|
|
45
|
+
"method",
|
|
46
|
+
"params",
|
|
47
|
+
}
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@dataclass(frozen=True, slots=True)
|
|
52
|
+
class AskUserOption:
|
|
53
|
+
"""One selectable answer offered to the user."""
|
|
54
|
+
|
|
55
|
+
label: str
|
|
56
|
+
description: str = ""
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@dataclass(frozen=True, slots=True)
|
|
60
|
+
class AskUserQuestion:
|
|
61
|
+
"""One question in an ask-user batch."""
|
|
62
|
+
|
|
63
|
+
question: str
|
|
64
|
+
header: str = ""
|
|
65
|
+
options: tuple[AskUserOption, ...] = ()
|
|
66
|
+
multi_select: bool = False
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@dataclass(frozen=True, slots=True)
|
|
70
|
+
class AskUserAnswer:
|
|
71
|
+
"""One positional answer to an :class:`AskUserQuestion`."""
|
|
72
|
+
|
|
73
|
+
values: tuple[str, ...] = ()
|
|
74
|
+
note: str = ""
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def answered(self) -> bool:
|
|
78
|
+
"""Return whether the user supplied a value or note."""
|
|
79
|
+
return bool(self.values) or bool(self.note)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@dataclass(frozen=True, slots=True)
|
|
83
|
+
class Cancelled:
|
|
84
|
+
"""Validated wire outcome indicating that no response was provided."""
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def normalize_ask_user_option_label(value: str) -> str:
|
|
88
|
+
"""Apply the historical ask-user option normalization used by the TUI."""
|
|
89
|
+
return value.translate(_ASK_USER_INVISIBLE_OPTION_CHARS).strip()
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _plain_string(value: object, *, strip: bool = False) -> str | None:
|
|
93
|
+
if not isinstance(value, str):
|
|
94
|
+
return None
|
|
95
|
+
# Model output decoded from JSON escapes can carry lone surrogates; they
|
|
96
|
+
# cannot cross the ACP wire or a strict UTF-8 write, so repair them here,
|
|
97
|
+
# the one place every question and answer string passes through.
|
|
98
|
+
text = replace_unpaired_surrogates(value if type(value) is str else str.__str__(value))
|
|
99
|
+
return text.strip() if strip else text
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _parse_option(raw: object) -> AskUserOption | None:
|
|
103
|
+
if isinstance(raw, str):
|
|
104
|
+
label = normalize_ask_user_option_label(_plain_string(raw) or "")
|
|
105
|
+
return AskUserOption(label=label) if label else None
|
|
106
|
+
if type(raw) is not dict:
|
|
107
|
+
return None
|
|
108
|
+
label_raw = raw.get("label")
|
|
109
|
+
label = normalize_ask_user_option_label(_plain_string(label_raw) or "")
|
|
110
|
+
if not label:
|
|
111
|
+
return None
|
|
112
|
+
description = _plain_string(raw.get("description")) or ""
|
|
113
|
+
return AskUserOption(label=label, description=description)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def _parse_question(raw: object) -> AskUserQuestion | None:
|
|
117
|
+
if type(raw) is not dict:
|
|
118
|
+
return None
|
|
119
|
+
question = _plain_string(raw.get("question"), strip=True)
|
|
120
|
+
if not question:
|
|
121
|
+
return None
|
|
122
|
+
header = _plain_string(raw.get("header")) or ""
|
|
123
|
+
options_raw = raw.get("options", [])
|
|
124
|
+
options: list[AskUserOption] = []
|
|
125
|
+
if type(options_raw) is list:
|
|
126
|
+
for option_raw in options_raw:
|
|
127
|
+
option = _parse_option(option_raw)
|
|
128
|
+
if option is not None:
|
|
129
|
+
options.append(option)
|
|
130
|
+
multi_select = raw.get("multi_select", raw.get("multiSelect", False))
|
|
131
|
+
return AskUserQuestion(
|
|
132
|
+
question=question,
|
|
133
|
+
header=header,
|
|
134
|
+
options=tuple(options),
|
|
135
|
+
multi_select=multi_select if type(multi_select) is bool else False,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def _parse_question_entries(raw_questions: object) -> tuple[AskUserQuestion, ...]:
|
|
140
|
+
if type(raw_questions) is not list:
|
|
141
|
+
return ()
|
|
142
|
+
questions: list[AskUserQuestion] = []
|
|
143
|
+
for entry in raw_questions:
|
|
144
|
+
question = _parse_question(entry)
|
|
145
|
+
if question is not None:
|
|
146
|
+
questions.append(question)
|
|
147
|
+
return tuple(questions)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def parse_ask_user_questions(raw: object) -> tuple[AskUserQuestion, ...]:
|
|
151
|
+
"""Tolerantly decode a ``questions`` list or an arguments dict; never raise."""
|
|
152
|
+
try:
|
|
153
|
+
if type(raw) is dict:
|
|
154
|
+
return _parse_question_entries(raw.get("questions"))
|
|
155
|
+
return _parse_question_entries(raw)
|
|
156
|
+
except Exception:
|
|
157
|
+
return ()
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def parse_recorded_ask_user_questions(raw: object) -> tuple[AskUserQuestion, ...]:
|
|
161
|
+
"""Decode recorded ask-user arguments for transcript replay; never raise.
|
|
162
|
+
|
|
163
|
+
Sessions recorded before the ``questions`` schema carry a single top-level
|
|
164
|
+
``question`` with plain-string ``options``. Only replay reads that shape;
|
|
165
|
+
live tool calls and the ACP wire accept ``questions`` alone.
|
|
166
|
+
"""
|
|
167
|
+
questions = parse_ask_user_questions(raw)
|
|
168
|
+
if questions or type(raw) is not dict:
|
|
169
|
+
return questions
|
|
170
|
+
try:
|
|
171
|
+
question = _plain_string(raw.get("question"), strip=True)
|
|
172
|
+
if not question:
|
|
173
|
+
return ()
|
|
174
|
+
return _parse_question_entries([{"question": question, "options": raw.get("options", [])}])
|
|
175
|
+
except Exception:
|
|
176
|
+
return ()
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def _repaired_answer(answer: AskUserAnswer) -> AskUserAnswer:
|
|
180
|
+
"""Return *answer* with every string passed through the surrogate repair."""
|
|
181
|
+
values = tuple(replace_unpaired_surrogates(value) for value in answer.values)
|
|
182
|
+
note = replace_unpaired_surrogates(answer.note)
|
|
183
|
+
if values == answer.values and note == answer.note:
|
|
184
|
+
return answer
|
|
185
|
+
return AskUserAnswer(values=values, note=note)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def parse_ask_user_answers(raw: object, *, question_count: int) -> tuple[AskUserAnswer, ...]:
|
|
189
|
+
"""Tolerantly decode answers, padding or dropping to fixed positional length."""
|
|
190
|
+
count = max(0, question_count)
|
|
191
|
+
answers: list[AskUserAnswer] = []
|
|
192
|
+
if type(raw) is list:
|
|
193
|
+
entries = cast("list[object]", raw)
|
|
194
|
+
elif type(raw) is tuple:
|
|
195
|
+
entries = raw
|
|
196
|
+
else:
|
|
197
|
+
entries = ()
|
|
198
|
+
if entries:
|
|
199
|
+
for entry in entries[:count]:
|
|
200
|
+
if isinstance(entry, AskUserAnswer):
|
|
201
|
+
answers.append(_repaired_answer(entry))
|
|
202
|
+
continue
|
|
203
|
+
if type(entry) is not dict:
|
|
204
|
+
answers.append(AskUserAnswer())
|
|
205
|
+
continue
|
|
206
|
+
values_raw = entry.get("values", [])
|
|
207
|
+
values: list[str] = []
|
|
208
|
+
if type(values_raw) is list:
|
|
209
|
+
value_entries = cast("list[object]", values_raw)
|
|
210
|
+
elif type(values_raw) is tuple:
|
|
211
|
+
value_entries = values_raw
|
|
212
|
+
else:
|
|
213
|
+
value_entries = ()
|
|
214
|
+
if value_entries:
|
|
215
|
+
for value in value_entries:
|
|
216
|
+
text = _plain_string(value)
|
|
217
|
+
if text is not None:
|
|
218
|
+
values.append(text)
|
|
219
|
+
note = _plain_string(entry.get("note")) or ""
|
|
220
|
+
answers.append(AskUserAnswer(values=tuple(values), note=note))
|
|
221
|
+
answers.extend(AskUserAnswer() for _ in range(count - len(answers)))
|
|
222
|
+
return tuple(answers)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def format_ask_user_result(
|
|
226
|
+
questions: tuple[AskUserQuestion, ...],
|
|
227
|
+
answers: tuple[AskUserAnswer, ...],
|
|
228
|
+
) -> str:
|
|
229
|
+
"""Format a lossless model-facing result for a completed ask-user call."""
|
|
230
|
+
normalized = parse_ask_user_answers(answers, question_count=len(questions))
|
|
231
|
+
if len(questions) == 1 and len(normalized[0].values) == 1 and not normalized[0].note:
|
|
232
|
+
return f"User response: {normalized[0].values[0]}"
|
|
233
|
+
responses: list[dict[str, object]] = []
|
|
234
|
+
for question, answer in zip(questions, normalized, strict=True):
|
|
235
|
+
entry: dict[str, object] = {
|
|
236
|
+
"question": question.question,
|
|
237
|
+
"answers": list(answer.values),
|
|
238
|
+
}
|
|
239
|
+
if answer.note:
|
|
240
|
+
entry["note"] = answer.note
|
|
241
|
+
if not answer.answered:
|
|
242
|
+
entry["unanswered"] = True
|
|
243
|
+
responses.append(entry)
|
|
244
|
+
return json.dumps({"responses": responses}, ensure_ascii=False, indent=2)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def _measure_wire_payload(value: object, *, depth: int = 0) -> tuple[int, int]:
|
|
248
|
+
if depth > _MAX_WIRE_PAYLOAD_DEPTH:
|
|
249
|
+
raise ValueError("ACP payload nesting is too deep.")
|
|
250
|
+
if isinstance(value, str):
|
|
251
|
+
if len(value) > _MAX_WIRE_STRING_CHARS:
|
|
252
|
+
raise ValueError("ACP payload string is too large.")
|
|
253
|
+
if find_unpaired_surrogate(value) >= 0:
|
|
254
|
+
raise ValueError("ACP payload string contains an unpaired surrogate.")
|
|
255
|
+
return len(value.encode("utf-8", errors="surrogatepass")), 1
|
|
256
|
+
if type(value) is dict:
|
|
257
|
+
if len(value) > _MAX_WIRE_COLLECTION_ITEMS:
|
|
258
|
+
raise ValueError("ACP payload object has too many fields.")
|
|
259
|
+
total = 0
|
|
260
|
+
items = 1
|
|
261
|
+
for key, item in value.items():
|
|
262
|
+
if type(key) is not str or len(key) > _MAX_WIRE_STRING_CHARS or find_unpaired_surrogate(key) >= 0:
|
|
263
|
+
raise ValueError("ACP payload has an invalid object key.")
|
|
264
|
+
total += len(key.encode("utf-8", errors="surrogatepass"))
|
|
265
|
+
child_bytes, child_items = _measure_wire_payload(item, depth=depth + 1)
|
|
266
|
+
total += child_bytes
|
|
267
|
+
items += child_items
|
|
268
|
+
return total, items
|
|
269
|
+
if type(value) is list:
|
|
270
|
+
sequence = cast("list[object]", value)
|
|
271
|
+
elif type(value) is tuple:
|
|
272
|
+
sequence = value
|
|
273
|
+
else:
|
|
274
|
+
sequence = None
|
|
275
|
+
if sequence is not None:
|
|
276
|
+
if len(sequence) > _MAX_WIRE_COLLECTION_ITEMS:
|
|
277
|
+
raise ValueError("ACP payload sequence has too many items.")
|
|
278
|
+
total = 0
|
|
279
|
+
items = 1
|
|
280
|
+
for item in sequence:
|
|
281
|
+
child_bytes, child_items = _measure_wire_payload(item, depth=depth + 1)
|
|
282
|
+
total += child_bytes
|
|
283
|
+
items += child_items
|
|
284
|
+
return total, items
|
|
285
|
+
return 16, 1
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def _validate_wire_payload_caps(value: object) -> None:
|
|
289
|
+
_total_bytes, total_items = _measure_wire_payload(value)
|
|
290
|
+
if total_items > _MAX_WIRE_COLLECTION_ITEMS:
|
|
291
|
+
raise ValueError("ACP payload has too many items in total.")
|
|
292
|
+
try:
|
|
293
|
+
encoded = json.dumps(value, ensure_ascii=True, separators=(",", ":")).encode("utf-8")
|
|
294
|
+
except (TypeError, ValueError, RecursionError) as exc:
|
|
295
|
+
raise ValueError("ACP payload is not JSON serializable.") from exc
|
|
296
|
+
if len(encoded) > _MAX_WIRE_PAYLOAD_BYTES:
|
|
297
|
+
raise ValueError("ACP retained payload exceeds the byte limit.")
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
def _validate_meta(meta: object) -> None:
|
|
301
|
+
if type(meta) is not dict or ASK_USER_META_COLLISION_KEYS.intersection(meta):
|
|
302
|
+
raise ValueError("Invalid request-input metadata.")
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
def _validate_question_caps(questions: tuple[AskUserQuestion, ...]) -> None:
|
|
306
|
+
if not questions or len(questions) > MAX_ASK_USER_QUESTIONS:
|
|
307
|
+
raise ValueError("Invalid request-input question count.")
|
|
308
|
+
for question in questions:
|
|
309
|
+
if not question.question.strip() or len(question.question) > MAX_ASK_USER_QUESTION_CHARS:
|
|
310
|
+
raise ValueError("Invalid request-input question.")
|
|
311
|
+
if len(question.header) > MAX_ASK_USER_HEADER_CHARS:
|
|
312
|
+
raise ValueError("Invalid request-input header.")
|
|
313
|
+
if len(question.options) > MAX_ASK_USER_OPTIONS:
|
|
314
|
+
raise ValueError("Invalid request-input option count.")
|
|
315
|
+
seen: set[str] = set()
|
|
316
|
+
for option in question.options:
|
|
317
|
+
if not option.label or len(option.label) > MAX_ASK_USER_LABEL_CHARS:
|
|
318
|
+
raise ValueError("Invalid request-input option label.")
|
|
319
|
+
if len(option.description) > MAX_ASK_USER_DESCRIPTION_CHARS:
|
|
320
|
+
raise ValueError("Invalid request-input option description.")
|
|
321
|
+
if option.label in seen:
|
|
322
|
+
raise ValueError("Duplicate request-input option label.")
|
|
323
|
+
seen.add(option.label)
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def validate_request_input_params(params: object) -> tuple[AskUserQuestion, ...]:
|
|
327
|
+
"""Strictly validate a ``chrys/request_input`` payload."""
|
|
328
|
+
_validate_wire_payload_caps(params)
|
|
329
|
+
if type(params) is not dict:
|
|
330
|
+
raise ValueError("Invalid request-input parameters.")
|
|
331
|
+
params_dict = cast("dict[str, object]", params)
|
|
332
|
+
if set(params_dict).difference(_REQUEST_INPUT_KEYS):
|
|
333
|
+
raise ValueError("Invalid request-input parameters.")
|
|
334
|
+
if not {"sessionId", "requestId", "questions"}.issubset(params_dict):
|
|
335
|
+
raise ValueError("Missing request-input parameters.")
|
|
336
|
+
if (
|
|
337
|
+
type(params_dict["sessionId"]) is not str
|
|
338
|
+
or type(params_dict["requestId"]) is not str
|
|
339
|
+
or (
|
|
340
|
+
"callerName" in params_dict
|
|
341
|
+
and params_dict["callerName"] is not None
|
|
342
|
+
and type(params_dict["callerName"]) is not str
|
|
343
|
+
)
|
|
344
|
+
):
|
|
345
|
+
raise ValueError("Invalid request-input parameter type.")
|
|
346
|
+
if "_meta" in params_dict:
|
|
347
|
+
_validate_meta(params_dict["_meta"])
|
|
348
|
+
|
|
349
|
+
raw_questions = params_dict["questions"]
|
|
350
|
+
if type(raw_questions) is not list:
|
|
351
|
+
raise ValueError("Invalid request-input questions.")
|
|
352
|
+
question_objects = cast("list[object]", raw_questions)
|
|
353
|
+
for raw_question in question_objects:
|
|
354
|
+
if type(raw_question) is not dict:
|
|
355
|
+
raise ValueError("Invalid request-input question object.")
|
|
356
|
+
question_dict = cast("dict[str, object]", raw_question)
|
|
357
|
+
if set(question_dict).difference(_QUESTION_KEYS):
|
|
358
|
+
raise ValueError("Invalid request-input question object.")
|
|
359
|
+
if type(question_dict.get("question")) is not str:
|
|
360
|
+
raise ValueError("Invalid request-input question text.")
|
|
361
|
+
if "header" in question_dict and type(question_dict["header"]) is not str:
|
|
362
|
+
raise ValueError("Invalid request-input question header.")
|
|
363
|
+
if "multiSelect" in question_dict and type(question_dict["multiSelect"]) is not bool:
|
|
364
|
+
raise ValueError("Invalid request-input multiSelect.")
|
|
365
|
+
question_options = question_dict.get("options", [])
|
|
366
|
+
if type(question_options) is not list:
|
|
367
|
+
raise ValueError("Invalid request-input question options.")
|
|
368
|
+
for raw_option in cast("list[object]", question_options):
|
|
369
|
+
if type(raw_option) is not dict:
|
|
370
|
+
raise ValueError("Invalid request-input option object.")
|
|
371
|
+
option_dict = cast("dict[str, object]", raw_option)
|
|
372
|
+
if set(option_dict).difference(_OPTION_KEYS):
|
|
373
|
+
raise ValueError("Invalid request-input option object.")
|
|
374
|
+
if type(option_dict.get("label")) is not str:
|
|
375
|
+
raise ValueError("Invalid request-input option label.")
|
|
376
|
+
if "description" in option_dict and type(option_dict["description"]) is not str:
|
|
377
|
+
raise ValueError("Invalid request-input option description.")
|
|
378
|
+
questions = parse_ask_user_questions(question_objects)
|
|
379
|
+
if len(questions) != len(question_objects):
|
|
380
|
+
raise ValueError("Invalid request-input question.")
|
|
381
|
+
_validate_question_caps(questions)
|
|
382
|
+
return questions
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
def validate_request_input_response(
|
|
386
|
+
payload: object,
|
|
387
|
+
*,
|
|
388
|
+
questions: tuple[AskUserQuestion, ...],
|
|
389
|
+
) -> tuple[AskUserAnswer, ...] | Cancelled:
|
|
390
|
+
"""Strictly validate a request-input response without partial fallback."""
|
|
391
|
+
try:
|
|
392
|
+
_validate_wire_payload_caps(payload)
|
|
393
|
+
except ValueError:
|
|
394
|
+
return Cancelled()
|
|
395
|
+
if type(payload) is not dict:
|
|
396
|
+
return Cancelled()
|
|
397
|
+
payload_dict = cast("dict[str, object]", payload)
|
|
398
|
+
if set(payload_dict).difference(_RESPONSE_KEYS):
|
|
399
|
+
return Cancelled()
|
|
400
|
+
if "_meta" in payload_dict:
|
|
401
|
+
try:
|
|
402
|
+
_validate_meta(payload_dict["_meta"])
|
|
403
|
+
except ValueError:
|
|
404
|
+
return Cancelled()
|
|
405
|
+
cancelled = payload_dict.get("cancelled", False)
|
|
406
|
+
if type(cancelled) is not bool:
|
|
407
|
+
return Cancelled()
|
|
408
|
+
if cancelled or "answers" not in payload_dict:
|
|
409
|
+
return Cancelled()
|
|
410
|
+
raw_answers = payload_dict["answers"]
|
|
411
|
+
if type(raw_answers) is not list:
|
|
412
|
+
return Cancelled()
|
|
413
|
+
answers: list[AskUserAnswer] = []
|
|
414
|
+
for raw_answer in cast("list[object]", raw_answers):
|
|
415
|
+
if type(raw_answer) is not dict:
|
|
416
|
+
return Cancelled()
|
|
417
|
+
answer_dict = cast("dict[str, object]", raw_answer)
|
|
418
|
+
if set(answer_dict).difference(_ANSWER_KEYS):
|
|
419
|
+
return Cancelled()
|
|
420
|
+
raw_values = answer_dict.get("values", [])
|
|
421
|
+
raw_note = answer_dict.get("note", "")
|
|
422
|
+
if type(raw_values) is not list or any(type(value) is not str for value in raw_values):
|
|
423
|
+
return Cancelled()
|
|
424
|
+
if type(raw_note) is not str:
|
|
425
|
+
return Cancelled()
|
|
426
|
+
answers.append(AskUserAnswer(values=tuple(cast("list[str]", raw_values)), note=raw_note))
|
|
427
|
+
validated = validate_ask_user_answers(tuple(answers), questions=questions)
|
|
428
|
+
return Cancelled() if validated is None else validated
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
def validate_ask_user_answers(
|
|
432
|
+
answers: Sequence[AskUserAnswer],
|
|
433
|
+
*,
|
|
434
|
+
questions: tuple[AskUserQuestion, ...],
|
|
435
|
+
) -> tuple[AskUserAnswer, ...] | None:
|
|
436
|
+
"""Normalize one positional answer per question, or return None when any breaks the contract.
|
|
437
|
+
|
|
438
|
+
Values are stripped, non-empty and unique; a single-select question takes
|
|
439
|
+
at most one value; several values must all be offered labels; a note only
|
|
440
|
+
accompanies values that are all labels.
|
|
441
|
+
"""
|
|
442
|
+
if not isinstance(answers, (list, tuple)) or len(answers) != len(questions):
|
|
443
|
+
return None
|
|
444
|
+
validated: list[AskUserAnswer] = []
|
|
445
|
+
for answer, question in zip(answers, questions, strict=True):
|
|
446
|
+
if (
|
|
447
|
+
not isinstance(answer, AskUserAnswer)
|
|
448
|
+
or not isinstance(answer.values, tuple)
|
|
449
|
+
or not all(isinstance(value, str) for value in answer.values)
|
|
450
|
+
or not isinstance(answer.note, str)
|
|
451
|
+
):
|
|
452
|
+
return None
|
|
453
|
+
# Lone surrogates are repaired (the ACP wire check already rejected
|
|
454
|
+
# them there); this also joins the pairs a JSON decoder would have
|
|
455
|
+
# joined, so the values encode strictly.
|
|
456
|
+
values = tuple(_plain_string(value, strip=True) or "" for value in answer.values)
|
|
457
|
+
if any(not value for value in values) or len(set(values)) != len(values):
|
|
458
|
+
return None
|
|
459
|
+
labels = {option.label for option in question.options}
|
|
460
|
+
if not question.multi_select and len(values) > 1:
|
|
461
|
+
return None
|
|
462
|
+
if len(values) > 1 and any(value not in labels for value in values):
|
|
463
|
+
return None
|
|
464
|
+
note = _plain_string(answer.note, strip=True) or ""
|
|
465
|
+
if note and (not values or any(value not in labels for value in values)):
|
|
466
|
+
return None
|
|
467
|
+
validated.append(AskUserAnswer(values=values, note=note))
|
|
468
|
+
return tuple(validated)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Immutable execution lease state shared with frontends."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from typing import Literal
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass(frozen=True)
|
|
12
|
+
class ExecutionSnapshot:
|
|
13
|
+
"""What holds the lease: nothing, a turn, or a workflow run (``run_id`` set)."""
|
|
14
|
+
|
|
15
|
+
kind: Literal["idle", "turn", "workflow"]
|
|
16
|
+
run_id: str = ""
|
|
17
|
+
cancellable: bool = False
|
|
18
|
+
request_id: str = ""
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""History marker constants for Chrys-owned session messages."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import TYPE_CHECKING, Any, Final
|
|
8
|
+
|
|
9
|
+
from chrys.foundation.i18n import msg
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from collections.abc import Mapping
|
|
13
|
+
|
|
14
|
+
# Persisted status-marker writer audit (closed set): fixed semantic statuses are
|
|
15
|
+
# interruption/failure fallbacks, checkpoint closure, and reload discard; dynamic
|
|
16
|
+
# diagnostic detail is ``last_error``; awaiting sub-agents is dynamic semantic
|
|
17
|
+
# status carried by ``_invocation_ids``.
|
|
18
|
+
EXECUTION_INTERRUPTED_MESSAGE = msg(
|
|
19
|
+
"history_markers.execution_interrupted",
|
|
20
|
+
fallback="Execution interrupted",
|
|
21
|
+
)
|
|
22
|
+
EXECUTION_FAILED_MESSAGE = msg(
|
|
23
|
+
"history_markers.execution_failed",
|
|
24
|
+
fallback="Execution failed",
|
|
25
|
+
)
|
|
26
|
+
SESSION_CLOSED_MESSAGE = msg(
|
|
27
|
+
"history_markers.session_closed",
|
|
28
|
+
fallback="Session closed before the turn finished",
|
|
29
|
+
)
|
|
30
|
+
SUB_AGENT_STATE_DISCARDED_MESSAGE = msg(
|
|
31
|
+
"history_markers.sub_agent_state_discarded",
|
|
32
|
+
fallback="Sub-agent state was discarded on reload",
|
|
33
|
+
)
|
|
34
|
+
AWAITING_SUB_AGENTS_MESSAGE = msg(
|
|
35
|
+
"history_markers.awaiting_sub_agents",
|
|
36
|
+
fallback="Awaiting {count} sub-agent(s)",
|
|
37
|
+
plural_fallback="Awaiting {count} sub-agent(s)",
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
ANTHROPIC_THINKING_STRIPPED_KEY: Final[str] = "_chrys_anthropic_thinking_stripped"
|
|
41
|
+
"""Set to True in a reasoning ``Content``'s ``additional_properties`` once it is left out for good.
|
|
42
|
+
|
|
43
|
+
Anthropic refused a request replaying it as bound to a different conversation,
|
|
44
|
+
and then accepted that request without any of the thinking it replayed: every
|
|
45
|
+
reasoning content the refused request replayed is marked, refused or not, and
|
|
46
|
+
never sent again.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class HistoryMarkerKind:
|
|
51
|
+
"""String constants stored in ``Message.additional_properties``."""
|
|
52
|
+
|
|
53
|
+
KEY: Final[str] = "_chrys_kind"
|
|
54
|
+
PROFILE_SWITCH_TO_KEY: Final[str] = "_switch_to"
|
|
55
|
+
STATUS_CODE_KEY: Final[str] = "_status_code"
|
|
56
|
+
|
|
57
|
+
STATUS_EXECUTION_INTERRUPTED: Final[str] = "execution_interrupted"
|
|
58
|
+
STATUS_EXECUTION_FAILED: Final[str] = "execution_failed"
|
|
59
|
+
STATUS_SESSION_CLOSED: Final[str] = "session_closed"
|
|
60
|
+
STATUS_SUB_AGENT_STATE_DISCARDED: Final[str] = "sub_agent_state_discarded"
|
|
61
|
+
STATUS_AWAITING_SUB_AGENTS: Final[str] = "awaiting_sub_agents"
|
|
62
|
+
STATUS_CODES: Final[frozenset[str]] = frozenset(
|
|
63
|
+
{
|
|
64
|
+
STATUS_EXECUTION_INTERRUPTED,
|
|
65
|
+
STATUS_EXECUTION_FAILED,
|
|
66
|
+
STATUS_SESSION_CLOSED,
|
|
67
|
+
STATUS_SUB_AGENT_STATE_DISCARDED,
|
|
68
|
+
STATUS_AWAITING_SUB_AGENTS,
|
|
69
|
+
}
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
# Mid-turn user-message flags (see ``chrys.foundation.models.turns``).
|
|
73
|
+
# ``_injected`` marks user-authored mid-turn input (live injections,
|
|
74
|
+
# resume guidance) — permanent user content that must not open a turn.
|
|
75
|
+
# ``_continuation`` marks the synthetic ``"continue"`` nudge the orchestration
|
|
76
|
+
# sends on resume — never user-authored, removed post-run. Both live in
|
|
77
|
+
# ``additional_properties``: never serialized to the wire, persisted
|
|
78
|
+
# wholesale in ``session.json``.
|
|
79
|
+
INJECTED_KEY: Final[str] = "_injected"
|
|
80
|
+
CONTINUATION_KEY: Final[str] = "_continuation"
|
|
81
|
+
MID_TURN_USER_KEYS: Final[frozenset[str]] = frozenset({INJECTED_KEY, CONTINUATION_KEY})
|
|
82
|
+
# Per-consumption identity for injected messages: stamped on the wire
|
|
83
|
+
# copy at consumption and on the persisted/replayed history copy, so
|
|
84
|
+
# crash-recovery replay dedups by identity — same-TEXT matching cannot
|
|
85
|
+
# distinguish a persisted copy of this consumption from a distinct
|
|
86
|
+
# earlier injection that happens to share the text.
|
|
87
|
+
INJECTION_ID_KEY: Final[str] = "_injection_id"
|
|
88
|
+
# System reminders a user message carried on an established provider
|
|
89
|
+
# request, as ``[{"kind": ..., "text": ...}]``. The reminder middleware
|
|
90
|
+
# re-renders them on every later call so the conversation prefix stays
|
|
91
|
+
# byte-identical across turns; the message's own contents never hold them.
|
|
92
|
+
SYSTEM_REMINDERS_KEY: Final[str] = "_chrys_system_reminders"
|
|
93
|
+
|
|
94
|
+
TURN: Final[str] = "turn"
|
|
95
|
+
SUMMARY: Final[str] = "summary"
|
|
96
|
+
INTERRUPTED: Final[str] = "interrupted"
|
|
97
|
+
AWAITING_SUB_AGENTS: Final[str] = "awaiting_sub_agents"
|
|
98
|
+
|
|
99
|
+
STATUS_MARKERS: Final[frozenset[str]] = frozenset({INTERRUPTED, AWAITING_SUB_AGENTS})
|
|
100
|
+
SESSION_COUNT_EXCLUDED: Final[frozenset[str]] = frozenset({TURN, INTERRUPTED, AWAITING_SUB_AGENTS})
|
|
101
|
+
LAST_WORDS_EXCLUDED: Final[frozenset[str]] = frozenset({TURN, SUMMARY, INTERRUPTED})
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def copy_reminder_record(source: Mapping[str, Any] | None, target: dict[str, Any]) -> None:
|
|
105
|
+
"""Carry *source*'s reminder record onto *target*, another copy of the same user message.
|
|
106
|
+
|
|
107
|
+
A rebuilt copy that lost the record would render bare on later requests
|
|
108
|
+
and change the cached prefix from there on, so every site that rebuilds
|
|
109
|
+
a user message calls this: the persisted injection copy, retry replay and
|
|
110
|
+
its failure fallback, the crash-recovery checkpoint and a child's retry
|
|
111
|
+
seed. Entries are copied fresh: the source dict may still be live.
|
|
112
|
+
"""
|
|
113
|
+
record = source.get(HistoryMarkerKind.SYSTEM_REMINDERS_KEY) if source is not None else None
|
|
114
|
+
if isinstance(record, list) and record:
|
|
115
|
+
target[HistoryMarkerKind.SYSTEM_REMINDERS_KEY] = [dict(entry) for entry in record if isinstance(entry, dict)]
|