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,209 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Restore-only repair of interrupted runs; the log alone owns terminal facts.
|
|
4
|
+
|
|
5
|
+
A read-only tail check skips finished runs. Unfinished logs are rechecked under
|
|
6
|
+
one reconciliation lock through the descriptor that receives the orphan terminal.
|
|
7
|
+
Torn tails are separated before append. No recovery events are published live.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import errno
|
|
13
|
+
import logging
|
|
14
|
+
import os
|
|
15
|
+
from collections.abc import Iterable, Iterator
|
|
16
|
+
from dataclasses import dataclass
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from typing import BinaryIO, Final
|
|
19
|
+
|
|
20
|
+
from chrys.foundation.platform.files import secure_open_owner_only_append, secure_open_owner_verified_binary
|
|
21
|
+
from chrys.foundation.trajectory.envelope import (
|
|
22
|
+
EnvelopeError,
|
|
23
|
+
EventDraft,
|
|
24
|
+
TrajectoryEvent,
|
|
25
|
+
build_event,
|
|
26
|
+
decode_event_line,
|
|
27
|
+
encode_event_line,
|
|
28
|
+
peek_envelope_header,
|
|
29
|
+
)
|
|
30
|
+
from chrys.foundation.trajectory.ids import new_analytics_id
|
|
31
|
+
from chrys.foundation.util.lock import FileLock
|
|
32
|
+
from chrys.service.workflows.layout import EVENTS_FILE, iter_run_dirs
|
|
33
|
+
from chrys.service.workflows.outcomes import ORPHAN_REASON_PROCESS_TERMINATED, RunOutcome
|
|
34
|
+
from chrys.service.workflows.store import WORKFLOW_EVENT_TYPES, RunRecord, RunTerminal, read_run_header
|
|
35
|
+
|
|
36
|
+
logger = logging.getLogger(__name__)
|
|
37
|
+
|
|
38
|
+
MAX_EVENTS_BYTES: Final = 256 * 1024 * 1024
|
|
39
|
+
"""Bounds reverse scanning, including malformed or sparse files, without allocating the whole log."""
|
|
40
|
+
_TAIL_BLOCK_BYTES: Final = 64 * 1024
|
|
41
|
+
RECONCILE_LOCK_FILE: Final = ".reconcile.lock"
|
|
42
|
+
RECONCILE_LOCK_TIMEOUT: Final = 30.0 # seconds
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@dataclass(frozen=True, slots=True)
|
|
46
|
+
class OrphanReconciliation:
|
|
47
|
+
"""What one pass did: runs given a terminal, runs already terminal, runs it could not judge."""
|
|
48
|
+
|
|
49
|
+
reconciled: tuple[str, ...] = ()
|
|
50
|
+
already_finished: tuple[str, ...] = ()
|
|
51
|
+
skipped: tuple[str, ...] = ()
|
|
52
|
+
truncated: bool = False
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def reconcile_orphaned_runs(session_dir: Path) -> OrphanReconciliation:
|
|
56
|
+
"""Give every unfinished run under *session_dir* its ``orphaned`` terminal; idempotent."""
|
|
57
|
+
run_dirs, truncated = iter_run_dirs(session_dir)
|
|
58
|
+
reconciled: list[str] = []
|
|
59
|
+
finished: list[str] = []
|
|
60
|
+
skipped: list[str] = []
|
|
61
|
+
for run_dir in run_dirs:
|
|
62
|
+
try:
|
|
63
|
+
outcome = _reconcile_run(run_dir)
|
|
64
|
+
except OSError, ValueError: # EnvelopeError is a ValueError
|
|
65
|
+
if not run_dir.exists(): # the session was deleted under a reconciliation a cancelled restore left running
|
|
66
|
+
logger.debug("workflow run %s was deleted during reconciliation", run_dir.name)
|
|
67
|
+
else:
|
|
68
|
+
logger.warning("workflow run %s could not be reconciled", run_dir.name, exc_info=True)
|
|
69
|
+
skipped.append(run_dir.name)
|
|
70
|
+
continue
|
|
71
|
+
(reconciled if outcome else finished).append(run_dir.name)
|
|
72
|
+
return OrphanReconciliation(tuple(reconciled), tuple(finished), tuple(skipped), truncated)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def read_run_terminal(run_dir: Path) -> RunTerminal | None:
|
|
76
|
+
"""Read a durable terminal without repairing files or acquiring the session's execution lock."""
|
|
77
|
+
try:
|
|
78
|
+
with secure_open_owner_verified_binary(run_dir / EVENTS_FILE) as handle:
|
|
79
|
+
_last, record = _last_complete(_reverse_complete_lines(handle))
|
|
80
|
+
except OSError as exc:
|
|
81
|
+
if exc.errno == errno.ENOENT:
|
|
82
|
+
return None
|
|
83
|
+
raise
|
|
84
|
+
return _terminal(record) if record is not None and record.event_type == RunRecord.RUN_FINISHED else None
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _reverse_complete_lines(handle: BinaryIO) -> Iterator[bytes]:
|
|
88
|
+
"""Scan backward from one EOF snapshot; ignore its torn tail, and stop on demand.
|
|
89
|
+
|
|
90
|
+
Only a line crossing block boundaries is retained. The existing ceiling
|
|
91
|
+
bounds pathological scans, not file size: a large live log needs one tail
|
|
92
|
+
block in the ordinary case. Joining a split line once avoids quadratic
|
|
93
|
+
copying for large records.
|
|
94
|
+
"""
|
|
95
|
+
position = handle.seek(0, os.SEEK_END)
|
|
96
|
+
scanned = 0
|
|
97
|
+
fragments: list[bytes] = []
|
|
98
|
+
torn_tail = True
|
|
99
|
+
while position:
|
|
100
|
+
if scanned == MAX_EVENTS_BYTES:
|
|
101
|
+
raise ValueError(f"{EVENTS_FILE} tail exceeds the {MAX_EVENTS_BYTES}-byte scan ceiling")
|
|
102
|
+
length = min(position, _TAIL_BLOCK_BYTES, MAX_EVENTS_BYTES - scanned)
|
|
103
|
+
position -= length
|
|
104
|
+
handle.seek(position)
|
|
105
|
+
pieces = handle.read(length).split(b"\n")
|
|
106
|
+
scanned += length
|
|
107
|
+
for piece in reversed(pieces[1:]):
|
|
108
|
+
if torn_tail:
|
|
109
|
+
torn_tail = False
|
|
110
|
+
else:
|
|
111
|
+
yield piece + b"".join(reversed(fragments))
|
|
112
|
+
fragments.clear()
|
|
113
|
+
if not torn_tail:
|
|
114
|
+
fragments.append(pieces[0])
|
|
115
|
+
if not torn_tail:
|
|
116
|
+
yield b"".join(reversed(fragments))
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def _terminal(record: TrajectoryEvent) -> RunTerminal:
|
|
120
|
+
reason = record.payload.get("reason")
|
|
121
|
+
return RunTerminal(
|
|
122
|
+
outcome=str(record.payload.get("outcome", "")),
|
|
123
|
+
last_seq=record.sequence,
|
|
124
|
+
reason=reason if isinstance(reason, str) else "",
|
|
125
|
+
finished_at=record.occurred_at,
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def _reconcile_run(run_dir: Path) -> bool:
|
|
130
|
+
"""Append once, without creating any directories if deletion races restoration."""
|
|
131
|
+
if read_run_terminal(run_dir) is not None:
|
|
132
|
+
return False
|
|
133
|
+
with FileLock(run_dir / RECONCILE_LOCK_FILE, timeout=RECONCILE_LOCK_TIMEOUT):
|
|
134
|
+
return _reconcile_run_locked(run_dir)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def _reconcile_run_locked(run_dir: Path) -> bool:
|
|
138
|
+
header = read_run_header(run_dir)
|
|
139
|
+
run_id = header.get("run_id")
|
|
140
|
+
session_id = header.get("session_id")
|
|
141
|
+
if not isinstance(run_id, str) or not run_id or not isinstance(session_id, str):
|
|
142
|
+
raise ValueError("run header lacks its identity")
|
|
143
|
+
events_path = run_dir / EVENTS_FILE
|
|
144
|
+
handle = secure_open_owner_only_append(events_path)
|
|
145
|
+
try:
|
|
146
|
+
# Read through the descriptor being appended to: the file examined is the file written.
|
|
147
|
+
with os.fdopen(os.dup(handle.fd), "rb") as reader:
|
|
148
|
+
last, last_record = _last_complete(_reverse_complete_lines(reader))
|
|
149
|
+
if last_record is not None and last_record.event_type == RunRecord.RUN_FINISHED:
|
|
150
|
+
return False
|
|
151
|
+
sequence = (last.sequence if last is not None else _highest_sequence(_reverse_complete_lines(reader))) + 1
|
|
152
|
+
size = reader.seek(0, os.SEEK_END)
|
|
153
|
+
if size:
|
|
154
|
+
reader.seek(-1, os.SEEK_END)
|
|
155
|
+
tail = bool(size and reader.read(1) != b"\n")
|
|
156
|
+
draft = EventDraft(
|
|
157
|
+
event_type=RunRecord.RUN_FINISHED,
|
|
158
|
+
payload={"outcome": RunOutcome.ORPHANED.value, "reason": ORPHAN_REASON_PROCESS_TERMINATED},
|
|
159
|
+
)
|
|
160
|
+
event = build_event(
|
|
161
|
+
draft,
|
|
162
|
+
sequence=sequence,
|
|
163
|
+
runtime_id=run_id,
|
|
164
|
+
coverage_id=last.coverage_id if last is not None else new_analytics_id(),
|
|
165
|
+
session_id=session_id,
|
|
166
|
+
branch_id=last.branch_id if last is not None else new_analytics_id(),
|
|
167
|
+
)
|
|
168
|
+
line = (b"\n" if tail else b"") + encode_event_line(event)
|
|
169
|
+
_write_all(handle.fd, line)
|
|
170
|
+
os.fsync(handle.fd)
|
|
171
|
+
finally:
|
|
172
|
+
os.close(handle.fd)
|
|
173
|
+
return True
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def _last_complete(lines: Iterable[bytes]) -> tuple[TrajectoryEvent | None, TrajectoryEvent | None]:
|
|
177
|
+
"""Read newest-first lines for the last envelope and last workflow record.
|
|
178
|
+
|
|
179
|
+
The two differ when the store closed its writer after the terminal: the
|
|
180
|
+
runtime markers that follow ``workflow.log.run.finished`` are the writer's,
|
|
181
|
+
not the run's.
|
|
182
|
+
"""
|
|
183
|
+
last: TrajectoryEvent | None = None
|
|
184
|
+
for raw in lines:
|
|
185
|
+
try:
|
|
186
|
+
event = decode_event_line(raw)
|
|
187
|
+
except EnvelopeError:
|
|
188
|
+
continue
|
|
189
|
+
if last is None:
|
|
190
|
+
last = event
|
|
191
|
+
if event.event_type in WORKFLOW_EVENT_TYPES:
|
|
192
|
+
return last, event
|
|
193
|
+
return last, None
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def _highest_sequence(lines: Iterable[bytes]) -> int:
|
|
197
|
+
highest = 0
|
|
198
|
+
for raw in lines:
|
|
199
|
+
header = peek_envelope_header(raw)
|
|
200
|
+
if header is not None:
|
|
201
|
+
highest = max(highest, header.sequence)
|
|
202
|
+
return highest
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def _write_all(fd: int, data: bytes) -> None:
|
|
206
|
+
view = memoryview(data)
|
|
207
|
+
while view:
|
|
208
|
+
written = os.write(fd, view)
|
|
209
|
+
view = view[written:]
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Run outcomes, cancellation reasons and their presentation status."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from enum import Enum
|
|
8
|
+
from typing import Final, Literal
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class RunOutcome(Enum):
|
|
12
|
+
"""Terminal outcomes, including restore-only orphan reconciliation."""
|
|
13
|
+
|
|
14
|
+
COMPLETED = "completed"
|
|
15
|
+
NODE_FAILED = "node_failed"
|
|
16
|
+
LOOP_EXHAUSTED = "loop_exhausted"
|
|
17
|
+
CANCELLED = "cancelled"
|
|
18
|
+
WORKER_LOST = "worker_lost"
|
|
19
|
+
STORAGE_FAILED = "storage_failed"
|
|
20
|
+
ORPHANED = "orphaned"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
REASON_DEADLINE_EXCEEDED: Final = "deadline_exceeded"
|
|
24
|
+
"""``WorkflowRunFinished.reason`` when the run-level timeout cancelled the run."""
|
|
25
|
+
REASON_SHUTDOWN: Final = "shutdown"
|
|
26
|
+
"""``WorkflowRunFinished.reason`` when the owning engine shut down under the run."""
|
|
27
|
+
REASON_INTERNAL_ERROR: Final = "internal_error"
|
|
28
|
+
"""``WorkflowRunFinished.reason`` when the runner itself failed and cancelled the run to converge it."""
|
|
29
|
+
ORPHAN_REASON_PROCESS_TERMINATED: Final = "process_terminated"
|
|
30
|
+
|
|
31
|
+
type RunStatus = Literal["running", "completed", "failed", "cancelled", "interrupted"]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def run_status(outcome: str | None, reason: str | None, *, active: bool) -> RunStatus:
|
|
35
|
+
"""Project stored or live outcome facts to the status shown in history."""
|
|
36
|
+
if outcome == RunOutcome.COMPLETED.value:
|
|
37
|
+
return "completed"
|
|
38
|
+
if outcome == RunOutcome.CANCELLED.value:
|
|
39
|
+
if reason in {REASON_DEADLINE_EXCEEDED, REASON_INTERNAL_ERROR}:
|
|
40
|
+
return "failed"
|
|
41
|
+
return "interrupted" if reason == REASON_SHUTDOWN else "cancelled"
|
|
42
|
+
if outcome == RunOutcome.ORPHANED.value:
|
|
43
|
+
return "interrupted"
|
|
44
|
+
if outcome:
|
|
45
|
+
return "failed"
|
|
46
|
+
return "running" if active else "interrupted"
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Wire contract between the main process and a workflow worker host.
|
|
4
|
+
|
|
5
|
+
Newline-framed JSON over the worker's stdio. The main process owns stdin/stdout
|
|
6
|
+
of the child: every frame the child writes is protocol, and the host moves the
|
|
7
|
+
user's ``fd 1``/``fd 2`` elsewhere before any user code runs. The two sides use
|
|
8
|
+
disjoint request-id spaces (main odd from 1, worker even from 2), so one reader
|
|
9
|
+
per side can demultiplex responses by id without agreement on ordering.
|
|
10
|
+
|
|
11
|
+
The host is a standalone stdlib file that cannot import this module; it carries
|
|
12
|
+
its own copy of the names below, and ``tests/service/workflows/test_protocol.py``
|
|
13
|
+
pins the two copies to each other.
|
|
14
|
+
|
|
15
|
+
Frames:
|
|
16
|
+
|
|
17
|
+
* request ``{"id": int, "method": str, "params": {...}}``
|
|
18
|
+
* response ``{"id": int, "result": {...}}`` or ``{"id": int, "error": {"code", "message", "data"}}``
|
|
19
|
+
* notification ``{"method": str, "params": {...}}``
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
import json
|
|
25
|
+
from collections.abc import Mapping
|
|
26
|
+
from dataclasses import dataclass
|
|
27
|
+
from enum import StrEnum
|
|
28
|
+
from typing import Any, Final
|
|
29
|
+
|
|
30
|
+
from chrys.service.workflows.scheduler import AttemptRef
|
|
31
|
+
|
|
32
|
+
PROTOCOL_VERSION: Final = 2
|
|
33
|
+
PYTHON_FLOOR: Final = (3, 9)
|
|
34
|
+
"""Oldest interpreter that can run the host and the injected SDK."""
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class Method(StrEnum):
|
|
38
|
+
"""Every method name on the wire."""
|
|
39
|
+
|
|
40
|
+
# worker → main, first frame
|
|
41
|
+
HELLO = "hello"
|
|
42
|
+
# main → worker requests
|
|
43
|
+
LOAD = "load"
|
|
44
|
+
RUN_PYTHON = "run_python"
|
|
45
|
+
EVAL_OUTGOING = "eval_outgoing"
|
|
46
|
+
EVAL_LOOP_UNTIL = "eval_loop_until"
|
|
47
|
+
COMBINE = "combine"
|
|
48
|
+
CANCEL = "cancel"
|
|
49
|
+
NATIVE_OUTPUT = "native_output"
|
|
50
|
+
SHUTDOWN = "shutdown"
|
|
51
|
+
# worker → main during an attempt
|
|
52
|
+
ASK = "ask"
|
|
53
|
+
EMIT = "emit"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class ErrorCode(StrEnum):
|
|
57
|
+
"""Worker failure codes; the runner maps attempt failures onto scheduler retry classes."""
|
|
58
|
+
|
|
59
|
+
USER_EXCEPTION = "user_exception"
|
|
60
|
+
VALUE_NOT_SERIALIZABLE = "value_not_serializable"
|
|
61
|
+
VALUE_TOO_LARGE = "value_too_large"
|
|
62
|
+
PROTOCOL_LIMIT = "protocol_limit"
|
|
63
|
+
ASK_UNAVAILABLE = "ask_unavailable"
|
|
64
|
+
ATTEMPT_TERMINATED = "attempt_terminated"
|
|
65
|
+
LOAD_FAILED = "load_failed"
|
|
66
|
+
INVALID_PARAMS = "invalid_params"
|
|
67
|
+
UNKNOWN_METHOD = "unknown_method"
|
|
68
|
+
INTERNAL = "internal"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
_MIB = 1024 * 1024
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@dataclass(frozen=True, slots=True)
|
|
75
|
+
class ProtocolLimits:
|
|
76
|
+
"""Resource bounds and deadlines shared with the standalone worker."""
|
|
77
|
+
|
|
78
|
+
# one frame, either direction; a larger value is value_too_large, any other frame protocol_limit
|
|
79
|
+
max_frame_bytes: int = 16 * _MIB
|
|
80
|
+
# WorkflowValue.data shape: nesting depth, total containers + scalars, one string's length
|
|
81
|
+
max_payload_depth: int = 64
|
|
82
|
+
max_payload_items: int = 200_000
|
|
83
|
+
max_string_chars: int = 4 * _MIB
|
|
84
|
+
# main → worker requests in flight
|
|
85
|
+
max_pending_requests: int = 256
|
|
86
|
+
# both directions, per run; exceeding either is a worker_lost-class failure
|
|
87
|
+
max_run_frames: int = 1_000_000
|
|
88
|
+
max_run_bytes: int = 4 * 1024 * _MIB
|
|
89
|
+
# join sources kept in memory for one combine call
|
|
90
|
+
max_join_retained_bytes: int = 12 * _MIB
|
|
91
|
+
# ctx.emit per attempt: sliding one-second rate, count, and bytes
|
|
92
|
+
emit_rate_per_s: int = 200
|
|
93
|
+
max_emits_per_attempt: int = 10_000
|
|
94
|
+
max_emit_bytes_per_attempt: int = 8 * _MIB
|
|
95
|
+
# main-side deadline in seconds for eval_outgoing / eval_loop_until / combine
|
|
96
|
+
eval_deadline: float = 30.0
|
|
97
|
+
# sync bodies and default-executor offloads; evaluations have their own pool
|
|
98
|
+
worker_thread_pool_size: int = 8
|
|
99
|
+
eval_thread_pool_size: int = 2
|
|
100
|
+
# cumulative abandoned work, attributed by the worker to the pool that actually owns it
|
|
101
|
+
worker_leak_budget: int = 8
|
|
102
|
+
eval_leak_budget: int = 2
|
|
103
|
+
load_timeout: float = 60.0 # seconds; includes executing the module and building its manifest
|
|
104
|
+
hello_timeout: float = 15.0 # seconds
|
|
105
|
+
shutdown_grace: float = 3.0 # seconds
|
|
106
|
+
# after cancelling an async body the host waits this many seconds for it to unwind before acknowledging;
|
|
107
|
+
# a body that keeps swallowing the cancellation is reported like a leaked thread
|
|
108
|
+
cancel_drain: float = 1.0
|
|
109
|
+
# captured sys.stdout/sys.stderr per attempt, and the run-level native tail
|
|
110
|
+
captured_output_bytes: int = 64 * 1024
|
|
111
|
+
native_output_tail_bytes: int = 64 * 1024
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
LIMITS: Final = ProtocolLimits()
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class ProtocolError(ValueError):
|
|
118
|
+
"""A frame that does not fit the contract; the connection is not recoverable."""
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def encode_frame(frame: Mapping[str, Any]) -> bytes:
|
|
122
|
+
"""Serialize one frame; raises :class:`ProtocolError` above the frame cap.
|
|
123
|
+
|
|
124
|
+
Frames carry filesystem identity (the entry path and the workspace, which on
|
|
125
|
+
POSIX may hold surrogateescaped bytes), so every str must survive the byte
|
|
126
|
+
form unchanged: lone surrogates pass through. Whether a *value* is valid
|
|
127
|
+
Unicode is the value layer's rule, checked where the value is produced.
|
|
128
|
+
"""
|
|
129
|
+
line = json.dumps(frame, ensure_ascii=False, sort_keys=True, separators=(",", ":"), allow_nan=False)
|
|
130
|
+
data = line.encode("utf-8", "surrogatepass") + b"\n"
|
|
131
|
+
if len(data) > LIMITS.max_frame_bytes:
|
|
132
|
+
raise ProtocolError(f"frame of {len(data)} bytes exceeds max_frame_bytes.")
|
|
133
|
+
return data
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def decode_frame(line: bytes) -> dict[str, Any]:
|
|
137
|
+
"""Parse one line into a frame dict, validating the envelope shape only."""
|
|
138
|
+
if len(line) > LIMITS.max_frame_bytes:
|
|
139
|
+
raise ProtocolError(f"frame of {len(line)} bytes exceeds max_frame_bytes.")
|
|
140
|
+
try:
|
|
141
|
+
frame = json.loads(line.decode("utf-8", "surrogatepass"))
|
|
142
|
+
except (UnicodeDecodeError, ValueError) as exc:
|
|
143
|
+
raise ProtocolError(f"frame is not UTF-8 JSON: {exc}") from exc
|
|
144
|
+
if not isinstance(frame, dict):
|
|
145
|
+
raise ProtocolError("frame is not a JSON object.")
|
|
146
|
+
if "id" in frame:
|
|
147
|
+
if not isinstance(frame["id"], int) or isinstance(frame["id"], bool) or frame["id"] < 1:
|
|
148
|
+
raise ProtocolError("frame id must be a positive int.")
|
|
149
|
+
if "method" in frame:
|
|
150
|
+
_check_request(frame)
|
|
151
|
+
elif ("result" in frame) == ("error" in frame):
|
|
152
|
+
raise ProtocolError("response carries exactly one of result/error.")
|
|
153
|
+
elif "error" in frame:
|
|
154
|
+
_check_error(frame["error"])
|
|
155
|
+
elif not isinstance(frame["result"], dict):
|
|
156
|
+
raise ProtocolError("response result must be an object.")
|
|
157
|
+
else:
|
|
158
|
+
_check_request(frame)
|
|
159
|
+
return frame
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def _check_request(frame: dict[str, Any]) -> None:
|
|
163
|
+
if not isinstance(frame.get("method"), str) or not frame["method"]:
|
|
164
|
+
raise ProtocolError("request method must be a non-empty string.")
|
|
165
|
+
if not isinstance(frame.get("params"), dict):
|
|
166
|
+
raise ProtocolError("request params must be an object.")
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def _check_error(error: Any) -> None:
|
|
170
|
+
if (
|
|
171
|
+
not isinstance(error, dict)
|
|
172
|
+
or not isinstance(error.get("code"), str)
|
|
173
|
+
or not isinstance(error.get("message"), str)
|
|
174
|
+
):
|
|
175
|
+
raise ProtocolError("error must carry a string code and message.")
|
|
176
|
+
if not isinstance(error.get("data", {}), dict):
|
|
177
|
+
raise ProtocolError("error data must be an object.")
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def ref_to_wire(ref: AttemptRef) -> dict[str, Any]:
|
|
181
|
+
return {
|
|
182
|
+
"run_id": ref.run_id,
|
|
183
|
+
"node_id": ref.node_id,
|
|
184
|
+
"activation_id": ref.activation_id,
|
|
185
|
+
"attempt": ref.attempt,
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def ref_from_wire(payload: Any) -> AttemptRef:
|
|
190
|
+
if not isinstance(payload, dict):
|
|
191
|
+
raise ProtocolError("ref must be an object.")
|
|
192
|
+
try:
|
|
193
|
+
run_id, node_id, activation_id, attempt = (
|
|
194
|
+
payload["run_id"],
|
|
195
|
+
payload["node_id"],
|
|
196
|
+
payload["activation_id"],
|
|
197
|
+
payload["attempt"],
|
|
198
|
+
)
|
|
199
|
+
except KeyError as exc:
|
|
200
|
+
raise ProtocolError(f"ref is missing {exc.args[0]!r}.") from exc
|
|
201
|
+
if not all(isinstance(part, str) and part for part in (run_id, node_id, activation_id)):
|
|
202
|
+
raise ProtocolError("ref ids must be non-empty strings.")
|
|
203
|
+
if not isinstance(attempt, int) or isinstance(attempt, bool) or attempt < 1:
|
|
204
|
+
raise ProtocolError("ref attempt must be an int >= 1.")
|
|
205
|
+
return AttemptRef(run_id=run_id, node_id=node_id, activation_id=activation_id, attempt=attempt)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def ref_key(ref: AttemptRef) -> str:
|
|
209
|
+
"""The wire identity of an attempt: what the fence on both sides keys on."""
|
|
210
|
+
return f"{ref.run_id}|{ref.node_id}|{ref.activation_id}|{ref.attempt}"
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Service-owned conversion from immutable run artifacts and log records to lifecycle facts."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from collections.abc import Mapping
|
|
8
|
+
from datetime import UTC, datetime
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
from chrys.foundation.events import types as events
|
|
13
|
+
from chrys.foundation.events.workflow import WorkflowRunEvent
|
|
14
|
+
from chrys.foundation.models.ask_user import AskUserQuestion
|
|
15
|
+
from chrys.foundation.trajectory.envelope import TrajectoryEvent
|
|
16
|
+
from chrys.foundation.util.time import parse_created_at
|
|
17
|
+
from chrys.service.state.workflow import decode_workflow_model
|
|
18
|
+
from chrys.service.workflows.layout import OUTPUT_INDEX_FILE
|
|
19
|
+
from chrys.service.workflows.store import (
|
|
20
|
+
MAX_OUTPUT_INDEX_BYTES,
|
|
21
|
+
RunRecord,
|
|
22
|
+
read_json_object,
|
|
23
|
+
read_run_header,
|
|
24
|
+
read_run_input,
|
|
25
|
+
read_run_spec,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def record_timestamp(value: object) -> datetime:
|
|
30
|
+
parsed = parse_created_at(value)
|
|
31
|
+
return parsed if parsed is not None and parsed.tzinfo is not None else datetime(1970, 1, 1, tzinfo=UTC)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def run_started_event(
|
|
35
|
+
header: Mapping[str, Any], spec: Mapping[str, Any], input_text: str, *, seq: int = 0
|
|
36
|
+
) -> events.WorkflowRunStarted:
|
|
37
|
+
"""The same start fact for live publication and historical replay."""
|
|
38
|
+
return events.WorkflowRunStarted(
|
|
39
|
+
seq=seq,
|
|
40
|
+
run_id=header["run_id"],
|
|
41
|
+
session_id=header["session_id"],
|
|
42
|
+
input_text=input_text,
|
|
43
|
+
workflow_id=header["workflow_id"],
|
|
44
|
+
source_kind=header["source_kind"],
|
|
45
|
+
canonical_path=header["canonical_path"],
|
|
46
|
+
title=header["title"],
|
|
47
|
+
spec_digest=header["spec_digest"],
|
|
48
|
+
manifest=dict(spec["manifest"]),
|
|
49
|
+
resolved_nodes=[dict(node) for node in spec["resolved_nodes"]],
|
|
50
|
+
model=decode_workflow_model(header["model"]),
|
|
51
|
+
timestamp=record_timestamp(header["started_at"]),
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def read_run_started(directory: Path, *, seq: int = 0) -> events.WorkflowRunStarted:
|
|
56
|
+
return run_started_event(read_run_header(directory), read_run_spec(directory), read_run_input(directory), seq=seq)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def decode_run_event(record: TrajectoryEvent, *, directory: Path) -> WorkflowRunEvent | None:
|
|
60
|
+
"""Decode the run-log namespace; trajectory runtime markers have no workflow projection."""
|
|
61
|
+
kind, payload = record.event_type, record.payload
|
|
62
|
+
if kind == RunRecord.RUN_STARTED:
|
|
63
|
+
return read_run_started(directory, seq=record.sequence)
|
|
64
|
+
common: dict[str, Any] = {
|
|
65
|
+
"run_id": record.runtime_id,
|
|
66
|
+
"session_id": record.session_id,
|
|
67
|
+
"seq": record.sequence,
|
|
68
|
+
"timestamp": record_timestamp(record.occurred_at),
|
|
69
|
+
}
|
|
70
|
+
if kind in {
|
|
71
|
+
RunRecord.NODE_STATE,
|
|
72
|
+
RunRecord.NODE_OUTPUT,
|
|
73
|
+
RunRecord.NODE_ASK,
|
|
74
|
+
RunRecord.NODE_ANSWER,
|
|
75
|
+
RunRecord.LOOP_ITERATION,
|
|
76
|
+
RunRecord.RUN_NOTICE,
|
|
77
|
+
}:
|
|
78
|
+
ref = {"activation_id": payload["activation"], "attempt": payload["attempt"]}
|
|
79
|
+
if kind == RunRecord.LOOP_ITERATION:
|
|
80
|
+
return events.WorkflowLoopIteration(
|
|
81
|
+
**common, **ref, loop_id=payload["node"], iteration=payload["iteration"], verdict=payload["verdict"]
|
|
82
|
+
)
|
|
83
|
+
ref["node_id"] = payload["node"]
|
|
84
|
+
if kind == RunRecord.NODE_STATE:
|
|
85
|
+
return events.WorkflowNodeStateChanged(
|
|
86
|
+
**common,
|
|
87
|
+
**ref,
|
|
88
|
+
state=payload["state"],
|
|
89
|
+
iteration=payload["iteration"],
|
|
90
|
+
failure_phase=payload["failure_phase"],
|
|
91
|
+
invocation_id=payload.get("invocation", ""),
|
|
92
|
+
error=payload.get("error", ""),
|
|
93
|
+
error_class=payload.get("error_class", ""),
|
|
94
|
+
)
|
|
95
|
+
if kind == RunRecord.NODE_OUTPUT:
|
|
96
|
+
return events.WorkflowNodeOutput(
|
|
97
|
+
**common, **ref, kind=payload["kind"], ordinal=payload["ordinal"], summary_text=payload["summary"]
|
|
98
|
+
)
|
|
99
|
+
if kind == RunRecord.NODE_ASK:
|
|
100
|
+
# Only the bounded summary is stored: a replayed ask is that summary as one open question.
|
|
101
|
+
question = AskUserQuestion(question=payload["prompt"])
|
|
102
|
+
return events.WorkflowNodeAskUser(**common, **ref, request_id=payload["request"], questions=(question,))
|
|
103
|
+
if kind == RunRecord.NODE_ANSWER:
|
|
104
|
+
return events.WorkflowNodeAnswered(**common, **ref, request_id=payload["request"], answer=payload["answer"])
|
|
105
|
+
return events.WorkflowRunNotice(**common, **ref, code=payload["code"], message=payload["message"])
|
|
106
|
+
if kind == RunRecord.RUN_FINISHED:
|
|
107
|
+
outputs = payload.get("outputs", [])
|
|
108
|
+
omitted = payload.get("outputs_omitted", 0)
|
|
109
|
+
if omitted:
|
|
110
|
+
try:
|
|
111
|
+
outputs = read_json_object(directory / OUTPUT_INDEX_FILE, MAX_OUTPUT_INDEX_BYTES)["outputs"]
|
|
112
|
+
if len(outputs) != omitted:
|
|
113
|
+
raise ValueError("Output count does not match the terminal.")
|
|
114
|
+
except (OSError, ValueError, KeyError, TypeError) as exc:
|
|
115
|
+
raise ValueError(f"Cannot read workflow output index: {exc}") from exc
|
|
116
|
+
if not isinstance(outputs, list):
|
|
117
|
+
raise ValueError("Workflow outputs must be an array.")
|
|
118
|
+
summaries = []
|
|
119
|
+
for output in outputs:
|
|
120
|
+
if (
|
|
121
|
+
not isinstance(output, dict)
|
|
122
|
+
or not isinstance(output.get("node"), str)
|
|
123
|
+
or not isinstance(output.get("activation"), str)
|
|
124
|
+
or type(output.get("attempt")) is not int
|
|
125
|
+
or output["attempt"] < 0
|
|
126
|
+
):
|
|
127
|
+
raise ValueError("Invalid workflow output identity in terminal or output index.")
|
|
128
|
+
summaries.append(
|
|
129
|
+
events.WorkflowOutputSummary(
|
|
130
|
+
node_id=output["node"], activation_id=output["activation"], attempt=output["attempt"]
|
|
131
|
+
)
|
|
132
|
+
)
|
|
133
|
+
return events.WorkflowRunFinished(
|
|
134
|
+
**common,
|
|
135
|
+
outcome=payload["outcome"],
|
|
136
|
+
outputs=summaries,
|
|
137
|
+
error=payload.get("error", ""),
|
|
138
|
+
duration=payload.get("duration", 0),
|
|
139
|
+
reason=payload.get("reason", ""),
|
|
140
|
+
node_id=payload.get("node", ""),
|
|
141
|
+
)
|
|
142
|
+
return None
|