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,216 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Idempotent kernel backstop for oversized local tool results."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from copy import copy
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from chrys.foundation.text.model_json import model_json
|
|
11
|
+
from chrys.foundation.text.tokenizer import MixedLanguageTokenizer
|
|
12
|
+
from chrys.foundation.text.tool_output import truncate_content_texts, truncate_output
|
|
13
|
+
from chrys.foundation.tool_result_metadata import record_payload_truncation, tool_payload_observation
|
|
14
|
+
|
|
15
|
+
from ._content import Content
|
|
16
|
+
|
|
17
|
+
_EXCEPTION_OMITTED = "[exception omitted]"
|
|
18
|
+
|
|
19
|
+
_tokenizer = MixedLanguageTokenizer()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
_CONTENT_TEXT_FIELDS = ("text", "result", "output", "message", "stdout", "stderr", "exception")
|
|
23
|
+
"""Every string field of a plain content the ceiling bounds."""
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _content_texts(content: Content) -> list[str]:
|
|
27
|
+
"""The strings *content* contributes to the ceiling, in bounding order."""
|
|
28
|
+
if content.type == "function_result":
|
|
29
|
+
texts = [item.text for item in (content.items or []) if item.type == "text" and isinstance(item.text, str)]
|
|
30
|
+
if isinstance(content.exception, str):
|
|
31
|
+
texts.append(content.exception)
|
|
32
|
+
return texts
|
|
33
|
+
return [value for name in _CONTENT_TEXT_FIELDS if isinstance(value := getattr(content, name, None), str)]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _original_text(result: Any) -> str:
|
|
37
|
+
"""What the tool produced, measured the way the ceiling measured it."""
|
|
38
|
+
if isinstance(result, str):
|
|
39
|
+
return result
|
|
40
|
+
if isinstance(result, Content):
|
|
41
|
+
return "\n".join(_content_texts(result))
|
|
42
|
+
if isinstance(result, list) and all(isinstance(item, Content) for item in result):
|
|
43
|
+
return "\n".join(item.text for item in result if item.type == "text" and isinstance(item.text, str))
|
|
44
|
+
return _canonical_result_text(result)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _canonical_result_text(result: Any) -> str:
|
|
48
|
+
try:
|
|
49
|
+
return model_json(result, default=str)
|
|
50
|
+
except TypeError, ValueError:
|
|
51
|
+
return str(result)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _bound_content_list(items: list[Content], ceiling: int) -> list[Content] | None:
|
|
55
|
+
texts = [item.text for item in items if item.type == "text" and isinstance(item.text, str)]
|
|
56
|
+
if not texts:
|
|
57
|
+
return None
|
|
58
|
+
bounded = truncate_content_texts(texts, ceiling)
|
|
59
|
+
if bounded is None:
|
|
60
|
+
return None
|
|
61
|
+
|
|
62
|
+
output: list[Content] = []
|
|
63
|
+
text_index = 0
|
|
64
|
+
for item in items:
|
|
65
|
+
if item.type == "text" and item.text is not None:
|
|
66
|
+
replacement = bounded[text_index]
|
|
67
|
+
text_index += 1
|
|
68
|
+
if replacement is None:
|
|
69
|
+
continue
|
|
70
|
+
if replacement == item.text:
|
|
71
|
+
output.append(item)
|
|
72
|
+
else:
|
|
73
|
+
item_copy = copy(item)
|
|
74
|
+
item_copy.text = replacement
|
|
75
|
+
output.append(item_copy)
|
|
76
|
+
else:
|
|
77
|
+
output.append(item)
|
|
78
|
+
return output
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _fit_texts_before_exception(texts: list[str], ceiling: int) -> tuple[list[str | None], str]:
|
|
82
|
+
"""Leave room for a non-empty exception sentinel under the same ceiling."""
|
|
83
|
+
exception = truncate_output(_EXCEPTION_OMITTED, ceiling)
|
|
84
|
+
item_budget = max(1, ceiling - _tokenizer.count_tokens(exception))
|
|
85
|
+
|
|
86
|
+
while item_budget >= 1:
|
|
87
|
+
bounded = truncate_content_texts(texts, item_budget)
|
|
88
|
+
values: list[str | None] = list(texts) if bounded is None else bounded
|
|
89
|
+
joined = "\n".join([*(value for value in values if value is not None), exception])
|
|
90
|
+
total = _tokenizer.count_tokens(joined)
|
|
91
|
+
if total <= ceiling:
|
|
92
|
+
return values, exception
|
|
93
|
+
if item_budget == 1:
|
|
94
|
+
break
|
|
95
|
+
item_budget = max(1, item_budget - max(1, total - ceiling))
|
|
96
|
+
|
|
97
|
+
return [None] * len(texts), exception
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _bound_function_result(content: Content, ceiling: int) -> Content:
|
|
101
|
+
items = list(content.items or [])
|
|
102
|
+
item_texts = [item.text for item in items if item.type == "text" and isinstance(item.text, str)]
|
|
103
|
+
fields = [*item_texts]
|
|
104
|
+
if isinstance(content.exception, str):
|
|
105
|
+
fields.append(content.exception)
|
|
106
|
+
if not fields:
|
|
107
|
+
return content
|
|
108
|
+
bounded = truncate_content_texts(fields, ceiling)
|
|
109
|
+
if bounded is None:
|
|
110
|
+
return content
|
|
111
|
+
if isinstance(content.exception, str) and bounded[-1] is None:
|
|
112
|
+
bounded_items, bounded_exception = _fit_texts_before_exception(item_texts, ceiling)
|
|
113
|
+
bounded = [*bounded_items, bounded_exception]
|
|
114
|
+
|
|
115
|
+
copied = copy(content)
|
|
116
|
+
output_items: list[Content] = []
|
|
117
|
+
text_index = 0
|
|
118
|
+
for item in items:
|
|
119
|
+
if item.type == "text" and isinstance(item.text, str):
|
|
120
|
+
replacement = bounded[text_index]
|
|
121
|
+
text_index += 1
|
|
122
|
+
if replacement is None:
|
|
123
|
+
continue
|
|
124
|
+
if replacement == item.text:
|
|
125
|
+
output_items.append(item)
|
|
126
|
+
else:
|
|
127
|
+
item_copy = copy(item)
|
|
128
|
+
item_copy.text = replacement
|
|
129
|
+
output_items.append(item_copy)
|
|
130
|
+
else:
|
|
131
|
+
output_items.append(item)
|
|
132
|
+
copied.items = output_items
|
|
133
|
+
copied.result = "\n".join(
|
|
134
|
+
item.text for item in output_items if item.type == "text" and isinstance(item.text, str) and item.text
|
|
135
|
+
)
|
|
136
|
+
if isinstance(content.exception, str):
|
|
137
|
+
copied.exception = bounded[-1]
|
|
138
|
+
return copied
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def _bound_content(content: Content, ceiling: int) -> Content:
|
|
142
|
+
if content.type == "function_result":
|
|
143
|
+
return _bound_function_result(content, ceiling)
|
|
144
|
+
|
|
145
|
+
candidates = tuple((name, getattr(content, name, None)) for name in _CONTENT_TEXT_FIELDS)
|
|
146
|
+
field_names: list[str] = []
|
|
147
|
+
values: list[str] = []
|
|
148
|
+
for name, value in candidates:
|
|
149
|
+
if isinstance(value, str):
|
|
150
|
+
field_names.append(name)
|
|
151
|
+
values.append(value)
|
|
152
|
+
if not values:
|
|
153
|
+
return content
|
|
154
|
+
bounded = truncate_content_texts(values, ceiling)
|
|
155
|
+
if bounded is None:
|
|
156
|
+
return content
|
|
157
|
+
|
|
158
|
+
copied = copy(content)
|
|
159
|
+
for name, value in zip(field_names, bounded, strict=True):
|
|
160
|
+
if name == "text":
|
|
161
|
+
copied.text = value
|
|
162
|
+
elif name == "result":
|
|
163
|
+
copied.result = value
|
|
164
|
+
elif name == "output":
|
|
165
|
+
copied.output = value
|
|
166
|
+
elif name == "message":
|
|
167
|
+
copied.message = value
|
|
168
|
+
elif name == "stdout":
|
|
169
|
+
copied.stdout = value
|
|
170
|
+
elif name == "stderr":
|
|
171
|
+
copied.stderr = value
|
|
172
|
+
else:
|
|
173
|
+
copied.exception = value
|
|
174
|
+
return copied
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def apply_result_ceiling(result: Any, ceiling: int | None) -> Any:
|
|
178
|
+
"""Return *result* bounded to *ceiling*, copying only when it changes."""
|
|
179
|
+
bounded = _bounded_result(result, ceiling)
|
|
180
|
+
if bounded is not result:
|
|
181
|
+
# The backstop is the last thing to shrink a result and the only one
|
|
182
|
+
# the payload observation would otherwise never hear about — without
|
|
183
|
+
# this the recorded payload claims it was never truncated.
|
|
184
|
+
record_payload_truncation(_original_text(result))
|
|
185
|
+
return bounded
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def preview_result_ceiling(result: Any, ceiling: int | None, *, observation: dict[str, object]) -> Any:
|
|
189
|
+
"""Return what the ceiling will leave of *result*, recording the cut in *observation*.
|
|
190
|
+
|
|
191
|
+
The middleware that reports the payload runs before this backstop and with
|
|
192
|
+
the call's observation window already closed, so it reopens the window for
|
|
193
|
+
this pass alone: without it the record measures text the model never sees
|
|
194
|
+
and calls it untruncated.
|
|
195
|
+
"""
|
|
196
|
+
token = tool_payload_observation.set(observation)
|
|
197
|
+
try:
|
|
198
|
+
return apply_result_ceiling(result, ceiling)
|
|
199
|
+
finally:
|
|
200
|
+
tool_payload_observation.reset(token)
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def _bounded_result(result: Any, ceiling: int | None) -> Any:
|
|
204
|
+
if ceiling is None or ceiling <= 0:
|
|
205
|
+
return result
|
|
206
|
+
if isinstance(result, str):
|
|
207
|
+
return truncate_output(result, ceiling)
|
|
208
|
+
if isinstance(result, list) and all(isinstance(item, Content) for item in result):
|
|
209
|
+
bounded = _bound_content_list(result, ceiling)
|
|
210
|
+
return result if bounded is None else bounded
|
|
211
|
+
if isinstance(result, Content):
|
|
212
|
+
return _bound_content(result, ceiling)
|
|
213
|
+
|
|
214
|
+
serialized = _canonical_result_text(result)
|
|
215
|
+
bounded_text = truncate_output(serialized, ceiling)
|
|
216
|
+
return result if bounded_text == serialized else bounded_text
|
|
@@ -0,0 +1,431 @@
|
|
|
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
|
+
"""Chrys-owned serialization primitives."""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import copy
|
|
10
|
+
import json
|
|
11
|
+
import logging
|
|
12
|
+
import math
|
|
13
|
+
import re
|
|
14
|
+
from collections.abc import Mapping, MutableMapping
|
|
15
|
+
from dataclasses import asdict, is_dataclass
|
|
16
|
+
from datetime import date, datetime
|
|
17
|
+
from typing import Any, ClassVar, Protocol, TypeVar, runtime_checkable
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
ClassT = TypeVar("ClassT", bound="SerializationMixin")
|
|
22
|
+
ProtocolT = TypeVar("ProtocolT", bound="SerializationProtocol")
|
|
23
|
+
|
|
24
|
+
# Regex pattern for converting CamelCase to snake_case
|
|
25
|
+
_CAMEL_TO_SNAKE_PATTERN = re.compile(r"(?<!^)(?=[A-Z])")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@runtime_checkable
|
|
29
|
+
class SerializationProtocol(Protocol):
|
|
30
|
+
"""Dictionary serialization contract for kernel objects.
|
|
31
|
+
|
|
32
|
+
``Message`` and ``FunctionTool`` implement it through ``SerializationMixin``.
|
|
33
|
+
Nested protocol instances are converted recursively by the mixin.
|
|
34
|
+
|
|
35
|
+
Example::
|
|
36
|
+
|
|
37
|
+
from chrys.kernel.types import Message
|
|
38
|
+
|
|
39
|
+
message = Message(role="user", contents=["Hello"])
|
|
40
|
+
restored = Message.from_dict(message.to_dict())
|
|
41
|
+
assert restored.text == "Hello"
|
|
42
|
+
assert restored.role == "user"
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
def to_dict(self, **kwargs: Any) -> dict[str, Any]:
|
|
46
|
+
"""Convert the instance to a dictionary.
|
|
47
|
+
|
|
48
|
+
Keyword Args:
|
|
49
|
+
kwargs: Additional keyword arguments for serialization.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
Dictionary representation of the instance.
|
|
53
|
+
"""
|
|
54
|
+
...
|
|
55
|
+
|
|
56
|
+
@classmethod
|
|
57
|
+
def from_dict(cls: type[ProtocolT], value: MutableMapping[str, Any], /, **kwargs: Any) -> ProtocolT:
|
|
58
|
+
"""Create an instance from a dictionary.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
value: Dictionary containing the instance data (positional-only).
|
|
62
|
+
|
|
63
|
+
Keyword Args:
|
|
64
|
+
kwargs: Additional keyword arguments for deserialization.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
New instance of the class.
|
|
68
|
+
"""
|
|
69
|
+
...
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def is_serializable(value: Any) -> bool:
|
|
73
|
+
"""Check if a value is JSON serializable.
|
|
74
|
+
|
|
75
|
+
This function tests whether a value can be directly serialized to JSON
|
|
76
|
+
without custom encoding. It checks for basic Python types that have
|
|
77
|
+
direct JSON equivalents.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
value: The value to check for JSON serializability.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
True if the value is one of the basic JSON-serializable types
|
|
84
|
+
(str, int, float, bool, None, list, dict), False otherwise.
|
|
85
|
+
|
|
86
|
+
Note:
|
|
87
|
+
This function only checks for direct JSON compatibility. Complex objects
|
|
88
|
+
that implement ``SerializationProtocol`` require conversion via ``to_dict()``
|
|
89
|
+
before JSON serialization.
|
|
90
|
+
"""
|
|
91
|
+
return isinstance(value, (str, int, float, bool, type(None), list, dict))
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class SerializationMixin:
|
|
95
|
+
"""Serialize object fields to dictionaries and reconstruct through the constructor.
|
|
96
|
+
|
|
97
|
+
Nested protocol instances are serialized recursively. Constructors must
|
|
98
|
+
accept mappings for nested objects they reconstruct. ``DEFAULT_EXCLUDE``
|
|
99
|
+
omits configured fields, and ``INJECTABLE`` keeps runtime dependencies out
|
|
100
|
+
of serialized data so callers can supply them to ``from_dict``.
|
|
101
|
+
|
|
102
|
+
Example::
|
|
103
|
+
|
|
104
|
+
from chrys.kernel.types import Message
|
|
105
|
+
|
|
106
|
+
message = Message(role="user", contents=["Hello"])
|
|
107
|
+
payload = message.to_dict()
|
|
108
|
+
restored = Message.from_dict(payload)
|
|
109
|
+
assert restored.text == message.text
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
DEFAULT_EXCLUDE: ClassVar[set[str]] = set()
|
|
113
|
+
INJECTABLE: ClassVar[set[str]] = set()
|
|
114
|
+
_SHALLOW_COPY_FIELDS: ClassVar[set[str]] = {"raw_representation"}
|
|
115
|
+
|
|
116
|
+
def __deepcopy__(self, memo: dict[int, Any]) -> SerializationMixin:
|
|
117
|
+
"""Create a deep copy, preserving ``_SHALLOW_COPY_FIELDS`` by reference.
|
|
118
|
+
|
|
119
|
+
Fields listed in ``_SHALLOW_COPY_FIELDS`` may contain LLM SDK objects
|
|
120
|
+
(e.g., proto/gRPC responses) that are not safe to deep-copy. They are
|
|
121
|
+
kept as shallow references in the copy; all other attributes are
|
|
122
|
+
deep-copied normally.
|
|
123
|
+
"""
|
|
124
|
+
cls = type(self)
|
|
125
|
+
result = cls.__new__(cls)
|
|
126
|
+
memo[id(self)] = result
|
|
127
|
+
for k, v in self.__dict__.items():
|
|
128
|
+
if k in cls._SHALLOW_COPY_FIELDS:
|
|
129
|
+
object.__setattr__(result, k, v)
|
|
130
|
+
else:
|
|
131
|
+
object.__setattr__(result, k, copy.deepcopy(v, memo))
|
|
132
|
+
return result
|
|
133
|
+
|
|
134
|
+
def to_dict(self, *, exclude: set[str] | None = None, exclude_none: bool = True) -> dict[str, Any]:
|
|
135
|
+
"""Convert the instance and any nested objects to a dictionary.
|
|
136
|
+
|
|
137
|
+
This method performs deep serialization, automatically converting nested
|
|
138
|
+
``SerializationProtocol`` objects, lists, and dictionaries containing
|
|
139
|
+
serializable objects. Non-serializable objects are skipped with debug logging.
|
|
140
|
+
|
|
141
|
+
Fields marked in ``DEFAULT_EXCLUDE`` and ``INJECTABLE`` are automatically
|
|
142
|
+
excluded from the output, as are any private attributes (starting with '_').
|
|
143
|
+
|
|
144
|
+
Keyword Args:
|
|
145
|
+
exclude: Additional field names to exclude from serialization beyond
|
|
146
|
+
the default exclusions (``DEFAULT_EXCLUDE`` and ``INJECTABLE``).
|
|
147
|
+
exclude_none: Whether to exclude None values from the output. When True,
|
|
148
|
+
None values are omitted from the dictionary. Defaults to True.
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
Dictionary representation of the instance including a 'type' field
|
|
152
|
+
for type identification during deserialization (unless 'type' is excluded).
|
|
153
|
+
"""
|
|
154
|
+
# Combine exclude sets
|
|
155
|
+
combined_exclude = set(self.DEFAULT_EXCLUDE)
|
|
156
|
+
if exclude:
|
|
157
|
+
combined_exclude.update(exclude)
|
|
158
|
+
combined_exclude.update(self.INJECTABLE)
|
|
159
|
+
|
|
160
|
+
# Get all instance attributes
|
|
161
|
+
result: dict[str, Any] = {} if "type" in combined_exclude else {"type": self._get_type_identifier()}
|
|
162
|
+
for key, value in self.__dict__.items():
|
|
163
|
+
if key not in combined_exclude and not key.startswith("_"):
|
|
164
|
+
if exclude_none and value is None:
|
|
165
|
+
continue
|
|
166
|
+
# Recursively serialize SerializationProtocol objects
|
|
167
|
+
if isinstance(value, SerializationProtocol):
|
|
168
|
+
result[key] = value.to_dict(exclude=exclude, exclude_none=exclude_none)
|
|
169
|
+
continue
|
|
170
|
+
# Handle lists containing SerializationProtocol objects
|
|
171
|
+
if isinstance(value, list):
|
|
172
|
+
value_as_list: list[Any] = []
|
|
173
|
+
for item in value: # pyright: ignore[reportUnknownVariableType]
|
|
174
|
+
if isinstance(item, SerializationProtocol):
|
|
175
|
+
value_as_list.append(item.to_dict(exclude=exclude, exclude_none=exclude_none))
|
|
176
|
+
continue
|
|
177
|
+
if is_serializable(item):
|
|
178
|
+
value_as_list.append(item)
|
|
179
|
+
continue
|
|
180
|
+
logger.debug(
|
|
181
|
+
f"Skipping non-serializable item in list attribute '{key}' of type {type(item).__name__}" # pyright: ignore[reportUnknownArgumentType]
|
|
182
|
+
)
|
|
183
|
+
result[key] = value_as_list
|
|
184
|
+
continue
|
|
185
|
+
# Handle dicts containing SerializationProtocol values
|
|
186
|
+
if isinstance(value, dict):
|
|
187
|
+
from datetime import date, datetime, time
|
|
188
|
+
|
|
189
|
+
serialized_dict: dict[str, Any] = {}
|
|
190
|
+
for raw_key, v in value.items(): # pyright: ignore[reportUnknownVariableType]
|
|
191
|
+
dict_key = str(raw_key) # pyright: ignore[reportUnknownArgumentType]
|
|
192
|
+
if isinstance(v, SerializationProtocol):
|
|
193
|
+
serialized_dict[dict_key] = v.to_dict(exclude=exclude, exclude_none=exclude_none)
|
|
194
|
+
continue
|
|
195
|
+
# Convert datetime objects to strings
|
|
196
|
+
if isinstance(v, (datetime, date, time)):
|
|
197
|
+
serialized_dict[dict_key] = str(v)
|
|
198
|
+
continue
|
|
199
|
+
# Check if the value is JSON serializable
|
|
200
|
+
if is_serializable(v):
|
|
201
|
+
serialized_dict[dict_key] = v
|
|
202
|
+
continue
|
|
203
|
+
logger.debug(
|
|
204
|
+
f"Skipping non-serializable value for key '{dict_key}' in dict attribute '{key}' "
|
|
205
|
+
f"of type {type(v).__name__}" # pyright: ignore[reportUnknownArgumentType]
|
|
206
|
+
)
|
|
207
|
+
result[key] = serialized_dict
|
|
208
|
+
continue
|
|
209
|
+
# Directly include JSON serializable values
|
|
210
|
+
if is_serializable(value):
|
|
211
|
+
result[key] = value
|
|
212
|
+
continue
|
|
213
|
+
logger.debug(f"Skipping non-serializable attribute '{key}' of type {type(value).__name__}")
|
|
214
|
+
|
|
215
|
+
return result
|
|
216
|
+
|
|
217
|
+
def to_json(self, *, exclude: set[str] | None = None, exclude_none: bool = True, **kwargs: Any) -> str:
|
|
218
|
+
"""Convert the instance to a JSON string.
|
|
219
|
+
|
|
220
|
+
This is a convenience method that calls ``to_dict()`` and then serializes
|
|
221
|
+
the result using ``json.dumps()``. All the same serialization rules apply
|
|
222
|
+
as in ``to_dict()``, including automatic exclusion of injectable dependencies
|
|
223
|
+
and deep serialization of nested objects.
|
|
224
|
+
|
|
225
|
+
Keyword Args:
|
|
226
|
+
exclude: Additional field names to exclude from serialization.
|
|
227
|
+
exclude_none: Whether to exclude None values from the output. Defaults to True.
|
|
228
|
+
**kwargs: Additional keyword arguments passed through to ``json.dumps()``.
|
|
229
|
+
Common options include ``indent`` for pretty-printing and
|
|
230
|
+
``ensure_ascii`` for Unicode handling.
|
|
231
|
+
|
|
232
|
+
Returns:
|
|
233
|
+
JSON string representation of the instance.
|
|
234
|
+
"""
|
|
235
|
+
return json.dumps(self.to_dict(exclude=exclude, exclude_none=exclude_none), **kwargs)
|
|
236
|
+
|
|
237
|
+
@classmethod
|
|
238
|
+
def from_dict(
|
|
239
|
+
cls: type[ClassT], value: MutableMapping[str, Any], /, *, dependencies: MutableMapping[str, Any] | None = None
|
|
240
|
+
) -> ClassT:
|
|
241
|
+
"""Reconstruct an object, validating its type and injecting runtime dependencies.
|
|
242
|
+
|
|
243
|
+
``dependencies`` is keyed by serialized type identifier. Within each type,
|
|
244
|
+
keys name injectable parameters; ``field:value`` keys select dependencies
|
|
245
|
+
for matching instances. Mapping-valued dependencies merge into existing
|
|
246
|
+
mapping parameters. Names outside ``INJECTABLE`` log a diagnostic but
|
|
247
|
+
are still injected.
|
|
248
|
+
A supplied ``type`` that differs from the class identifier raises ``ValueError``.
|
|
249
|
+
|
|
250
|
+
Example::
|
|
251
|
+
|
|
252
|
+
from chrys.kernel.tools import FunctionTool
|
|
253
|
+
|
|
254
|
+
async def echo(text: str) -> str:
|
|
255
|
+
return text
|
|
256
|
+
|
|
257
|
+
original = FunctionTool(name="echo", description="Echo text", func=echo)
|
|
258
|
+
payload = original.to_dict()
|
|
259
|
+
restored = FunctionTool.from_dict(
|
|
260
|
+
payload, dependencies={"function_tool": {"func": echo}}
|
|
261
|
+
)
|
|
262
|
+
assert restored.func is echo
|
|
263
|
+
"""
|
|
264
|
+
if dependencies is None:
|
|
265
|
+
dependencies = {}
|
|
266
|
+
|
|
267
|
+
# Resolve the expected identifier from the class itself (matching what
|
|
268
|
+
# to_dict emits); resolving from the payload would make the mismatch
|
|
269
|
+
# check below compare the payload against itself and never fire.
|
|
270
|
+
type_id = cls._get_type_identifier()
|
|
271
|
+
|
|
272
|
+
if (supplied_type := value.get("type")) and supplied_type != type_id:
|
|
273
|
+
raise ValueError(f"Type mismatch: expected '{type_id}', got '{supplied_type}'")
|
|
274
|
+
|
|
275
|
+
# Create a copy of the value dict to work with, filtering out the 'type' key
|
|
276
|
+
kwargs = {k: v for k, v in value.items() if k != "type"}
|
|
277
|
+
|
|
278
|
+
# Process dependencies using dict-based structure
|
|
279
|
+
type_deps = dependencies.get(type_id, {})
|
|
280
|
+
for dep_key, dep_value in type_deps.items():
|
|
281
|
+
# Check if this is an instance-specific dependency (field:name format)
|
|
282
|
+
if ":" in dep_key:
|
|
283
|
+
field, name = dep_key.split(":", 1)
|
|
284
|
+
# Only apply if the instance matches
|
|
285
|
+
if kwargs.get(field) == name and isinstance(dep_value, dict):
|
|
286
|
+
# Apply instance-specific dependencies
|
|
287
|
+
for raw_param_name, param_value in dep_value.items(): # pyright: ignore[reportUnknownVariableType]
|
|
288
|
+
param_name = str(raw_param_name) # pyright: ignore[reportUnknownArgumentType]
|
|
289
|
+
if param_name not in cls.INJECTABLE:
|
|
290
|
+
logger.debug(
|
|
291
|
+
f"Dependency '{param_name}' for type '{type_id}' is not in INJECTABLE set. "
|
|
292
|
+
f"Available injectable parameters: {cls.INJECTABLE}"
|
|
293
|
+
)
|
|
294
|
+
# Handle nested dict parameters
|
|
295
|
+
if (
|
|
296
|
+
isinstance(param_value, dict)
|
|
297
|
+
and param_name in kwargs
|
|
298
|
+
and isinstance(kwargs[param_name], dict)
|
|
299
|
+
):
|
|
300
|
+
kwargs[param_name] = {**kwargs[param_name], **param_value}
|
|
301
|
+
else:
|
|
302
|
+
kwargs[param_name] = param_value
|
|
303
|
+
else:
|
|
304
|
+
# Regular parameter dependency
|
|
305
|
+
if dep_key not in cls.INJECTABLE:
|
|
306
|
+
logger.debug(
|
|
307
|
+
f"Dependency '{dep_key}' for type '{type_id}' is not in INJECTABLE set. "
|
|
308
|
+
f"Available injectable parameters: {cls.INJECTABLE}"
|
|
309
|
+
)
|
|
310
|
+
# Handle dict parameters - merge if both are dicts
|
|
311
|
+
if isinstance(dep_value, dict) and dep_key in kwargs and isinstance(kwargs[dep_key], dict):
|
|
312
|
+
kwargs[dep_key] = {**kwargs[dep_key], **dep_value}
|
|
313
|
+
else:
|
|
314
|
+
kwargs[dep_key] = dep_value
|
|
315
|
+
|
|
316
|
+
return cls(**kwargs)
|
|
317
|
+
|
|
318
|
+
@classmethod
|
|
319
|
+
def from_json(cls: type[ClassT], value: str, /, *, dependencies: MutableMapping[str, Any] | None = None) -> ClassT:
|
|
320
|
+
"""Create an instance from a JSON string.
|
|
321
|
+
|
|
322
|
+
This is a convenience method that parses the JSON string using ``json.loads()``
|
|
323
|
+
and then calls ``from_dict()`` to reconstruct the object. All dependency injection
|
|
324
|
+
capabilities are available through the ``dependencies`` parameter.
|
|
325
|
+
|
|
326
|
+
Args:
|
|
327
|
+
value: The JSON string containing the instance data (positional-only).
|
|
328
|
+
Must be valid JSON that deserializes to a dictionary with a 'type' field.
|
|
329
|
+
|
|
330
|
+
Keyword Args:
|
|
331
|
+
dependencies: A nested dictionary mapping type identifiers to their injectable dependencies.
|
|
332
|
+
See :meth:`from_dict` for detailed structure and examples of the three
|
|
333
|
+
injection patterns (simple, dict parameter, and instance-specific).
|
|
334
|
+
|
|
335
|
+
Returns:
|
|
336
|
+
New instance of the class with any specified dependencies injected.
|
|
337
|
+
|
|
338
|
+
Raises:
|
|
339
|
+
json.JSONDecodeError: If the JSON string is malformed.
|
|
340
|
+
ValueError: If the parsed data doesn't contain a valid 'type' field.
|
|
341
|
+
"""
|
|
342
|
+
data = json.loads(value)
|
|
343
|
+
return cls.from_dict(data, dependencies=dependencies)
|
|
344
|
+
|
|
345
|
+
@classmethod
|
|
346
|
+
def _get_type_identifier(cls, value: Mapping[str, Any] | None = None) -> str:
|
|
347
|
+
"""Get the type identifier for this class.
|
|
348
|
+
|
|
349
|
+
The type identifier is used in serialized data to enable proper deserialization.
|
|
350
|
+
It follows a priority order to determine the identifier:
|
|
351
|
+
|
|
352
|
+
1. If ``value`` contains a 'type' field, return that value (payload-supplied)
|
|
353
|
+
2. If the class has a ``type`` attribute, use that value (instance-level)
|
|
354
|
+
3. If the class has a ``TYPE`` attribute, use that value (class-level constant)
|
|
355
|
+
4. Otherwise, convert the class name to snake_case as fallback
|
|
356
|
+
|
|
357
|
+
``from_dict`` calls this WITHOUT ``value`` so the identifier comes from
|
|
358
|
+
the class and the payload's 'type' can be validated against it.
|
|
359
|
+
|
|
360
|
+
Args:
|
|
361
|
+
value: Optional mapping containing serialized data that may have a 'type' field.
|
|
362
|
+
|
|
363
|
+
Returns:
|
|
364
|
+
Type identifier string used for serialization and dependency injection mapping.
|
|
365
|
+
"""
|
|
366
|
+
if value and (type_ := value.get("type")) and isinstance(type_, str):
|
|
367
|
+
return type_ # type:ignore[no-any-return]
|
|
368
|
+
# for todict when defined per instance
|
|
369
|
+
if (type_ := getattr(cls, "type", None)) and isinstance(type_, str):
|
|
370
|
+
return type_ # type:ignore[no-any-return]
|
|
371
|
+
# for both when defined on class.
|
|
372
|
+
if (type_ := getattr(cls, "TYPE", None)) and isinstance(type_, str):
|
|
373
|
+
return type_ # type:ignore[no-any-return]
|
|
374
|
+
# Fallback and default
|
|
375
|
+
# Convert class name to snake_case
|
|
376
|
+
return _CAMEL_TO_SNAKE_PATTERN.sub("_", cls.__name__).lower()
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
def make_json_safe(obj: Any) -> Any:
|
|
380
|
+
"""Recursively convert an object to a JSON-serializable form.
|
|
381
|
+
|
|
382
|
+
Handles dataclasses, Pydantic models, objects with ``to_dict``/``dict``/``__dict__``,
|
|
383
|
+
datetimes, lists, dicts, and primitives. Falls back to ``str()`` for any remaining
|
|
384
|
+
non-serializable value so that ``json.dumps`` never raises a ``TypeError``.
|
|
385
|
+
|
|
386
|
+
Args:
|
|
387
|
+
obj: Object to make JSON safe.
|
|
388
|
+
|
|
389
|
+
Returns:
|
|
390
|
+
A JSON-serializable version of the object.
|
|
391
|
+
"""
|
|
392
|
+
return _make_json_safe(obj, depth=0)
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
def _make_json_safe(obj: Any, *, depth: int) -> Any:
|
|
396
|
+
if depth > 20:
|
|
397
|
+
return str(obj)
|
|
398
|
+
if obj is None or isinstance(obj, (str, int, bool)):
|
|
399
|
+
return obj
|
|
400
|
+
if isinstance(obj, float):
|
|
401
|
+
return obj if math.isfinite(obj) else str(obj)
|
|
402
|
+
if isinstance(obj, bytes):
|
|
403
|
+
return obj.decode("utf-8", errors="replace")
|
|
404
|
+
if isinstance(obj, (datetime, date)):
|
|
405
|
+
return obj.isoformat()
|
|
406
|
+
if is_dataclass(obj) and not isinstance(obj, type):
|
|
407
|
+
return _make_json_safe(asdict(obj), depth=depth + 1) # type: ignore[arg-type]
|
|
408
|
+
if callable(getattr(obj, "model_dump", None)):
|
|
409
|
+
try:
|
|
410
|
+
return _make_json_safe(obj.model_dump(), depth=depth + 1) # type: ignore[no-any-return]
|
|
411
|
+
except TypeError:
|
|
412
|
+
pass
|
|
413
|
+
if callable(getattr(obj, "to_dict", None)):
|
|
414
|
+
try:
|
|
415
|
+
return _make_json_safe(obj.to_dict(), depth=depth + 1) # type: ignore[no-any-return]
|
|
416
|
+
except TypeError:
|
|
417
|
+
pass
|
|
418
|
+
if callable(getattr(obj, "dict", None)):
|
|
419
|
+
try:
|
|
420
|
+
return _make_json_safe(obj.dict(), depth=depth + 1) # type: ignore[no-any-return]
|
|
421
|
+
except TypeError:
|
|
422
|
+
pass
|
|
423
|
+
if isinstance(obj, Mapping):
|
|
424
|
+
return {str(key): _make_json_safe(value, depth=depth + 1) for key, value in obj.items()} # type: ignore[misc]
|
|
425
|
+
if isinstance(obj, (list, tuple)):
|
|
426
|
+
return [_make_json_safe(item, depth=depth + 1) for item in obj] # type: ignore[misc]
|
|
427
|
+
if isinstance(obj, (set, frozenset)):
|
|
428
|
+
return [_make_json_safe(item, depth=depth + 1) for item in sorted(obj, key=repr)] # type: ignore[misc]
|
|
429
|
+
if hasattr(obj, "__dict__"):
|
|
430
|
+
return {key: _make_json_safe(value, depth=depth + 1) for key, value in vars(obj).items()} # type: ignore[misc]
|
|
431
|
+
return str(obj)
|