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,148 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Session trajectory spans for a workflow run and each activation attempt.
|
|
4
|
+
|
|
5
|
+
The runner supplies scheduler states, including failures entering retry waits.
|
|
6
|
+
Values, prompts, source paths and diagnostic prose stay in the workflow store.
|
|
7
|
+
Cancellation terminals wait for the runner's drain so child agent operations
|
|
8
|
+
finish inside their node span. Recorder failures never affect execution.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import logging
|
|
14
|
+
import threading
|
|
15
|
+
import time
|
|
16
|
+
from typing import Any
|
|
17
|
+
|
|
18
|
+
from chrys.foundation.trajectory.context import TrajectoryContext
|
|
19
|
+
from chrys.foundation.trajectory.envelope import EventDraft, MeasurementSource, measurement
|
|
20
|
+
from chrys.foundation.trajectory.event_types import EventType, WorkflowNodeOutcome
|
|
21
|
+
from chrys.foundation.trajectory.ids import new_analytics_id
|
|
22
|
+
from chrys.service.workflows.scheduler import ActivationState, NodeStateChanged
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class _Span:
|
|
28
|
+
"""An opening owns its terminal only once the writer commits its sequence."""
|
|
29
|
+
|
|
30
|
+
def __init__(
|
|
31
|
+
self,
|
|
32
|
+
context: TrajectoryContext,
|
|
33
|
+
started_type: str,
|
|
34
|
+
finished_type: str,
|
|
35
|
+
payload: dict[str, Any],
|
|
36
|
+
*,
|
|
37
|
+
operation_id: str | None = None,
|
|
38
|
+
) -> None:
|
|
39
|
+
self.context = context
|
|
40
|
+
self.operation_id = operation_id or new_analytics_id()
|
|
41
|
+
self._started_type = started_type
|
|
42
|
+
self._finished_type = finished_type
|
|
43
|
+
self._payload = payload
|
|
44
|
+
self._started_ns = time.monotonic_ns()
|
|
45
|
+
self._committed = False
|
|
46
|
+
self._finished = False
|
|
47
|
+
self._lock = threading.Lock()
|
|
48
|
+
|
|
49
|
+
def _draft(self, event_type: str, payload: dict[str, Any]) -> EventDraft:
|
|
50
|
+
return self.context.draft(
|
|
51
|
+
event_type,
|
|
52
|
+
operation_id=self.operation_id,
|
|
53
|
+
parent_operation_id=self.context.innermost_model_operation_id,
|
|
54
|
+
payload={**self._payload, **payload},
|
|
55
|
+
measurements={"/payload/duration_ms": measurement(MeasurementSource.MONOTONIC_CLOCK, method_version=1)}
|
|
56
|
+
if event_type == self._finished_type
|
|
57
|
+
else {},
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
async def started(self) -> None:
|
|
61
|
+
def commit(_sequence: int) -> dict[str, Any]:
|
|
62
|
+
with self._lock:
|
|
63
|
+
if self._finished:
|
|
64
|
+
raise RuntimeError("Workflow span closed before its start committed")
|
|
65
|
+
self.context.finalizers.add(self.abandon)
|
|
66
|
+
self._committed = True
|
|
67
|
+
return self._payload
|
|
68
|
+
|
|
69
|
+
try:
|
|
70
|
+
await self.context.sink.emit(self._draft(self._started_type, {}), payload_factory=commit)
|
|
71
|
+
except Exception:
|
|
72
|
+
logger.debug("Trajectory workflow start emit failed", exc_info=True)
|
|
73
|
+
|
|
74
|
+
def finished(self, outcome: str) -> None:
|
|
75
|
+
with self._lock:
|
|
76
|
+
if self._finished:
|
|
77
|
+
return
|
|
78
|
+
self._finished = True
|
|
79
|
+
self.context.finalizers.discard(self.abandon)
|
|
80
|
+
if not self._committed:
|
|
81
|
+
return
|
|
82
|
+
try:
|
|
83
|
+
self.context.sink.emit_soon(
|
|
84
|
+
self._draft(
|
|
85
|
+
self._finished_type,
|
|
86
|
+
{"outcome": outcome, "duration_ms": max(0, (time.monotonic_ns() - self._started_ns) // 1_000_000)},
|
|
87
|
+
)
|
|
88
|
+
)
|
|
89
|
+
except Exception:
|
|
90
|
+
logger.debug("Trajectory workflow finish emit failed", exc_info=True)
|
|
91
|
+
|
|
92
|
+
def abandon(self) -> None:
|
|
93
|
+
self.finished(WorkflowNodeOutcome.ABANDONED)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class WorkflowTrace:
|
|
97
|
+
"""One run's recording state; attempts are keyed by activation and attempt, never just node name."""
|
|
98
|
+
|
|
99
|
+
def __init__(self, context: TrajectoryContext, *, run_id: str, workflow_id: str) -> None:
|
|
100
|
+
self._run = _Span(
|
|
101
|
+
context,
|
|
102
|
+
EventType.WORKFLOW_RUN_STARTED,
|
|
103
|
+
EventType.WORKFLOW_RUN_FINISHED,
|
|
104
|
+
{"workflow": workflow_id, "run_id": run_id},
|
|
105
|
+
operation_id=run_id,
|
|
106
|
+
)
|
|
107
|
+
self._nodes: dict[tuple[str, int], _Span] = {}
|
|
108
|
+
self._cancelled: set[tuple[str, int]] = set()
|
|
109
|
+
|
|
110
|
+
async def started(self) -> None:
|
|
111
|
+
await self._run.started()
|
|
112
|
+
|
|
113
|
+
async def node_state(self, decision: NodeStateChanged, *, kind: str) -> None:
|
|
114
|
+
ref, state = decision.ref, decision.state
|
|
115
|
+
key = (ref.activation_id, ref.attempt)
|
|
116
|
+
span = self._nodes.get(key)
|
|
117
|
+
if span is None:
|
|
118
|
+
span = _Span(
|
|
119
|
+
self._run.context.with_run(self._run.operation_id),
|
|
120
|
+
EventType.WORKFLOW_NODE_STARTED,
|
|
121
|
+
EventType.WORKFLOW_NODE_FINISHED,
|
|
122
|
+
{
|
|
123
|
+
"run_id": ref.run_id,
|
|
124
|
+
"node": ref.node_id,
|
|
125
|
+
"activation": ref.activation_id,
|
|
126
|
+
"attempt": ref.attempt,
|
|
127
|
+
"kind": kind,
|
|
128
|
+
},
|
|
129
|
+
)
|
|
130
|
+
self._nodes[key] = span
|
|
131
|
+
await span.started()
|
|
132
|
+
if state is ActivationState.CANCELLED:
|
|
133
|
+
self._cancelled.add(key)
|
|
134
|
+
elif state in (ActivationState.RETRYING, ActivationState.AWAITING_RETRY, ActivationState.FAILED):
|
|
135
|
+
span.finished(WorkflowNodeOutcome.FAILED)
|
|
136
|
+
elif state is ActivationState.COMPLETED:
|
|
137
|
+
span.finished(WorkflowNodeOutcome.COMPLETED)
|
|
138
|
+
elif state is ActivationState.SKIPPED:
|
|
139
|
+
span.finished(WorkflowNodeOutcome.SKIPPED)
|
|
140
|
+
|
|
141
|
+
def node_context(self, activation: str, attempt: int) -> TrajectoryContext | None:
|
|
142
|
+
span = self._nodes.get((activation, attempt))
|
|
143
|
+
return span.context.with_run(span.operation_id) if span is not None else None
|
|
144
|
+
|
|
145
|
+
def finished(self, outcome: str) -> None:
|
|
146
|
+
for key, span in self._nodes.items():
|
|
147
|
+
span.finished(WorkflowNodeOutcome.CANCELLED if key in self._cancelled else WorkflowNodeOutcome.ABANDONED)
|
|
148
|
+
self._run.finished(outcome)
|
chrys/service/vision.py
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Per-agent image capability wiring."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from collections.abc import Sequence
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from chrys.kernel import GROUP_ANNOTATION_KEY, Content, FunctionTool, Message
|
|
11
|
+
from chrys.kernel import is_image_content as _is_image_content
|
|
12
|
+
from chrys.kernel.compaction import GROUP_TOKEN_COUNT_KEY, GROUP_TOKEN_ESTIMATOR_VERSION_KEY
|
|
13
|
+
from chrys.kernel.middleware import ChatContext, ChatMiddleware
|
|
14
|
+
|
|
15
|
+
VIEW_IMAGE_TOOL_NAME = "view_image"
|
|
16
|
+
# Persisted with history: token counts may describe the temporary text view
|
|
17
|
+
# even though the stored contents still contain the original image.
|
|
18
|
+
_IMAGE_STUB_TOKEN_VIEW_KEY = "_chrys_image_stub_token_view"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def filter_image_tools(tools: Sequence[Any], *, vision_enabled: bool) -> list[Any]:
|
|
22
|
+
"""Return tools with image-reading tools removed for text-only agents."""
|
|
23
|
+
if vision_enabled:
|
|
24
|
+
return list(tools)
|
|
25
|
+
return [item for item in tools if not (isinstance(item, FunctionTool) and item.name == VIEW_IMAGE_TOOL_NAME)]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def image_stub_middleware_for_model(*, vision_enabled: bool) -> ChatMiddleware:
|
|
29
|
+
"""Prepare image views and invalidate counts when their representation changes."""
|
|
30
|
+
if vision_enabled:
|
|
31
|
+
return VisionImageTokenCacheMiddleware()
|
|
32
|
+
return NonVisionImageStubMiddleware()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _invalidate_image_token_count(message: Message) -> None:
|
|
36
|
+
"""Drop only the estimate, preserving shared exclusion and summary metadata."""
|
|
37
|
+
annotation = message.additional_properties.get(GROUP_ANNOTATION_KEY)
|
|
38
|
+
if isinstance(annotation, dict):
|
|
39
|
+
annotation = dict(annotation)
|
|
40
|
+
annotation.pop(GROUP_TOKEN_COUNT_KEY, None)
|
|
41
|
+
annotation.pop(GROUP_TOKEN_ESTIMATOR_VERSION_KEY, None)
|
|
42
|
+
message.additional_properties[GROUP_ANNOTATION_KEY] = annotation
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class VisionImageTokenCacheMiddleware(ChatMiddleware):
|
|
46
|
+
"""Discard persisted placeholder estimates before sending full images."""
|
|
47
|
+
|
|
48
|
+
async def process(self, context: ChatContext, call_next: Any) -> None:
|
|
49
|
+
for message in context.messages:
|
|
50
|
+
if message.additional_properties.pop(_IMAGE_STUB_TOKEN_VIEW_KEY, False):
|
|
51
|
+
_invalidate_image_token_count(message)
|
|
52
|
+
await call_next()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class NonVisionImageStubMiddleware(ChatMiddleware):
|
|
56
|
+
"""Replace model-visible image content with text stubs for text-only models."""
|
|
57
|
+
|
|
58
|
+
async def process(self, context: ChatContext, call_next: Any) -> None:
|
|
59
|
+
replacement_messages: list[Message] = []
|
|
60
|
+
changed = False
|
|
61
|
+
for message in context.messages:
|
|
62
|
+
replacement_contents: list[Content] = []
|
|
63
|
+
message_changed = False
|
|
64
|
+
for content in message.contents:
|
|
65
|
+
replacement = _stub_content_images(content)
|
|
66
|
+
replacement_contents.append(replacement)
|
|
67
|
+
if replacement is not content:
|
|
68
|
+
message_changed = True
|
|
69
|
+
if message_changed:
|
|
70
|
+
# The history retains the image, but this call counts its stub.
|
|
71
|
+
# Invalidate on every replacement: an earlier full-history
|
|
72
|
+
# annotation may have counted the original image in between calls.
|
|
73
|
+
_invalidate_image_token_count(message)
|
|
74
|
+
message.additional_properties[_IMAGE_STUB_TOKEN_VIEW_KEY] = True
|
|
75
|
+
refreshed = Message(
|
|
76
|
+
message.role,
|
|
77
|
+
replacement_contents,
|
|
78
|
+
author_name=message.author_name,
|
|
79
|
+
message_id=message.message_id,
|
|
80
|
+
raw_representation=message.raw_representation,
|
|
81
|
+
)
|
|
82
|
+
# Downstream compaction flags must write through to owned history.
|
|
83
|
+
refreshed.additional_properties = message.additional_properties
|
|
84
|
+
replacement_messages.append(refreshed)
|
|
85
|
+
changed = True
|
|
86
|
+
else:
|
|
87
|
+
replacement_messages.append(message)
|
|
88
|
+
if changed:
|
|
89
|
+
context.messages = replacement_messages
|
|
90
|
+
await call_next()
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _stub_content_images(content: Content) -> Content:
|
|
94
|
+
if content.type == "function_result" and content.items:
|
|
95
|
+
replacement_items: list[Content] = []
|
|
96
|
+
changed = False
|
|
97
|
+
for item in content.items:
|
|
98
|
+
replacement = _stub_direct_image(item)
|
|
99
|
+
replacement_items.append(replacement)
|
|
100
|
+
if replacement is not item:
|
|
101
|
+
changed = True
|
|
102
|
+
if not changed:
|
|
103
|
+
return content
|
|
104
|
+
return Content.from_function_result(
|
|
105
|
+
content.call_id or "",
|
|
106
|
+
result=replacement_items,
|
|
107
|
+
exception=content.exception,
|
|
108
|
+
annotations=content.annotations,
|
|
109
|
+
additional_properties=content.additional_properties,
|
|
110
|
+
raw_representation=content.raw_representation,
|
|
111
|
+
)
|
|
112
|
+
return _stub_direct_image(content)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def _stub_direct_image(content: Content) -> Content:
|
|
116
|
+
if not _is_image_content(content):
|
|
117
|
+
return content
|
|
118
|
+
return Content.from_text(_image_stub_text(content), annotations=content.annotations)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _image_stub_text(content: Content) -> str:
|
|
122
|
+
props = content.additional_properties
|
|
123
|
+
width = props.get("width")
|
|
124
|
+
height = props.get("height")
|
|
125
|
+
media_type = content.media_type or props.get("media_type") or "image"
|
|
126
|
+
if isinstance(width, int) and isinstance(height, int) and width > 0 and height > 0:
|
|
127
|
+
return f"[image {width}x{height} {media_type} omitted: model is not vision-capable]"
|
|
128
|
+
return f"[image {media_type} omitted: model is not vision-capable]"
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Manifest admission: the spec digest, and the agent/model binding every agent node needs before a run starts.
|
|
4
|
+
|
|
5
|
+
Admission is deterministic and runs no user code. It validates the data-only
|
|
6
|
+
manifest as a graph, then binds each agent node to the profile and model the
|
|
7
|
+
run will use. The binding snapshot is what ``run.json`` and
|
|
8
|
+
``WorkflowRunStarted`` carry, so the user sees exactly which agent and model
|
|
9
|
+
each node runs on, and the shell opens the same objects at activation time.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import hashlib
|
|
15
|
+
from collections.abc import Mapping
|
|
16
|
+
from dataclasses import dataclass
|
|
17
|
+
from types import MappingProxyType
|
|
18
|
+
from typing import Any, Final
|
|
19
|
+
|
|
20
|
+
from chrys.foundation.config.settings import Settings
|
|
21
|
+
from chrys.service.llm.clients import effective_model_base_url
|
|
22
|
+
from chrys.service.profiles.agents.registry import AgentProfileRegistry
|
|
23
|
+
from chrys.service.profiles.agents.schema import AgentProfile
|
|
24
|
+
from chrys.service.profiles.models.registry import ModelProfileRegistry
|
|
25
|
+
from chrys.service.profiles.models.resolver import resolve_for_agent, resolve_selectable_profile
|
|
26
|
+
from chrys.service.profiles.models.schema import ModelProfile, is_model_profile_selectable
|
|
27
|
+
from chrys.service.session.sub_agent_logs import sanitize_base_url_origin
|
|
28
|
+
from chrys.service.workflows.graph import KIND_AGENT, GraphSpec, ManifestError
|
|
29
|
+
from chrys.service.workflows.values import canonical_json
|
|
30
|
+
|
|
31
|
+
REJECT_MANIFEST_INVALID: Final = "manifest_invalid"
|
|
32
|
+
REJECT_AGENT_PROFILE_MISSING: Final = "agent_profile_missing"
|
|
33
|
+
REJECT_MODEL_UNRESOLVABLE: Final = "model_unresolvable"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class AdmissionError(Exception):
|
|
37
|
+
"""The manifest cannot be run against the current registries; ``code`` is the rejection reason.
|
|
38
|
+
|
|
39
|
+
``node_id`` names the agent node that could not be bound, when one is at fault.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
def __init__(self, code: str, message: str, *, node_id: str | None = None) -> None:
|
|
43
|
+
super().__init__(message)
|
|
44
|
+
self.code = code
|
|
45
|
+
self.message = message
|
|
46
|
+
self.node_id = node_id
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def spec_digest(entry_digest: str, manifest_digest: str, schema_version: int) -> str:
|
|
50
|
+
"""One digest over the triple the worker reports; the ledger and every run record pin this."""
|
|
51
|
+
payload = canonical_json({"entry": entry_digest, "manifest": manifest_digest, "schema": schema_version})
|
|
52
|
+
return hashlib.sha256(payload.encode("utf-8")).hexdigest()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@dataclass(frozen=True, slots=True)
|
|
56
|
+
class AgentBinding:
|
|
57
|
+
"""The profile and model an agent node runs on, plus the data-only snapshot the run records."""
|
|
58
|
+
|
|
59
|
+
node_id: str
|
|
60
|
+
agent: AgentProfile
|
|
61
|
+
model: ModelProfile | None
|
|
62
|
+
instructions_suffix: str
|
|
63
|
+
|
|
64
|
+
def snapshot(self) -> dict[str, Any]:
|
|
65
|
+
model = self.model
|
|
66
|
+
acp = self.agent.acp
|
|
67
|
+
return {
|
|
68
|
+
"node_id": self.node_id,
|
|
69
|
+
"agent": self.agent.name,
|
|
70
|
+
"agent_id": self.agent.id,
|
|
71
|
+
"agent_display_name": self.agent.display_name or self.agent.name,
|
|
72
|
+
"acp": self.agent.acp is not None,
|
|
73
|
+
"model_profile_id": model.id if model is not None else "",
|
|
74
|
+
"model_profile_name": model.name if model is not None else "",
|
|
75
|
+
"provider": model.provider if model is not None else "",
|
|
76
|
+
"api_style": model.api_style if model is not None else "",
|
|
77
|
+
"model_id": model.model_id if model is not None else acp.model_id if acp is not None else "",
|
|
78
|
+
"base_url_origin": sanitize_base_url_origin(effective_model_base_url(model)) if model is not None else "",
|
|
79
|
+
"instructions_suffix": self.instructions_suffix,
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@dataclass(frozen=True, slots=True)
|
|
84
|
+
class AdmittedManifest:
|
|
85
|
+
graph: GraphSpec
|
|
86
|
+
bindings: Mapping[str, AgentBinding]
|
|
87
|
+
|
|
88
|
+
def binding(self, node_id: str) -> AgentBinding:
|
|
89
|
+
return self.bindings[node_id]
|
|
90
|
+
|
|
91
|
+
def resolved_nodes(self) -> list[dict[str, Any]]:
|
|
92
|
+
return [binding.snapshot() for binding in self.bindings.values()]
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def admit_manifest(
|
|
96
|
+
manifest: Mapping[str, Any],
|
|
97
|
+
*,
|
|
98
|
+
agent_registry: AgentProfileRegistry,
|
|
99
|
+
model_registry: ModelProfileRegistry | None,
|
|
100
|
+
settings: Settings,
|
|
101
|
+
) -> AdmittedManifest:
|
|
102
|
+
"""Validate the manifest as a graph and bind every agent node, in node order.
|
|
103
|
+
|
|
104
|
+
Agent nodes name a profile by selector (id, name or display name); a node
|
|
105
|
+
that names a model resolves it as a selectable profile, otherwise the
|
|
106
|
+
profile's own model binding applies exactly as it does for a sub-agent.
|
|
107
|
+
ACP profiles use their remote model id unless the node explicitly overrides
|
|
108
|
+
it with a selectable Chrys model profile; no kernel client is constructed.
|
|
109
|
+
"""
|
|
110
|
+
try:
|
|
111
|
+
graph = GraphSpec.from_manifest(manifest)
|
|
112
|
+
except ManifestError as exc:
|
|
113
|
+
raise AdmissionError(REJECT_MANIFEST_INVALID, str(exc)) from exc
|
|
114
|
+
bindings: dict[str, AgentBinding] = {}
|
|
115
|
+
for node_id in graph.node_order:
|
|
116
|
+
node = graph.nodes[node_id]
|
|
117
|
+
if node.kind != KIND_AGENT:
|
|
118
|
+
continue
|
|
119
|
+
agent = node.agent
|
|
120
|
+
if agent is None:
|
|
121
|
+
raise RuntimeError("A validated agent node has no agent specification.")
|
|
122
|
+
selector = agent.profile
|
|
123
|
+
profile = agent_registry.resolve_selector(selector)
|
|
124
|
+
if profile is None:
|
|
125
|
+
raise AdmissionError(
|
|
126
|
+
REJECT_AGENT_PROFILE_MISSING,
|
|
127
|
+
f"Node {node_id!r} names agent profile {selector!r}, which is not available.",
|
|
128
|
+
node_id=node_id,
|
|
129
|
+
)
|
|
130
|
+
model_selector = agent.model
|
|
131
|
+
if profile.acp is not None and not model_selector:
|
|
132
|
+
bindings[node_id] = AgentBinding(node_id, profile, None, agent.instructions_suffix)
|
|
133
|
+
continue
|
|
134
|
+
if model_selector is not None:
|
|
135
|
+
model = resolve_selectable_profile(model_registry, model_selector)
|
|
136
|
+
if model is None:
|
|
137
|
+
raise AdmissionError(
|
|
138
|
+
REJECT_MODEL_UNRESOLVABLE,
|
|
139
|
+
f"Node {node_id!r} names model profile {model_selector!r}, which is not available.",
|
|
140
|
+
node_id=node_id,
|
|
141
|
+
)
|
|
142
|
+
else:
|
|
143
|
+
model = resolve_for_agent(model_registry, settings, profile)
|
|
144
|
+
if not is_model_profile_selectable(model):
|
|
145
|
+
raise AdmissionError(
|
|
146
|
+
REJECT_MODEL_UNRESOLVABLE,
|
|
147
|
+
f"Node {node_id!r} has no usable model: agent profile {profile.name!r} resolves to no model.",
|
|
148
|
+
node_id=node_id,
|
|
149
|
+
)
|
|
150
|
+
bindings[node_id] = AgentBinding(node_id, profile, model, agent.instructions_suffix)
|
|
151
|
+
return AdmittedManifest(graph, MappingProxyType(bindings))
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Session run listings and narrow, path-based workflow artifact readers."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
from chrys.foundation.events import types as events
|
|
12
|
+
from chrys.foundation.platform.files import read_owner_verified_bounded
|
|
13
|
+
from chrys.service.workflows.discovery import MAX_SOURCE_BYTES
|
|
14
|
+
from chrys.service.workflows.layout import SOURCE_FILE, iter_run_dirs
|
|
15
|
+
from chrys.service.workflows.orphans import read_run_terminal
|
|
16
|
+
from chrys.service.workflows.records import RunRecord, decode_run_event
|
|
17
|
+
from chrys.service.workflows.store import (
|
|
18
|
+
NODE_RECORD_INPUT,
|
|
19
|
+
NODE_RECORD_OUTPUT,
|
|
20
|
+
RunTerminal,
|
|
21
|
+
node_stderr_path,
|
|
22
|
+
read_node_diagnostics,
|
|
23
|
+
read_node_emits,
|
|
24
|
+
read_node_value,
|
|
25
|
+
read_run_events,
|
|
26
|
+
read_run_header,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass(frozen=True, slots=True)
|
|
31
|
+
class NodeRecords:
|
|
32
|
+
input: dict[str, Any] | None
|
|
33
|
+
output: dict[str, Any] | None
|
|
34
|
+
emits: list[tuple[int, str]]
|
|
35
|
+
diagnostics: dict[str, Any] | None
|
|
36
|
+
stderr_path: Path | None = None
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass(frozen=True, slots=True)
|
|
40
|
+
class WorkflowRunRecord:
|
|
41
|
+
"""A header-only history entry; larger artifacts are read only when requested."""
|
|
42
|
+
|
|
43
|
+
directory: Path
|
|
44
|
+
header: dict[str, Any]
|
|
45
|
+
terminal: RunTerminal | None = None
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def read_node_records(directory: Path, activation_id: str, attempt: int, *, node_kind: str = "") -> NodeRecords:
|
|
49
|
+
stderr = node_stderr_path(directory, activation_id)
|
|
50
|
+
return NodeRecords(
|
|
51
|
+
input=read_node_value(directory, activation_id, attempt, NODE_RECORD_INPUT, node_kind=node_kind),
|
|
52
|
+
output=read_node_value(directory, activation_id, attempt, NODE_RECORD_OUTPUT, node_kind=node_kind),
|
|
53
|
+
emits=read_node_emits(directory, activation_id, attempt),
|
|
54
|
+
diagnostics=read_node_diagnostics(directory, activation_id, attempt),
|
|
55
|
+
stderr_path=stderr if stderr.is_file() else None,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def read_node_output(
|
|
60
|
+
directory: Path, activation_id: str, attempt: int, *, node_kind: str = ""
|
|
61
|
+
) -> dict[str, Any] | None:
|
|
62
|
+
"""Read a result without loading its input, emit log or diagnostics."""
|
|
63
|
+
return read_node_value(directory, activation_id, attempt, NODE_RECORD_OUTPUT, node_kind=node_kind)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def read_run_source(directory: Path) -> bytes:
|
|
67
|
+
return read_owner_verified_bounded(directory / SOURCE_FILE, max_bytes=MAX_SOURCE_BYTES)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def session_runs(session_dir: Path) -> list[WorkflowRunRecord]:
|
|
71
|
+
"""Read and order headers once when a caller needs history for multiple sources."""
|
|
72
|
+
try:
|
|
73
|
+
directories, _truncated = iter_run_dirs(session_dir)
|
|
74
|
+
except OSError:
|
|
75
|
+
return []
|
|
76
|
+
records: list[WorkflowRunRecord] = []
|
|
77
|
+
for directory in directories:
|
|
78
|
+
try:
|
|
79
|
+
header = read_run_header(directory)
|
|
80
|
+
except OSError, ValueError:
|
|
81
|
+
continue
|
|
82
|
+
try:
|
|
83
|
+
terminal = read_run_terminal(directory)
|
|
84
|
+
except OSError, ValueError:
|
|
85
|
+
terminal = None
|
|
86
|
+
records.append(WorkflowRunRecord(directory, header, terminal))
|
|
87
|
+
records.sort(key=lambda record: str(record.header.get("started_at", "")), reverse=True)
|
|
88
|
+
return records
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def latest_node_output(directory: Path, node_id: str, *, node_kind: str) -> dict[str, Any] | None:
|
|
92
|
+
"""Locate one node's latest stored result without projecting a run or reading usage archives."""
|
|
93
|
+
candidates: dict[tuple[str, int], None] = {}
|
|
94
|
+
for record in read_run_events(directory).events:
|
|
95
|
+
if (
|
|
96
|
+
record.event_type not in (RunRecord.NODE_STATE, RunRecord.NODE_OUTPUT)
|
|
97
|
+
or record.payload.get("node") != node_id
|
|
98
|
+
):
|
|
99
|
+
continue
|
|
100
|
+
event = decode_run_event(record, directory=directory)
|
|
101
|
+
if isinstance(event, events.WorkflowNodeStateChanged) or (
|
|
102
|
+
isinstance(event, events.WorkflowNodeOutput) and event.kind == events.WORKFLOW_OUTPUT_FINAL
|
|
103
|
+
):
|
|
104
|
+
candidates[event.activation_id, event.attempt] = None
|
|
105
|
+
for activation_id, attempt in reversed(candidates):
|
|
106
|
+
output = read_node_output(directory, activation_id, attempt, node_kind=node_kind)
|
|
107
|
+
if output is not None:
|
|
108
|
+
return output
|
|
109
|
+
return None
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""The main-process side of ``ctx.ask``: wire questions in, answers out, bounded summaries.
|
|
4
|
+
|
|
5
|
+
The SDK (``sdk/_ask.py``) guarantees every rule :func:`questions_from_wire`
|
|
6
|
+
checks, so a violation means a broken worker and ends the connection. The
|
|
7
|
+
chat ask-user model carries the questions to the dialog and back; answers are
|
|
8
|
+
validated by the shared :func:`validate_ask_user_answers` before they get here.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from typing import Any, cast
|
|
14
|
+
|
|
15
|
+
from chrys.foundation.models.ask_user import (
|
|
16
|
+
MAX_ASK_USER_DESCRIPTION_CHARS,
|
|
17
|
+
MAX_ASK_USER_HEADER_CHARS,
|
|
18
|
+
MAX_ASK_USER_LABEL_CHARS,
|
|
19
|
+
MAX_ASK_USER_OPTIONS,
|
|
20
|
+
MAX_ASK_USER_QUESTIONS,
|
|
21
|
+
AskUserAnswer,
|
|
22
|
+
AskUserOption,
|
|
23
|
+
AskUserQuestion,
|
|
24
|
+
)
|
|
25
|
+
from chrys.foundation.util.unicode_scalars import find_unpaired_surrogate
|
|
26
|
+
from chrys.service.workflows.protocol import ProtocolError
|
|
27
|
+
|
|
28
|
+
_QUESTION_KEYS = frozenset({"question", "header", "options", "multi_select"})
|
|
29
|
+
_OPTION_KEYS = frozenset({"label", "description"})
|
|
30
|
+
NO_ANSWER = "(no answer)"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def questions_from_wire(raw: object) -> tuple[AskUserQuestion, ...]:
|
|
34
|
+
"""Strictly decode an ask frame's ``questions``; raises :class:`ProtocolError`."""
|
|
35
|
+
if type(raw) is not list or not 1 <= len(raw) <= MAX_ASK_USER_QUESTIONS:
|
|
36
|
+
raise ProtocolError(f"ask needs 1 to {MAX_ASK_USER_QUESTIONS} questions.")
|
|
37
|
+
return tuple(_question_from_wire(item) for item in raw)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _text(raw: dict[str, object], key: str, limit: int | None = None) -> str:
|
|
41
|
+
value = raw[key]
|
|
42
|
+
if type(value) is not str or find_unpaired_surrogate(value) >= 0:
|
|
43
|
+
raise ProtocolError(f"ask {key} must be valid text.")
|
|
44
|
+
if limit is not None and len(value) > limit:
|
|
45
|
+
raise ProtocolError(f"ask {key} is longer than {limit} characters.")
|
|
46
|
+
return value
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _question_from_wire(item: object) -> AskUserQuestion:
|
|
50
|
+
if type(item) is not dict or set(item) != _QUESTION_KEYS:
|
|
51
|
+
raise ProtocolError("ask question is malformed.")
|
|
52
|
+
raw = cast("dict[str, object]", item)
|
|
53
|
+
question = _text(raw, "question")
|
|
54
|
+
if not question.strip():
|
|
55
|
+
raise ProtocolError("ask question is blank.")
|
|
56
|
+
header = _text(raw, "header", MAX_ASK_USER_HEADER_CHARS)
|
|
57
|
+
multi_select = raw["multi_select"]
|
|
58
|
+
options_raw = raw["options"]
|
|
59
|
+
if type(multi_select) is not bool:
|
|
60
|
+
raise ProtocolError("ask multi_select must be a bool.")
|
|
61
|
+
if type(options_raw) is not list or len(options_raw) > MAX_ASK_USER_OPTIONS:
|
|
62
|
+
raise ProtocolError(f"ask options must be a list of at most {MAX_ASK_USER_OPTIONS}.")
|
|
63
|
+
options = tuple(_option_from_wire(option) for option in options_raw)
|
|
64
|
+
labels = {option.label for option in options}
|
|
65
|
+
if len(labels) != len(options):
|
|
66
|
+
raise ProtocolError("ask option labels must be unique.")
|
|
67
|
+
if multi_select and not options:
|
|
68
|
+
raise ProtocolError("ask multi_select needs options.")
|
|
69
|
+
return AskUserQuestion(question=question, header=header, options=options, multi_select=multi_select)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _option_from_wire(item: object) -> AskUserOption:
|
|
73
|
+
if type(item) is not dict or set(item) != _OPTION_KEYS:
|
|
74
|
+
raise ProtocolError("ask option is malformed.")
|
|
75
|
+
raw = cast("dict[str, object]", item)
|
|
76
|
+
label = _text(raw, "label", MAX_ASK_USER_LABEL_CHARS)
|
|
77
|
+
# The shared answer validator strips values, so only a stripped label can come back selected.
|
|
78
|
+
if not label or label != label.strip():
|
|
79
|
+
raise ProtocolError("ask option label must be stripped and non-empty.")
|
|
80
|
+
return AskUserOption(label=label, description=_text(raw, "description", MAX_ASK_USER_DESCRIPTION_CHARS))
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def answers_to_wire(questions: tuple[AskUserQuestion, ...], answers: tuple[AskUserAnswer, ...]) -> list[dict[str, Any]]:
|
|
84
|
+
"""Map validated answers to the SDK's ``{"selected", "text"}`` shape.
|
|
85
|
+
|
|
86
|
+
Values naming offered labels are the selection (option order) and the note
|
|
87
|
+
is the text; a single other value is custom text. The dialog records no
|
|
88
|
+
click provenance, so a typed label counts as selected.
|
|
89
|
+
"""
|
|
90
|
+
wire: list[dict[str, Any]] = []
|
|
91
|
+
for question, answer in zip(questions, answers, strict=True):
|
|
92
|
+
labels = [option.label for option in question.options]
|
|
93
|
+
if answer.values and all(value in labels for value in answer.values):
|
|
94
|
+
chosen = set(answer.values)
|
|
95
|
+
wire.append({"selected": [label for label in labels if label in chosen], "text": answer.note})
|
|
96
|
+
elif len(answer.values) == 1 and not answer.note:
|
|
97
|
+
wire.append({"selected": [], "text": answer.values[0]})
|
|
98
|
+
elif not answer.values and not answer.note:
|
|
99
|
+
wire.append({"selected": [], "text": ""})
|
|
100
|
+
else:
|
|
101
|
+
raise ValueError("Workflow ask answers must be validated before they are mapped.")
|
|
102
|
+
return wire
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _prefix(index: int, question: AskUserQuestion) -> str:
|
|
106
|
+
return question.header or f"Q{index + 1}"
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _answer_text(answer: AskUserAnswer) -> str:
|
|
110
|
+
text = ", ".join(answer.values)
|
|
111
|
+
if answer.note:
|
|
112
|
+
text = f"{text} — {answer.note}"
|
|
113
|
+
return text or NO_ANSWER
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def ask_summary(questions: tuple[AskUserQuestion, ...]) -> str:
|
|
117
|
+
"""English text for the run store, each of several questions under its header (the journal bounds it)."""
|
|
118
|
+
if len(questions) == 1:
|
|
119
|
+
return questions[0].question
|
|
120
|
+
return "\n".join(f"{_prefix(index, question)}: {question.question}" for index, question in enumerate(questions))
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def answer_summary(questions: tuple[AskUserQuestion, ...], answers: tuple[AskUserAnswer, ...]) -> str:
|
|
124
|
+
"""English text for the run store and ``WorkflowNodeAnswered``, each of several answers under its header."""
|
|
125
|
+
if len(answers) == 1:
|
|
126
|
+
return _answer_text(answers[0])
|
|
127
|
+
return "\n".join(
|
|
128
|
+
f"{_prefix(index, question)}: {_answer_text(answer)}"
|
|
129
|
+
for index, (question, answer) in enumerate(zip(questions, answers, strict=True))
|
|
130
|
+
)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Workflow templates shipped with chrys.
|
|
4
|
+
|
|
5
|
+
Every ``*.py`` file here is a workflow the discovery layer lists under the
|
|
6
|
+
``builtin`` source kind, shadowed by a user file of the same id. Templates are
|
|
7
|
+
standard-library only and run on the default interpreter: a read-only install
|
|
8
|
+
location cannot depend on anything the user's machine happens to provide. A
|
|
9
|
+
``<id>.manifest.json`` sibling is the template's pre-generated manifest, so
|
|
10
|
+
listings show its metadata without executing the file. Templates carry no
|
|
11
|
+
copyright header: users copy them as the start of their own workflows.
|
|
12
|
+
"""
|