agent-log-server 0.2.122__py3-none-android_24_arm64_v8a.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.
- agent_log_server-0.2.122.dist-info/METADATA +186 -0
- agent_log_server-0.2.122.dist-info/RECORD +256 -0
- agent_log_server-0.2.122.dist-info/WHEEL +5 -0
- agent_log_server-0.2.122.dist-info/entry_points.txt +4 -0
- agent_log_server-0.2.122.dist-info/licenses/LICENSE +649 -0
- agent_log_server-0.2.122.dist-info/top_level.txt +6 -0
- agent_log_server_rs/DEVELOPER_MESSAGE_TEMPLATE.md +517 -0
- agent_log_server_rs/__init__.py +1 -0
- agent_log_server_rs/adapter_protocol.py +548 -0
- agent_log_server_rs/adapters/__init__.py +1 -0
- agent_log_server_rs/adapters/embedded_adapter.py +157 -0
- agent_log_server_rs/adapters/extension_adapter.py +1925 -0
- agent_log_server_rs/adapters/rpc_common.py +137 -0
- agent_log_server_rs/bin/als-server +0 -0
- agent_log_server_rs/bin/als-server.manifest.json +10 -0
- agent_log_server_rs/bootstrap.py +706 -0
- agent_log_server_rs/codec.py +85 -0
- agent_log_server_rs/extension_cli.py +520 -0
- agent_log_server_rs/rust/crates/als-server/src/static/app.js +151 -0
- agent_log_server_rs/rust/crates/als-server/src/static/appserver.css +240 -0
- agent_log_server_rs/rust/crates/als-server/src/static/appserver.js +208 -0
- agent_log_server_rs/rust/crates/als-server/src/static/codex_agent.css +4024 -0
- agent_log_server_rs/rust/crates/als-server/src/static/codex_agent.ts +2610 -0
- agent_log_server_rs/rust/crates/als-server/src/static/codexas-icon.svg +5 -0
- agent_log_server_rs/rust/crates/als-server/src/static/dist/codex_agent.js +26 -0
- agent_log_server_rs/rust/crates/als-server/src/static/dist/codex_agent.js.map +7 -0
- agent_log_server_rs/rust/crates/als-server/src/static/images/green-right-arrow.png +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/approvals/ui.ts +949 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/assistant_stream.ts +165 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/boot/init_flow.ts +341 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/boot/input_flow.ts +592 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/client_identity.ts +10 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/composer/runtime.ts +1065 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/conversation/runtime.ts +345 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/conversation_drawer/actions.ts +523 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/conversation_drawer/index.ts +100 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/conversation_drawer/list.ts +966 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/conversation_drawer.ts +1 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/conversation_modal.ts +147 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/diff/rendering.ts +857 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/events/router.ts +779 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/events/socket.ts +140 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/host/runtime.ts +357 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/layout/viewport.ts +95 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/layout/widescreen.ts +168 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/markdown.ts +576 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/orchestrator/rpc_flow.ts +73 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/orchestrator/session_flow.ts +191 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/path_label.ts +76 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/plan/runtime.ts +446 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/plan_modal.ts +102 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/plan_overlay.ts +235 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/project_modal.ts +1398 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/render/utils.ts +456 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/request_cards/runtime.ts +236 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/rpc/conversations/client.ts +1021 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/rpc/conversations/contract.ts +406 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/rpc/namespaces.ts +18 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/rpc/registry.ts +113 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/rpc/settings/client.ts +662 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/rpc/settings/contract.ts +49 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/rpc/transport.ts +463 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/rpc/ui/client.ts +588 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/rpc/ui/contract.ts +50 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/runtime_footer.ts +373 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/settings/runtime_helpers.ts +20 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/settings/save_flow.ts +332 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/settings/ui_flow.ts +1148 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/shared_types.ts +61 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/shell_render.ts +377 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/shell_semantic.ts +606 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/subagents/collapsible.ts +224 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/terminal_ansi.ts +134 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/timeline/live_items.ts +594 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/timeline/replay.ts +820 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/timeline/rows.ts +290 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/timeline/virtualizer.ts +1123 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/timeline_sticky_headers.ts +492 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/tool_render.ts +789 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/transcript_card_metadata.ts +228 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/transcript_cards.ts +780 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/transcript_config.ts +10 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/transcript_loader.ts +511 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/transcript_metrics.ts +28 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/transcript_stream.ts +561 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/transcript_stream_url.ts +7 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/vendor_modules.d.ts +5 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/codex_agent/vendor_runtime.ts +106 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/console_bridge.js +229 -0
- agent_log_server_rs/rust/crates/als-server/src/static/js/socketio_runtime.js +27 -0
- agent_log_server_rs/rust/crates/als-server/src/static/modals/rollout_picker.ts +46 -0
- agent_log_server_rs/rust/crates/als-server/src/static/modals/settings_modal.ts +63 -0
- agent_log_server_rs/rust/crates/als-server/src/static/modals/settings_schema.ts +3666 -0
- agent_log_server_rs/rust/crates/als-server/src/static/modals/warning_modal.ts +65 -0
- agent_log_server_rs/rust/crates/als-server/src/static/style.css +194 -0
- agent_log_server_rs/rust/crates/als-server/src/static/ui/extension_settings.ts +493 -0
- agent_log_server_rs/rust/crates/als-server/src/static/ui/splash_settings.ts +41 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-cyrillic-400-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-cyrillic-400-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-cyrillic-500-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-cyrillic-500-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-cyrillic-600-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-cyrillic-600-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-cyrillic-700-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-cyrillic-700-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-cyrillic-ext-400-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-cyrillic-ext-400-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-cyrillic-ext-500-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-cyrillic-ext-500-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-cyrillic-ext-600-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-cyrillic-ext-600-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-cyrillic-ext-700-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-cyrillic-ext-700-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-greek-400-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-greek-400-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-greek-500-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-greek-500-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-greek-600-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-greek-600-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-greek-700-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-greek-700-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-latin-400-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-latin-400-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-latin-500-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-latin-500-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-latin-600-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-latin-600-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-latin-700-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-latin-700-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-latin-ext-400-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-latin-ext-400-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-latin-ext-500-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-latin-ext-500-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-latin-ext-600-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-latin-ext-600-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-latin-ext-700-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-latin-ext-700-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-vietnamese-400-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-vietnamese-400-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-vietnamese-500-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-vietnamese-500-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-vietnamese-600-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-vietnamese-600-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-vietnamese-700-italic.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono/jetbrains-mono-vietnamese-700-normal.woff2 +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/fonts/jetbrains-mono.css +481 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/socket.io/socket.io.min.js +7 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/socket.io-msgpack-parser/socket.io-msgpack-parser.js +2 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/socket.io-msgpack-parser/socket.io-msgpack-parser.js.map +7 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/tree-sitter-bash/highlights.scm +56 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/tree-sitter-bash/tree-sitter-bash.wasm +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/web-tree-sitter/tree-sitter.js +3278 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/web-tree-sitter/tree-sitter.wasm +0 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/web-tree-sitter/web-tree-sitter.js +4007 -0
- agent_log_server_rs/rust/crates/als-server/src/static/vendor/web-tree-sitter/web-tree-sitter.wasm +0 -0
- agent_log_server_rs/shellspec/extension_adapter.yaml +15 -0
- agent_log_server_rs/tests/test_bootstrap.py +435 -0
- agent_log_server_rs/tests/test_codec.py +97 -0
- agent_log_server_rs/tests/test_codex_ext_client_resume.py +37 -0
- agent_log_server_rs/tests/test_codex_ext_router_atomic_diff.py +221 -0
- agent_log_server_rs/tests/test_codex_ext_runtime_protocol.py +109 -0
- agent_log_server_rs/tests/test_codex_ext_transport_resume.py +190 -0
- agent_log_server_rs/tests/test_extension_adapter_dispatch.py +170 -0
- agent_log_server_rs/tests/test_kb_and_codex_search.py +415 -0
- agent_log_server_rs/tests/test_mcp_socketio_serializer.py +53 -0
- agent_log_server_rs/tests/test_release_binary_wheel.py +119 -0
- als_deprecated/__init__.py +2 -0
- als_deprecated/__main__.py +5 -0
- als_deprecated/agent_log_subsystem.py +276 -0
- als_deprecated/agent_pty_http_shim_lifecycle.py +171 -0
- als_deprecated/appserver_routes.py +1930 -0
- als_deprecated/appserver_socketio.py +1223 -0
- als_deprecated/ask_user_interactions.py +415 -0
- als_deprecated/conversation_store.py +279 -0
- als_deprecated/conversation_todos.py +271 -0
- als_deprecated/conversations_rpc_contract.py +849 -0
- als_deprecated/extension_api.py +1041 -0
- als_deprecated/extension_cli.py +347 -0
- als_deprecated/host_routes.py +493 -0
- als_deprecated/index.py +30 -0
- als_deprecated/ipc_auth.py +36 -0
- als_deprecated/markdown_sections.py +141 -0
- als_deprecated/mcp_agent_pty_http_shim.py +30 -0
- als_deprecated/page_routes.py +71 -0
- als_deprecated/pending_context.py +671 -0
- als_deprecated/prompt_context.py +165 -0
- als_deprecated/repo_memory_delta.py +126 -0
- als_deprecated/rpc_stdio_mirror.py +134 -0
- als_deprecated/server.py +2004 -0
- als_deprecated/settings_ui_rpc_contract.py +311 -0
- als_deprecated/shellspec/agent_log.yaml +13 -0
- als_deprecated/shellspec/mcp_agent_pty.yaml +54 -0
- als_deprecated/socketio_config.py +53 -0
- als_deprecated/te2_assets/console_bridge.js +208 -0
- als_deprecated/te2_assets/framework_shells_README.md +448 -0
- als_deprecated/te2_assets/proxy_shell_wrapper_README.md +18 -0
- als_deprecated/te2_mcp_config.py +83 -0
- als_deprecated/te2_runtime.py +35 -0
- als_deprecated/te2_sync.py +78 -0
- als_deprecated/templates/template.html +46 -0
- als_deprecated/transcript_card_metadata.py +211 -0
- als_deprecated/typing_helpers.py +26 -0
- als_deprecated/web_pages.py +770 -0
- extensions/__init__.py +3107 -0
- extensions/codex_ext/__init__.py +1 -0
- extensions/codex_ext/client.py +1843 -0
- extensions/codex_ext/dependencies.py +143 -0
- extensions/codex_ext/devins_contract.py +25 -0
- extensions/codex_ext/manifest.json +138 -0
- extensions/codex_ext/mcp_contract.py +183 -0
- extensions/codex_ext/plan_utils.py +74 -0
- extensions/codex_ext/rollout_import.py +204 -0
- extensions/codex_ext/router.py +3772 -0
- extensions/codex_ext/runtime_protocol.py +1699 -0
- extensions/codex_ext/settings_schema.json +172 -0
- extensions/codex_ext/shellspec/app_server.yaml +19 -0
- extensions/codex_ext/transport.py +1412 -0
- extensions/codex_ext/ui/request_cards/codex_ext_request_card.js +882 -0
- extensions/copilot_sdk/VENDORED_SDK.md +17 -0
- extensions/copilot_sdk/__init__.py +2 -0
- extensions/copilot_sdk/_vendor/__init__.py +1 -0
- extensions/copilot_sdk/_vendor/copilot/__init__.py +80 -0
- extensions/copilot_sdk/_vendor/copilot/_diagnostics.py +29 -0
- extensions/copilot_sdk/_vendor/copilot/_jsonrpc.py +442 -0
- extensions/copilot_sdk/_vendor/copilot/_sdk_protocol_version.py +19 -0
- extensions/copilot_sdk/_vendor/copilot/_telemetry.py +48 -0
- extensions/copilot_sdk/_vendor/copilot/client.py +3157 -0
- extensions/copilot_sdk/_vendor/copilot/generated/__init__.py +0 -0
- extensions/copilot_sdk/_vendor/copilot/generated/rpc.py +7149 -0
- extensions/copilot_sdk/_vendor/copilot/generated/session_events.py +5009 -0
- extensions/copilot_sdk/_vendor/copilot/py.typed +1 -0
- extensions/copilot_sdk/_vendor/copilot/session.py +2415 -0
- extensions/copilot_sdk/_vendor/copilot/session_fs_provider.py +223 -0
- extensions/copilot_sdk/_vendor/copilot/tools.py +327 -0
- extensions/copilot_sdk/client.py +3871 -0
- extensions/copilot_sdk/dependencies.py +108 -0
- extensions/copilot_sdk/devins_contract.py +25 -0
- extensions/copilot_sdk/file_change_preview.py +80 -0
- extensions/copilot_sdk/fws_pipe_process.py +382 -0
- extensions/copilot_sdk/manifest.json +135 -0
- extensions/copilot_sdk/mcp_contract.py +63 -0
- extensions/copilot_sdk/plan_utils.py +56 -0
- extensions/copilot_sdk/protocol_adapter.py +342 -0
- extensions/copilot_sdk/protocol_registry.py +149 -0
- extensions/copilot_sdk/router.py +1789 -0
- extensions/copilot_sdk/schemas/api.schema.json +1063 -0
- extensions/copilot_sdk/schemas/session-events.schema.json +6369 -0
- extensions/copilot_sdk/settings_schema.json +165 -0
- extensions/copilot_sdk/shellspec/copilot_cli.yaml +20 -0
- extensions/copilot_sdk/te2_runtime.py +78 -0
- extensions/copilot_sdk/ui/request_cards/copilot_request_card.js +449 -0
- extensions/extensions.json +19 -0
- extensions/message_card_contracts.py +213 -0
- extensions/tool_card_contracts.py +102 -0
- mcp_agent_pty_http_shim.py +321 -0
- mcp_agent_pty_server.py +2931 -0
|
@@ -0,0 +1,849 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import uuid
|
|
5
|
+
from collections.abc import Callable
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from typing import Literal, TypeAlias, cast
|
|
8
|
+
|
|
9
|
+
from fastapi import HTTPException
|
|
10
|
+
|
|
11
|
+
from als_deprecated.typing_helpers import (
|
|
12
|
+
ObjectList,
|
|
13
|
+
ObjectMap,
|
|
14
|
+
RequestId,
|
|
15
|
+
coerce_object_list,
|
|
16
|
+
coerce_object_map,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
CONVERSATIONS_RPC_NAMESPACE = "/rpc/conversations"
|
|
20
|
+
CONVERSATION_SEND_METHOD = "conversation.send"
|
|
21
|
+
CONVERSATION_INTERRUPT_METHOD = "conversation.interrupt"
|
|
22
|
+
CONVERSATION_COMPACT_METHOD = "conversation.compact"
|
|
23
|
+
CONVERSATION_REPLAY_GET_CHUNK_METHOD = "conversation.replay.getChunk"
|
|
24
|
+
CONVERSATION_APPROVAL_RESPONSE_METHOD = "conversation.approval.respond"
|
|
25
|
+
CONVERSATION_SHELL_EXEC_METHOD = "conversation.shell.exec"
|
|
26
|
+
CONVERSATION_GET_METHOD = "conversation.get"
|
|
27
|
+
CONVERSATION_LIST_METHOD = "conversation.list"
|
|
28
|
+
CONVERSATION_CREATE_METHOD = "conversation.create"
|
|
29
|
+
CONVERSATION_SELECT_METHOD = "conversation.select"
|
|
30
|
+
CONVERSATION_UPDATE_METHOD = "conversation.update"
|
|
31
|
+
CONVERSATION_DELETE_METHOD = "conversation.delete"
|
|
32
|
+
CONVERSATION_PINS_SET_METHOD = "conversation.pins.set"
|
|
33
|
+
CONVERSATION_DRAFT_SET_METHOD = "conversation.draft.set"
|
|
34
|
+
CONVERSATIONS_RPC_NOTIFICATION_METHOD_BY_EVENT_TYPE: dict[str, str] = {
|
|
35
|
+
"activity": "conversation.activity",
|
|
36
|
+
"approval": "conversation.approval.request",
|
|
37
|
+
"approval_handoff": "conversation.approval.handoff",
|
|
38
|
+
"assistant_delta": "conversation.message.delta",
|
|
39
|
+
"assistant_end": "conversation.message.final",
|
|
40
|
+
"assistant_finalize": "conversation.message.final",
|
|
41
|
+
"command_result": "conversation.command.result",
|
|
42
|
+
"context_compacted": "conversation.context.compacted",
|
|
43
|
+
"diff": "conversation.diff",
|
|
44
|
+
"diff_declined": "conversation.diff.declined",
|
|
45
|
+
"draft_update": "conversation.draft.updated",
|
|
46
|
+
"error": "conversation.error",
|
|
47
|
+
"mention_insert": "conversation.mention.inserted",
|
|
48
|
+
"message": "conversation.user.message",
|
|
49
|
+
"meta_updated": "conversation.meta.updated",
|
|
50
|
+
"mode": "conversation.mode.changed",
|
|
51
|
+
"plan": "conversation.plan",
|
|
52
|
+
"plan_state": "conversation.plan.state",
|
|
53
|
+
"plan_update": "conversation.plan.update",
|
|
54
|
+
"preview_updated": "conversation.preview.updated",
|
|
55
|
+
"reasoning_delta": "conversation.reasoning.delta",
|
|
56
|
+
"reasoning_end": "conversation.reasoning.final",
|
|
57
|
+
"reasoning_finalize": "conversation.reasoning.final",
|
|
58
|
+
"shell_begin": "conversation.command.begin",
|
|
59
|
+
"shell_delta": "conversation.command.delta",
|
|
60
|
+
"shell_end": "conversation.command.end",
|
|
61
|
+
"status": "conversation.status",
|
|
62
|
+
"subagent_end": "conversation.subagent.end",
|
|
63
|
+
"subagent_start": "conversation.subagent.start",
|
|
64
|
+
"thought": "conversation.thought",
|
|
65
|
+
"toast": "conversation.toast",
|
|
66
|
+
"token_count": "conversation.token.updated",
|
|
67
|
+
"tool_interaction": "conversation.tool.interaction",
|
|
68
|
+
"tool_begin": "conversation.tool.begin",
|
|
69
|
+
"tool_delta": "conversation.tool.delta",
|
|
70
|
+
"tool_end": "conversation.tool.end",
|
|
71
|
+
"search": "conversation.search",
|
|
72
|
+
"view": "conversation.view",
|
|
73
|
+
"warning": "conversation.warning",
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
ConversationsRpcMethod: TypeAlias = Literal[
|
|
77
|
+
"conversation.get",
|
|
78
|
+
"conversation.list",
|
|
79
|
+
"conversation.create",
|
|
80
|
+
"conversation.select",
|
|
81
|
+
"conversation.update",
|
|
82
|
+
"conversation.delete",
|
|
83
|
+
"conversation.pins.set",
|
|
84
|
+
"conversation.draft.set",
|
|
85
|
+
"conversation.send",
|
|
86
|
+
"conversation.interrupt",
|
|
87
|
+
"conversation.compact",
|
|
88
|
+
"conversation.replay.getChunk",
|
|
89
|
+
"conversation.approval.respond",
|
|
90
|
+
"conversation.shell.exec",
|
|
91
|
+
]
|
|
92
|
+
SanitizeConversationId: TypeAlias = Callable[[str], str]
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class ConversationsRpcProtocolError(Exception):
|
|
96
|
+
def __init__(
|
|
97
|
+
self,
|
|
98
|
+
request_id: RequestId,
|
|
99
|
+
*,
|
|
100
|
+
code: int,
|
|
101
|
+
message: str,
|
|
102
|
+
data: ObjectMap | None = None,
|
|
103
|
+
) -> None:
|
|
104
|
+
super().__init__(message)
|
|
105
|
+
self.request_id = request_id
|
|
106
|
+
self.code = code
|
|
107
|
+
self.message = message
|
|
108
|
+
self.data = data or {}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@dataclass(frozen=True)
|
|
112
|
+
class JsonRpcSuccessResponse:
|
|
113
|
+
request_id: RequestId
|
|
114
|
+
result: ObjectMap
|
|
115
|
+
|
|
116
|
+
def to_json(self) -> ObjectMap:
|
|
117
|
+
return {
|
|
118
|
+
"jsonrpc": "2.0",
|
|
119
|
+
"id": self.request_id,
|
|
120
|
+
"result": self.result,
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
@dataclass(frozen=True)
|
|
125
|
+
class JsonRpcErrorResponse:
|
|
126
|
+
request_id: RequestId
|
|
127
|
+
code: int
|
|
128
|
+
message: str
|
|
129
|
+
data: ObjectMap | None = None
|
|
130
|
+
|
|
131
|
+
def to_json(self) -> ObjectMap:
|
|
132
|
+
error: ObjectMap = {
|
|
133
|
+
"code": self.code,
|
|
134
|
+
"message": self.message,
|
|
135
|
+
}
|
|
136
|
+
if self.data:
|
|
137
|
+
error["data"] = self.data
|
|
138
|
+
return {
|
|
139
|
+
"jsonrpc": "2.0",
|
|
140
|
+
"id": self.request_id,
|
|
141
|
+
"error": error,
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@dataclass(frozen=True)
|
|
146
|
+
class ParsedConversationsRpcRequest:
|
|
147
|
+
request_id: RequestId
|
|
148
|
+
method: ConversationsRpcMethod
|
|
149
|
+
params: ObjectMap
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
@dataclass(frozen=True)
|
|
153
|
+
class ConversationSendParams:
|
|
154
|
+
conversation_id: str
|
|
155
|
+
text: str
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
@dataclass(frozen=True)
|
|
159
|
+
class ConversationGetParams:
|
|
160
|
+
conversation_id: str | None
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
@dataclass(frozen=True)
|
|
164
|
+
class ConversationCreateParams:
|
|
165
|
+
settings: ObjectMap | None
|
|
166
|
+
|
|
167
|
+
def to_json(self) -> ObjectMap:
|
|
168
|
+
payload: ObjectMap = {}
|
|
169
|
+
if self.settings:
|
|
170
|
+
payload["settings"] = self.settings
|
|
171
|
+
return payload
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
@dataclass(frozen=True)
|
|
175
|
+
class ConversationSelectParams:
|
|
176
|
+
conversation_id: str
|
|
177
|
+
view: Literal["splash", "conversation"] | None = None
|
|
178
|
+
|
|
179
|
+
def to_json(self) -> ObjectMap:
|
|
180
|
+
payload: ObjectMap = {"conversation_id": self.conversation_id}
|
|
181
|
+
if self.view is not None:
|
|
182
|
+
payload["view"] = self.view
|
|
183
|
+
return payload
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
@dataclass(frozen=True)
|
|
187
|
+
class ConversationUpdateParams:
|
|
188
|
+
conversation_id: str | None
|
|
189
|
+
settings: ObjectMap | None = None
|
|
190
|
+
thread_id: str | None = None
|
|
191
|
+
|
|
192
|
+
def to_json(self) -> ObjectMap:
|
|
193
|
+
payload: ObjectMap = {}
|
|
194
|
+
if self.conversation_id:
|
|
195
|
+
payload["conversation_id"] = self.conversation_id
|
|
196
|
+
if self.settings is not None:
|
|
197
|
+
payload["settings"] = self.settings
|
|
198
|
+
if self.thread_id:
|
|
199
|
+
payload["thread_id"] = self.thread_id
|
|
200
|
+
return payload
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
@dataclass(frozen=True)
|
|
204
|
+
class ConversationDeleteParams:
|
|
205
|
+
conversation_id: str
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
@dataclass(frozen=True)
|
|
209
|
+
class ConversationPinsSetParams:
|
|
210
|
+
pinned_conversations: list[str]
|
|
211
|
+
|
|
212
|
+
def to_json(self) -> ObjectMap:
|
|
213
|
+
return {"pinned_conversations": list(self.pinned_conversations)}
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
@dataclass(frozen=True)
|
|
217
|
+
class ConversationDraftSetParams:
|
|
218
|
+
conversation_id: str | None
|
|
219
|
+
draft: str
|
|
220
|
+
|
|
221
|
+
def to_json(self) -> ObjectMap:
|
|
222
|
+
payload: ObjectMap = {"draft": self.draft}
|
|
223
|
+
if self.conversation_id:
|
|
224
|
+
payload["conversation_id"] = self.conversation_id
|
|
225
|
+
return payload
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
@dataclass(frozen=True)
|
|
229
|
+
class ConversationControlParams:
|
|
230
|
+
conversation_id: str
|
|
231
|
+
|
|
232
|
+
def to_json(self) -> ObjectMap:
|
|
233
|
+
return {"conversation_id": self.conversation_id}
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
@dataclass(frozen=True)
|
|
237
|
+
class ConversationApprovalResponseParams:
|
|
238
|
+
payload: ObjectMap
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
@dataclass(frozen=True)
|
|
242
|
+
class ConversationShellExecParams:
|
|
243
|
+
payload: ObjectMap
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
@dataclass(frozen=True)
|
|
247
|
+
class ReplayChunkCursor:
|
|
248
|
+
offset: int
|
|
249
|
+
|
|
250
|
+
def to_json(self) -> ObjectMap:
|
|
251
|
+
return {"offset": self.offset}
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
@dataclass(frozen=True)
|
|
255
|
+
class ConversationReplayGetChunkParams:
|
|
256
|
+
conversation_id: str | None
|
|
257
|
+
cursor: ReplayChunkCursor
|
|
258
|
+
max_entries: int
|
|
259
|
+
max_bytes: int
|
|
260
|
+
include_internal: bool
|
|
261
|
+
format_name: Literal["jsonl"] = "jsonl"
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
@dataclass(frozen=True)
|
|
265
|
+
class ConversationSendResult:
|
|
266
|
+
conversation_id: str
|
|
267
|
+
accepted: bool
|
|
268
|
+
payload: ObjectMap
|
|
269
|
+
|
|
270
|
+
def to_json(self) -> ObjectMap:
|
|
271
|
+
normalized = dict(self.payload)
|
|
272
|
+
normalized.setdefault("conversation_id", self.conversation_id)
|
|
273
|
+
normalized["accepted"] = self.accepted
|
|
274
|
+
return normalized
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
@dataclass(frozen=True)
|
|
278
|
+
class ConversationControlResult:
|
|
279
|
+
ok: bool
|
|
280
|
+
error: str | None
|
|
281
|
+
payload: ObjectMap
|
|
282
|
+
|
|
283
|
+
def to_json(self) -> ObjectMap:
|
|
284
|
+
normalized = dict(self.payload)
|
|
285
|
+
normalized.setdefault("ok", self.ok)
|
|
286
|
+
if self.error is not None:
|
|
287
|
+
normalized.setdefault("error", self.error)
|
|
288
|
+
return normalized
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
@dataclass(frozen=True)
|
|
292
|
+
class ReplayRangeData:
|
|
293
|
+
conversation_id: str | None
|
|
294
|
+
items: ObjectList
|
|
295
|
+
offset: int
|
|
296
|
+
total_count: int
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
@dataclass(frozen=True)
|
|
300
|
+
class ReplayJsonlChunk:
|
|
301
|
+
jsonl: str
|
|
302
|
+
item_count: int
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
@dataclass(frozen=True)
|
|
306
|
+
class ReplayChunkFrame:
|
|
307
|
+
format_name: Literal["jsonl"]
|
|
308
|
+
offset: int
|
|
309
|
+
item_count: int
|
|
310
|
+
total_count: int
|
|
311
|
+
chunk_index: int
|
|
312
|
+
complete: bool
|
|
313
|
+
next_cursor: ReplayChunkCursor | None
|
|
314
|
+
jsonl: str
|
|
315
|
+
|
|
316
|
+
def to_json(self) -> ObjectMap:
|
|
317
|
+
return {
|
|
318
|
+
"format": self.format_name,
|
|
319
|
+
"offset": self.offset,
|
|
320
|
+
"item_count": self.item_count,
|
|
321
|
+
"total_count": self.total_count,
|
|
322
|
+
"chunk_index": self.chunk_index,
|
|
323
|
+
"complete": self.complete,
|
|
324
|
+
"next_cursor": None if self.next_cursor is None else self.next_cursor.to_json(),
|
|
325
|
+
"jsonl": self.jsonl,
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
@dataclass(frozen=True)
|
|
330
|
+
class ReplayChunkResult:
|
|
331
|
+
conversation_id: str | None
|
|
332
|
+
replay_id: str
|
|
333
|
+
frame: ReplayChunkFrame
|
|
334
|
+
|
|
335
|
+
def to_json(self) -> ObjectMap:
|
|
336
|
+
return {
|
|
337
|
+
"conversation_id": self.conversation_id,
|
|
338
|
+
"replay_id": self.replay_id,
|
|
339
|
+
"frame": self.frame.to_json(),
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
def coerce_request_id(value: object) -> RequestId:
|
|
344
|
+
if isinstance(value, bool):
|
|
345
|
+
return None
|
|
346
|
+
return value if isinstance(value, (str, int)) else None
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
def conversation_rpc_notification_method(evt_type: object) -> str | None:
|
|
350
|
+
normalized = str(evt_type or "").strip().lower()
|
|
351
|
+
if not normalized:
|
|
352
|
+
return None
|
|
353
|
+
return CONVERSATIONS_RPC_NOTIFICATION_METHOD_BY_EVENT_TYPE.get(normalized)
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
def build_jsonrpc_success_response(
|
|
357
|
+
request_id: RequestId,
|
|
358
|
+
result: ObjectMap,
|
|
359
|
+
) -> JsonRpcSuccessResponse:
|
|
360
|
+
return JsonRpcSuccessResponse(request_id=request_id, result=result)
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
def build_jsonrpc_error_response(
|
|
364
|
+
request_id: RequestId,
|
|
365
|
+
*,
|
|
366
|
+
code: int,
|
|
367
|
+
message: str,
|
|
368
|
+
data: ObjectMap | None = None,
|
|
369
|
+
) -> JsonRpcErrorResponse:
|
|
370
|
+
return JsonRpcErrorResponse(
|
|
371
|
+
request_id=request_id,
|
|
372
|
+
code=code,
|
|
373
|
+
message=message,
|
|
374
|
+
data=data,
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
def build_jsonrpc_error_response_from_http_exception(
|
|
379
|
+
request_id: RequestId,
|
|
380
|
+
*,
|
|
381
|
+
method: str,
|
|
382
|
+
exc: HTTPException,
|
|
383
|
+
) -> JsonRpcErrorResponse:
|
|
384
|
+
status_code = int(getattr(exc, "status_code", 500) or 500)
|
|
385
|
+
detail = exc.detail
|
|
386
|
+
message = detail if isinstance(detail, str) and detail.strip() else "Request failed"
|
|
387
|
+
if status_code == 400:
|
|
388
|
+
code = -32602
|
|
389
|
+
error_code = "INVALID_REQUEST"
|
|
390
|
+
elif status_code == 404:
|
|
391
|
+
code = -32004
|
|
392
|
+
error_code = "NOT_FOUND"
|
|
393
|
+
elif status_code == 409:
|
|
394
|
+
code = -32009
|
|
395
|
+
error_code = "CONFLICT"
|
|
396
|
+
else:
|
|
397
|
+
code = -32603
|
|
398
|
+
error_code = "INTERNAL_ERROR"
|
|
399
|
+
return build_jsonrpc_error_response(
|
|
400
|
+
request_id,
|
|
401
|
+
code=code,
|
|
402
|
+
message=message,
|
|
403
|
+
data={
|
|
404
|
+
"code": error_code,
|
|
405
|
+
"status_code": status_code,
|
|
406
|
+
"method": method,
|
|
407
|
+
},
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
def parse_conversations_rpc_request(payload: object) -> ParsedConversationsRpcRequest:
|
|
412
|
+
request_id = coerce_request_id(payload.get("id") if isinstance(payload, dict) else None)
|
|
413
|
+
if not isinstance(payload, dict):
|
|
414
|
+
raise ConversationsRpcProtocolError(
|
|
415
|
+
request_id,
|
|
416
|
+
code=-32600,
|
|
417
|
+
message="Invalid request",
|
|
418
|
+
data={"code": "INVALID_REQUEST", "reason": "Payload must be an object"},
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
payload_map = coerce_object_map(payload)
|
|
422
|
+
if payload_map.get("jsonrpc") != "2.0":
|
|
423
|
+
raise ConversationsRpcProtocolError(
|
|
424
|
+
request_id,
|
|
425
|
+
code=-32600,
|
|
426
|
+
message="Invalid request",
|
|
427
|
+
data={"code": "INVALID_REQUEST", "reason": "jsonrpc must be '2.0'"},
|
|
428
|
+
)
|
|
429
|
+
|
|
430
|
+
method_value = payload_map.get("method")
|
|
431
|
+
if not isinstance(method_value, str) or not method_value.strip():
|
|
432
|
+
raise ConversationsRpcProtocolError(
|
|
433
|
+
request_id,
|
|
434
|
+
code=-32600,
|
|
435
|
+
message="Invalid request",
|
|
436
|
+
data={"code": "INVALID_REQUEST", "reason": "method is required"},
|
|
437
|
+
)
|
|
438
|
+
|
|
439
|
+
params_value = payload_map.get("params", {})
|
|
440
|
+
if params_value is None:
|
|
441
|
+
params_value = {}
|
|
442
|
+
if not isinstance(params_value, dict):
|
|
443
|
+
raise ConversationsRpcProtocolError(
|
|
444
|
+
request_id,
|
|
445
|
+
code=-32602,
|
|
446
|
+
message="Invalid params",
|
|
447
|
+
data={"code": "INVALID_REQUEST", "reason": "params must be an object"},
|
|
448
|
+
)
|
|
449
|
+
|
|
450
|
+
method = method_value.strip()
|
|
451
|
+
if method == CONVERSATION_GET_METHOD:
|
|
452
|
+
parsed_method: ConversationsRpcMethod = CONVERSATION_GET_METHOD
|
|
453
|
+
elif method == CONVERSATION_LIST_METHOD:
|
|
454
|
+
parsed_method = CONVERSATION_LIST_METHOD
|
|
455
|
+
elif method == CONVERSATION_CREATE_METHOD:
|
|
456
|
+
parsed_method = CONVERSATION_CREATE_METHOD
|
|
457
|
+
elif method == CONVERSATION_SELECT_METHOD:
|
|
458
|
+
parsed_method = CONVERSATION_SELECT_METHOD
|
|
459
|
+
elif method == CONVERSATION_UPDATE_METHOD:
|
|
460
|
+
parsed_method = CONVERSATION_UPDATE_METHOD
|
|
461
|
+
elif method == CONVERSATION_DELETE_METHOD:
|
|
462
|
+
parsed_method = CONVERSATION_DELETE_METHOD
|
|
463
|
+
elif method == CONVERSATION_PINS_SET_METHOD:
|
|
464
|
+
parsed_method = CONVERSATION_PINS_SET_METHOD
|
|
465
|
+
elif method == CONVERSATION_DRAFT_SET_METHOD:
|
|
466
|
+
parsed_method = CONVERSATION_DRAFT_SET_METHOD
|
|
467
|
+
elif method == CONVERSATION_SEND_METHOD:
|
|
468
|
+
parsed_method = CONVERSATION_SEND_METHOD
|
|
469
|
+
elif method == CONVERSATION_INTERRUPT_METHOD:
|
|
470
|
+
parsed_method = CONVERSATION_INTERRUPT_METHOD
|
|
471
|
+
elif method == CONVERSATION_COMPACT_METHOD:
|
|
472
|
+
parsed_method = CONVERSATION_COMPACT_METHOD
|
|
473
|
+
elif method == CONVERSATION_REPLAY_GET_CHUNK_METHOD:
|
|
474
|
+
parsed_method = CONVERSATION_REPLAY_GET_CHUNK_METHOD
|
|
475
|
+
elif method == CONVERSATION_APPROVAL_RESPONSE_METHOD:
|
|
476
|
+
parsed_method = CONVERSATION_APPROVAL_RESPONSE_METHOD
|
|
477
|
+
elif method == CONVERSATION_SHELL_EXEC_METHOD:
|
|
478
|
+
parsed_method = CONVERSATION_SHELL_EXEC_METHOD
|
|
479
|
+
else:
|
|
480
|
+
raise ConversationsRpcProtocolError(
|
|
481
|
+
request_id,
|
|
482
|
+
code=-32601,
|
|
483
|
+
message="Method not found",
|
|
484
|
+
data={"code": "NOT_FOUND", "method": method},
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
return ParsedConversationsRpcRequest(
|
|
488
|
+
request_id=request_id,
|
|
489
|
+
method=parsed_method,
|
|
490
|
+
params=coerce_object_map(params_value),
|
|
491
|
+
)
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
def parse_conversation_send_params(
|
|
495
|
+
params: ObjectMap,
|
|
496
|
+
*,
|
|
497
|
+
sanitize_conversation_id: SanitizeConversationId,
|
|
498
|
+
) -> ConversationSendParams:
|
|
499
|
+
conversation_id = _require_sanitized_conversation_id(
|
|
500
|
+
params.get("conversation_id"),
|
|
501
|
+
sanitize_conversation_id=sanitize_conversation_id,
|
|
502
|
+
detail="conversation_id and text required",
|
|
503
|
+
)
|
|
504
|
+
text_value = params.get("text")
|
|
505
|
+
text = text_value if isinstance(text_value, str) else ""
|
|
506
|
+
if not text:
|
|
507
|
+
raise HTTPException(status_code=400, detail="conversation_id and text required")
|
|
508
|
+
return ConversationSendParams(conversation_id=conversation_id, text=text)
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
def parse_conversation_control_params(
|
|
512
|
+
params: ObjectMap,
|
|
513
|
+
*,
|
|
514
|
+
sanitize_conversation_id: SanitizeConversationId,
|
|
515
|
+
) -> ConversationControlParams:
|
|
516
|
+
conversation_id = _require_sanitized_conversation_id(
|
|
517
|
+
params.get("conversation_id"),
|
|
518
|
+
sanitize_conversation_id=sanitize_conversation_id,
|
|
519
|
+
detail="Missing required field: conversation_id",
|
|
520
|
+
)
|
|
521
|
+
return ConversationControlParams(conversation_id=conversation_id)
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
def parse_conversation_get_params(
|
|
525
|
+
params: ObjectMap,
|
|
526
|
+
*,
|
|
527
|
+
sanitize_conversation_id: SanitizeConversationId,
|
|
528
|
+
active_conversation_id: str | None,
|
|
529
|
+
) -> ConversationGetParams:
|
|
530
|
+
conversation_id_raw = params.get("conversation_id")
|
|
531
|
+
if isinstance(conversation_id_raw, str) and conversation_id_raw.strip():
|
|
532
|
+
return ConversationGetParams(
|
|
533
|
+
conversation_id=sanitize_conversation_id(conversation_id_raw.strip()),
|
|
534
|
+
)
|
|
535
|
+
if isinstance(active_conversation_id, str) and active_conversation_id.strip():
|
|
536
|
+
return ConversationGetParams(
|
|
537
|
+
conversation_id=sanitize_conversation_id(active_conversation_id.strip()),
|
|
538
|
+
)
|
|
539
|
+
return ConversationGetParams(conversation_id=None)
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
def parse_conversation_approval_response_params(
|
|
543
|
+
params: ObjectMap,
|
|
544
|
+
) -> ConversationApprovalResponseParams:
|
|
545
|
+
request_id_value = params.get("request_id", params.get("requestId", params.get("id")))
|
|
546
|
+
request_id = str(request_id_value or "").strip()
|
|
547
|
+
if not request_id:
|
|
548
|
+
raise HTTPException(status_code=400, detail="Missing request_id")
|
|
549
|
+
return ConversationApprovalResponseParams(payload=dict(params))
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
def parse_conversation_shell_exec_params(
|
|
553
|
+
params: ObjectMap,
|
|
554
|
+
*,
|
|
555
|
+
sanitize_conversation_id: SanitizeConversationId,
|
|
556
|
+
) -> ConversationShellExecParams:
|
|
557
|
+
conversation_id = _require_sanitized_conversation_id(
|
|
558
|
+
params.get("conversation_id"),
|
|
559
|
+
sanitize_conversation_id=sanitize_conversation_id,
|
|
560
|
+
detail="Missing required field: conversation_id",
|
|
561
|
+
)
|
|
562
|
+
command = params.get("command")
|
|
563
|
+
if not isinstance(command, str) or not command.strip():
|
|
564
|
+
raise HTTPException(status_code=400, detail="No command provided")
|
|
565
|
+
payload = dict(params)
|
|
566
|
+
payload["conversation_id"] = conversation_id
|
|
567
|
+
payload["command"] = command
|
|
568
|
+
return ConversationShellExecParams(payload=payload)
|
|
569
|
+
|
|
570
|
+
|
|
571
|
+
def parse_conversation_create_params(params: ObjectMap) -> ConversationCreateParams:
|
|
572
|
+
settings_value = params.get("settings")
|
|
573
|
+
settings = coerce_object_map(settings_value) if isinstance(settings_value, dict) else None
|
|
574
|
+
return ConversationCreateParams(settings=settings or None)
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
def parse_conversation_select_params(
|
|
578
|
+
params: ObjectMap,
|
|
579
|
+
*,
|
|
580
|
+
sanitize_conversation_id: SanitizeConversationId,
|
|
581
|
+
) -> ConversationSelectParams:
|
|
582
|
+
conversation_id = _require_sanitized_conversation_id(
|
|
583
|
+
params.get("conversation_id", params.get("id")),
|
|
584
|
+
sanitize_conversation_id=sanitize_conversation_id,
|
|
585
|
+
detail="Missing conversation_id",
|
|
586
|
+
)
|
|
587
|
+
view_value = params.get("view")
|
|
588
|
+
view: Literal["splash", "conversation"] | None = None
|
|
589
|
+
if isinstance(view_value, str):
|
|
590
|
+
normalized_view = view_value.strip().lower()
|
|
591
|
+
if normalized_view in {"splash", "conversation"}:
|
|
592
|
+
view = cast(Literal["splash", "conversation"], normalized_view)
|
|
593
|
+
return ConversationSelectParams(conversation_id=conversation_id, view=view)
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
def parse_conversation_update_params(
|
|
597
|
+
params: ObjectMap,
|
|
598
|
+
*,
|
|
599
|
+
sanitize_conversation_id: SanitizeConversationId,
|
|
600
|
+
) -> ConversationUpdateParams:
|
|
601
|
+
conversation_id_raw = params.get("conversation_id")
|
|
602
|
+
conversation_id = (
|
|
603
|
+
sanitize_conversation_id(conversation_id_raw.strip())
|
|
604
|
+
if isinstance(conversation_id_raw, str) and conversation_id_raw.strip()
|
|
605
|
+
else None
|
|
606
|
+
)
|
|
607
|
+
settings_value = params.get("settings")
|
|
608
|
+
settings = coerce_object_map(settings_value) if isinstance(settings_value, dict) else None
|
|
609
|
+
thread_id_value = params.get("thread_id")
|
|
610
|
+
thread_id = thread_id_value.strip() if isinstance(thread_id_value, str) and thread_id_value.strip() else None
|
|
611
|
+
return ConversationUpdateParams(
|
|
612
|
+
conversation_id=conversation_id,
|
|
613
|
+
settings=settings,
|
|
614
|
+
thread_id=thread_id,
|
|
615
|
+
)
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
def parse_conversation_delete_params(
|
|
619
|
+
params: ObjectMap,
|
|
620
|
+
*,
|
|
621
|
+
sanitize_conversation_id: SanitizeConversationId,
|
|
622
|
+
) -> ConversationDeleteParams:
|
|
623
|
+
conversation_id = _require_sanitized_conversation_id(
|
|
624
|
+
params.get("conversation_id"),
|
|
625
|
+
sanitize_conversation_id=sanitize_conversation_id,
|
|
626
|
+
detail="Missing conversation_id",
|
|
627
|
+
)
|
|
628
|
+
return ConversationDeleteParams(conversation_id=conversation_id)
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
def parse_conversation_pins_set_params(
|
|
632
|
+
params: ObjectMap,
|
|
633
|
+
*,
|
|
634
|
+
sanitize_conversation_id: SanitizeConversationId,
|
|
635
|
+
) -> ConversationPinsSetParams:
|
|
636
|
+
requested = params.get("pinned_conversations")
|
|
637
|
+
if not isinstance(requested, list):
|
|
638
|
+
raise HTTPException(status_code=400, detail="pinned_conversations must be a list")
|
|
639
|
+
pinned: list[str] = []
|
|
640
|
+
for item in requested:
|
|
641
|
+
if not isinstance(item, str) or not item.strip():
|
|
642
|
+
continue
|
|
643
|
+
convo_id = sanitize_conversation_id(item.strip())
|
|
644
|
+
if convo_id and convo_id not in pinned:
|
|
645
|
+
pinned.append(convo_id)
|
|
646
|
+
return ConversationPinsSetParams(pinned_conversations=pinned)
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
def parse_conversation_draft_set_params(
|
|
650
|
+
params: ObjectMap,
|
|
651
|
+
*,
|
|
652
|
+
sanitize_conversation_id: SanitizeConversationId,
|
|
653
|
+
) -> ConversationDraftSetParams:
|
|
654
|
+
conversation_id_raw = params.get("conversation_id")
|
|
655
|
+
conversation_id = (
|
|
656
|
+
sanitize_conversation_id(conversation_id_raw.strip())
|
|
657
|
+
if isinstance(conversation_id_raw, str) and conversation_id_raw.strip()
|
|
658
|
+
else None
|
|
659
|
+
)
|
|
660
|
+
draft_value = params.get("draft", "")
|
|
661
|
+
draft = draft_value if isinstance(draft_value, str) else ""
|
|
662
|
+
return ConversationDraftSetParams(conversation_id=conversation_id, draft=draft)
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
def parse_conversation_replay_get_chunk_params(
|
|
666
|
+
params: ObjectMap,
|
|
667
|
+
*,
|
|
668
|
+
sanitize_conversation_id: SanitizeConversationId,
|
|
669
|
+
active_conversation_id: str | None,
|
|
670
|
+
) -> ConversationReplayGetChunkParams:
|
|
671
|
+
conversation_id_raw = params.get("conversation_id")
|
|
672
|
+
conversation_id = (
|
|
673
|
+
sanitize_conversation_id(conversation_id_raw.strip())
|
|
674
|
+
if isinstance(conversation_id_raw, str) and conversation_id_raw.strip()
|
|
675
|
+
else None
|
|
676
|
+
)
|
|
677
|
+
if conversation_id is None and isinstance(active_conversation_id, str) and active_conversation_id.strip():
|
|
678
|
+
conversation_id = sanitize_conversation_id(active_conversation_id.strip())
|
|
679
|
+
|
|
680
|
+
cursor_value = params.get("cursor") or {}
|
|
681
|
+
if not isinstance(cursor_value, dict):
|
|
682
|
+
raise HTTPException(status_code=400, detail="cursor must be an object")
|
|
683
|
+
cursor_map = coerce_object_map(cursor_value)
|
|
684
|
+
offset = _parse_int(cursor_map.get("offset", 0), detail="cursor.offset must be an integer")
|
|
685
|
+
max_entries = min(max(_parse_int(params.get("max_entries", 500), detail="max_entries must be an integer"), 1), 500)
|
|
686
|
+
max_bytes = max(_parse_int(params.get("max_bytes", 524288), detail="max_bytes must be an integer"), 1)
|
|
687
|
+
|
|
688
|
+
format_name = str(params.get("format", "jsonl") or "jsonl").strip().lower()
|
|
689
|
+
if format_name != "jsonl":
|
|
690
|
+
raise HTTPException(status_code=400, detail="Only format=jsonl is supported")
|
|
691
|
+
|
|
692
|
+
return ConversationReplayGetChunkParams(
|
|
693
|
+
conversation_id=conversation_id,
|
|
694
|
+
cursor=ReplayChunkCursor(offset=offset),
|
|
695
|
+
max_entries=max_entries,
|
|
696
|
+
max_bytes=max_bytes,
|
|
697
|
+
include_internal=(params.get("include_internal") is True),
|
|
698
|
+
)
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
def normalize_conversation_send_result(
|
|
702
|
+
result: object,
|
|
703
|
+
*,
|
|
704
|
+
conversation_id: str,
|
|
705
|
+
) -> ConversationSendResult:
|
|
706
|
+
payload = (
|
|
707
|
+
coerce_object_map(result)
|
|
708
|
+
if isinstance(result, dict)
|
|
709
|
+
else {"ok": False, "error": "Invalid send result"}
|
|
710
|
+
)
|
|
711
|
+
return ConversationSendResult(
|
|
712
|
+
conversation_id=conversation_id,
|
|
713
|
+
accepted=(payload.get("ok") is True),
|
|
714
|
+
payload=payload,
|
|
715
|
+
)
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
def normalize_conversation_control_result(
|
|
719
|
+
result: object,
|
|
720
|
+
*,
|
|
721
|
+
invalid_error: str,
|
|
722
|
+
) -> ConversationControlResult:
|
|
723
|
+
payload = (
|
|
724
|
+
coerce_object_map(result)
|
|
725
|
+
if isinstance(result, dict)
|
|
726
|
+
else {"ok": False, "error": invalid_error}
|
|
727
|
+
)
|
|
728
|
+
error_value = payload.get("error")
|
|
729
|
+
return ConversationControlResult(
|
|
730
|
+
ok=(payload.get("ok") is True),
|
|
731
|
+
error=error_value if isinstance(error_value, str) else None,
|
|
732
|
+
payload=payload,
|
|
733
|
+
)
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
def normalize_replay_range_data(range_data: object) -> ReplayRangeData:
|
|
737
|
+
range_map = coerce_object_map(range_data)
|
|
738
|
+
conversation_id_value = range_map.get("conversation_id")
|
|
739
|
+
return ReplayRangeData(
|
|
740
|
+
conversation_id=conversation_id_value if isinstance(conversation_id_value, str) else None,
|
|
741
|
+
items=coerce_object_list(range_map.get("items")),
|
|
742
|
+
offset=_parse_int(range_map.get("offset"), detail="Invalid replay offset", default=0),
|
|
743
|
+
total_count=_parse_int(range_map.get("total"), detail="Invalid replay total", default=0),
|
|
744
|
+
)
|
|
745
|
+
|
|
746
|
+
|
|
747
|
+
def encode_replay_items_jsonl(
|
|
748
|
+
items: ObjectList,
|
|
749
|
+
*,
|
|
750
|
+
max_bytes: int,
|
|
751
|
+
) -> ReplayJsonlChunk:
|
|
752
|
+
jsonl_parts: list[str] = []
|
|
753
|
+
kept_item_count = 0
|
|
754
|
+
encoded_bytes = 0
|
|
755
|
+
for item in items:
|
|
756
|
+
line = json.dumps(item, ensure_ascii=False, separators=(",", ":")) + "\n"
|
|
757
|
+
line_size = len(line.encode("utf-8"))
|
|
758
|
+
if kept_item_count > 0 and encoded_bytes + line_size > max_bytes:
|
|
759
|
+
break
|
|
760
|
+
jsonl_parts.append(line)
|
|
761
|
+
kept_item_count += 1
|
|
762
|
+
encoded_bytes += line_size
|
|
763
|
+
|
|
764
|
+
if not jsonl_parts and items:
|
|
765
|
+
jsonl_parts.append(json.dumps(items[0], ensure_ascii=False, separators=(",", ":")) + "\n")
|
|
766
|
+
kept_item_count = 1
|
|
767
|
+
|
|
768
|
+
return ReplayJsonlChunk(
|
|
769
|
+
jsonl="".join(jsonl_parts),
|
|
770
|
+
item_count=kept_item_count,
|
|
771
|
+
)
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
def build_empty_replay_chunk_result(
|
|
775
|
+
*,
|
|
776
|
+
conversation_id: str | None,
|
|
777
|
+
) -> ReplayChunkResult:
|
|
778
|
+
return ReplayChunkResult(
|
|
779
|
+
conversation_id=conversation_id,
|
|
780
|
+
replay_id=_next_replay_id(),
|
|
781
|
+
frame=ReplayChunkFrame(
|
|
782
|
+
format_name="jsonl",
|
|
783
|
+
offset=0,
|
|
784
|
+
item_count=0,
|
|
785
|
+
total_count=0,
|
|
786
|
+
chunk_index=0,
|
|
787
|
+
complete=True,
|
|
788
|
+
next_cursor=None,
|
|
789
|
+
jsonl="",
|
|
790
|
+
),
|
|
791
|
+
)
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
def build_replay_chunk_result(
|
|
795
|
+
*,
|
|
796
|
+
params: ConversationReplayGetChunkParams,
|
|
797
|
+
range_data: ReplayRangeData,
|
|
798
|
+
jsonl_chunk: ReplayJsonlChunk,
|
|
799
|
+
) -> ReplayChunkResult:
|
|
800
|
+
next_offset = range_data.offset + jsonl_chunk.item_count
|
|
801
|
+
complete = next_offset >= range_data.total_count
|
|
802
|
+
return ReplayChunkResult(
|
|
803
|
+
conversation_id=range_data.conversation_id,
|
|
804
|
+
replay_id=_next_replay_id(),
|
|
805
|
+
frame=ReplayChunkFrame(
|
|
806
|
+
format_name=params.format_name,
|
|
807
|
+
offset=range_data.offset,
|
|
808
|
+
item_count=jsonl_chunk.item_count,
|
|
809
|
+
total_count=range_data.total_count,
|
|
810
|
+
chunk_index=range_data.offset // max(params.max_entries, 1),
|
|
811
|
+
complete=complete,
|
|
812
|
+
next_cursor=None if complete else ReplayChunkCursor(offset=next_offset),
|
|
813
|
+
jsonl=jsonl_chunk.jsonl,
|
|
814
|
+
),
|
|
815
|
+
)
|
|
816
|
+
|
|
817
|
+
|
|
818
|
+
def _next_replay_id() -> str:
|
|
819
|
+
return f"replay_{uuid.uuid4().hex[:12]}"
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
def _require_sanitized_conversation_id(
|
|
823
|
+
value: object,
|
|
824
|
+
*,
|
|
825
|
+
sanitize_conversation_id: SanitizeConversationId,
|
|
826
|
+
detail: str,
|
|
827
|
+
) -> str:
|
|
828
|
+
if not isinstance(value, str) or not value.strip():
|
|
829
|
+
raise HTTPException(status_code=400, detail=detail)
|
|
830
|
+
return sanitize_conversation_id(value.strip())
|
|
831
|
+
|
|
832
|
+
|
|
833
|
+
def _parse_int(
|
|
834
|
+
value: object,
|
|
835
|
+
*,
|
|
836
|
+
detail: str,
|
|
837
|
+
default: int | None = None,
|
|
838
|
+
) -> int:
|
|
839
|
+
candidate = default if value is None else value
|
|
840
|
+
if isinstance(candidate, bool):
|
|
841
|
+
raise HTTPException(status_code=400, detail=detail)
|
|
842
|
+
if isinstance(candidate, int):
|
|
843
|
+
return candidate
|
|
844
|
+
if isinstance(candidate, str):
|
|
845
|
+
try:
|
|
846
|
+
return int(candidate)
|
|
847
|
+
except ValueError as exc:
|
|
848
|
+
raise HTTPException(status_code=400, detail=detail) from exc
|
|
849
|
+
raise HTTPException(status_code=400, detail=detail)
|