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,690 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Cross-turn compression state and fold execution toolkit."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import uuid
|
|
8
|
+
import weakref
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
11
|
+
|
|
12
|
+
from chrys.foundation.models.history_markers import HistoryMarkerKind
|
|
13
|
+
from chrys.foundation.trajectory.envelope import MeasurementSource
|
|
14
|
+
from chrys.kernel import EXCLUDED_KEY, Message, set_excluded
|
|
15
|
+
from chrys.kernel.compaction import _token_count, included_token_count
|
|
16
|
+
from chrys.kernel.identity import WeakIdentityRegistry
|
|
17
|
+
from chrys.service.context.providers.history import PRE_OUTPUT_HISTORY_LEN_STATE_KEY
|
|
18
|
+
|
|
19
|
+
from .events import (
|
|
20
|
+
_REASON_COMPRESSION,
|
|
21
|
+
CachedCompressedContextSummary,
|
|
22
|
+
CompressInfo,
|
|
23
|
+
PendingCompression,
|
|
24
|
+
_compressed_turn_range,
|
|
25
|
+
)
|
|
26
|
+
from .exclusions import ExclusionLedger
|
|
27
|
+
from .groups import (
|
|
28
|
+
_carries_only,
|
|
29
|
+
_content_object_ids,
|
|
30
|
+
_fold_summary_ids,
|
|
31
|
+
_matches_summary_id,
|
|
32
|
+
_message_present,
|
|
33
|
+
)
|
|
34
|
+
from .turns import _resolve_turns
|
|
35
|
+
|
|
36
|
+
if TYPE_CHECKING:
|
|
37
|
+
from chrys.service.context.providers.history import CompressedBlock
|
|
38
|
+
|
|
39
|
+
from .strategy import UnifiedContextStrategy
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass(frozen=True, slots=True)
|
|
43
|
+
class _FoldMatch:
|
|
44
|
+
"""Recognizes a wire message as the per-call copy of a folded state message.
|
|
45
|
+
|
|
46
|
+
Tiers: the same contents list (legacy same-object lists), only the fold's
|
|
47
|
+
content objects (the kernel's per-call wire views: fresh wrapper and
|
|
48
|
+
contents list), the same ``additional_properties`` (the reminder
|
|
49
|
+
middleware's enriched user messages: fresh contents, the original's dict)
|
|
50
|
+
or a summary of a folded occurrence. Every fold site matches through
|
|
51
|
+
this one predicate so a new copy shape can't reach only some of them.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
contents: WeakIdentityRegistry | set[int]
|
|
55
|
+
content_objects: WeakIdentityRegistry | set[int]
|
|
56
|
+
properties_ids: set[int]
|
|
57
|
+
summary_ids: set[str] | frozenset[str]
|
|
58
|
+
|
|
59
|
+
@classmethod
|
|
60
|
+
def of_range(cls, fold_range: list[Message], summary_ids: set[str] | frozenset[str]) -> _FoldMatch:
|
|
61
|
+
"""Frame-local match for a fold range still held by the caller.
|
|
62
|
+
|
|
63
|
+
The ``additional_properties`` ids are safe keys: the fold flags these
|
|
64
|
+
very dicts excluded afterwards, so a wire message sharing one leaves
|
|
65
|
+
the request either way; matching it only places the summary where the
|
|
66
|
+
range starts.
|
|
67
|
+
"""
|
|
68
|
+
return cls(
|
|
69
|
+
contents={id(message.contents) for message in fold_range},
|
|
70
|
+
content_objects=_content_object_ids(fold_range),
|
|
71
|
+
properties_ids={id(message.additional_properties) for message in fold_range},
|
|
72
|
+
summary_ids=summary_ids,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
@classmethod
|
|
76
|
+
def of_cached(cls, cached: CachedCompressedContextSummary) -> _FoldMatch:
|
|
77
|
+
"""Match for a cached fold whose originals may have been collected.
|
|
78
|
+
|
|
79
|
+
The ``additional_properties`` ids are read now from the originals
|
|
80
|
+
still alive, so none is the recycled id of a collected dict.
|
|
81
|
+
"""
|
|
82
|
+
return cls(
|
|
83
|
+
contents=cached.folded_contents,
|
|
84
|
+
content_objects=cached.folded_content_objects,
|
|
85
|
+
properties_ids={
|
|
86
|
+
id(message.additional_properties) for ref in cached.folded_messages if (message := ref()) is not None
|
|
87
|
+
},
|
|
88
|
+
summary_ids=cached.folded_summary_ids,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
def matches(self, message: Message) -> bool:
|
|
92
|
+
contents = self.contents
|
|
93
|
+
same_contents = (
|
|
94
|
+
message.contents in contents
|
|
95
|
+
if isinstance(contents, WeakIdentityRegistry)
|
|
96
|
+
else id(message.contents) in contents
|
|
97
|
+
)
|
|
98
|
+
return (
|
|
99
|
+
same_contents
|
|
100
|
+
or _carries_only(message, self.content_objects)
|
|
101
|
+
or id(message.additional_properties) in self.properties_ids
|
|
102
|
+
or (bool(self.summary_ids) and _matches_summary_id(message, self.summary_ids))
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _fold_tokens(fold_range: list[Message]) -> int:
|
|
107
|
+
"""Local token estimate of a fold range; untokenized messages count as 0."""
|
|
108
|
+
total = 0
|
|
109
|
+
for message in fold_range:
|
|
110
|
+
token_count = _token_count(message)
|
|
111
|
+
if token_count is not None:
|
|
112
|
+
total += token_count
|
|
113
|
+
return total
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class CompressionEngine:
|
|
117
|
+
"""Own provider compression state and compose site-specific folds."""
|
|
118
|
+
|
|
119
|
+
def __init__(self, strategy: UnifiedContextStrategy, ledger: ExclusionLedger) -> None:
|
|
120
|
+
self._strategy = strategy
|
|
121
|
+
self._ledger = ledger
|
|
122
|
+
self._state: dict[str, Any] | None = None
|
|
123
|
+
self._pending_compressions: list[PendingCompression] = []
|
|
124
|
+
self._compressed_context_cache: dict[str, CachedCompressedContextSummary] = {}
|
|
125
|
+
# Strong references to folds whose on_compress publication completed.
|
|
126
|
+
# Retry snapshots retain only an index into this monotonic journal;
|
|
127
|
+
# rollback can then replay every later fold with its original block
|
|
128
|
+
# identity/metadata and without publishing a duplicate UI event.
|
|
129
|
+
self._published_folds: list[CompressedBlock] = []
|
|
130
|
+
|
|
131
|
+
def bind_state(self, state: dict[str, Any]) -> None:
|
|
132
|
+
"""Bind the provider state and clear only the same-run summary cache."""
|
|
133
|
+
self._compressed_context_cache.clear()
|
|
134
|
+
self._state = state
|
|
135
|
+
|
|
136
|
+
def queue_compression(self, marker_id: str, summary_text: str) -> tuple[str, int]:
|
|
137
|
+
"""Validate and queue one agent-requested compression."""
|
|
138
|
+
if self._state is None:
|
|
139
|
+
raise RuntimeError("Strategy not bound — call bind_state() first.")
|
|
140
|
+
|
|
141
|
+
from chrys.service.context.providers.history import _compress_state_validate
|
|
142
|
+
|
|
143
|
+
freed_count = _compress_state_validate(self._state, marker_id)
|
|
144
|
+
ctx_id = f"ctx_{uuid.uuid4().hex[:8]}"
|
|
145
|
+
self._pending_compressions.append(
|
|
146
|
+
PendingCompression(
|
|
147
|
+
compressed_context_id=ctx_id,
|
|
148
|
+
marker_id=marker_id,
|
|
149
|
+
summary_text=summary_text,
|
|
150
|
+
freed_count=freed_count,
|
|
151
|
+
)
|
|
152
|
+
)
|
|
153
|
+
return ctx_id, freed_count
|
|
154
|
+
|
|
155
|
+
def list_compressed(self) -> dict[str, Any]:
|
|
156
|
+
"""List compressed blocks and markers not consumed by queued work."""
|
|
157
|
+
if self._state is None:
|
|
158
|
+
return {"blocks": [], "markers": []}
|
|
159
|
+
|
|
160
|
+
from chrys.service.context.providers.history import CompressibleHistoryProvider
|
|
161
|
+
|
|
162
|
+
info = CompressibleHistoryProvider.list_compressed(self._state)
|
|
163
|
+
pending_markers = {pending.marker_id for pending in self._pending_compressions}
|
|
164
|
+
if pending_markers:
|
|
165
|
+
info["markers"] = [marker for marker in info["markers"] if marker["marker_id"] not in pending_markers]
|
|
166
|
+
return info
|
|
167
|
+
|
|
168
|
+
def execute_fold(
|
|
169
|
+
self,
|
|
170
|
+
marker_id: str,
|
|
171
|
+
summary: str,
|
|
172
|
+
compressed_context_id: str | None = None,
|
|
173
|
+
) -> tuple[str, list[Message]]:
|
|
174
|
+
"""Apply one provider-state fold; callers own exception boundaries."""
|
|
175
|
+
if self._state is None:
|
|
176
|
+
raise RuntimeError("Strategy not bound — call bind_state() first.")
|
|
177
|
+
|
|
178
|
+
from chrys.service.context.providers.history import _compress_state
|
|
179
|
+
|
|
180
|
+
if compressed_context_id is None:
|
|
181
|
+
return _compress_state(self._state, marker_id, summary)
|
|
182
|
+
return _compress_state(self._state, marker_id, summary, compressed_context_id)
|
|
183
|
+
|
|
184
|
+
def published_fold_count(self) -> int:
|
|
185
|
+
"""Return the monotonic fold-journal boundary for a retry snapshot."""
|
|
186
|
+
return len(self._published_folds)
|
|
187
|
+
|
|
188
|
+
def replay_published_folds(self, start_index: int) -> None:
|
|
189
|
+
"""Silently reapply published folds created after *start_index*.
|
|
190
|
+
|
|
191
|
+
The executor restores the pre-attempt message list and truncates new
|
|
192
|
+
compressed blocks before calling this method. Replaying in journal
|
|
193
|
+
order is well-defined because Phase 3 folds only completed turns;
|
|
194
|
+
each block's marker is therefore present in that restored baseline.
|
|
195
|
+
The existing block object is put back after ``_compress_state`` does
|
|
196
|
+
the list rewrite so its id, archived messages, turn range, and
|
|
197
|
+
timestamp remain byte-for-byte stable.
|
|
198
|
+
"""
|
|
199
|
+
if self._state is None:
|
|
200
|
+
return
|
|
201
|
+
|
|
202
|
+
from chrys.service.context.providers.history import _compress_state
|
|
203
|
+
|
|
204
|
+
for block in self._published_folds[start_index:]:
|
|
205
|
+
if self._state_has_compressed_block(block.compressed_context_id):
|
|
206
|
+
continue
|
|
207
|
+
_compress_state(
|
|
208
|
+
self._state,
|
|
209
|
+
block.marker_id,
|
|
210
|
+
block.summary_text,
|
|
211
|
+
block.compressed_context_id,
|
|
212
|
+
)
|
|
213
|
+
compressed_blocks = self._state.get("compressed_msgs", [])
|
|
214
|
+
if not isinstance(compressed_blocks, list) or not compressed_blocks:
|
|
215
|
+
raise RuntimeError("Replayed compression did not append its block.")
|
|
216
|
+
compressed_blocks[-1] = block
|
|
217
|
+
self._record_pre_output_history_len()
|
|
218
|
+
|
|
219
|
+
def _record_published_fold(self, compressed_context_id: str) -> None:
|
|
220
|
+
"""Append the committed provider block after on_compress returns."""
|
|
221
|
+
if self._state is None:
|
|
222
|
+
return
|
|
223
|
+
compressed_blocks = self._state.get("compressed_msgs", [])
|
|
224
|
+
if not isinstance(compressed_blocks, list):
|
|
225
|
+
return
|
|
226
|
+
|
|
227
|
+
from chrys.service.context.providers.history import CompressedBlock
|
|
228
|
+
|
|
229
|
+
for block in reversed(compressed_blocks):
|
|
230
|
+
if isinstance(block, CompressedBlock) and block.compressed_context_id == compressed_context_id:
|
|
231
|
+
if not self._published_folds or self._published_folds[-1] is not block:
|
|
232
|
+
self._published_folds.append(block)
|
|
233
|
+
return
|
|
234
|
+
|
|
235
|
+
def exclude_wire_matches(
|
|
236
|
+
self,
|
|
237
|
+
messages: list[Message],
|
|
238
|
+
fold_range: list[Message],
|
|
239
|
+
fold_summary_ids: set[str],
|
|
240
|
+
*,
|
|
241
|
+
match_summary_refs: bool,
|
|
242
|
+
skip_already_excluded: bool,
|
|
243
|
+
insertion_index: int | None = None,
|
|
244
|
+
) -> int | None:
|
|
245
|
+
"""Exclude the wire projection for a fold under explicit site policy.
|
|
246
|
+
|
|
247
|
+
Match wire-list entries against the fold range (state objects) with
|
|
248
|
+
:class:`_FoldMatch`; summary references count only when
|
|
249
|
+
*match_summary_refs* is set.
|
|
250
|
+
"""
|
|
251
|
+
fold = _FoldMatch.of_range(fold_range, fold_summary_ids if match_summary_refs else frozenset())
|
|
252
|
+
for idx, message in enumerate(messages):
|
|
253
|
+
if skip_already_excluded and message.additional_properties.get(EXCLUDED_KEY, False):
|
|
254
|
+
continue
|
|
255
|
+
if not fold.matches(message):
|
|
256
|
+
continue
|
|
257
|
+
if insertion_index is None:
|
|
258
|
+
insertion_index = idx
|
|
259
|
+
set_excluded(message, excluded=True, reason=_REASON_COMPRESSION)
|
|
260
|
+
return insertion_index
|
|
261
|
+
|
|
262
|
+
def insert_and_cache_summary(
|
|
263
|
+
self,
|
|
264
|
+
messages: list[Message],
|
|
265
|
+
compressed_context_id: str,
|
|
266
|
+
fold_range: list[Message],
|
|
267
|
+
fold_summary_ids: set[str],
|
|
268
|
+
insertion_index: int | None,
|
|
269
|
+
) -> None:
|
|
270
|
+
"""Keep a state-fold summary visible on this and later wire views."""
|
|
271
|
+
summary_msg = self._find_state_summary(compressed_context_id)
|
|
272
|
+
if summary_msg is None:
|
|
273
|
+
return
|
|
274
|
+
if insertion_index is not None and not _message_present(messages, summary_msg):
|
|
275
|
+
messages.insert(insertion_index, summary_msg)
|
|
276
|
+
folded_contents = WeakIdentityRegistry()
|
|
277
|
+
folded_content_objects = WeakIdentityRegistry()
|
|
278
|
+
for folded in fold_range:
|
|
279
|
+
folded_contents.register(folded.contents)
|
|
280
|
+
for content in folded.contents:
|
|
281
|
+
folded_content_objects.register(content)
|
|
282
|
+
self._compressed_context_cache[compressed_context_id] = CachedCompressedContextSummary(
|
|
283
|
+
summary_message=summary_msg,
|
|
284
|
+
folded_contents=folded_contents,
|
|
285
|
+
folded_summary_ids=frozenset(fold_summary_ids),
|
|
286
|
+
folded_content_objects=folded_content_objects,
|
|
287
|
+
folded_messages=tuple(weakref.ref(folded) for folded in fold_range),
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
async def run_queued(self, messages: list[Message]) -> bool:
|
|
291
|
+
"""Execute queued folds against provider state and the live wire list."""
|
|
292
|
+
# ---- Step 0: Process pending cross-turn compressions ----
|
|
293
|
+
# Compressions modify self._state["messages"] (has turn markers)
|
|
294
|
+
# and set _excluded on the wire message list (the `messages`
|
|
295
|
+
# parameter). History messages reach the wire un-copied (kernel
|
|
296
|
+
# SessionContext.extend_messages), so the contents-identity match is
|
|
297
|
+
# a direct hit for them; it stays a *match* rather than an identity
|
|
298
|
+
# walk because streaming finalizers rebuild current-turn messages
|
|
299
|
+
# into fresh objects with fresh contents lists.
|
|
300
|
+
compressions_processed = False
|
|
301
|
+
if self._pending_compressions and self._state is not None:
|
|
302
|
+
for pending in self._pending_compressions:
|
|
303
|
+
try:
|
|
304
|
+
_ctx_id, fold_range = self.execute_fold(
|
|
305
|
+
pending.marker_id,
|
|
306
|
+
pending.summary_text,
|
|
307
|
+
pending.compressed_context_id,
|
|
308
|
+
)
|
|
309
|
+
except ValueError:
|
|
310
|
+
continue
|
|
311
|
+
self._record_pre_output_history_len()
|
|
312
|
+
fold_summary_ids = _fold_summary_ids(fold_range)
|
|
313
|
+
insertion_index = self.exclude_wire_matches(
|
|
314
|
+
messages,
|
|
315
|
+
fold_range,
|
|
316
|
+
fold_summary_ids,
|
|
317
|
+
match_summary_refs=False,
|
|
318
|
+
skip_already_excluded=False,
|
|
319
|
+
)
|
|
320
|
+
self.insert_and_cache_summary(
|
|
321
|
+
messages,
|
|
322
|
+
pending.compressed_context_id,
|
|
323
|
+
fold_range,
|
|
324
|
+
fold_summary_ids,
|
|
325
|
+
insertion_index,
|
|
326
|
+
)
|
|
327
|
+
# The state-side fold range is re-flagged even when absent
|
|
328
|
+
# from the wire projection.
|
|
329
|
+
freed_tokens = _fold_tokens(fold_range)
|
|
330
|
+
for message in fold_range:
|
|
331
|
+
set_excluded(message, excluded=True, reason=_REASON_COMPRESSION)
|
|
332
|
+
self._ledger.invalidate_for_fold(fold_range)
|
|
333
|
+
compressions_processed = True
|
|
334
|
+
tokens_before = self._strategy.last_included_tokens
|
|
335
|
+
await self._strategy._notify_compress(
|
|
336
|
+
CompressInfo(
|
|
337
|
+
compressed_context_id=pending.compressed_context_id,
|
|
338
|
+
summary=pending.summary_text,
|
|
339
|
+
freed_messages=len(fold_range),
|
|
340
|
+
turn_range=_compressed_turn_range(self._state, pending.compressed_context_id),
|
|
341
|
+
source="agent",
|
|
342
|
+
),
|
|
343
|
+
trigger="agent_request",
|
|
344
|
+
tokens_before=tokens_before,
|
|
345
|
+
tokens_after=max(0, tokens_before - freed_tokens),
|
|
346
|
+
)
|
|
347
|
+
self._record_published_fold(pending.compressed_context_id)
|
|
348
|
+
self._pending_compressions.clear()
|
|
349
|
+
|
|
350
|
+
return compressions_processed
|
|
351
|
+
|
|
352
|
+
async def flush_pending_compressions(self) -> bool:
|
|
353
|
+
"""Execute queued folds after a run, without a wire projection."""
|
|
354
|
+
if not self._pending_compressions or self._state is None:
|
|
355
|
+
return False
|
|
356
|
+
|
|
357
|
+
any_processed = False
|
|
358
|
+
for pending in self._pending_compressions:
|
|
359
|
+
try:
|
|
360
|
+
_ctx_id, fold_range = self.execute_fold(
|
|
361
|
+
pending.marker_id,
|
|
362
|
+
pending.summary_text,
|
|
363
|
+
pending.compressed_context_id,
|
|
364
|
+
)
|
|
365
|
+
except ValueError:
|
|
366
|
+
continue
|
|
367
|
+
any_processed = True
|
|
368
|
+
self._ledger.invalidate_for_fold(fold_range)
|
|
369
|
+
tokens_before = self._strategy.last_included_tokens
|
|
370
|
+
await self._strategy._notify_compress(
|
|
371
|
+
CompressInfo(
|
|
372
|
+
compressed_context_id=pending.compressed_context_id,
|
|
373
|
+
summary=pending.summary_text,
|
|
374
|
+
freed_messages=len(fold_range),
|
|
375
|
+
turn_range=_compressed_turn_range(self._state, pending.compressed_context_id),
|
|
376
|
+
source="agent",
|
|
377
|
+
),
|
|
378
|
+
trigger="agent_request",
|
|
379
|
+
tokens_before=tokens_before,
|
|
380
|
+
tokens_after=max(0, tokens_before - _fold_tokens(fold_range)),
|
|
381
|
+
)
|
|
382
|
+
self._record_published_fold(pending.compressed_context_id)
|
|
383
|
+
self._pending_compressions.clear()
|
|
384
|
+
return any_processed
|
|
385
|
+
|
|
386
|
+
async def force_compress(
|
|
387
|
+
self,
|
|
388
|
+
marker_id: str,
|
|
389
|
+
summary: str,
|
|
390
|
+
source: str = "auto",
|
|
391
|
+
*,
|
|
392
|
+
usage_pct: float = 0.0,
|
|
393
|
+
tokens_before: int = 0,
|
|
394
|
+
) -> str | None:
|
|
395
|
+
"""Execute a fold after-run without wire exclusion or invalidation."""
|
|
396
|
+
if self._state is None:
|
|
397
|
+
return None
|
|
398
|
+
|
|
399
|
+
try:
|
|
400
|
+
await self._strategy._fire_pre_compact("force", usage_pct=usage_pct, tokens_before=tokens_before)
|
|
401
|
+
ctx_id, fold_range = self.execute_fold(marker_id, summary)
|
|
402
|
+
except ValueError:
|
|
403
|
+
return None
|
|
404
|
+
# ``tokens_before`` is the provider-reported occupancy that tripped
|
|
405
|
+
# the force threshold; the fold's own size is the local estimate.
|
|
406
|
+
await self._strategy._notify_compress(
|
|
407
|
+
CompressInfo(
|
|
408
|
+
compressed_context_id=ctx_id,
|
|
409
|
+
summary=summary,
|
|
410
|
+
freed_messages=len(fold_range),
|
|
411
|
+
turn_range=_compressed_turn_range(self._state, ctx_id),
|
|
412
|
+
source=source,
|
|
413
|
+
),
|
|
414
|
+
trigger="force",
|
|
415
|
+
tokens_before=tokens_before,
|
|
416
|
+
tokens_after=max(0, tokens_before - _fold_tokens(fold_range)),
|
|
417
|
+
token_source=MeasurementSource.PROVIDER,
|
|
418
|
+
)
|
|
419
|
+
self._record_published_fold(ctx_id)
|
|
420
|
+
return ctx_id
|
|
421
|
+
|
|
422
|
+
async def emergency_compress_oldest_turn(
|
|
423
|
+
self,
|
|
424
|
+
messages: list[Message],
|
|
425
|
+
*,
|
|
426
|
+
usage_pct: float,
|
|
427
|
+
tokens_before: int,
|
|
428
|
+
) -> tuple[bool, bool]:
|
|
429
|
+
"""Fold the oldest eligible completed turn into a visible summary.
|
|
430
|
+
|
|
431
|
+
This is the Phase 3 pre-request counterpart to ``force_compress``.
|
|
432
|
+
|
|
433
|
+
Returns ``(progressed, compressed)``. Empty markers can be consumed
|
|
434
|
+
without creating a summary, so ``progressed`` may be true while
|
|
435
|
+
``compressed`` is false.
|
|
436
|
+
"""
|
|
437
|
+
if self._state is None:
|
|
438
|
+
return False, False
|
|
439
|
+
|
|
440
|
+
from chrys.service.context.providers.history import CompressibleHistoryProvider, _auto_summary
|
|
441
|
+
|
|
442
|
+
info = CompressibleHistoryProvider.list_compressed(self._state)
|
|
443
|
+
markers = info.get("markers", [])
|
|
444
|
+
if not markers:
|
|
445
|
+
return False, False
|
|
446
|
+
|
|
447
|
+
# §4.1 defensive eligibility clamp: never fold at or past the
|
|
448
|
+
# current real turn's start. Resolved over the LIVE WIRE list (the
|
|
449
|
+
# same list the phases compact, in-flight input included) with the
|
|
450
|
+
# provider state supplying marker positions; the resolver locates
|
|
451
|
+
# the current span's boundary message in state and returns it as
|
|
452
|
+
# ``state_boundary`` — the clamp reads that field rather than
|
|
453
|
+
# re-projecting, so projection and clamp cannot drift. ``None``
|
|
454
|
+
# means the input is not stored yet (fresh prompt) — inputs are
|
|
455
|
+
# stored before outputs, so state holds no current-turn work and
|
|
456
|
+
# there is nothing to protect. The clamp is re-evaluated on every
|
|
457
|
+
# call, and the Phase 3 loop calls this method again after each
|
|
458
|
+
# progressed fold, so the boundary is never cached across a
|
|
459
|
+
# ``state["messages"]`` replacement. In mainline resume flows
|
|
460
|
+
# dispatch stripping removes interior markers before this can
|
|
461
|
+
# trigger; the clamp turns "P3 never folds current-task work" into
|
|
462
|
+
# a local guarantee (crash-leftover interior markers included).
|
|
463
|
+
resolved = _resolve_turns(messages, self._state)
|
|
464
|
+
current_span = resolved.current
|
|
465
|
+
state_boundary = current_span.state_boundary if current_span is not None else None
|
|
466
|
+
|
|
467
|
+
marker: dict[str, Any] | None = None
|
|
468
|
+
marker_id = ""
|
|
469
|
+
marker_position = 0
|
|
470
|
+
insertion_index: int | None = None
|
|
471
|
+
|
|
472
|
+
for candidate in markers:
|
|
473
|
+
candidate_id = candidate.get("marker_id")
|
|
474
|
+
candidate_position = candidate.get("position")
|
|
475
|
+
if not isinstance(candidate_id, str) or not candidate_id:
|
|
476
|
+
return False, False
|
|
477
|
+
if not isinstance(candidate_position, int):
|
|
478
|
+
return False, False
|
|
479
|
+
if state_boundary is not None and candidate_position >= state_boundary:
|
|
480
|
+
# Folding up to this marker would swallow the current real
|
|
481
|
+
# turn's work (fold ranges are inclusive of the marker).
|
|
482
|
+
continue
|
|
483
|
+
|
|
484
|
+
fold_range = self._state_fold_range(candidate_position)
|
|
485
|
+
if not fold_range or not self._fold_range_has_content(fold_range):
|
|
486
|
+
return self._discard_state_marker(candidate), False
|
|
487
|
+
|
|
488
|
+
candidate_insertion_index = self._visible_fold_insertion_index(
|
|
489
|
+
messages, _FoldMatch.of_range(fold_range, _fold_summary_ids(fold_range))
|
|
490
|
+
)
|
|
491
|
+
if candidate_insertion_index is None:
|
|
492
|
+
continue
|
|
493
|
+
|
|
494
|
+
marker = candidate
|
|
495
|
+
marker_id = candidate_id
|
|
496
|
+
marker_position = candidate_position
|
|
497
|
+
insertion_index = candidate_insertion_index
|
|
498
|
+
break
|
|
499
|
+
|
|
500
|
+
if marker is None:
|
|
501
|
+
return False, False
|
|
502
|
+
|
|
503
|
+
summary = _auto_summary(self._state, marker_position)
|
|
504
|
+
|
|
505
|
+
try:
|
|
506
|
+
await self._strategy._fire_pre_compact("phase3", usage_pct=usage_pct, tokens_before=tokens_before)
|
|
507
|
+
compressed_context_id, fold_range = self.execute_fold(marker_id, summary)
|
|
508
|
+
except ValueError:
|
|
509
|
+
return False, False
|
|
510
|
+
self._record_pre_output_history_len()
|
|
511
|
+
|
|
512
|
+
fold_summary_ids = _fold_summary_ids(fold_range)
|
|
513
|
+
insertion_index = self.exclude_wire_matches(
|
|
514
|
+
messages,
|
|
515
|
+
fold_range,
|
|
516
|
+
fold_summary_ids,
|
|
517
|
+
match_summary_refs=True,
|
|
518
|
+
skip_already_excluded=True,
|
|
519
|
+
insertion_index=insertion_index,
|
|
520
|
+
)
|
|
521
|
+
self.insert_and_cache_summary(
|
|
522
|
+
messages,
|
|
523
|
+
compressed_context_id,
|
|
524
|
+
fold_range,
|
|
525
|
+
fold_summary_ids,
|
|
526
|
+
insertion_index,
|
|
527
|
+
)
|
|
528
|
+
|
|
529
|
+
for message in fold_range:
|
|
530
|
+
set_excluded(message, excluded=True, reason=_REASON_COMPRESSION)
|
|
531
|
+
|
|
532
|
+
self._ledger.invalidate_for_fold(fold_range)
|
|
533
|
+
|
|
534
|
+
await self._strategy._notify_compress(
|
|
535
|
+
CompressInfo(
|
|
536
|
+
compressed_context_id=compressed_context_id,
|
|
537
|
+
summary=summary,
|
|
538
|
+
freed_messages=len(fold_range),
|
|
539
|
+
turn_range=_compressed_turn_range(self._state, compressed_context_id),
|
|
540
|
+
source="auto",
|
|
541
|
+
),
|
|
542
|
+
trigger="usage_threshold",
|
|
543
|
+
tokens_before=tokens_before,
|
|
544
|
+
tokens_after=included_token_count(messages),
|
|
545
|
+
)
|
|
546
|
+
self._record_published_fold(compressed_context_id)
|
|
547
|
+
|
|
548
|
+
return True, True
|
|
549
|
+
|
|
550
|
+
def _record_pre_output_history_len(self) -> None:
|
|
551
|
+
"""Remember the provider-state length after request-time compression."""
|
|
552
|
+
if self._state is None:
|
|
553
|
+
return
|
|
554
|
+
state_messages = self._state.get("messages", [])
|
|
555
|
+
if isinstance(state_messages, list):
|
|
556
|
+
self._state[PRE_OUTPUT_HISTORY_LEN_STATE_KEY] = len(state_messages)
|
|
557
|
+
|
|
558
|
+
def _state_fold_range(self, marker_position: int) -> list[Message]:
|
|
559
|
+
"""Return the pending state fold range ending at *marker_position*."""
|
|
560
|
+
if self._state is None:
|
|
561
|
+
return []
|
|
562
|
+
state_messages = self._state.get("messages", [])
|
|
563
|
+
if not isinstance(state_messages, list) or marker_position < 0 or marker_position >= len(state_messages):
|
|
564
|
+
return []
|
|
565
|
+
# Compaction state is bound to the kernel history provider's Message list.
|
|
566
|
+
typed_state_messages = cast("list[Message]", state_messages)
|
|
567
|
+
|
|
568
|
+
fold_start = 0
|
|
569
|
+
for idx, message in enumerate(typed_state_messages):
|
|
570
|
+
if message.additional_properties.get(HistoryMarkerKind.KEY) == HistoryMarkerKind.SUMMARY:
|
|
571
|
+
fold_start = idx + 1
|
|
572
|
+
if fold_start > marker_position:
|
|
573
|
+
return []
|
|
574
|
+
return typed_state_messages[fold_start : marker_position + 1]
|
|
575
|
+
|
|
576
|
+
@staticmethod
|
|
577
|
+
def _fold_range_has_content(fold_range: list[Message]) -> bool:
|
|
578
|
+
"""Return whether *fold_range* contains something other than turn markers."""
|
|
579
|
+
return any(
|
|
580
|
+
message.additional_properties.get(HistoryMarkerKind.KEY) != HistoryMarkerKind.TURN for message in fold_range
|
|
581
|
+
)
|
|
582
|
+
|
|
583
|
+
def _visible_fold_insertion_index(self, messages: list[Message], fold: _FoldMatch) -> int | None:
|
|
584
|
+
"""Return where a visible compressed summary should be inserted."""
|
|
585
|
+
for idx, message in enumerate(messages):
|
|
586
|
+
if message.additional_properties.get(EXCLUDED_KEY, False):
|
|
587
|
+
continue
|
|
588
|
+
if fold.matches(message):
|
|
589
|
+
return idx
|
|
590
|
+
return None
|
|
591
|
+
|
|
592
|
+
def _discard_state_marker(self, marker: dict[str, Any]) -> bool:
|
|
593
|
+
"""Remove an empty state marker without creating a compressed block."""
|
|
594
|
+
if self._state is None:
|
|
595
|
+
return False
|
|
596
|
+
state_messages = self._state.get("messages", [])
|
|
597
|
+
if not isinstance(state_messages, list):
|
|
598
|
+
return False
|
|
599
|
+
# Compaction state is bound to the kernel history provider's Message list.
|
|
600
|
+
typed_state_messages = cast("list[Message]", state_messages)
|
|
601
|
+
|
|
602
|
+
position = marker.get("position")
|
|
603
|
+
if (
|
|
604
|
+
isinstance(position, int)
|
|
605
|
+
and 0 <= position < len(state_messages)
|
|
606
|
+
and typed_state_messages[position].additional_properties.get(HistoryMarkerKind.KEY)
|
|
607
|
+
== HistoryMarkerKind.TURN
|
|
608
|
+
):
|
|
609
|
+
del typed_state_messages[position]
|
|
610
|
+
self._record_pre_output_history_len()
|
|
611
|
+
return True
|
|
612
|
+
|
|
613
|
+
marker_id = marker.get("marker_id")
|
|
614
|
+
if not isinstance(marker_id, str) or not marker_id:
|
|
615
|
+
return False
|
|
616
|
+
for idx, message in enumerate(typed_state_messages):
|
|
617
|
+
if message.additional_properties.get("_turn_id") == marker_id:
|
|
618
|
+
del typed_state_messages[idx]
|
|
619
|
+
self._record_pre_output_history_len()
|
|
620
|
+
return True
|
|
621
|
+
return False
|
|
622
|
+
|
|
623
|
+
def _find_state_summary(self, compressed_context_id: str) -> Message | None:
|
|
624
|
+
"""Return the state summary message for a compressed block."""
|
|
625
|
+
if self._state is None:
|
|
626
|
+
return None
|
|
627
|
+
state_messages = self._state.get("messages", [])
|
|
628
|
+
if not isinstance(state_messages, list):
|
|
629
|
+
return None
|
|
630
|
+
for message in state_messages:
|
|
631
|
+
if (
|
|
632
|
+
isinstance(message, Message)
|
|
633
|
+
and message.additional_properties.get(HistoryMarkerKind.KEY) == HistoryMarkerKind.SUMMARY
|
|
634
|
+
and message.additional_properties.get("_block_id") == compressed_context_id
|
|
635
|
+
):
|
|
636
|
+
return message
|
|
637
|
+
return None
|
|
638
|
+
|
|
639
|
+
def _state_has_compressed_block(self, compressed_context_id: str) -> bool:
|
|
640
|
+
"""Return whether the provider state still owns *compressed_context_id*."""
|
|
641
|
+
if self._state is None:
|
|
642
|
+
return False
|
|
643
|
+
compressed_blocks = self._state.get("compressed_msgs", [])
|
|
644
|
+
if not isinstance(compressed_blocks, list):
|
|
645
|
+
return False
|
|
646
|
+
|
|
647
|
+
from chrys.service.context.providers.history import CompressedBlock
|
|
648
|
+
|
|
649
|
+
for block in compressed_blocks:
|
|
650
|
+
if isinstance(block, CompressedBlock) and block.compressed_context_id == compressed_context_id:
|
|
651
|
+
return True
|
|
652
|
+
if isinstance(block, dict) and block.get("compressed_context_id") == compressed_context_id:
|
|
653
|
+
return True
|
|
654
|
+
return False
|
|
655
|
+
|
|
656
|
+
def _prune_stale_compressed_context_cache(self) -> None:
|
|
657
|
+
"""Drop cached summaries that no longer match provider state."""
|
|
658
|
+
stale_block_ids = [
|
|
659
|
+
block_id
|
|
660
|
+
for block_id in self._compressed_context_cache
|
|
661
|
+
if self._find_state_summary(block_id) is None or not self._state_has_compressed_block(block_id)
|
|
662
|
+
]
|
|
663
|
+
for block_id in stale_block_ids:
|
|
664
|
+
self._compressed_context_cache.pop(block_id, None)
|
|
665
|
+
|
|
666
|
+
def reinject_summaries(self, messages: list[Message]) -> None:
|
|
667
|
+
"""Re-inject emergency compressed summaries into per-call copies."""
|
|
668
|
+
if not self._compressed_context_cache:
|
|
669
|
+
return
|
|
670
|
+
self._prune_stale_compressed_context_cache()
|
|
671
|
+
if not self._compressed_context_cache:
|
|
672
|
+
return
|
|
673
|
+
|
|
674
|
+
needed: dict[str, int] = {}
|
|
675
|
+
for block_id, cached in self._compressed_context_cache.items():
|
|
676
|
+
if _message_present(messages, cached.summary_message):
|
|
677
|
+
continue
|
|
678
|
+
|
|
679
|
+
insertion_index: int | None = None
|
|
680
|
+
fold = _FoldMatch.of_cached(cached)
|
|
681
|
+
for idx, message in enumerate(messages):
|
|
682
|
+
if fold.matches(message):
|
|
683
|
+
insertion_index = idx
|
|
684
|
+
break
|
|
685
|
+
|
|
686
|
+
if insertion_index is not None:
|
|
687
|
+
needed[block_id] = insertion_index
|
|
688
|
+
|
|
689
|
+
for block_id in sorted(needed, key=lambda item: needed[item], reverse=True):
|
|
690
|
+
messages.insert(needed[block_id], self._compressed_context_cache[block_id].summary_message)
|