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,510 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""InjectionMiddleware — delivers user messages sent during agent execution.
|
|
4
|
+
|
|
5
|
+
When a user sends a message while the agent is running (mid-tool-loop),
|
|
6
|
+
the text is queued and appended to the messages before the next LLM call.
|
|
7
|
+
|
|
8
|
+
This is a **ChatMiddleware** (fires per LLM call within the tool loop).
|
|
9
|
+
Before each model call, any pending injection texts are appended to
|
|
10
|
+
``context.messages`` so the LLM sees them on its next iteration.
|
|
11
|
+
|
|
12
|
+
Persistence is handled separately by the engine after agent.run() completes,
|
|
13
|
+
to ensure correct message ordering in the session history.
|
|
14
|
+
|
|
15
|
+
One middleware drain is an immutable transaction: all clean wire messages and
|
|
16
|
+
retry records are created before the first callback await. A transient retry
|
|
17
|
+
replays that transaction outside the cancellable pending queue, preserving its
|
|
18
|
+
consumption identities while re-anchoring it to the successful attempt.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import hashlib
|
|
24
|
+
import json
|
|
25
|
+
import weakref
|
|
26
|
+
from copy import copy
|
|
27
|
+
from dataclasses import dataclass, field, replace
|
|
28
|
+
from datetime import datetime
|
|
29
|
+
from typing import TYPE_CHECKING, Any
|
|
30
|
+
from uuid import uuid4
|
|
31
|
+
|
|
32
|
+
from chrys.foundation.models.history_markers import HistoryMarkerKind, copy_reminder_record
|
|
33
|
+
from chrys.foundation.trajectory.ids import new_analytics_id
|
|
34
|
+
from chrys.foundation.trajectory.metadata import ensure_analytics_item_id
|
|
35
|
+
from chrys.kernel import Content, Message
|
|
36
|
+
from chrys.kernel.identity import ContentList
|
|
37
|
+
from chrys.kernel.middleware import ChatMiddleware
|
|
38
|
+
|
|
39
|
+
if TYPE_CHECKING:
|
|
40
|
+
from collections.abc import Awaitable, Callable
|
|
41
|
+
|
|
42
|
+
from chrys.kernel.middleware import ChatContext
|
|
43
|
+
from chrys.service.trajectory.preparation import PreparationTrace
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _message_call_ids(msg: Message) -> tuple[str, ...]:
|
|
47
|
+
"""Return call ids carried by framework content items."""
|
|
48
|
+
return tuple(c.call_id for c in msg.contents if c.call_id)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _content_signature(msg: Message) -> tuple[tuple[str, str | None, str | None, str], ...]:
|
|
52
|
+
"""Return a stable, compact signature for message contents."""
|
|
53
|
+
parts: list[tuple[str, str | None, str | None, str]] = []
|
|
54
|
+
for content in msg.contents:
|
|
55
|
+
content_type = content.type
|
|
56
|
+
call_id = content.call_id or None
|
|
57
|
+
name = content.name or None
|
|
58
|
+
payload = _content_payload(content, content_type)
|
|
59
|
+
parts.append((content_type, call_id, name, _payload_digest(payload)))
|
|
60
|
+
return tuple(parts)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _content_payload(content: Content, content_type: str) -> Any:
|
|
64
|
+
if content_type == "function_call":
|
|
65
|
+
return content.arguments
|
|
66
|
+
if content_type == "function_result":
|
|
67
|
+
return content.result
|
|
68
|
+
if content_type == "text":
|
|
69
|
+
return content.text
|
|
70
|
+
return content.to_dict()
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _payload_digest(payload: Any) -> str:
|
|
74
|
+
try:
|
|
75
|
+
data = json.dumps(payload, sort_keys=True, default=str, ensure_ascii=False)
|
|
76
|
+
except TypeError:
|
|
77
|
+
data = str(payload)
|
|
78
|
+
return hashlib.sha256(data.encode("utf-8", errors="surrogatepass")).hexdigest()
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@dataclass(frozen=True)
|
|
82
|
+
class QueuedInjection:
|
|
83
|
+
"""A user injection waiting to be delivered to the next model call."""
|
|
84
|
+
|
|
85
|
+
text: str
|
|
86
|
+
created_at: datetime | str | None = None
|
|
87
|
+
injection_id: str | None = None
|
|
88
|
+
reminders: tuple[str, ...] = ()
|
|
89
|
+
"""Hook/skill reminders for this injection. They join the turn's reminders
|
|
90
|
+
only when a call drains it, so they ride the very call that sends the text;
|
|
91
|
+
a cancelled or undelivered injection never queues them."""
|
|
92
|
+
consumption_id: str | None = None
|
|
93
|
+
"""Stable persistence identity after the first retryable consumption."""
|
|
94
|
+
analytics_item_id: str | None = None
|
|
95
|
+
"""Stable trajectory identity shared by wire, retry and persisted copies."""
|
|
96
|
+
preparation: PreparationTrace | None = None
|
|
97
|
+
"""Input-admission trace whose terminal is owned by this queued item."""
|
|
98
|
+
target_turn_id: str | None = None
|
|
99
|
+
"""Turn captured when ownership moved out of the admission coroutine."""
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@dataclass(frozen=True)
|
|
103
|
+
class InjectionAnchor:
|
|
104
|
+
"""Where a consumed injection should land in persisted state.
|
|
105
|
+
|
|
106
|
+
Captures multiple identifying keys because no single one survives every
|
|
107
|
+
framework path:
|
|
108
|
+
|
|
109
|
+
- ``contents_ref``: weak reference to the anchor message's ``contents``
|
|
110
|
+
list. Stable in **non-streaming** runs (state stores the same Message
|
|
111
|
+
instances the middleware saw). Lost in **streaming** runs because
|
|
112
|
+
``ChatResponse.from_updates`` / ``AgentResponse.from_updates`` rebuild
|
|
113
|
+
every Message from stream updates with brand-new contents lists.
|
|
114
|
+
|
|
115
|
+
- ``content_refs``: weak references to the content OBJECTS themselves.
|
|
116
|
+
The kernel wire hands middleware per-call message views — fresh
|
|
117
|
+
wrapper + fresh contents list — so ``contents_ref`` never matches
|
|
118
|
+
state for a viewed message, but the content objects are shared and
|
|
119
|
+
each lives in exactly one state message.
|
|
120
|
+
|
|
121
|
+
Identity tiers are WEAK: a dead reference matches nothing (a recycled
|
|
122
|
+
address can never false-match) and an anchor never keeps its source
|
|
123
|
+
alive; placement degrades to the structural fallback, exactly the
|
|
124
|
+
streaming-rebuild path.
|
|
125
|
+
|
|
126
|
+
- ``role`` + ``call_ids``: the anchor message's role together with the
|
|
127
|
+
tuple of ``call_id`` values from its ``function_call`` /
|
|
128
|
+
``function_result`` contents. Role
|
|
129
|
+
is required because an assistant ``function_call`` and the matching
|
|
130
|
+
tool ``function_result`` share the same call_id; without role the
|
|
131
|
+
injection would land after the assistant call instead of after the
|
|
132
|
+
tool result. This pair is kept as a fallback because it survives
|
|
133
|
+
streaming rebuilds, but exact identity/message_id are preferred first
|
|
134
|
+
since call ids can be reused by tests, providers, or old replayed
|
|
135
|
+
sessions.
|
|
136
|
+
|
|
137
|
+
- ``message_id``: framework-assigned ``Message.message_id`` when set
|
|
138
|
+
(typically on assistant LLM responses).
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
role: str | None = None
|
|
142
|
+
contents_ref: weakref.ref[ContentList] | None = None
|
|
143
|
+
call_ids: tuple[str, ...] = ()
|
|
144
|
+
content_signature: tuple[tuple[str, str | None, str | None, str], ...] = ()
|
|
145
|
+
message_id: str | None = None
|
|
146
|
+
content_refs: tuple[weakref.ref[Content], ...] = ()
|
|
147
|
+
|
|
148
|
+
@classmethod
|
|
149
|
+
def from_message(cls, msg: Message | None) -> InjectionAnchor:
|
|
150
|
+
"""Build an anchor from the live message the injection lands after."""
|
|
151
|
+
if msg is None:
|
|
152
|
+
return cls()
|
|
153
|
+
return cls(
|
|
154
|
+
role=msg.role,
|
|
155
|
+
contents_ref=weakref.ref(msg.contents),
|
|
156
|
+
call_ids=_message_call_ids(msg),
|
|
157
|
+
content_signature=_content_signature(msg),
|
|
158
|
+
message_id=msg.message_id or None,
|
|
159
|
+
content_refs=tuple(weakref.ref(c) for c in msg.contents),
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
def find_in(self, messages: list[Message]) -> int | None:
|
|
163
|
+
"""Return the index of the first matching message, or ``None``.
|
|
164
|
+
|
|
165
|
+
Tries each captured key in turn so a single missing key does not
|
|
166
|
+
block placement:
|
|
167
|
+
|
|
168
|
+
1. ``contents_ref`` — exact identity match (non-streaming runs),
|
|
169
|
+
accepted only when captured structural keys also agree.
|
|
170
|
+
2. ``content_refs`` — exact identity of the shared content objects,
|
|
171
|
+
for anchors captured from per-call wire views whose fresh
|
|
172
|
+
contents lists defeat ``contents_ref``.
|
|
173
|
+
3. ``message_id`` — the assistant response's Message identifier,
|
|
174
|
+
accepted only when captured structural keys also agree.
|
|
175
|
+
4. ``role`` + content signature / ``call_ids`` — survives the
|
|
176
|
+
streaming rebuild and disambiguates assistant function_call from
|
|
177
|
+
tool function_result (both carry the same call_ids). Search from
|
|
178
|
+
the end so a duplicate call_id in an earlier turn cannot steal
|
|
179
|
+
the anchor.
|
|
180
|
+
"""
|
|
181
|
+
snapshot = self.contents_ref() if self.contents_ref is not None else None
|
|
182
|
+
if snapshot is not None:
|
|
183
|
+
for i, m in enumerate(messages):
|
|
184
|
+
if m.contents is snapshot and self._matches_shape(m):
|
|
185
|
+
return i
|
|
186
|
+
# The wire hands clients per-call views: fresh wrapper + fresh
|
|
187
|
+
# contents LIST, but the content OBJECTS are shared with the state
|
|
188
|
+
# original — matching on their identity keeps identity-level
|
|
189
|
+
# precision for anchors snapshotted from a view. A dead ref matches
|
|
190
|
+
# nothing: ``ref() is c`` cannot hold for a live content.
|
|
191
|
+
if self.content_refs:
|
|
192
|
+
for i, m in enumerate(messages):
|
|
193
|
+
if (
|
|
194
|
+
len(m.contents) == len(self.content_refs)
|
|
195
|
+
and all(ref() is c for ref, c in zip(self.content_refs, m.contents, strict=True))
|
|
196
|
+
and self._matches_shape(m)
|
|
197
|
+
):
|
|
198
|
+
return i
|
|
199
|
+
if self.message_id:
|
|
200
|
+
for i, m in enumerate(messages):
|
|
201
|
+
if m.message_id == self.message_id and self._matches_shape(m):
|
|
202
|
+
return i
|
|
203
|
+
if self.content_signature or self.call_ids:
|
|
204
|
+
for i in range(len(messages) - 1, -1, -1):
|
|
205
|
+
m = messages[i]
|
|
206
|
+
if self._matches_shape(m):
|
|
207
|
+
return i
|
|
208
|
+
return None
|
|
209
|
+
|
|
210
|
+
def _matches_shape(self, msg: Message) -> bool:
|
|
211
|
+
"""Return whether *msg* matches the stable structural anchor keys."""
|
|
212
|
+
if self.role is not None and msg.role != self.role:
|
|
213
|
+
return False
|
|
214
|
+
if self.call_ids and _message_call_ids(msg) != self.call_ids:
|
|
215
|
+
return False
|
|
216
|
+
return not self.content_signature or _content_signature(msg) == self.content_signature
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
@dataclass(frozen=True)
|
|
220
|
+
class ConsumedInjection:
|
|
221
|
+
"""A delivered injection and the persisted-history anchor it should follow.
|
|
222
|
+
|
|
223
|
+
Two identities, deliberately distinct:
|
|
224
|
+
|
|
225
|
+
* ``injection_id`` — the frontend's queue handle, round-tripped
|
|
226
|
+
UNCHANGED into ``UserInjectResult`` (``None`` for frontends without
|
|
227
|
+
pending tracking, e.g. the ACP path; the TUI keys input-ownership on
|
|
228
|
+
exactly this value, so a synthesized id here would break its
|
|
229
|
+
id-less-legacy branch).
|
|
230
|
+
* ``consumption_id`` — the per-consumption persistence identity, always
|
|
231
|
+
populated by :meth:`InjectionMiddleware.process` (the queue handle
|
|
232
|
+
when present, synthesized otherwise). Crash-recovery replay dedups
|
|
233
|
+
on it; ``None`` only for hand-built legacy values, which fall back to
|
|
234
|
+
text matching.
|
|
235
|
+
"""
|
|
236
|
+
|
|
237
|
+
text: str
|
|
238
|
+
anchor: InjectionAnchor
|
|
239
|
+
created_at: datetime | str | None = None
|
|
240
|
+
injection_id: str | None = None
|
|
241
|
+
consumption_id: str | None = None
|
|
242
|
+
analytics_item_id: str | None = None
|
|
243
|
+
preparation: PreparationTrace | None = None
|
|
244
|
+
target_turn_id: str | None = None
|
|
245
|
+
wire_properties: dict[str, Any] | None = field(default=None, compare=False, repr=False)
|
|
246
|
+
"""The consumed wire message's live ``additional_properties``.
|
|
247
|
+
|
|
248
|
+
The reminder middleware records the reminders the message carried there
|
|
249
|
+
once a request is established — after consumption — and persistence
|
|
250
|
+
copies that record onto the history copy it builds.
|
|
251
|
+
"""
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
@dataclass(frozen=True)
|
|
255
|
+
class _InjectionBatch:
|
|
256
|
+
"""An ordered retryable injection transaction and its history anchor."""
|
|
257
|
+
|
|
258
|
+
injections: tuple[QueuedInjection, ...]
|
|
259
|
+
anchor: InjectionAnchor
|
|
260
|
+
wire_properties: tuple[dict[str, Any], ...] = ()
|
|
261
|
+
"""The live ``additional_properties`` of the wire messages this batch was
|
|
262
|
+
last consumed as, one per injection (empty before the first consumption).
|
|
263
|
+
|
|
264
|
+
A retry replays each injection as a fresh message; it takes over the
|
|
265
|
+
reminder record the reminder middleware wrote there once that request
|
|
266
|
+
was established, so the replay re-sends the same bytes.
|
|
267
|
+
"""
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
class InjectionMiddleware(ChatMiddleware):
|
|
271
|
+
"""Delivers queued user messages before each LLM call in the tool loop.
|
|
272
|
+
|
|
273
|
+
Before each model call (``call_next()``), pending texts are appended
|
|
274
|
+
as ``Message("user", [text])`` to ``context.messages``. The LLM
|
|
275
|
+
sees these messages on the current iteration.
|
|
276
|
+
|
|
277
|
+
The on-consumed callback receives a :class:`ConsumedInjection` with
|
|
278
|
+
the injected text, timestamp metadata, and an :class:`InjectionAnchor`
|
|
279
|
+
describing the message the injection should land *after* in session
|
|
280
|
+
history. The engine uses this to position the injection
|
|
281
|
+
deterministically across both streaming and non-streaming framework
|
|
282
|
+
paths.
|
|
283
|
+
"""
|
|
284
|
+
|
|
285
|
+
def __init__(self) -> None:
|
|
286
|
+
self._pending: list[QueuedInjection] = []
|
|
287
|
+
self._retry_replay: list[_InjectionBatch] = []
|
|
288
|
+
self._retry_consumed: list[_InjectionBatch] = []
|
|
289
|
+
self._retry_active = False
|
|
290
|
+
self._consumed_injection_messages: list[Message] = []
|
|
291
|
+
self._on_consumed: Callable[[ConsumedInjection], Awaitable[None]] | None = None
|
|
292
|
+
self._on_consumed_batch: Callable[[tuple[ConsumedInjection, ...]], Awaitable[None]] | None = None
|
|
293
|
+
self._on_drained_reminders: Callable[[list[str]], None] | None = None
|
|
294
|
+
|
|
295
|
+
def set_on_drained_reminders(self, callback: Callable[[list[str]], None]) -> None:
|
|
296
|
+
"""Set the synchronous sink for the reminders of freshly drained injections."""
|
|
297
|
+
self._on_drained_reminders = callback
|
|
298
|
+
|
|
299
|
+
def set_on_consumed_batch(
|
|
300
|
+
self,
|
|
301
|
+
callback: Callable[[tuple[ConsumedInjection, ...]], Awaitable[None]],
|
|
302
|
+
) -> None:
|
|
303
|
+
"""Set one callback for each complete consumed wire transaction."""
|
|
304
|
+
self._on_consumed_batch = callback
|
|
305
|
+
self._on_consumed = None
|
|
306
|
+
|
|
307
|
+
def set_on_consumed(self, callback: Callable[[ConsumedInjection], Awaitable[None]]) -> None:
|
|
308
|
+
"""Set a callback invoked for each message successfully injected.
|
|
309
|
+
|
|
310
|
+
Args:
|
|
311
|
+
callback: ``async (ConsumedInjection) -> None``.
|
|
312
|
+
"""
|
|
313
|
+
self._on_consumed = callback
|
|
314
|
+
self._on_consumed_batch = None
|
|
315
|
+
|
|
316
|
+
def queue(
|
|
317
|
+
self,
|
|
318
|
+
text: str,
|
|
319
|
+
created_at: datetime | str | None = None,
|
|
320
|
+
injection_id: str | None = None,
|
|
321
|
+
reminders: tuple[str, ...] = (),
|
|
322
|
+
preparation: PreparationTrace | None = None,
|
|
323
|
+
target_turn_id: str | None = None,
|
|
324
|
+
) -> None:
|
|
325
|
+
"""Queue text for injection before the next model call."""
|
|
326
|
+
self._pending.append(
|
|
327
|
+
QueuedInjection(
|
|
328
|
+
text=text,
|
|
329
|
+
created_at=created_at,
|
|
330
|
+
injection_id=injection_id,
|
|
331
|
+
reminders=reminders,
|
|
332
|
+
analytics_item_id=new_analytics_id(),
|
|
333
|
+
preparation=preparation,
|
|
334
|
+
target_turn_id=target_turn_id,
|
|
335
|
+
)
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
def drain_consumed_injection_messages(self) -> list[Message]:
|
|
339
|
+
"""Return clean injections consumed by the latest provider call."""
|
|
340
|
+
messages = self._consumed_injection_messages
|
|
341
|
+
self._consumed_injection_messages = []
|
|
342
|
+
return messages
|
|
343
|
+
|
|
344
|
+
def begin_retry(self) -> None:
|
|
345
|
+
"""Track consumed injections for one retryable outer ``Agent.run``."""
|
|
346
|
+
if self._retry_active:
|
|
347
|
+
raise RuntimeError("An injection retry is already active.")
|
|
348
|
+
self._retry_active = True
|
|
349
|
+
self._retry_replay = []
|
|
350
|
+
self._retry_consumed = []
|
|
351
|
+
self._consumed_injection_messages = []
|
|
352
|
+
|
|
353
|
+
def restore_for_retry(self) -> None:
|
|
354
|
+
"""Reserve the failed attempt's immutable batches for replay."""
|
|
355
|
+
if not self._retry_active:
|
|
356
|
+
return
|
|
357
|
+
# A retry may fail in a context provider before chat middleware runs.
|
|
358
|
+
# Preserve the existing replay unless this attempt actually consumed
|
|
359
|
+
# a replacement batch.
|
|
360
|
+
if self._retry_consumed:
|
|
361
|
+
self._retry_replay = self._retry_consumed.copy()
|
|
362
|
+
self._retry_consumed = []
|
|
363
|
+
self._consumed_injection_messages = []
|
|
364
|
+
|
|
365
|
+
def commit_logical_call(self) -> None:
|
|
366
|
+
"""Forget retry batches consumed by a completed logical wire call."""
|
|
367
|
+
if not self._retry_active:
|
|
368
|
+
return
|
|
369
|
+
self._retry_replay = []
|
|
370
|
+
self._retry_consumed = []
|
|
371
|
+
|
|
372
|
+
def end_retry(self) -> None:
|
|
373
|
+
"""Release retry-only state after the outer run terminates."""
|
|
374
|
+
self._retry_active = False
|
|
375
|
+
self._retry_replay = []
|
|
376
|
+
self._retry_consumed = []
|
|
377
|
+
self._consumed_injection_messages = []
|
|
378
|
+
|
|
379
|
+
def cancel(self, injection_id: str) -> QueuedInjection | None:
|
|
380
|
+
"""Remove and return the pending injection with *injection_id*, if any.
|
|
381
|
+
|
|
382
|
+
Other pending injections keep their relative order. Returns ``None``
|
|
383
|
+
when the id is unknown or the injection was already consumed.
|
|
384
|
+
"""
|
|
385
|
+
for i, injection in enumerate(self._pending):
|
|
386
|
+
if injection.injection_id == injection_id:
|
|
387
|
+
return self._pending.pop(i)
|
|
388
|
+
return None
|
|
389
|
+
|
|
390
|
+
def drain_pending(self) -> list[QueuedInjection]:
|
|
391
|
+
"""Return and clear any un-consumed pending injections."""
|
|
392
|
+
drained = self._pending.copy()
|
|
393
|
+
self._pending.clear()
|
|
394
|
+
return drained
|
|
395
|
+
|
|
396
|
+
async def process(
|
|
397
|
+
self,
|
|
398
|
+
context: ChatContext,
|
|
399
|
+
call_next: Callable[[], Awaitable[None]],
|
|
400
|
+
) -> None:
|
|
401
|
+
request_options = context.options
|
|
402
|
+
if request_options and request_options.get("continuation_token") is not None:
|
|
403
|
+
# A continuation poll retrieves an already-created response — the
|
|
404
|
+
# provider ignores request messages, so consuming an injection
|
|
405
|
+
# here would persist text the model never saw. Hold pending and
|
|
406
|
+
# replayed batches for the next request that creates a response.
|
|
407
|
+
await call_next()
|
|
408
|
+
return
|
|
409
|
+
# Before the LLM call, inject queued and retry-reserved transactions.
|
|
410
|
+
current_anchor = InjectionAnchor.from_message(context.messages[-1] if context.messages else None)
|
|
411
|
+
batches = [replace(batch, anchor=current_anchor) if context.messages else batch for batch in self._retry_replay]
|
|
412
|
+
if self._pending:
|
|
413
|
+
injections = tuple(
|
|
414
|
+
replace(
|
|
415
|
+
injection,
|
|
416
|
+
consumption_id=injection.consumption_id or injection.injection_id or uuid4().hex[:12],
|
|
417
|
+
analytics_item_id=injection.analytics_item_id or new_analytics_id(),
|
|
418
|
+
)
|
|
419
|
+
for injection in self._pending
|
|
420
|
+
)
|
|
421
|
+
batches.append(_InjectionBatch(injections, current_anchor))
|
|
422
|
+
# Queue before any await: an injection committed while this call
|
|
423
|
+
# awaits its checkpoint is not in this batch, so its reminders
|
|
424
|
+
# must not ride this call either. A replayed batch queued its
|
|
425
|
+
# reminders when it was first drained.
|
|
426
|
+
drained_reminders = [reminder for injection in injections for reminder in injection.reminders]
|
|
427
|
+
if drained_reminders and self._on_drained_reminders is not None:
|
|
428
|
+
self._on_drained_reminders(drained_reminders)
|
|
429
|
+
|
|
430
|
+
self._retry_replay = []
|
|
431
|
+
self._pending.clear()
|
|
432
|
+
if batches:
|
|
433
|
+
mutable: list[Any] = list(context.messages)
|
|
434
|
+
consumed_transaction: list[ConsumedInjection] = []
|
|
435
|
+
for batch in batches:
|
|
436
|
+
batch_properties: list[dict[str, Any]] = []
|
|
437
|
+
stable_injections = tuple(
|
|
438
|
+
replace(
|
|
439
|
+
injection,
|
|
440
|
+
consumption_id=injection.consumption_id or injection.injection_id or uuid4().hex[:12],
|
|
441
|
+
analytics_item_id=injection.analytics_item_id or new_analytics_id(),
|
|
442
|
+
)
|
|
443
|
+
for injection in batch.injections
|
|
444
|
+
)
|
|
445
|
+
for index, injection in enumerate(stable_injections):
|
|
446
|
+
# Every consumption gets a per-consumption identity — it
|
|
447
|
+
# travels on the wire copy, the ConsumedInjection mirror, and
|
|
448
|
+
# the persisted history copy, so crash-recovery replay dedups
|
|
449
|
+
# by identity instead of text (same-text distinct injections
|
|
450
|
+
# must both survive). Queued ids (UI cancel handles) are
|
|
451
|
+
# reused; id-less queues get one synthesized here. The
|
|
452
|
+
# ORIGINAL queue handle is forwarded separately as
|
|
453
|
+
# ``injection_id`` — event consumers key on it and must see
|
|
454
|
+
# ``None`` for id-less frontends, never a synthesized value.
|
|
455
|
+
consumption_id = injection.consumption_id
|
|
456
|
+
if consumption_id is None:
|
|
457
|
+
raise RuntimeError("Queued injection is missing its consumption identity.")
|
|
458
|
+
# Flag the wire copy at creation time so the very call that
|
|
459
|
+
# consumes the injection classifies it as mid-turn (the
|
|
460
|
+
# persisted copy is stamped independently by
|
|
461
|
+
# ``persist_consumed_injections``).
|
|
462
|
+
msg = Message("user", [injection.text])
|
|
463
|
+
msg.additional_properties[HistoryMarkerKind.INJECTED_KEY] = True
|
|
464
|
+
msg.additional_properties[HistoryMarkerKind.INJECTION_ID_KEY] = consumption_id
|
|
465
|
+
ensure_analytics_item_id(
|
|
466
|
+
msg.additional_properties,
|
|
467
|
+
item_id=injection.analytics_item_id,
|
|
468
|
+
)
|
|
469
|
+
if index < len(batch.wire_properties):
|
|
470
|
+
copy_reminder_record(batch.wire_properties[index], msg.additional_properties)
|
|
471
|
+
batch_properties.append(msg.additional_properties)
|
|
472
|
+
mutable.append(msg)
|
|
473
|
+
# Retain a structural copy, never the wire object: the
|
|
474
|
+
# client receives ``msg`` on this very call and may mutate
|
|
475
|
+
# its contents list in place, and the retained copy is what
|
|
476
|
+
# later tool iterations re-send and persistence captures.
|
|
477
|
+
# The props dict stays shared (the sanctioned metadata
|
|
478
|
+
# write-through channel) and the content object stays
|
|
479
|
+
# shared like everywhere else.
|
|
480
|
+
retained = copy(msg)
|
|
481
|
+
retained.contents = list(msg.contents)
|
|
482
|
+
self._consumed_injection_messages.append(retained)
|
|
483
|
+
consumed_transaction.append(
|
|
484
|
+
ConsumedInjection(
|
|
485
|
+
text=injection.text,
|
|
486
|
+
anchor=batch.anchor,
|
|
487
|
+
created_at=injection.created_at,
|
|
488
|
+
injection_id=injection.injection_id,
|
|
489
|
+
consumption_id=consumption_id,
|
|
490
|
+
analytics_item_id=injection.analytics_item_id,
|
|
491
|
+
preparation=injection.preparation,
|
|
492
|
+
target_turn_id=injection.target_turn_id,
|
|
493
|
+
wire_properties=msg.additional_properties,
|
|
494
|
+
)
|
|
495
|
+
)
|
|
496
|
+
# Register the complete batch before the first callback await.
|
|
497
|
+
# Cancellation can therefore replay all messages or none; it
|
|
498
|
+
# cannot strand the unvisited tail of a multi-message drain.
|
|
499
|
+
if self._retry_active:
|
|
500
|
+
self._retry_consumed.append(
|
|
501
|
+
_InjectionBatch(stable_injections, batch.anchor, tuple(batch_properties))
|
|
502
|
+
)
|
|
503
|
+
context.messages = mutable
|
|
504
|
+
if self._on_consumed_batch is not None:
|
|
505
|
+
await self._on_consumed_batch(tuple(consumed_transaction))
|
|
506
|
+
elif self._on_consumed is not None:
|
|
507
|
+
for consumed in consumed_transaction:
|
|
508
|
+
await self._on_consumed(consumed)
|
|
509
|
+
|
|
510
|
+
await call_next()
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""The content sources ``SystemReminderMiddleware`` composes, one module per reminder.
|
|
4
|
+
|
|
5
|
+
A source owns what one reminder says and the state behind it. The middleware
|
|
6
|
+
(``system_reminder``) owns when each one is sent, how it is recorded and the
|
|
7
|
+
send order; sources never build reminder items or records.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from dataclasses import dataclass
|
|
13
|
+
from typing import TYPE_CHECKING
|
|
14
|
+
|
|
15
|
+
from .archive_pointer import ArchivePointerSource
|
|
16
|
+
from .context_usage import ContextWarningSource
|
|
17
|
+
from .file_change import FileChangeSource
|
|
18
|
+
from .mcp import McpSource
|
|
19
|
+
from .profile_switch import ProfileSwitchSource
|
|
20
|
+
from .runtime_env import RuntimeEnvSource
|
|
21
|
+
from .skills import SkillsSource
|
|
22
|
+
from .sub_agents import SubAgentsSource
|
|
23
|
+
from .todo import TodoSource
|
|
24
|
+
from .turn_line import TurnLineSource
|
|
25
|
+
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
from collections.abc import Callable, Sequence
|
|
28
|
+
from pathlib import Path
|
|
29
|
+
|
|
30
|
+
from chrys.foundation.models.session_env import SessionEnvironment
|
|
31
|
+
from chrys.service.context.compaction.spill import SpillQuota
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass(frozen=True, slots=True)
|
|
35
|
+
class ReminderSources:
|
|
36
|
+
"""One middleware's sources, one named field per reminder.
|
|
37
|
+
|
|
38
|
+
The middleware drives their turn transitions; code outside it uses only the
|
|
39
|
+
members ``tests/architecture/test_hygiene_reminder_sources.py`` allows.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
turn_line: TurnLineSource
|
|
43
|
+
context_warning: ContextWarningSource
|
|
44
|
+
runtime_env: RuntimeEnvSource
|
|
45
|
+
sub_agents: SubAgentsSource
|
|
46
|
+
todo: TodoSource
|
|
47
|
+
skills: SkillsSource
|
|
48
|
+
mcp: McpSource
|
|
49
|
+
file_change: FileChangeSource
|
|
50
|
+
profile_switch: ProfileSwitchSource
|
|
51
|
+
archive_pointer: ArchivePointerSource
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def build_sources(
|
|
55
|
+
*,
|
|
56
|
+
runtime: SessionEnvironment | None,
|
|
57
|
+
max_context_tokens: int,
|
|
58
|
+
warn_threshold_pct: float,
|
|
59
|
+
shell_tool_enabled: bool,
|
|
60
|
+
sub_agent_names: Sequence[str] | None,
|
|
61
|
+
todo_state_provider: Callable[[], str | None] | None,
|
|
62
|
+
skill_catalog_provider: Callable[[], str | None] | None,
|
|
63
|
+
mcp_instructions_provider: Callable[[], str | None] | None,
|
|
64
|
+
file_change_provider: Callable[[], str | None] | None,
|
|
65
|
+
tool_names: Sequence[str] | None,
|
|
66
|
+
session_root: Path | None,
|
|
67
|
+
file_read_available: bool,
|
|
68
|
+
spill_quota: SpillQuota | None,
|
|
69
|
+
catalog_pointer_enabled: bool,
|
|
70
|
+
) -> ReminderSources:
|
|
71
|
+
"""The sources for one middleware, from its constructor inputs."""
|
|
72
|
+
return ReminderSources(
|
|
73
|
+
turn_line=TurnLineSource(runtime, max_context_tokens=max_context_tokens),
|
|
74
|
+
context_warning=ContextWarningSource(
|
|
75
|
+
max_context_tokens=max_context_tokens,
|
|
76
|
+
warn_threshold_pct=warn_threshold_pct,
|
|
77
|
+
),
|
|
78
|
+
runtime_env=RuntimeEnvSource(runtime, shell_tool_enabled=shell_tool_enabled),
|
|
79
|
+
sub_agents=SubAgentsSource(sub_agent_names),
|
|
80
|
+
todo=TodoSource(todo_state_provider),
|
|
81
|
+
skills=SkillsSource(skill_catalog_provider),
|
|
82
|
+
mcp=McpSource(mcp_instructions_provider),
|
|
83
|
+
file_change=FileChangeSource(file_change_provider),
|
|
84
|
+
profile_switch=ProfileSwitchSource(tool_names),
|
|
85
|
+
archive_pointer=ArchivePointerSource(
|
|
86
|
+
session_root=session_root,
|
|
87
|
+
file_read_available=file_read_available,
|
|
88
|
+
spill_quota=spill_quota,
|
|
89
|
+
enabled=catalog_pointer_enabled,
|
|
90
|
+
),
|
|
91
|
+
)
|