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,261 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Weak exclusion anchors for compaction state propagation."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import weakref
|
|
8
|
+
from copy import copy
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
|
|
11
|
+
from chrys.foundation.trajectory.metadata import read_analytics_item_id
|
|
12
|
+
from chrys.kernel import (
|
|
13
|
+
EXCLUDE_REASON_KEY,
|
|
14
|
+
EXCLUDED_KEY,
|
|
15
|
+
GROUP_ANNOTATION_KEY,
|
|
16
|
+
GROUP_ID_KEY,
|
|
17
|
+
SUMMARIZED_BY_SUMMARY_ID_KEY,
|
|
18
|
+
SUMMARY_OF_GROUP_IDS_KEY,
|
|
19
|
+
Content,
|
|
20
|
+
Message,
|
|
21
|
+
set_excluded,
|
|
22
|
+
)
|
|
23
|
+
from chrys.kernel.identity import ContentList
|
|
24
|
+
|
|
25
|
+
from .events import _COMPACTION_EXCLUDE_REASONS, _REASON_COMPRESSION, CachedSummary
|
|
26
|
+
from .groups import _content_signature, _message_call_ids
|
|
27
|
+
from .summaries import _set_summarized
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass(frozen=True)
|
|
31
|
+
class _ExclusionAnchor:
|
|
32
|
+
"""Persist a tool-loop exclusion onto the matching state message.
|
|
33
|
+
|
|
34
|
+
Per-call wire views can copy a Message's contents list, so contents-list
|
|
35
|
+
identity alone cannot locate every anchor in the stored messages.
|
|
36
|
+
Structural fallback is intentionally limited to role + call_ids, and scans
|
|
37
|
+
from the end so current-turn tool calls win over older reused call ids.
|
|
38
|
+
|
|
39
|
+
Identity tiers hold WEAK references. Anchors may survive an interrupted
|
|
40
|
+
run whose ``after_run`` never fired; a weak tier lives exactly as long
|
|
41
|
+
as its object, so a collected list or content simply stops matching —
|
|
42
|
+
a recycled address can never false-match, and the anchor never keeps
|
|
43
|
+
its source alive.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
reason: str | None
|
|
47
|
+
role: str
|
|
48
|
+
contents_ref: weakref.ref[ContentList] | None
|
|
49
|
+
call_ids: tuple[str, ...] = ()
|
|
50
|
+
content_signature: tuple[tuple[str, str | None, str | None, str], ...] = ()
|
|
51
|
+
message_id: str | None = None
|
|
52
|
+
content_refs: tuple[weakref.ref[Content], ...] = ()
|
|
53
|
+
summary_id: str | None = None
|
|
54
|
+
|
|
55
|
+
@classmethod
|
|
56
|
+
def from_message(cls, msg: Message) -> _ExclusionAnchor:
|
|
57
|
+
annotation = msg.additional_properties.get(GROUP_ANNOTATION_KEY)
|
|
58
|
+
summary_id = annotation.get(SUMMARIZED_BY_SUMMARY_ID_KEY) if isinstance(annotation, dict) else None
|
|
59
|
+
return cls(
|
|
60
|
+
reason=msg.additional_properties.get(EXCLUDE_REASON_KEY),
|
|
61
|
+
role=msg.role,
|
|
62
|
+
contents_ref=weakref.ref(msg.contents),
|
|
63
|
+
call_ids=_message_call_ids(msg),
|
|
64
|
+
content_signature=_content_signature(msg),
|
|
65
|
+
message_id=msg.message_id,
|
|
66
|
+
content_refs=tuple(weakref.ref(c) for c in msg.contents),
|
|
67
|
+
summary_id=summary_id if isinstance(summary_id, str) else None,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
def find_in(self, messages: list[Message], used_indices: set[int]) -> int | None:
|
|
71
|
+
snapshot = self.contents_ref() if self.contents_ref is not None else None
|
|
72
|
+
if snapshot is not None:
|
|
73
|
+
for i, msg in enumerate(messages):
|
|
74
|
+
if i not in used_indices and msg.contents is snapshot and self._matches_shape(msg):
|
|
75
|
+
return i
|
|
76
|
+
# The wire hands clients per-call views: fresh wrapper + fresh
|
|
77
|
+
# contents LIST, but the content OBJECTS are shared with the state
|
|
78
|
+
# original — matching on their identity keeps identity-level
|
|
79
|
+
# precision for anchors snapshotted from a view. A dead ref matches
|
|
80
|
+
# nothing: ``ref() is c`` cannot hold for a live content.
|
|
81
|
+
if self.content_refs:
|
|
82
|
+
for i, msg in enumerate(messages):
|
|
83
|
+
if (
|
|
84
|
+
i not in used_indices
|
|
85
|
+
and len(msg.contents) == len(self.content_refs)
|
|
86
|
+
and all(ref() is c for ref, c in zip(self.content_refs, msg.contents, strict=True))
|
|
87
|
+
and self._matches_shape(msg)
|
|
88
|
+
):
|
|
89
|
+
return i
|
|
90
|
+
if self.message_id:
|
|
91
|
+
for i, msg in enumerate(messages):
|
|
92
|
+
if i not in used_indices and msg.message_id == self.message_id and self._matches_shape(msg):
|
|
93
|
+
return i
|
|
94
|
+
if self.content_signature or self.call_ids:
|
|
95
|
+
for i in range(len(messages) - 1, -1, -1):
|
|
96
|
+
if i in used_indices:
|
|
97
|
+
continue
|
|
98
|
+
msg = messages[i]
|
|
99
|
+
if self._matches_shape(msg):
|
|
100
|
+
return i
|
|
101
|
+
return None
|
|
102
|
+
|
|
103
|
+
def _matches_shape(self, msg: Message) -> bool:
|
|
104
|
+
"""Return whether *msg* matches the stable structural anchor keys."""
|
|
105
|
+
if msg.role != self.role:
|
|
106
|
+
return False
|
|
107
|
+
if self.call_ids and _message_call_ids(msg) != self.call_ids:
|
|
108
|
+
return False
|
|
109
|
+
return not self.content_signature or _content_signature(msg) == self.content_signature
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class ExclusionLedger:
|
|
113
|
+
"""Own compaction caches and weak exclusion anchors."""
|
|
114
|
+
|
|
115
|
+
def __init__(self) -> None:
|
|
116
|
+
self._summary_cache: dict[str, CachedSummary] = {}
|
|
117
|
+
self._removed_group_ids: set[str] = set()
|
|
118
|
+
self._excluded_anchors: list[_ExclusionAnchor] = []
|
|
119
|
+
|
|
120
|
+
def reset_stale_exclusions(self, messages: list[Message]) -> None:
|
|
121
|
+
"""Reset stale foreign exclusions while retaining owned state."""
|
|
122
|
+
if self._summary_cache or self._removed_group_ids:
|
|
123
|
+
self.reinject_cached_summaries(messages)
|
|
124
|
+
# Reset _excluded only for messages NOT managed by our compaction
|
|
125
|
+
for msg in messages:
|
|
126
|
+
if not msg.additional_properties.get(EXCLUDED_KEY, False):
|
|
127
|
+
continue
|
|
128
|
+
annotation = msg.additional_properties.get(GROUP_ANNOTATION_KEY)
|
|
129
|
+
if isinstance(annotation, dict):
|
|
130
|
+
if SUMMARIZED_BY_SUMMARY_ID_KEY in annotation:
|
|
131
|
+
continue # Keep excluded — our cached summary replaces it
|
|
132
|
+
# Keep excluded if the group was fully removed (Phase 2/3)
|
|
133
|
+
gid = annotation.get(GROUP_ID_KEY)
|
|
134
|
+
if gid and gid in self._removed_group_ids:
|
|
135
|
+
continue
|
|
136
|
+
# Keep excluded if it's a summary of a removed group
|
|
137
|
+
summary_of = annotation.get(SUMMARY_OF_GROUP_IDS_KEY)
|
|
138
|
+
if summary_of and any(g in self._removed_group_ids for g in summary_of):
|
|
139
|
+
continue
|
|
140
|
+
# Preserve exclusions from prior-session compaction that
|
|
141
|
+
# this strategy instance doesn't track in its caches.
|
|
142
|
+
reason = msg.additional_properties.get(EXCLUDE_REASON_KEY)
|
|
143
|
+
if reason in _COMPACTION_EXCLUDE_REASONS:
|
|
144
|
+
continue
|
|
145
|
+
msg.additional_properties[EXCLUDED_KEY] = False
|
|
146
|
+
else:
|
|
147
|
+
for msg in messages:
|
|
148
|
+
if msg.additional_properties.get(EXCLUDED_KEY, False):
|
|
149
|
+
# Preserve exclusions set by compaction in a prior
|
|
150
|
+
# session — the _exclude_reason annotation survives
|
|
151
|
+
# serialization and identifies legitimate compaction
|
|
152
|
+
# flags even when the strategy has no cache.
|
|
153
|
+
reason = msg.additional_properties.get(EXCLUDE_REASON_KEY)
|
|
154
|
+
if reason in _COMPACTION_EXCLUDE_REASONS:
|
|
155
|
+
continue
|
|
156
|
+
msg.additional_properties[EXCLUDED_KEY] = False
|
|
157
|
+
|
|
158
|
+
def persist_to_state(self, state_messages: list[Message]) -> None:
|
|
159
|
+
"""Persist exclusions and their replacement summaries before history filters."""
|
|
160
|
+
used_indices: set[int] = set()
|
|
161
|
+
for anchor in self._excluded_anchors:
|
|
162
|
+
idx = anchor.find_in(state_messages, used_indices)
|
|
163
|
+
if idx is None:
|
|
164
|
+
continue
|
|
165
|
+
used_indices.add(idx)
|
|
166
|
+
set_excluded(state_messages[idx], excluded=True, reason=anchor.reason)
|
|
167
|
+
if anchor.summary_id is not None:
|
|
168
|
+
_set_summarized(state_messages[idx], anchor.summary_id)
|
|
169
|
+
self._excluded_anchors = []
|
|
170
|
+
self.reinject_cached_summaries(state_messages)
|
|
171
|
+
|
|
172
|
+
def snapshot_retry_state(self) -> tuple[_ExclusionAnchor, ...]:
|
|
173
|
+
"""Capture the current consume-once anchor list."""
|
|
174
|
+
return tuple(self._excluded_anchors)
|
|
175
|
+
|
|
176
|
+
def restore_retry_state(self, anchors: tuple[_ExclusionAnchor, ...]) -> None:
|
|
177
|
+
"""Restore anchors captured at retry-attempt entry."""
|
|
178
|
+
self._excluded_anchors = list(anchors)
|
|
179
|
+
|
|
180
|
+
def snapshot_excluded_anchors(self, messages: list[Message]) -> None:
|
|
181
|
+
"""Snapshot non-compression exclusions for after-run propagation."""
|
|
182
|
+
self._excluded_anchors = [
|
|
183
|
+
_ExclusionAnchor.from_message(msg)
|
|
184
|
+
for msg in messages
|
|
185
|
+
if msg.additional_properties.get(EXCLUDED_KEY, False)
|
|
186
|
+
and msg.additional_properties.get(EXCLUDE_REASON_KEY) != _REASON_COMPRESSION
|
|
187
|
+
]
|
|
188
|
+
|
|
189
|
+
def invalidate_for_fold(self, fold_range: list[Message]) -> None:
|
|
190
|
+
"""Remove compaction cache entries for messages folded by compression.
|
|
191
|
+
|
|
192
|
+
When a cross-turn compression folds messages that were previously
|
|
193
|
+
compacted (Phase 1) or removed (Phase 2/3), the corresponding
|
|
194
|
+
``_summary_cache`` and ``_removed_group_ids`` entries become stale.
|
|
195
|
+
"""
|
|
196
|
+
for msg in fold_range:
|
|
197
|
+
# A fold may contain only a persisted summary: originals have
|
|
198
|
+
# already been filtered out of the provider's visible history.
|
|
199
|
+
item_id = read_analytics_item_id(msg.additional_properties)
|
|
200
|
+
if item_id is not None:
|
|
201
|
+
self._summary_cache.pop(f"tool_summary_{item_id}", None)
|
|
202
|
+
annotation = msg.additional_properties.get(GROUP_ANNOTATION_KEY)
|
|
203
|
+
if not isinstance(annotation, dict):
|
|
204
|
+
continue
|
|
205
|
+
summary_id = annotation.get(SUMMARIZED_BY_SUMMARY_ID_KEY)
|
|
206
|
+
if isinstance(summary_id, str):
|
|
207
|
+
self._summary_cache.pop(summary_id, None)
|
|
208
|
+
gid = annotation.get(GROUP_ID_KEY)
|
|
209
|
+
if gid:
|
|
210
|
+
self._removed_group_ids.discard(gid)
|
|
211
|
+
|
|
212
|
+
def reinject_cached_summaries(self, messages: list[Message]) -> None:
|
|
213
|
+
"""Re-inject cached tool summaries missing from a replayed list.
|
|
214
|
+
|
|
215
|
+
This is normally unnecessary for the active tool loop because
|
|
216
|
+
compaction mutates the loop's list in place. It remains
|
|
217
|
+
useful for copied/replayed lists where excluded originals reference a
|
|
218
|
+
cached summary via ``SUMMARIZED_BY_SUMMARY_ID_KEY`` but the summary
|
|
219
|
+
message itself is absent.
|
|
220
|
+
"""
|
|
221
|
+
if not self._summary_cache:
|
|
222
|
+
return
|
|
223
|
+
|
|
224
|
+
# Collect summary_ids referenced by messages in this list
|
|
225
|
+
present_ids = {read_analytics_item_id(msg.additional_properties) for msg in messages}
|
|
226
|
+
needed: dict[str, int] = {}
|
|
227
|
+
|
|
228
|
+
for i, msg in enumerate(messages):
|
|
229
|
+
annotation = msg.additional_properties.get(GROUP_ANNOTATION_KEY)
|
|
230
|
+
if not isinstance(annotation, dict):
|
|
231
|
+
continue
|
|
232
|
+
sid = annotation.get(SUMMARIZED_BY_SUMMARY_ID_KEY)
|
|
233
|
+
if (
|
|
234
|
+
isinstance(sid, str)
|
|
235
|
+
and sid in self._summary_cache
|
|
236
|
+
and self._summary_cache[sid].item_id not in present_ids
|
|
237
|
+
and sid not in needed
|
|
238
|
+
):
|
|
239
|
+
needed[sid] = i
|
|
240
|
+
|
|
241
|
+
# Insert in reverse order to preserve indices
|
|
242
|
+
for sid in sorted(needed, key=lambda item: needed[item], reverse=True):
|
|
243
|
+
cached = self._summary_cache[sid]
|
|
244
|
+
# Keep wrapper/list ownership separate, but share content identity
|
|
245
|
+
# and metadata so later exclusions also reach the stored summary.
|
|
246
|
+
summary_msg = copy(cached.message)
|
|
247
|
+
summary_msg.contents = list(cached.message.contents)
|
|
248
|
+
messages.insert(needed[sid], summary_msg)
|
|
249
|
+
|
|
250
|
+
def discard_unreferenced_summaries(self, messages: list[Message]) -> None:
|
|
251
|
+
"""Drop attempt-local summaries after history rollback removes their references."""
|
|
252
|
+
referenced: set[str] = set()
|
|
253
|
+
for message in messages:
|
|
254
|
+
item_id = read_analytics_item_id(message.additional_properties)
|
|
255
|
+
if item_id is not None:
|
|
256
|
+
referenced.add(f"tool_summary_{item_id}")
|
|
257
|
+
annotation = message.additional_properties.get(GROUP_ANNOTATION_KEY)
|
|
258
|
+
if isinstance(annotation, dict) and isinstance(sid := annotation.get(SUMMARIZED_BY_SUMMARY_ID_KEY), str):
|
|
259
|
+
referenced.add(sid)
|
|
260
|
+
for sid in self._summary_cache.keys() - referenced:
|
|
261
|
+
del self._summary_cache[sid]
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
# Copyright (c) Microsoft. All rights reserved.
|
|
2
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
3
|
+
# Contains code adapted from Microsoft Agent Framework (MIT License; see NOTICE).
|
|
4
|
+
|
|
5
|
+
"""Message content signatures and compaction group walkers."""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import hashlib
|
|
10
|
+
import json
|
|
11
|
+
import logging
|
|
12
|
+
from collections.abc import Iterable
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
from chrys.foundation.text.images import hashable_image_identity
|
|
16
|
+
from chrys.foundation.trajectory.metadata import read_analytics_item_id
|
|
17
|
+
from chrys.kernel import (
|
|
18
|
+
EXCLUDED_KEY,
|
|
19
|
+
GROUP_ANNOTATION_KEY,
|
|
20
|
+
SUMMARIZED_BY_SUMMARY_ID_KEY,
|
|
21
|
+
SUMMARY_OF_GROUP_IDS_KEY,
|
|
22
|
+
Content,
|
|
23
|
+
Message,
|
|
24
|
+
is_image_content,
|
|
25
|
+
)
|
|
26
|
+
from chrys.kernel.compaction import _group_id, _group_kind
|
|
27
|
+
from chrys.kernel.identity import WeakIdentityRegistry
|
|
28
|
+
from chrys.service.context.tool_content import tool_call_name
|
|
29
|
+
|
|
30
|
+
_log = logging.getLogger(__name__)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _tool_call_name(content: Content) -> str | None:
|
|
34
|
+
"""Compatibility facade for compaction and recall consumers."""
|
|
35
|
+
return tool_call_name(content)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _message_call_ids(msg: Message) -> tuple[str, ...]:
|
|
39
|
+
"""Return call ids carried by framework content items."""
|
|
40
|
+
return tuple(c.call_id for c in msg.contents if c.call_id)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _render_tool_result_value(value: Any) -> str:
|
|
44
|
+
"""Render one result payload without leaking Content object reprs."""
|
|
45
|
+
if value is None:
|
|
46
|
+
return ""
|
|
47
|
+
if isinstance(value, str):
|
|
48
|
+
return value
|
|
49
|
+
if isinstance(value, list | tuple):
|
|
50
|
+
return "\n".join(part for item in value if (part := _render_tool_result_value(item)))
|
|
51
|
+
if isinstance(value, Content):
|
|
52
|
+
if value.type == "text":
|
|
53
|
+
return value.text or ""
|
|
54
|
+
if value.type == "shell_command_output":
|
|
55
|
+
parts = []
|
|
56
|
+
if value.stdout:
|
|
57
|
+
parts.append(value.stdout)
|
|
58
|
+
if value.stderr:
|
|
59
|
+
parts.append(f"stderr: {value.stderr}")
|
|
60
|
+
if value.exit_code is not None:
|
|
61
|
+
parts.append(f"exit code: {value.exit_code}")
|
|
62
|
+
if value.timed_out:
|
|
63
|
+
parts.append("timed out")
|
|
64
|
+
return "\n".join(parts)
|
|
65
|
+
if value.type == "hosted_file":
|
|
66
|
+
return f"[file: {value.name or value.file_id or 'hosted file'}]"
|
|
67
|
+
if value.type == "hosted_vector_store":
|
|
68
|
+
return f"[vector store: {value.vector_store_id or 'hosted vector store'}]"
|
|
69
|
+
if value.type in {"data", "uri"}:
|
|
70
|
+
media_type = value.media_type or "binary"
|
|
71
|
+
if media_type.startswith("image/") or (value.uri or "").startswith("data:image/"):
|
|
72
|
+
return f"[{media_type} image]"
|
|
73
|
+
return f"[{media_type} artifact]"
|
|
74
|
+
return json.dumps(value.to_dict(exclude={"raw_representation"}), ensure_ascii=False, default=str)
|
|
75
|
+
if isinstance(value, dict):
|
|
76
|
+
return json.dumps(_without_inline_binary(value), ensure_ascii=False, sort_keys=True, default=str)
|
|
77
|
+
return str(value)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _without_inline_binary(value: Any) -> Any:
|
|
81
|
+
"""Return *value* with inline base64 payloads replaced by a short placeholder.
|
|
82
|
+
|
|
83
|
+
Provider payloads kept as plain data (an Anthropic ``{"type": "base64"}``
|
|
84
|
+
source, such as a fetched PDF) would otherwise put their encoded bytes
|
|
85
|
+
into summaries.
|
|
86
|
+
"""
|
|
87
|
+
if isinstance(value, dict):
|
|
88
|
+
if value.get("type") == "base64" and isinstance(value.get("data"), str):
|
|
89
|
+
return _inline_binary_placeholder(value.get("media_type"))
|
|
90
|
+
return {key: _without_inline_binary(item) for key, item in value.items()}
|
|
91
|
+
if isinstance(value, list | tuple):
|
|
92
|
+
return [_without_inline_binary(item) for item in value]
|
|
93
|
+
return value
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _inline_binary_placeholder(media_type: object) -> str:
|
|
97
|
+
kind = media_type if isinstance(media_type, str) and media_type else "binary"
|
|
98
|
+
return f"[{kind} image]" if kind.startswith("image/") else f"[{kind} artifact]"
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def _tool_result_text(content: Content) -> str:
|
|
102
|
+
"""Render live or restored local/hosted result payloads for summaries."""
|
|
103
|
+
if content.type == "function_result":
|
|
104
|
+
value = content.result if content.result is not None else content.items
|
|
105
|
+
return _render_tool_result_value(value)
|
|
106
|
+
if content.type in {"hosted_tool_result", "search_tool_result"}:
|
|
107
|
+
value = content.items or content.result
|
|
108
|
+
return _render_tool_result_value(value)
|
|
109
|
+
if content.type == "mcp_server_tool_result":
|
|
110
|
+
return _render_tool_result_value(content.output)
|
|
111
|
+
if content.type in {
|
|
112
|
+
"code_interpreter_tool_result",
|
|
113
|
+
"image_generation_tool_result",
|
|
114
|
+
"shell_tool_result",
|
|
115
|
+
}:
|
|
116
|
+
return _render_tool_result_value(content.outputs)
|
|
117
|
+
return ""
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def _content_signature(msg: Message) -> tuple[tuple[str, str | None, str | None, str], ...]:
|
|
121
|
+
"""Return a stable, compact signature for message contents."""
|
|
122
|
+
parts: list[tuple[str, str | None, str | None, str]] = []
|
|
123
|
+
for content in msg.contents:
|
|
124
|
+
content_type = content.type
|
|
125
|
+
call_id = content.call_id or None
|
|
126
|
+
name = content.name or None
|
|
127
|
+
payload = _content_payload(content, content_type)
|
|
128
|
+
parts.append((content_type, call_id, name, _payload_digest(payload)))
|
|
129
|
+
return tuple(parts)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _content_payload(content: Any, content_type: str) -> Any:
|
|
133
|
+
if content_type == "function_call":
|
|
134
|
+
return getattr(content, "arguments", None)
|
|
135
|
+
if content_type == "function_result":
|
|
136
|
+
if isinstance(content, Content) and content.items:
|
|
137
|
+
image_payload = _function_result_image_payload(content)
|
|
138
|
+
if image_payload:
|
|
139
|
+
return {"result": content.result, "images": image_payload}
|
|
140
|
+
return getattr(content, "result", None)
|
|
141
|
+
if content_type == "text":
|
|
142
|
+
return getattr(content, "text", None)
|
|
143
|
+
if isinstance(content, str):
|
|
144
|
+
return content
|
|
145
|
+
to_dict = getattr(content, "to_dict", None)
|
|
146
|
+
if callable(to_dict):
|
|
147
|
+
return to_dict()
|
|
148
|
+
return repr(content)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def _function_result_image_payload(content: Content) -> list[dict[str, Any]]:
|
|
152
|
+
images: list[dict[str, Any]] = []
|
|
153
|
+
if not content.items:
|
|
154
|
+
return images
|
|
155
|
+
for item in content.items:
|
|
156
|
+
if not is_image_content(item):
|
|
157
|
+
continue
|
|
158
|
+
byte_length, identity = hashable_image_identity(item.uri or "")
|
|
159
|
+
images.append(
|
|
160
|
+
{
|
|
161
|
+
"media_type": item.media_type,
|
|
162
|
+
"byte_length": byte_length,
|
|
163
|
+
"hash": hashlib.sha256(identity.encode("utf-8", errors="surrogatepass")).hexdigest()[:16],
|
|
164
|
+
}
|
|
165
|
+
)
|
|
166
|
+
return images
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def _payload_digest(payload: Any) -> str:
|
|
170
|
+
try:
|
|
171
|
+
data = json.dumps(payload, sort_keys=True, default=str, ensure_ascii=False)
|
|
172
|
+
except TypeError:
|
|
173
|
+
data = str(payload)
|
|
174
|
+
return hashlib.sha256(data.encode("utf-8", errors="surrogatepass")).hexdigest()
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
# ---------------------------------------------------------------------------
|
|
178
|
+
# Group walkers over annotation metadata (chrys-owned data-structure tools;
|
|
179
|
+
# the per-message accessors ``_group_id``/``_group_kind`` come from
|
|
180
|
+
# ``chrys.kernel.compaction``)
|
|
181
|
+
# ---------------------------------------------------------------------------
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def _ordered_group_ids(messages: list[Message]) -> list[str]:
|
|
185
|
+
ids: list[str] = []
|
|
186
|
+
seen: set[str] = set()
|
|
187
|
+
for msg in messages:
|
|
188
|
+
gid = _group_id(msg)
|
|
189
|
+
if gid is not None and gid not in seen:
|
|
190
|
+
seen.add(gid)
|
|
191
|
+
ids.append(gid)
|
|
192
|
+
return ids
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def _group_messages_by_id(messages: list[Message]) -> dict[str, list[Message]]:
|
|
196
|
+
grouped: dict[str, list[Message]] = {}
|
|
197
|
+
for msg in messages:
|
|
198
|
+
gid = _group_id(msg)
|
|
199
|
+
if gid is not None:
|
|
200
|
+
grouped.setdefault(gid, []).append(msg)
|
|
201
|
+
return grouped
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def _included_group_ids(messages: list[Message], ordered_ids: list[str]) -> list[str]:
|
|
205
|
+
grouped = _group_messages_by_id(messages)
|
|
206
|
+
return [
|
|
207
|
+
gid
|
|
208
|
+
for gid in ordered_ids
|
|
209
|
+
if any(not m.additional_properties.get(EXCLUDED_KEY, False) for m in grouped.get(gid, []))
|
|
210
|
+
]
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def _group_start_indices(messages: list[Message]) -> dict[str, int]:
|
|
214
|
+
starts: dict[str, int] = {}
|
|
215
|
+
for idx, msg in enumerate(messages):
|
|
216
|
+
gid = _group_id(msg)
|
|
217
|
+
if gid is not None and gid not in starts:
|
|
218
|
+
starts[gid] = idx
|
|
219
|
+
return starts
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def _group_kind_map(messages: list[Message]) -> dict[str, str]:
|
|
223
|
+
kinds: dict[str, str] = {}
|
|
224
|
+
for msg in messages:
|
|
225
|
+
gid = _group_id(msg)
|
|
226
|
+
kind = _group_kind(msg)
|
|
227
|
+
if gid is not None and kind is not None and gid not in kinds:
|
|
228
|
+
kinds[gid] = kind
|
|
229
|
+
return kinds
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def _fold_summary_ids(messages: list[Message]) -> set[str]:
|
|
233
|
+
"""Collect summary occurrences owned or referenced by a fold.
|
|
234
|
+
|
|
235
|
+
Positional group IDs can be reused in a later wire view. Only the stable
|
|
236
|
+
summary reference and analytics identity can associate its replacement
|
|
237
|
+
across copies. Legacy summaries without that identity still match through
|
|
238
|
+
the fold's shared content objects, never through their group labels.
|
|
239
|
+
"""
|
|
240
|
+
summary_ids: set[str] = set()
|
|
241
|
+
for message in messages:
|
|
242
|
+
annotation = message.additional_properties.get(GROUP_ANNOTATION_KEY)
|
|
243
|
+
if not isinstance(annotation, dict):
|
|
244
|
+
continue
|
|
245
|
+
summary_id = annotation.get(SUMMARIZED_BY_SUMMARY_ID_KEY)
|
|
246
|
+
if isinstance(summary_id, str):
|
|
247
|
+
summary_ids.add(summary_id)
|
|
248
|
+
if isinstance(annotation.get(SUMMARY_OF_GROUP_IDS_KEY), list):
|
|
249
|
+
item_id = read_analytics_item_id(message.additional_properties)
|
|
250
|
+
if item_id is not None:
|
|
251
|
+
summary_ids.add(f"tool_summary_{item_id}")
|
|
252
|
+
return summary_ids
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def _matches_summary_id(message: Message, summary_ids: set[str] | frozenset[str]) -> bool:
|
|
256
|
+
"""Match a replacement by occurrence, independently of its wire labels."""
|
|
257
|
+
item_id = read_analytics_item_id(message.additional_properties)
|
|
258
|
+
return item_id is not None and f"tool_summary_{item_id}" in summary_ids
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
def _message_present(messages: list[Message], needle: Message) -> bool:
|
|
262
|
+
"""Return whether *needle* is already represented in *messages*."""
|
|
263
|
+
if any(msg is needle for msg in messages):
|
|
264
|
+
return True
|
|
265
|
+
needle_block_id = needle.additional_properties.get("_block_id")
|
|
266
|
+
if needle_block_id is None:
|
|
267
|
+
return False
|
|
268
|
+
return any(msg.additional_properties.get("_block_id") == needle_block_id for msg in messages)
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def _content_object_ids(messages: Iterable[Message]) -> set[int]:
|
|
272
|
+
"""Identity set of every content OBJECT carried by *messages*.
|
|
273
|
+
|
|
274
|
+
The stable cross-view currency: the kernel wire hands every layer
|
|
275
|
+
per-call message VIEWS — fresh wrapper + fresh contents list — so
|
|
276
|
+
wrapper identity and ``id(msg.contents)`` both break across the
|
|
277
|
+
state↔wire boundary, while the content objects stay shared. Bare-id
|
|
278
|
+
form for FRAME-LOCAL use only — a caller persisting identities across
|
|
279
|
+
calls builds a ``WeakIdentityRegistry`` instead, whose entries die
|
|
280
|
+
with their objects.
|
|
281
|
+
"""
|
|
282
|
+
return {id(c) for m in messages for c in m.contents}
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
def _carries_only(msg: Message, members: WeakIdentityRegistry | set[int] | frozenset[int]) -> bool:
|
|
286
|
+
"""Whether *msg*'s contents are drawn entirely from *members*.
|
|
287
|
+
|
|
288
|
+
*members* is either a frame-local bare-id set or a persisted weak
|
|
289
|
+
registry (whose dead entries never match). Empty messages never match:
|
|
290
|
+
an empty contents list carries no identity evidence, and ``all()``
|
|
291
|
+
over it would vacuously claim membership.
|
|
292
|
+
"""
|
|
293
|
+
if not msg.contents:
|
|
294
|
+
return False
|
|
295
|
+
if isinstance(members, WeakIdentityRegistry):
|
|
296
|
+
return all(c in members for c in msg.contents)
|
|
297
|
+
return all(id(c) in members for c in msg.contents)
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
def _tool_groups_in_range(
|
|
301
|
+
start: int,
|
|
302
|
+
end: int,
|
|
303
|
+
ordered_ids: list[str],
|
|
304
|
+
kinds: dict[str, str],
|
|
305
|
+
starts: dict[str, int],
|
|
306
|
+
grouped: dict[str, list[Message]],
|
|
307
|
+
) -> list[str]:
|
|
308
|
+
"""Return included tool-call group IDs whose first message is in [start, end)."""
|
|
309
|
+
return [
|
|
310
|
+
gid
|
|
311
|
+
for gid in ordered_ids
|
|
312
|
+
if kinds.get(gid) == "tool_call"
|
|
313
|
+
and start <= starts.get(gid, -1) < end
|
|
314
|
+
and any(not m.additional_properties.get(EXCLUDED_KEY, False) for m in grouped.get(gid, []))
|
|
315
|
+
]
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
def _any_tool_groups_in_range(
|
|
319
|
+
start: int,
|
|
320
|
+
end: int,
|
|
321
|
+
ordered_ids: list[str],
|
|
322
|
+
kinds: dict[str, str],
|
|
323
|
+
starts: dict[str, int],
|
|
324
|
+
) -> list[str]:
|
|
325
|
+
"""Return ALL tool-call group IDs in [start, end), regardless of exclusion.
|
|
326
|
+
|
|
327
|
+
Used by Phase 2/3 which need to find groups that were already summarised
|
|
328
|
+
by Phase 1 (originals excluded, summary still visible).
|
|
329
|
+
"""
|
|
330
|
+
return [gid for gid in ordered_ids if kinds.get(gid) == "tool_call" and start <= starts.get(gid, -1) < end]
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
# ---------------------------------------------------------------------------
|
|
334
|
+
# Message ID deduplication
|
|
335
|
+
# ---------------------------------------------------------------------------
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def _dedup_message_ids(messages: list[Message]) -> None:
|
|
339
|
+
"""Assign unique ``message_id`` values to messages with duplicate IDs.
|
|
340
|
+
|
|
341
|
+
Response aggregation can reuse sequential IDs (``msg_1``, ``msg_2``, …)
|
|
342
|
+
across runs within the same session. ``annotate_message_groups`` uses
|
|
343
|
+
``message_id`` to form group IDs, so duplicates cause unrelated tool calls
|
|
344
|
+
from different turns to merge into a single mega-group, breaking
|
|
345
|
+
compaction completely.
|
|
346
|
+
|
|
347
|
+
This function detects duplicates and reassigns them with a positional
|
|
348
|
+
suffix (e.g. ``msg_2`` → ``msg_2_i42``) so each message gets its own
|
|
349
|
+
unique identity. Already-unique IDs and messages without IDs are left
|
|
350
|
+
untouched.
|
|
351
|
+
"""
|
|
352
|
+
seen: dict[str, int] = {}
|
|
353
|
+
for idx, msg in enumerate(messages):
|
|
354
|
+
mid = msg.message_id
|
|
355
|
+
if not mid:
|
|
356
|
+
continue
|
|
357
|
+
if mid in seen:
|
|
358
|
+
# Duplicate — reassign with positional suffix
|
|
359
|
+
msg.message_id = f"{mid}_i{idx}"
|
|
360
|
+
else:
|
|
361
|
+
seen[mid] = idx
|