xdog-coding 2.4.2__tar.gz → 2.4.3__tar.gz
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.
- xdog_coding-2.4.2/README.md → xdog_coding-2.4.3/PKG-INFO +80 -17
- xdog_coding-2.4.2/PKG-INFO → xdog_coding-2.4.3/README.md +48 -47
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/pyproject.toml +7 -4
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/__init__.py +1 -1
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/config.py +1 -1
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/agent_session.py +86 -9
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/child_agents.py +35 -9
- xdog_coding-2.4.3/src/xdog/coding/core/goal_adapter.py +366 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/sessions/controller.py +32 -8
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/sessions/inbox_models.py +1 -1
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/sessions/inbox_runtime.py +56 -14
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/sessions/inbox_store.py +37 -4
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/sessions/runtime.py +1 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/slash_commands.py +11 -2
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/modes/interactive/interactive_mode.py +1 -3
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/modes/interactive/session_events.py +3 -6
- xdog_coding-2.4.3/tests/goal_installed_consumer.py +233 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_access_scope.py +6 -5
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_acp_artifact_contract.py +5 -1
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_acp_review_regressions.py +44 -13
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_active_tool_retirement.py +13 -8
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_child_agents.py +50 -9
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_compaction_controls_ui.py +3 -2
- xdog_coding-2.4.3/tests/test_goal_adapter.py +302 -0
- xdog_coding-2.4.3/tests/test_goal_extension_views.py +212 -0
- xdog_coding-2.4.3/tests/test_goal_lifecycle.py +268 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_inbox_auto_consume.py +5 -2
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_runtime_prompt.py +3 -2
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_session_mode_routing.py +2 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_slash_skills.py +2 -0
- xdog_coding-2.4.3/tests/test_unified_inbox_review_fixes.py +397 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/.gitignore +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/LICENSE +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/LICENSE-EXCEPTION.md +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/acp/__init__.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/acp/backend.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/acp/bridge.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/acp/cli.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/acp/client.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/acp/extensions.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/acp/ingress.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/acp/ingress_backend.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/acp/ingress_main.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/acp/server.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/cli/__init__.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/cli/args.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/cli/config_selector.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/cli/enqueue.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/cli/file_processor.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/cli/initial_message.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/cli/list_models.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/cli/session_picker.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/__init__.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/bash_executor.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/canonical_source.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/compaction/__init__.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/compaction/compaction.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/compaction/utils.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/context_messages.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/defaults.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/event_bus.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/exec_utils.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/extensions/__init__.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/extensions/loader.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/extensions/runner.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/extensions/types.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/inbox_commands.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/keybindings.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/messages.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/model_catalog.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/navigation.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/permissions.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/prompt_templates.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/remote_session.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/resource_loader.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/sdk.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/session_manager.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/session_staging.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/sessions/__init__.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/sessions/availability.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/sessions/batches.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/sessions/inbox_views.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/sessions/intake.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/sessions/models.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/sessions/operations.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/sessions/ownership.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/sessions/router.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/sessions/store.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/sessions/turns.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/settings_manager.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/system_prompt.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/timings.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/tools/__init__.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/core/transcript_source.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/main.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/modes/__init__.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/modes/interactive/__init__.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/modes/interactive/components/__init__.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/modes/interactive/components/assistant_message.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/modes/interactive/components/chat_log.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/modes/interactive/components/custom_editor.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/modes/interactive/components/editor_layout.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/modes/interactive/components/footer.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/modes/interactive/components/permission_prompt.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/modes/interactive/components/tool_execution.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/modes/interactive/components/user_message.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/modes/interactive/provider_auth.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/modes/interactive/run_status.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/modes/interactive/session_presenter.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/modes/interactive/theme.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/modes/interactive/tool_renderers.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/modes/print_mode.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/py.typed +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/utils/__init__.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/utils/frontmatter.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/utils/git.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/utils/mime.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/utils/shell.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/src/xdog/coding/utils/sleep.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/acp_owner_agent.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/batch_helpers.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/conftest.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/extension_session_helpers.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/fixtures/benchmark_tui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/fixtures/terminal_client.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/fixtures/terminal_review.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/session_owner_process.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_acp_backend.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_acp_batch_intake.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_acp_bridge.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_acp_cli.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_acp_enqueue_cli.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_acp_ingress.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_acp_ingress_lifecycle.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_acp_offline_inbox.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_acp_optional_imports.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_active_tool_persistence.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_after_run_compaction.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_after_run_name.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_agent_session.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_batch_config.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_batch_display.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_batch_mode_errors.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_batch_turns.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_child_active_tools.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_child_image_admission.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_child_image_submission.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_child_queue_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_cli_args.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_cli_config_selector.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_cli_file_processor.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_coding_config.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_command_artifact_export_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_compact_layout.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_compaction_recovery.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_context_message_compaction.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_event_bus.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_extension_command_results_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_extension_core_readonly.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_extension_editor_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_extension_input_draft_isolation.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_extension_input_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_extension_navigation_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_extension_provider_startup.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_extension_readonly_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_extension_session_context_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_footer_context.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_image_composer.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_image_lifecycle_admission.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_inbox_activation_navigation.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_inbox_commands.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_inbox_controller.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_inbox_crash.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_inbox_display.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_inbox_store.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_inbox_v2.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_interactive_commands.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_interactive_keymap.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_interactive_mode.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_live_extensions.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_mcp_auth_projection.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_mcp_browser.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_mcp_catalog_watch_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_mcp_combined_watch_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_mcp_manual_picker_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_mcp_modern_browser_cancel.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_mcp_modern_browser_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_mcp_retired_gateway.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_mcp_roots_review_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_mcp_sampling_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_mcp_task_terminal.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_messages.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_native_session_queue.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_no_coding_rpc.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_no_legacy_event_host.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_oauth_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_owned_native_model.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_permissions.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_prompt_templates.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_provider_oauth_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_queue_controls.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_readonly_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_removed_child_return_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_rendered_image_context.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_renderer_contracts_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_repository_review.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_resource_loader.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_retained_history.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_run_status.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_saved_child_drafts.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_saved_source_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_sdk_compaction_compat.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_sdk_runtime_compatibility.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_sdk_session_state.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_session_batches.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_session_control_fences.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_session_controller.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_session_history_display.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_session_input_store.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_session_manager.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_session_message_display.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_session_name_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_session_navigation.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_session_ownership.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_session_picker.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_session_router.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_session_smoke.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_session_staging.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_session_turns.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_settings_manager.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_skill_controls_ui.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_slash_commands.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_system_prompt.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_terminal_acceptance.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_timings.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_tools_browser.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_transcript_interaction.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_transcript_output.py +0 -0
- {xdog_coding-2.4.2 → xdog_coding-2.4.3}/tests/test_tui_usability.py +0 -0
|
@@ -1,3 +1,35 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: xdog-coding
|
|
3
|
+
Version: 2.4.3
|
|
4
|
+
Summary: Interactive coding agent CLI
|
|
5
|
+
Project-URL: Homepage, https://xdog.942295.xyz
|
|
6
|
+
Project-URL: Repository, https://github.com/litterzhang/xdog
|
|
7
|
+
Project-URL: Documentation, https://xdog.942295.xyz
|
|
8
|
+
Project-URL: Issues, https://github.com/litterzhang/xdog/issues
|
|
9
|
+
Author: HugeMan
|
|
10
|
+
License-Expression: AGPL-3.0-or-later
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
License-File: LICENSE-EXCEPTION.md
|
|
13
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Python: >=3.12
|
|
22
|
+
Requires-Dist: agent-client-protocol<0.13,>=0.12.1; python_version < '3.15'
|
|
23
|
+
Requires-Dist: click>=8.1.0
|
|
24
|
+
Requires-Dist: pydantic>=2.0
|
|
25
|
+
Requires-Dist: pyyaml>=6.0
|
|
26
|
+
Requires-Dist: xdog-agent>=2.4.3
|
|
27
|
+
Requires-Dist: xdog-ai[openai]>=2.4.3
|
|
28
|
+
Requires-Dist: xdog-tui>=2.4.3
|
|
29
|
+
Provides-Extra: skills
|
|
30
|
+
Requires-Dist: xdog-skills>=2.4.3; extra == 'skills'
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
1
33
|
# xdog-coding
|
|
2
34
|
|
|
3
35
|
> Platform scope: **Linux only**. Non-Linux adapters and native-platform support
|
|
@@ -548,7 +580,8 @@ continuation silently reconnects, replays POSTs or expands configured disclosure
|
|
|
548
580
|
|
|
549
581
|
### Task planning and host read-only scope
|
|
550
582
|
|
|
551
|
-
The builtin **`xdog-planning`** skill
|
|
583
|
+
The builtin **`xdog-planning`** skill, supplied by `xdog-skills` (install the
|
|
584
|
+
`skills` extra), uses ordinary conversation or task documents
|
|
552
585
|
for objectives, dependencies, acceptance criteria and evidence-backed progress.
|
|
553
586
|
It does not create a separate plan database, inspector, execution mode or model
|
|
554
587
|
loop. The former `/plan`, `PlanPanel` and `update_plan` UI/tool APIs are removed.
|
|
@@ -745,7 +778,7 @@ none of these interfaces grants tool permission or full Pi API compatibility.
|
|
|
745
778
|
|
|
746
779
|
### Supervised child agents
|
|
747
780
|
|
|
748
|
-
`/agents start TASK` starts
|
|
781
|
+
`/agents start TASK` starts host-managed read-only child work. `/agents start --inherit
|
|
749
782
|
TASK` inherits the current host policy; it does not copy approval grants or bypass
|
|
750
783
|
read-only. Inspect with `/agents list` or `/agents inspect ID`; use `steer ID TEXT`,
|
|
751
784
|
`follow-up ID TEXT`, `cancel ID`, `wait ID` and `close ID` under `/agents`.
|
|
@@ -754,10 +787,34 @@ recursively delegate through their parent's supervision tools.
|
|
|
754
787
|
|
|
755
788
|
Children share the workspace, so coordinate conflicting writes. Context is copied
|
|
756
789
|
at admission through a complete tool/result checkpoint. Model/options/tool execution
|
|
757
|
-
mode are inherited.
|
|
758
|
-
|
|
759
|
-
threshold
|
|
760
|
-
|
|
790
|
+
mode are inherited. There is no fixed concurrent-child or retained-record count
|
|
791
|
+
limit, elapsed-time deadline, model-call cap or cumulative reported-token stop
|
|
792
|
+
threshold. The main Agent/host manages lifecycle with cancel/wait/close. Usage
|
|
793
|
+
counters remain reported usage, not exact billable accounting; actual model
|
|
794
|
+
output/context limits, permissions and message/input/image/per-file capacities
|
|
795
|
+
still apply. Complete history uses atomic segmented persistence instead of a
|
|
796
|
+
cumulative 512 KiB / 2,000-message execution cutoff; tool/result pairs are not
|
|
797
|
+
silently truncated.
|
|
798
|
+
|
|
799
|
+
Coding and Claw child factories explicitly enable the Agent's existing built-in
|
|
800
|
+
compaction policy through `AgentConfig(compaction=selected.compaction(child_stream))`
|
|
801
|
+
and provide `archive_compaction=store.archive_compaction` to the supervisor.
|
|
802
|
+
This does **not** change the generic Agent default: automatic compaction is off
|
|
803
|
+
unless explicitly configured. The selected helper uses the executing adapter's
|
|
804
|
+
real context/prompt/output capacity; unknown metadata, context capacity or output
|
|
805
|
+
reserve returns `None` (auto-compaction remains off), not a guessed fallback.
|
|
806
|
+
A host requiring automatic compaction must reject that case or explicitly supply
|
|
807
|
+
trusted capacity/reserve through native `CompactionConfig`.
|
|
808
|
+
|
|
809
|
+
With the policy enabled, one long tool turn can compact repeatedly at safe paired
|
|
810
|
+
boundaries. The supervisor waits for a durable full pre-compaction snapshot before
|
|
811
|
+
the native summary request starts. Archive, summary or stream-cleanup failure does
|
|
812
|
+
not commit a history cut, and cancellation settles owned writes/cleanup. The native
|
|
813
|
+
summary's per-request timeout/capacity checks remain; there is no replacement child
|
|
814
|
+
lifetime cap. Inspect shows the current retained context, possibly with summaries;
|
|
815
|
+
`children.store.compaction_archives(child_id)` reads full earlier snapshots without
|
|
816
|
+
replay. These child archives are separate from the parent session's `/tree`
|
|
817
|
+
compaction checkpoints.
|
|
761
818
|
|
|
762
819
|
Each child has independent Coding approvals and extension workers/state. Parent
|
|
763
820
|
validation/context hooks and current read-only/permission gates remain authoritative;
|
|
@@ -800,10 +857,10 @@ still uses silent no-UI answers to avoid borrowing its separate dialog reservati
|
|
|
800
857
|
Complex extension forms are removed; basic child dialogs retain these ownership and cancellation checks.
|
|
801
858
|
|
|
802
859
|
|
|
803
|
-
### Child specialization and limits
|
|
860
|
+
### Child specialization and protocol limits
|
|
804
861
|
|
|
805
862
|
`/agents start --label Reviewer --instructions "Inspect only" --tools filesystem,current_time
|
|
806
|
-
--fresh --
|
|
863
|
+
--fresh -- TASK` specializes a child without
|
|
807
864
|
changing parent permissions. Options precede the task; `--` preserves a task that
|
|
808
865
|
starts with flags. Plain tasks preserve quotes/newlines. `--tools none` gives the
|
|
809
866
|
child no executable tools; otherwise selected names must exist in its inherited tool
|
|
@@ -812,11 +869,15 @@ fail visibly. Instructions append to, rather than replace, parent restrictions.
|
|
|
812
869
|
|
|
813
870
|
In `/agents` press `n`, then Ctrl+G for settings JSON. Supported keys are `label`,
|
|
814
871
|
`instructions`, `tools` (array or null for inherited tools), `inherit_context`,
|
|
815
|
-
`
|
|
872
|
+
`model`, `thinking` and `preset`. Enter applies the settings draft only;
|
|
816
873
|
start review requires every page to be painted before confirmation. Resize invalidates
|
|
817
874
|
that review. This confirmation does NOT approve tool use. Effective settings persist
|
|
818
|
-
with child results and appear in complete child source.
|
|
819
|
-
|
|
875
|
+
with child results and appear in complete child source. Runtime budget options
|
|
876
|
+
`--timeout`, `--calls`, `--tokens` and config/preset keys `timeout`, `max_model_calls`,
|
|
877
|
+
`max_tokens` are removed and rejected for new starts. Historical child records with
|
|
878
|
+
these budget fields remain readable; the fields are inert and never reapply a
|
|
879
|
+
budget or restart work. This removal does not remove the actual model's per-request
|
|
880
|
+
output token ceiling.
|
|
820
881
|
`--fresh` omits canonical history/child entry inheritance, not mandatory parent
|
|
821
882
|
validation/context or the shared workspace. Model/reasoning inherit by default; explicit overrides now use the actual adapter.
|
|
822
883
|
Named presets now use explicit user configuration. Claw specialized
|
|
@@ -840,9 +901,12 @@ host native-tool overrides. Switching to a nonreasoning model disables inherited
|
|
|
840
901
|
reasoning; unsupported positive choices fail visibly. Model switches omit inherited/
|
|
841
902
|
transformed provider continuity and old reasoning from the CHILD copy, leaving parent
|
|
842
903
|
provenance/history intact. Transformed images are validated; oversized switched-model
|
|
843
|
-
contexts
|
|
844
|
-
|
|
845
|
-
|
|
904
|
+
contexts use the same built-in text-token estimate as native compaction, rather
|
|
905
|
+
than comparing text bytes to token capacity. This is not exact tokenizer accounting.
|
|
906
|
+
Host-enabled compaction runs before forwarding the next model request; context that
|
|
907
|
+
cannot be safely compacted or fit still fails explicitly with original history
|
|
908
|
+
retained. Image/capability and actual output limits remain enforced. Parent
|
|
909
|
+
model/options/settings/grants never change. Named presets use explicit user configuration.
|
|
846
910
|
|
|
847
911
|
|
|
848
912
|
### Named child presets
|
|
@@ -859,15 +923,14 @@ using this descriptor shape:
|
|
|
859
923
|
"instructions": "Review requested code; return findings with file locations.",
|
|
860
924
|
"tools": ["filesystem", "current_time"],
|
|
861
925
|
"inherit_context": false,
|
|
862
|
-
"
|
|
863
|
-
"max_tokens": 8000
|
|
926
|
+
"label": "Reviewer"
|
|
864
927
|
}
|
|
865
928
|
}
|
|
866
929
|
}
|
|
867
930
|
}
|
|
868
931
|
```
|
|
869
932
|
|
|
870
|
-
Browse `/agents presets`, or use `/agents start --preset reviewer --
|
|
933
|
+
Browse `/agents presets`, or use `/agents start --preset reviewer --label Audit --
|
|
871
934
|
TASK`. Explicit flags override template fields. Ctrl+P selects a template in a new
|
|
872
935
|
child form, Ctrl+G adjusts the draft, and full expanded settings/task review still
|
|
873
936
|
precedes execution. Selection itself makes no model request. Templates cannot encode
|
|
@@ -1,33 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.5
|
|
2
|
-
Name: xdog-coding
|
|
3
|
-
Version: 2.4.2
|
|
4
|
-
Summary: Interactive coding agent CLI
|
|
5
|
-
Project-URL: Homepage, https://xdog.942295.xyz
|
|
6
|
-
Project-URL: Repository, https://github.com/litterzhang/xdog
|
|
7
|
-
Project-URL: Documentation, https://xdog.942295.xyz
|
|
8
|
-
Project-URL: Issues, https://github.com/litterzhang/xdog/issues
|
|
9
|
-
Author: HugeMan
|
|
10
|
-
License-Expression: AGPL-3.0-or-later
|
|
11
|
-
License-File: LICENSE
|
|
12
|
-
License-File: LICENSE-EXCEPTION.md
|
|
13
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
-
Classifier: Intended Audience :: Developers
|
|
15
|
-
Classifier: Operating System :: POSIX :: Linux
|
|
16
|
-
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
-
Classifier: Topic :: Software Development :: Libraries
|
|
20
|
-
Classifier: Typing :: Typed
|
|
21
|
-
Requires-Python: >=3.12
|
|
22
|
-
Requires-Dist: agent-client-protocol<0.13,>=0.12.1; python_version < '3.15'
|
|
23
|
-
Requires-Dist: click>=8.1.0
|
|
24
|
-
Requires-Dist: pydantic>=2.0
|
|
25
|
-
Requires-Dist: pyyaml>=6.0
|
|
26
|
-
Requires-Dist: xdog-agent>=2.4.2
|
|
27
|
-
Requires-Dist: xdog-ai[openai]>=2.4.2
|
|
28
|
-
Requires-Dist: xdog-tui>=2.4.2
|
|
29
|
-
Description-Content-Type: text/markdown
|
|
30
|
-
|
|
31
1
|
# xdog-coding
|
|
32
2
|
|
|
33
3
|
> Platform scope: **Linux only**. Non-Linux adapters and native-platform support
|
|
@@ -578,7 +548,8 @@ continuation silently reconnects, replays POSTs or expands configured disclosure
|
|
|
578
548
|
|
|
579
549
|
### Task planning and host read-only scope
|
|
580
550
|
|
|
581
|
-
The builtin **`xdog-planning`** skill
|
|
551
|
+
The builtin **`xdog-planning`** skill, supplied by `xdog-skills` (install the
|
|
552
|
+
`skills` extra), uses ordinary conversation or task documents
|
|
582
553
|
for objectives, dependencies, acceptance criteria and evidence-backed progress.
|
|
583
554
|
It does not create a separate plan database, inspector, execution mode or model
|
|
584
555
|
loop. The former `/plan`, `PlanPanel` and `update_plan` UI/tool APIs are removed.
|
|
@@ -775,7 +746,7 @@ none of these interfaces grants tool permission or full Pi API compatibility.
|
|
|
775
746
|
|
|
776
747
|
### Supervised child agents
|
|
777
748
|
|
|
778
|
-
`/agents start TASK` starts
|
|
749
|
+
`/agents start TASK` starts host-managed read-only child work. `/agents start --inherit
|
|
779
750
|
TASK` inherits the current host policy; it does not copy approval grants or bypass
|
|
780
751
|
read-only. Inspect with `/agents list` or `/agents inspect ID`; use `steer ID TEXT`,
|
|
781
752
|
`follow-up ID TEXT`, `cancel ID`, `wait ID` and `close ID` under `/agents`.
|
|
@@ -784,10 +755,34 @@ recursively delegate through their parent's supervision tools.
|
|
|
784
755
|
|
|
785
756
|
Children share the workspace, so coordinate conflicting writes. Context is copied
|
|
786
757
|
at admission through a complete tool/result checkpoint. Model/options/tool execution
|
|
787
|
-
mode are inherited.
|
|
788
|
-
|
|
789
|
-
threshold
|
|
790
|
-
|
|
758
|
+
mode are inherited. There is no fixed concurrent-child or retained-record count
|
|
759
|
+
limit, elapsed-time deadline, model-call cap or cumulative reported-token stop
|
|
760
|
+
threshold. The main Agent/host manages lifecycle with cancel/wait/close. Usage
|
|
761
|
+
counters remain reported usage, not exact billable accounting; actual model
|
|
762
|
+
output/context limits, permissions and message/input/image/per-file capacities
|
|
763
|
+
still apply. Complete history uses atomic segmented persistence instead of a
|
|
764
|
+
cumulative 512 KiB / 2,000-message execution cutoff; tool/result pairs are not
|
|
765
|
+
silently truncated.
|
|
766
|
+
|
|
767
|
+
Coding and Claw child factories explicitly enable the Agent's existing built-in
|
|
768
|
+
compaction policy through `AgentConfig(compaction=selected.compaction(child_stream))`
|
|
769
|
+
and provide `archive_compaction=store.archive_compaction` to the supervisor.
|
|
770
|
+
This does **not** change the generic Agent default: automatic compaction is off
|
|
771
|
+
unless explicitly configured. The selected helper uses the executing adapter's
|
|
772
|
+
real context/prompt/output capacity; unknown metadata, context capacity or output
|
|
773
|
+
reserve returns `None` (auto-compaction remains off), not a guessed fallback.
|
|
774
|
+
A host requiring automatic compaction must reject that case or explicitly supply
|
|
775
|
+
trusted capacity/reserve through native `CompactionConfig`.
|
|
776
|
+
|
|
777
|
+
With the policy enabled, one long tool turn can compact repeatedly at safe paired
|
|
778
|
+
boundaries. The supervisor waits for a durable full pre-compaction snapshot before
|
|
779
|
+
the native summary request starts. Archive, summary or stream-cleanup failure does
|
|
780
|
+
not commit a history cut, and cancellation settles owned writes/cleanup. The native
|
|
781
|
+
summary's per-request timeout/capacity checks remain; there is no replacement child
|
|
782
|
+
lifetime cap. Inspect shows the current retained context, possibly with summaries;
|
|
783
|
+
`children.store.compaction_archives(child_id)` reads full earlier snapshots without
|
|
784
|
+
replay. These child archives are separate from the parent session's `/tree`
|
|
785
|
+
compaction checkpoints.
|
|
791
786
|
|
|
792
787
|
Each child has independent Coding approvals and extension workers/state. Parent
|
|
793
788
|
validation/context hooks and current read-only/permission gates remain authoritative;
|
|
@@ -830,10 +825,10 @@ still uses silent no-UI answers to avoid borrowing its separate dialog reservati
|
|
|
830
825
|
Complex extension forms are removed; basic child dialogs retain these ownership and cancellation checks.
|
|
831
826
|
|
|
832
827
|
|
|
833
|
-
### Child specialization and limits
|
|
828
|
+
### Child specialization and protocol limits
|
|
834
829
|
|
|
835
830
|
`/agents start --label Reviewer --instructions "Inspect only" --tools filesystem,current_time
|
|
836
|
-
--fresh --
|
|
831
|
+
--fresh -- TASK` specializes a child without
|
|
837
832
|
changing parent permissions. Options precede the task; `--` preserves a task that
|
|
838
833
|
starts with flags. Plain tasks preserve quotes/newlines. `--tools none` gives the
|
|
839
834
|
child no executable tools; otherwise selected names must exist in its inherited tool
|
|
@@ -842,11 +837,15 @@ fail visibly. Instructions append to, rather than replace, parent restrictions.
|
|
|
842
837
|
|
|
843
838
|
In `/agents` press `n`, then Ctrl+G for settings JSON. Supported keys are `label`,
|
|
844
839
|
`instructions`, `tools` (array or null for inherited tools), `inherit_context`,
|
|
845
|
-
`
|
|
840
|
+
`model`, `thinking` and `preset`. Enter applies the settings draft only;
|
|
846
841
|
start review requires every page to be painted before confirmation. Resize invalidates
|
|
847
842
|
that review. This confirmation does NOT approve tool use. Effective settings persist
|
|
848
|
-
with child results and appear in complete child source.
|
|
849
|
-
|
|
843
|
+
with child results and appear in complete child source. Runtime budget options
|
|
844
|
+
`--timeout`, `--calls`, `--tokens` and config/preset keys `timeout`, `max_model_calls`,
|
|
845
|
+
`max_tokens` are removed and rejected for new starts. Historical child records with
|
|
846
|
+
these budget fields remain readable; the fields are inert and never reapply a
|
|
847
|
+
budget or restart work. This removal does not remove the actual model's per-request
|
|
848
|
+
output token ceiling.
|
|
850
849
|
`--fresh` omits canonical history/child entry inheritance, not mandatory parent
|
|
851
850
|
validation/context or the shared workspace. Model/reasoning inherit by default; explicit overrides now use the actual adapter.
|
|
852
851
|
Named presets now use explicit user configuration. Claw specialized
|
|
@@ -870,9 +869,12 @@ host native-tool overrides. Switching to a nonreasoning model disables inherited
|
|
|
870
869
|
reasoning; unsupported positive choices fail visibly. Model switches omit inherited/
|
|
871
870
|
transformed provider continuity and old reasoning from the CHILD copy, leaving parent
|
|
872
871
|
provenance/history intact. Transformed images are validated; oversized switched-model
|
|
873
|
-
contexts
|
|
874
|
-
|
|
875
|
-
|
|
872
|
+
contexts use the same built-in text-token estimate as native compaction, rather
|
|
873
|
+
than comparing text bytes to token capacity. This is not exact tokenizer accounting.
|
|
874
|
+
Host-enabled compaction runs before forwarding the next model request; context that
|
|
875
|
+
cannot be safely compacted or fit still fails explicitly with original history
|
|
876
|
+
retained. Image/capability and actual output limits remain enforced. Parent
|
|
877
|
+
model/options/settings/grants never change. Named presets use explicit user configuration.
|
|
876
878
|
|
|
877
879
|
|
|
878
880
|
### Named child presets
|
|
@@ -889,15 +891,14 @@ using this descriptor shape:
|
|
|
889
891
|
"instructions": "Review requested code; return findings with file locations.",
|
|
890
892
|
"tools": ["filesystem", "current_time"],
|
|
891
893
|
"inherit_context": false,
|
|
892
|
-
"
|
|
893
|
-
"max_tokens": 8000
|
|
894
|
+
"label": "Reviewer"
|
|
894
895
|
}
|
|
895
896
|
}
|
|
896
897
|
}
|
|
897
898
|
}
|
|
898
899
|
```
|
|
899
900
|
|
|
900
|
-
Browse `/agents presets`, or use `/agents start --preset reviewer --
|
|
901
|
+
Browse `/agents presets`, or use `/agents start --preset reviewer --label Audit --
|
|
901
902
|
TASK`. Explicit flags override template fields. Ctrl+P selects a template in a new
|
|
902
903
|
child form, Ctrl+G adjusts the draft, and full expanded settings/task review still
|
|
903
904
|
precedes execution. Selection itself makes no model request. Templates cannot encode
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "xdog-coding"
|
|
7
|
-
version = "2.4.
|
|
7
|
+
version = "2.4.3"
|
|
8
8
|
description = "Interactive coding agent CLI"
|
|
9
9
|
requires-python = ">=3.12"
|
|
10
10
|
classifiers = [
|
|
@@ -22,15 +22,18 @@ readme = "README.md"
|
|
|
22
22
|
license = "AGPL-3.0-or-later"
|
|
23
23
|
license-files = ["LICENSE", "LICENSE-EXCEPTION.md"]
|
|
24
24
|
dependencies = [
|
|
25
|
-
"xdog-ai[openai]>=2.4.
|
|
26
|
-
"xdog-agent>=2.4.
|
|
25
|
+
"xdog-ai[openai]>=2.4.3",
|
|
26
|
+
"xdog-agent>=2.4.3",
|
|
27
27
|
"agent-client-protocol>=0.12.1,<0.13; python_version < '3.15'",
|
|
28
|
-
"xdog-tui>=2.4.
|
|
28
|
+
"xdog-tui>=2.4.3",
|
|
29
29
|
"pyyaml>=6.0",
|
|
30
30
|
"click>=8.1.0",
|
|
31
31
|
"pydantic>=2.0",
|
|
32
32
|
]
|
|
33
33
|
|
|
34
|
+
[project.optional-dependencies]
|
|
35
|
+
skills = ["xdog-skills>=2.4.3"]
|
|
36
|
+
|
|
34
37
|
[project.urls]
|
|
35
38
|
Homepage = "https://xdog.942295.xyz"
|
|
36
39
|
Repository = "https://github.com/litterzhang/xdog"
|
|
@@ -10,6 +10,7 @@ import uuid
|
|
|
10
10
|
from collections.abc import Awaitable, Callable
|
|
11
11
|
from dataclasses import dataclass, field, replace
|
|
12
12
|
from functools import wraps
|
|
13
|
+
from importlib.util import find_spec
|
|
13
14
|
from pathlib import Path
|
|
14
15
|
from typing import TYPE_CHECKING, Any, Concatenate, ParamSpec, TypeVar
|
|
15
16
|
|
|
@@ -55,6 +56,7 @@ from xdog.coding.core.system_prompt import build_system_prompt
|
|
|
55
56
|
if TYPE_CHECKING:
|
|
56
57
|
from concurrent.futures import Future
|
|
57
58
|
|
|
59
|
+
from xdog.coding.core.goal_adapter import CodingGoalHost
|
|
58
60
|
from xdog.coding.core.session_staging import StagedExtensions
|
|
59
61
|
from xdog.coding.core.sessions.batches import TurnInput
|
|
60
62
|
from xdog.coding.core.sessions.controller import SessionController
|
|
@@ -80,11 +82,14 @@ def _idle_change(method: Callable[Concatenate["AgentSession", P], R]) -> Callabl
|
|
|
80
82
|
async def owned() -> R:
|
|
81
83
|
return wrapped(self, *args, **kwargs)
|
|
82
84
|
try:
|
|
83
|
-
|
|
85
|
+
asyncio.get_running_loop()
|
|
84
86
|
except RuntimeError:
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
pass
|
|
88
|
+
else:
|
|
89
|
+
# A synchronous wait would block this caller's loop, which may
|
|
90
|
+
# own the admitted producer's completion/cancellation signal.
|
|
91
|
+
raise RuntimeError("Session controls must be submitted to the session owner; "
|
|
92
|
+
"use an owner operation or asyncio.to_thread from async callers")
|
|
88
93
|
borrowed = runtime is None
|
|
89
94
|
if borrowed:
|
|
90
95
|
with self._sdk_lock:
|
|
@@ -144,6 +149,7 @@ def _idle_change(method: Callable[Concatenate["AgentSession", P], R]) -> Callabl
|
|
|
144
149
|
async def rebind_sdk() -> None:
|
|
145
150
|
from xdog.coding.core.sessions.store import InputStore
|
|
146
151
|
await asyncio.wrap_future(discarded)
|
|
152
|
+
await self._settle_retired_goals()
|
|
147
153
|
previous = controller.inbox
|
|
148
154
|
if previous is not None:
|
|
149
155
|
await previous.retire()
|
|
@@ -194,6 +200,11 @@ class AgentSession:
|
|
|
194
200
|
_sdk_closing: Future[None] | None = field(default=None, init=False, repr=False)
|
|
195
201
|
_sdk_retiring_leases: set[SessionLease] = field(default_factory=set, init=False, repr=False)
|
|
196
202
|
_sdk_disposing: bool = field(default=False, init=False, repr=False)
|
|
203
|
+
_retired_goal_hosts: list[CodingGoalHost] = field(default_factory=list, init=False, repr=False)
|
|
204
|
+
_goal_start: asyncio.Task[None] | None = field(default=None, init=False, repr=False)
|
|
205
|
+
_user_prompt_messages: dict[int, UserMessage] = field(default_factory=dict, init=False, repr=False)
|
|
206
|
+
_authorized_messages: dict[int, UserMessage] = field(default_factory=dict, init=False, repr=False)
|
|
207
|
+
_user_operation_authorized: bool = field(default=False, init=False, repr=False)
|
|
197
208
|
_sdk_lock: threading.Lock = field(default_factory=threading.Lock, init=False, repr=False)
|
|
198
209
|
_lease: SessionLease | None = field(default=None, init=False, repr=False)
|
|
199
210
|
_pending_lease: SessionLease | None = field(default=None, init=False, repr=False)
|
|
@@ -259,13 +270,17 @@ class AgentSession:
|
|
|
259
270
|
|
|
260
271
|
async def _transform_user_input(self, message: UserMessage, source: str,
|
|
261
272
|
cancel: asyncio.Event | None = None) -> UserMessage | HandledInput:
|
|
273
|
+
authorized = self._user_prompt_messages.get(id(message)) is message
|
|
262
274
|
try:
|
|
263
275
|
if self._base_input_transform is not None:
|
|
264
276
|
value = await self._base_input_transform(message, source, cancel)
|
|
265
277
|
if isinstance(value, HandledInput):
|
|
266
278
|
return value
|
|
267
279
|
message = value
|
|
268
|
-
|
|
280
|
+
value = await self.extensions.input(message, source, channel="coding")
|
|
281
|
+
if authorized and isinstance(value, UserMessage):
|
|
282
|
+
self._authorized_messages[id(value)] = value
|
|
283
|
+
return value
|
|
269
284
|
finally:
|
|
270
285
|
await self._sync_extension_tools()
|
|
271
286
|
|
|
@@ -321,7 +336,8 @@ class AgentSession:
|
|
|
321
336
|
|
|
322
337
|
def _load_children(self) -> None:
|
|
323
338
|
self.children = CodingChildren(self)
|
|
324
|
-
base = tuple(tool for tool in self.agent.state.tools if tool.name not in {"agent_spawn", "agent_control"}
|
|
339
|
+
base = tuple(tool for tool in self.agent.state.tools if tool.name not in {"agent_spawn", "agent_control"}
|
|
340
|
+
and not any(tool is host.tool for host in self._retired_goal_hosts))
|
|
325
341
|
self.agent.set_tools((*base, *self.children.supervisor.tools()))
|
|
326
342
|
|
|
327
343
|
def _children_idle(self) -> None:
|
|
@@ -374,6 +390,42 @@ class AgentSession:
|
|
|
374
390
|
finally:
|
|
375
391
|
await self._sync_extension_tools()
|
|
376
392
|
|
|
393
|
+
async def initialize_goals(self) -> None:
|
|
394
|
+
"""Attach an installed capability on the existing session execution owner."""
|
|
395
|
+
if find_spec("xdog.skills") is None:
|
|
396
|
+
return
|
|
397
|
+
await self._settle_retired_goals()
|
|
398
|
+
if self.children.goal_host is not None:
|
|
399
|
+
return
|
|
400
|
+
if self._goal_start is None:
|
|
401
|
+
async def start() -> None:
|
|
402
|
+
from xdog.coding.core.goal_adapter import CodingGoalHost
|
|
403
|
+
from xdog.skills.goal.host import OperationContext
|
|
404
|
+
host = await CodingGoalHost.open(
|
|
405
|
+
self, context=lambda: OperationContext(self._user_operation_authorized))
|
|
406
|
+
await host.flush() # Durable obligations only; no model/Goal-state polling.
|
|
407
|
+
self._goal_start = asyncio.create_task(start())
|
|
408
|
+
from xdog.agent.async_work import wait_owned
|
|
409
|
+
try:
|
|
410
|
+
await wait_owned(self._goal_start)
|
|
411
|
+
finally:
|
|
412
|
+
if self._goal_start.done():
|
|
413
|
+
self._goal_start = None
|
|
414
|
+
|
|
415
|
+
def _retire_goal_host(self, host: CodingGoalHost) -> None:
|
|
416
|
+
if host not in self._retired_goal_hosts:
|
|
417
|
+
self._retired_goal_hosts.append(host)
|
|
418
|
+
# The controller's existing settling/close path joins these exact hosts;
|
|
419
|
+
# scheduling is not permission to release their callback loop/lease.
|
|
420
|
+
if not host.loop.is_closed():
|
|
421
|
+
host.loop.call_soon_threadsafe(lambda: asyncio.create_task(host.aclose()))
|
|
422
|
+
|
|
423
|
+
async def _settle_retired_goals(self) -> None:
|
|
424
|
+
from xdog.agent.supervision import settle_on
|
|
425
|
+
for host in tuple(self._retired_goal_hosts):
|
|
426
|
+
await settle_on(host.loop, host.aclose())
|
|
427
|
+
self._retired_goal_hosts.remove(host)
|
|
428
|
+
|
|
377
429
|
async def initialize_extensions(self) -> None:
|
|
378
430
|
try:
|
|
379
431
|
if self.extensions.enabled:
|
|
@@ -639,6 +691,8 @@ class AgentSession:
|
|
|
639
691
|
async def _close_sdk_owner(self, controller: SessionController) -> None:
|
|
640
692
|
if controller.inbox is not None:
|
|
641
693
|
await controller.inbox.retire()
|
|
694
|
+
if self._sdk_disposing or self.children.goal_host is not None or self._retired_goal_hosts:
|
|
695
|
+
await self._aclose_resources()
|
|
642
696
|
self._release_sdk_leases()
|
|
643
697
|
|
|
644
698
|
async def _acquire_owner(self) -> tuple[SessionController, bool]:
|
|
@@ -664,7 +718,10 @@ class AgentSession:
|
|
|
664
718
|
from xdog.coding.core.sessions.intake import attach_inbox
|
|
665
719
|
attach_inbox(controller)
|
|
666
720
|
controller._close_hook = lambda: self._close_sdk_owner(controller)
|
|
667
|
-
|
|
721
|
+
# Optional callback capabilities outlive an individual
|
|
722
|
+
# SDK await/asyncio.run; retain the one controller's own
|
|
723
|
+
# supported loop, never a second controller or daemon.
|
|
724
|
+
controller.start(own_thread=find_spec("xdog.skills") is not None)
|
|
668
725
|
self._sdk_controller = controller
|
|
669
726
|
self._sdk_users += 1
|
|
670
727
|
return self._sdk_controller, True
|
|
@@ -673,7 +730,8 @@ class AgentSession:
|
|
|
673
730
|
def _release_sdk_owner(self, controller: SessionController) -> Future[None] | None:
|
|
674
731
|
with self._sdk_lock:
|
|
675
732
|
self._sdk_users -= 1
|
|
676
|
-
if self._sdk_users == 0 and self._sdk_controller is controller
|
|
733
|
+
if (self._sdk_users == 0 and self._sdk_controller is controller
|
|
734
|
+
and self.children.goal_host is None and not self._retired_goal_hosts):
|
|
677
735
|
self._sdk_controller = None
|
|
678
736
|
self._sdk_closing = controller.close()
|
|
679
737
|
return self._sdk_closing
|
|
@@ -746,7 +804,10 @@ class AgentSession:
|
|
|
746
804
|
raise ValueError('A turn requires distinct input messages')
|
|
747
805
|
if not isinstance(batch_id, str) or not batch_id.strip() or len(batch_id.encode()) > 256 or '\x00' in batch_id:
|
|
748
806
|
raise ValueError('Invalid batch identity')
|
|
749
|
-
if
|
|
807
|
+
owner = self.runtime.controller if self.runtime is not None else self._sdk_controller
|
|
808
|
+
maximum = (owner.input_byte_limit(inputs[0])
|
|
809
|
+
if len(inputs) == 1 and owner is not None and owner.owns_current_task else MAX_BATCH_BYTES)
|
|
810
|
+
if sum(input_size(item) for item in inputs) > maximum:
|
|
750
811
|
raise ValueError('Batch input exceeds capacity')
|
|
751
812
|
origins = tuple(item.input_origin or ('user' if item.value.origin == 'human' else 'session_input')
|
|
752
813
|
for item in inputs)
|
|
@@ -756,8 +817,12 @@ class AgentSession:
|
|
|
756
817
|
raise ValueError('Canonical continuation cannot share a batch')
|
|
757
818
|
images = tuple(image for item in inputs for image in item.images)
|
|
758
819
|
context_snapshot = await self.context_messages.capture() if 'user' in origins else None
|
|
820
|
+
self._user_operation_authorized = False
|
|
821
|
+
self._user_prompt_messages.clear()
|
|
822
|
+
self._authorized_messages.clear()
|
|
759
823
|
try:
|
|
760
824
|
self.handled_feedback = []
|
|
825
|
+
await self.initialize_goals()
|
|
761
826
|
if images:
|
|
762
827
|
from xdog.ai.utils.image_files import validate_references
|
|
763
828
|
await asyncio.to_thread(validate_references, images, self.model_info)
|
|
@@ -794,6 +859,9 @@ class AgentSession:
|
|
|
794
859
|
event_stream = await self.agent.continue_()
|
|
795
860
|
else:
|
|
796
861
|
messages = [agent_message(item) for item in inputs]
|
|
862
|
+
self._user_prompt_messages = {
|
|
863
|
+
id(message): message for message, origin in zip(messages, origins, strict=True)
|
|
864
|
+
if origin == "user" and isinstance(message, UserMessage)}
|
|
797
865
|
event_stream = await self.agent.prompt(messages,
|
|
798
866
|
initial_prompt_context=(lambda: self.context_messages.admit(context_snapshot))
|
|
799
867
|
if context_snapshot is not None else None)
|
|
@@ -817,6 +885,9 @@ class AgentSession:
|
|
|
817
885
|
|
|
818
886
|
return last_assistant
|
|
819
887
|
finally:
|
|
888
|
+
self._user_operation_authorized = False
|
|
889
|
+
self._user_prompt_messages.clear()
|
|
890
|
+
self._authorized_messages.clear()
|
|
820
891
|
await self._sync_extension_tools()
|
|
821
892
|
self._expire_turn_scoped_skills()
|
|
822
893
|
|
|
@@ -1519,6 +1590,9 @@ class AgentSession:
|
|
|
1519
1590
|
self.agent.set_system_prompt(prompt + self.access.state.prompt())
|
|
1520
1591
|
def _on_agent_event(self, event: AgentEvent) -> None:
|
|
1521
1592
|
"""Handle agent lifecycle events."""
|
|
1593
|
+
if (isinstance(event, MessageEndEvent) and isinstance(event.message, UserMessage)
|
|
1594
|
+
and self._authorized_messages.get(id(event.message)) is event.message):
|
|
1595
|
+
self._user_operation_authorized = True
|
|
1522
1596
|
if isinstance(event, AgentEndEvent):
|
|
1523
1597
|
self._persist()
|
|
1524
1598
|
|
|
@@ -1607,6 +1681,9 @@ class AgentSession:
|
|
|
1607
1681
|
|
|
1608
1682
|
async def _aclose_resources(self) -> None:
|
|
1609
1683
|
await self.children.supervisor.aclose()
|
|
1684
|
+
if self.children.goal_host is not None:
|
|
1685
|
+
await self.children.goal_host.aclose()
|
|
1686
|
+
await self._settle_retired_goals()
|
|
1610
1687
|
self.extension_dialogs.close()
|
|
1611
1688
|
await self.extensions.aclose()
|
|
1612
1689
|
if self.mcp is not None:
|