synapse-cli-agent 0.1.16__tar.gz → 0.1.17__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.
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/AGENTS.md +0 -22
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/CHANGELOG.md +17 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/PKG-INFO +1 -1
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/pyproject.toml +1 -1
- synapse_cli_agent-0.1.17/release_body.md +16 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-search-core/Cargo.lock +1 -1
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-search-core/Cargo.toml +1 -1
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-search-core/pyproject.toml +1 -1
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-search-core/src/lib.rs +6 -3
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/app/agent.py +10 -1
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/content/prompts.py +3 -3
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/runtime/backends.py +13 -2
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/runtime/harness.py +14 -13
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/runtime/middleware.py +11 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/runtime/tool_ignore.py +13 -6
- synapse_cli_agent-0.1.17/src/synapse/tools/__init__.py +10 -0
- synapse_cli_agent-0.1.17/src/synapse/tools/filesystem_search.py +162 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_agent_factory.py +36 -2
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_capabilities.py +7 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_compact_tool_descriptions.py +25 -8
- synapse_cli_agent-0.1.17/tests/test_filesystem_search_tools.py +122 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_tool_ignore.py +7 -2
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/uv.lock +1 -1
- synapse_cli_agent-0.1.16/release_body.md +0 -14
- synapse_cli_agent-0.1.16/src/synapse/tools/__init__.py +0 -5
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/.github/workflows/ci.yml +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/.github/workflows/docs.yml +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/.github/workflows/native-compression-wheels.yml +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/.github/workflows/native-search-wheels.yml +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/.github/workflows/release.yml +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/.gitignore +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/.python-version +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/.readthedocs.yaml +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/README.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/agent_upstream.txt +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/cli_upstream.txt +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/agent-development-guide.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/architecture-flow.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/architecture.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/cli.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/codex-session-discovery-phase-1.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/codex-session-import-phase-2.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/config.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/design.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/index.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/install.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/mcp.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/models.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/native-compression-core.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/native-search-core.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/permissions.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/quickstart.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/sessions.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/skills.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/smith_output.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/tool-output-transform.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/tui-cursor-refactor.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/tutorial.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/docs/x-agent-development-guide.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/examples/mcp.example.json +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/examples/models.example.json +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/examples/settings.example.json +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/middleware_upstream.txt +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/mkdocs.yml +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-search-core/LICENSE +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-search-core/NOTICE +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-search-core/README.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-search-core/python/synapse_search_core/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/Cargo.lock +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/Cargo.toml +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/LICENSE +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/NOTICE +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/README.md +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/pyproject.toml +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/python/synapse_tool_compress_core/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/ccr.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/ccr_in_memory.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/mod.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/relevance/base.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/relevance/bm25.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/signals/keyword_detector.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/signals/line_importance.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/adaptive_sizer.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/anchor_selector.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/code_compressor.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/diff_compressor.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/log_compressor.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/search_compressor.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/analyzer.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/anchors.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/builder.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/classifier.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/compaction/classifier.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/compaction/compactor.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/compaction/formatter.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/compaction/ir.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/compaction/mod.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/compaction/walker.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/config.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/constraints.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/crusher.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/crushers.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/error_keywords.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/field_detect.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/hashing.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/mod.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/observer.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/orchestration.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/outliers.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/planning.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/statistics.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/stats_math.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/traits.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/types.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/rust/synapse-tool-compress-core/src/lib.rs +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/scripts/install.ps1 +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/scripts/release.ps1 +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/slash_cmds_upstream.txt +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/__main__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/app/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/app/agent_md.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/cli.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/commands/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/commands/compression.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/commands/helpers.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/commands/mcp.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/commands/model.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/commands/result.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/commands/sessions.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/commands/slash_cmds.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/commands/slash_complete.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/commands/theme.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/config.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/content/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/content/input_history.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/content/multimodal.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/content/skills_catalog.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/integrations/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/integrations/checkpoint_seed.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/integrations/codex_history.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/integrations/codex_import.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/integrations/codex_sessions.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/integrations/describe_image.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/integrations/http_clients.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/integrations/llm_openai_compat.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/integrations/llm_openai_websocket.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/integrations/mcp_client.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/integrations/openai_oauth.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/integrations/openai_oauth_middleware.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/integrations/vision_middleware.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/memory/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/memory/auto_recorder.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/memory/embedder.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/memory/long_term.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/models/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/models/config.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/models/helpers.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/models/profile.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/models/registry.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/models_registry.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/observability/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/observability/startup_trace.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/parallel_subagents.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/planner/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/planner/task_planner.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/rag/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/rag/knowledge_base.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/runtime/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/runtime/async_runtime.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/runtime/context_compact.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/runtime/execute_capture.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/runtime/fs_permissions.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/runtime/hitl.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/runtime/interaction_ledger.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/runtime/model_request_compression_middleware.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/runtime/pathing.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/runtime/safety.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/runtime/steer.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/runtime/subagents.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/runtime/tool_output_eval.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/runtime/tool_output_middleware.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/runtime/tool_output_usage_middleware.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/sessions/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/sessions/cancel_repair.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/sessions/session_recap.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/sessions/store.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/sessions/transcript.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/settings/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/settings/config_paths.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/settings/schema.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/subagent_monitor.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/tool_output/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/tool_output/detection.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/tool_output/metrics.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/tool_output/models.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/tool_output/pipeline.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/tool_output/repository.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/tool_output/transformers.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/tools/session_tools.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/answer_divider.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/bottombar/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/bottombar/components/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/bottombar/components/key_hints.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/bottombar/components/mcp.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/bottombar/components/mode.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/bottombar/components/model.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/bottombar/components/thread.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/bottombar/context.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/bottombar/core.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/clipboard.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/dialogs/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/dialogs/base.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/dialogs/codex_session_list.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/dialogs/compression_diagnostics.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/dialogs/git_explore.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/dialogs/mcp_panel.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/dialogs/model_picker.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/dialogs/safety_panel.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/dialogs/session_list.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/dialogs/subagent_monitor.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/dialogs/theme_designer.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/dialogs/theme_picker.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/formatters.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/git_explore/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/git_explore/engine.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/git_explore/provider.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/git_explore/unified.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/rendering.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/selectable_static.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/selectable_text.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/sink.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/steer_widget.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/stream.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/stream_events.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/stream_runtime.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/textual_stream_sink.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/theme.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/timeline.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/tool_blocks.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/topbar/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/topbar/components/__init__.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/topbar/components/branch.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/topbar/components/title.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/topbar/components/tool_output.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/topbar/components/usage.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/topbar/components/workspace.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/topbar/context.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/topbar/core.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/topbar/git_changes_popover.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/topbar/git_chrome.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/topbar/tool_output_popover.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/topbar/widget.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/transcript_blocks.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/tui.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/turn_rail.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/turn_rail_widgets.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/user_turn.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/user_turn_block.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/src/synapse/ui/welcome.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/synapse.cmd +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/fixtures/codex_rollouts/duplicate_response_item.jsonl +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/fixtures/codex_rollouts/incomplete_and_aborted.jsonl +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/fixtures/codex_rollouts/legacy_compaction.jsonl +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/fixtures/codex_rollouts/normal_completed.jsonl +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/fixtures/codex_rollouts/replacement_history.jsonl +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/fixtures/codex_rollouts/rollback.jsonl +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/fixtures/codex_rollouts/unsupported_replacement.jsonl +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/fixtures/sample_repo/calculator.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/fixtures/sample_repo/test_calculator.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/fixtures/tool_output_eval.json +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_async_checkpointer.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_backends.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_bottombar_registry.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_cancel_repair.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_checkpoint_seed.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_cli.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_cli_codex_import.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_codex_history.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_codex_import.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_codex_sessions.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_codex_sessions_windows.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_config.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_context_compact.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_context_window.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_dag_parallel.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_describe_image.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_dialogs.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_git_changes_popover.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_git_chrome.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_git_explore.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_http_clients.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_input_history.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_iteration_abc.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_layered_config.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_mcp_schema.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_mermaid_render.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_middleware_async.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_model_request_compression_middleware.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_model_retry.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_multimodal.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_openai_compat_reasoning.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_openai_oauth.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_openai_oauth_middleware.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_openai_websocket.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_pathing.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_safety.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_session_recap.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_slash_and_mcp.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_slash_complete.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_startup_defer.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_steer.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_stream_cancel.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_stream_tool_items.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_stream_ui.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_subagent_monitor_dialog.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_subagent_status.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_theme.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_timeline.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_tool_intent.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_tool_output.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_tool_output_eval.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_tool_output_slash.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_tool_output_usage_middleware.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_topbar_context_ratio.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_topbar_registry.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_transcript.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_tui_codex_import.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_tui_selection.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_tui_sink.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_turn_rail_minimap.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_usage_restore.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_user_turn_style.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/test_welcome.py +0 -0
- {synapse_cli_agent-0.1.16 → synapse_cli_agent-0.1.17}/tests/tool_output_plugin_fixture.py +0 -0
|
@@ -1,27 +1,5 @@
|
|
|
1
1
|
# Synapse 项目协作指南
|
|
2
2
|
|
|
3
|
-
## 用户信息
|
|
4
|
-
- 姓名:肖前程
|
|
5
|
-
- 年龄:35 岁
|
|
6
|
-
- 职业:Java 程序员
|
|
7
|
-
- 当前学习方向:Agent 应用开发
|
|
8
|
-
- 主语言背景:Java → 正在学习 Python/LangChain Agent 生态
|
|
9
|
-
|
|
10
|
-
## 用户信息
|
|
11
|
-
- 姓名:肖前程
|
|
12
|
-
- 年龄:35 岁
|
|
13
|
-
- 职业:Java 程序员
|
|
14
|
-
- 当前学习方向:Agent 应用开发
|
|
15
|
-
- 主语言背景:Java → 正在学习 Python/LangChain Agent 生态
|
|
16
|
-
|
|
17
|
-
## 约定
|
|
18
|
-
- Python 依赖使用 `uv` 管理。
|
|
19
|
-
- 优先小步、可测试的改动。
|
|
20
|
-
- CLI 输出简洁,不使用 emoji。
|
|
21
|
-
- 默认关闭人工审批(自动放行);除非用户要求,不要自行加审批门槛。
|
|
22
|
-
- Backend 仅使用 `LocalShellBackend`,无远程 sandbox。
|
|
23
|
-
- 对用户回复与模型思考过程使用中文;代码标识符/路径/命令可保留原文。
|
|
24
|
-
|
|
25
3
|
## 当前仓库结构
|
|
26
4
|
|
|
27
5
|
| 路径 | 主要职责 |
|
|
@@ -7,6 +7,23 @@ The release workflow automatically extracts the matching section as release note
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## v0.1.17
|
|
11
|
+
|
|
12
|
+
### 新功能
|
|
13
|
+
|
|
14
|
+
- `find_files` / `search_files` 工具新增 `context_lines`、`case_insensitive`、`head_limit`、`offset` 参数。
|
|
15
|
+
- `search_files` 支持忽略大小写(`case_insensitive`,由 `synapse-search-core` 原生引擎实现)。
|
|
16
|
+
- 支持分页查询(`head_limit` + `offset`),Agent 可按需翻页而非一次性获取全部结果。
|
|
17
|
+
|
|
18
|
+
### 工程改进
|
|
19
|
+
|
|
20
|
+
- 工具的 Pydantic schema 不再定义 `intent` 字段,改由 `build_intent_schema_middleware` 中间件统一管理。
|
|
21
|
+
- 新增 Synapse 自有文件搜索工具 `find_files` / `search_files`,排除 deepagents 内置 `ls`/`glob`/`grep` 工具。
|
|
22
|
+
- 系统提示词中的 `glob`/`grep` 工具名修正为 `find_files` / `search_files`。
|
|
23
|
+
- `synapse-search-core` 升级至 0.1.1(新增 `case_insensitive` 参数)。
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
10
27
|
## v0.1.16
|
|
11
28
|
|
|
12
29
|
### 新功能
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: synapse-cli-agent
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.17
|
|
4
4
|
Summary: Local coding agent built on LangChain Deep Agents (LocalShell, no sandbox)
|
|
5
5
|
Project-URL: Homepage, https://github.com/alex8224/synapse-agent
|
|
6
6
|
Project-URL: Repository, https://github.com/alex8224/synapse-agent
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
## v0.1.17
|
|
2
|
+
|
|
3
|
+
### 新功能
|
|
4
|
+
|
|
5
|
+
- `find_files` / `search_files` 工具新增 `context_lines`、`case_insensitive`、`head_limit`、`offset` 参数。
|
|
6
|
+
- `search_files` 支持忽略大小写(`case_insensitive`,由 `synapse-search-core` 原生引擎实现)。
|
|
7
|
+
- 支持分页查询(`head_limit` + `offset`),Agent 可按需翻页而非一次性获取全部结果。
|
|
8
|
+
|
|
9
|
+
### 工程改进
|
|
10
|
+
|
|
11
|
+
- 工具的 Pydantic schema 不再定义 `intent` 字段,改由 `build_intent_schema_middleware` 中间件统一管理。
|
|
12
|
+
- 新增 Synapse 自有文件搜索工具 `find_files` / `search_files`,排除 deepagents 内置 `ls`/`glob`/`grep` 工具。
|
|
13
|
+
- 系统提示词中的 `glob`/`grep` 工具名修正为 `find_files` / `search_files`。
|
|
14
|
+
- `synapse-search-core` 升级至 0.1.1(新增 `case_insensitive` 参数)。
|
|
15
|
+
|
|
16
|
+
---
|
|
@@ -3,7 +3,7 @@ use std::path::{Path, PathBuf};
|
|
|
3
3
|
use std::time::UNIX_EPOCH;
|
|
4
4
|
|
|
5
5
|
use globset::{Glob, GlobSet, GlobSetBuilder};
|
|
6
|
-
use grep_regex::RegexMatcher;
|
|
6
|
+
use grep_regex::{RegexMatcher, RegexMatcherBuilder};
|
|
7
7
|
use grep_searcher::{BinaryDetection, Searcher, SearcherBuilder, Sink, SinkContext, SinkMatch};
|
|
8
8
|
use ignore::WalkBuilder;
|
|
9
9
|
use pyo3::exceptions::PyValueError;
|
|
@@ -121,7 +121,7 @@ fn search_file(
|
|
|
121
121
|
Ok(sink.result)
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
#[pyfunction(signature = (base_path, pattern, include_glob=None, max_results=1000, context_lines=0))]
|
|
124
|
+
#[pyfunction(signature = (base_path, pattern, include_glob=None, max_results=1000, context_lines=0, case_insensitive=false))]
|
|
125
125
|
fn grep(
|
|
126
126
|
py: Python<'_>,
|
|
127
127
|
base_path: &str,
|
|
@@ -129,6 +129,7 @@ fn grep(
|
|
|
129
129
|
include_glob: Option<&str>,
|
|
130
130
|
max_results: usize,
|
|
131
131
|
context_lines: usize,
|
|
132
|
+
case_insensitive: bool,
|
|
132
133
|
) -> PyResult<Py<PyDict>> {
|
|
133
134
|
if pattern.is_empty() {
|
|
134
135
|
return Err(PyValueError::new_err("pattern must not be empty"));
|
|
@@ -143,7 +144,9 @@ fn grep(
|
|
|
143
144
|
base_path.display()
|
|
144
145
|
)));
|
|
145
146
|
}
|
|
146
|
-
let matcher =
|
|
147
|
+
let matcher = RegexMatcherBuilder::new()
|
|
148
|
+
.case_insensitive(case_insensitive)
|
|
149
|
+
.build(pattern)
|
|
147
150
|
.map_err(|error| PyValueError::new_err(format!("invalid regex pattern: {error}")))?;
|
|
148
151
|
let include = include_glob
|
|
149
152
|
.map(compile_glob)
|
|
@@ -35,6 +35,7 @@ from synapse.runtime.middleware import (
|
|
|
35
35
|
build_strip_redundant_prompt_blocks,
|
|
36
36
|
build_task_namespace_middleware,
|
|
37
37
|
build_tool_error_recovery_middleware,
|
|
38
|
+
build_tool_exclusion_middleware,
|
|
38
39
|
)
|
|
39
40
|
from synapse.runtime.model_request_compression_middleware import (
|
|
40
41
|
build_model_request_compression_middleware,
|
|
@@ -48,7 +49,7 @@ from synapse.settings import Settings
|
|
|
48
49
|
from synapse.tool_output.pipeline import ToolOutputTransformPipeline
|
|
49
50
|
from synapse.tool_output.repository import ToolOutputRepository
|
|
50
51
|
from synapse.tool_output.transformers import load_transformer_plugins
|
|
51
|
-
from synapse.tools import build_session_tools
|
|
52
|
+
from synapse.tools import build_filesystem_search_tools, build_session_tools
|
|
52
53
|
|
|
53
54
|
|
|
54
55
|
def _build_checkpointer(settings: Settings):
|
|
@@ -228,6 +229,12 @@ def build_coding_agent(
|
|
|
228
229
|
readonly=settings.readonly,
|
|
229
230
|
excluded_tools=settings.excluded_tools,
|
|
230
231
|
)
|
|
232
|
+
# Keep deepagents' built-in ``ls``, ``glob``, and ``grep`` out of model
|
|
233
|
+
# requests. Synapse registers the non-conflicting ``find_files`` and
|
|
234
|
+
# ``search_files`` tools explicitly below.
|
|
235
|
+
model_request_excluded_tools = set(settings.excluded_tools) | {"ls", "glob", "grep"}
|
|
236
|
+
if settings.readonly:
|
|
237
|
+
model_request_excluded_tools.update({"execute", "write_file", "edit_file"})
|
|
231
238
|
|
|
232
239
|
interrupt_on = build_interrupt_on(require_approval=settings.require_approval)
|
|
233
240
|
with span("checkpointer"):
|
|
@@ -279,6 +286,7 @@ def build_coding_agent(
|
|
|
279
286
|
tools: list[Any] = []
|
|
280
287
|
if extra_tools:
|
|
281
288
|
tools.extend(extra_tools)
|
|
289
|
+
tools.extend(build_filesystem_search_tools(backend))
|
|
282
290
|
# 跨会话查阅工具
|
|
283
291
|
try:
|
|
284
292
|
session_tools = build_session_tools(
|
|
@@ -392,6 +400,7 @@ def build_coding_agent(
|
|
|
392
400
|
),
|
|
393
401
|
build_model_retry_middleware(),
|
|
394
402
|
build_task_namespace_middleware(),
|
|
403
|
+
build_tool_exclusion_middleware(model_request_excluded_tools),
|
|
395
404
|
]
|
|
396
405
|
transform_enabled = bool(getattr(settings, "enable_tool_output_transform", True))
|
|
397
406
|
try:
|
|
@@ -46,7 +46,7 @@ Never scan the entire repository without a specific reason.
|
|
|
46
46
|
|
|
47
47
|
## Virtual filesystem
|
|
48
48
|
|
|
49
|
-
File tools such as `
|
|
49
|
+
File tools such as `find_files`, `search_files`, `read_file`, `edit_file`, and `write_file`
|
|
50
50
|
operate on a virtual filesystem rooted at `/`.
|
|
51
51
|
|
|
52
52
|
Valid paths:
|
|
@@ -109,7 +109,7 @@ Do not use generic intent values such as `run tool` or `read_file`.
|
|
|
109
109
|
Search only when required by a clear task.
|
|
110
110
|
Keep searches targeted and avoid unnecessary full-file output.
|
|
111
111
|
|
|
112
|
-
For
|
|
112
|
+
For the `search_files` tool, automatically exclude common build artifacts and caches via the `glob` parameter:
|
|
113
113
|
* `target/`
|
|
114
114
|
* `.venv/`
|
|
115
115
|
* `.node_modules/`
|
|
@@ -133,7 +133,7 @@ Run independent tool calls in parallel within the same turn.
|
|
|
133
133
|
Parallelize when arguments are already known and results do not depend on each other, including:
|
|
134
134
|
|
|
135
135
|
* Multiple file reads
|
|
136
|
-
* `
|
|
136
|
+
* `find_files` and related file reads
|
|
137
137
|
* `execute` and related reads
|
|
138
138
|
* Edits to different files
|
|
139
139
|
* Independent test or lint commands
|
|
@@ -205,6 +205,9 @@ class CodingLocalShellBackend(LocalShellBackend):
|
|
|
205
205
|
pattern: str,
|
|
206
206
|
path: str | None = None,
|
|
207
207
|
glob: str | None = None,
|
|
208
|
+
max_results: int = 1000,
|
|
209
|
+
context_lines: int = 0,
|
|
210
|
+
case_insensitive: bool = False,
|
|
208
211
|
) -> Any:
|
|
209
212
|
"""Search with the required native Rust engine using regular expressions."""
|
|
210
213
|
import synapse_search_core
|
|
@@ -215,7 +218,8 @@ class CodingLocalShellBackend(LocalShellBackend):
|
|
|
215
218
|
return GrepResult(matches=[])
|
|
216
219
|
try:
|
|
217
220
|
payload = synapse_search_core.grep(
|
|
218
|
-
str(base_path), pattern, include_glob=glob, max_results=
|
|
221
|
+
str(base_path), pattern, include_glob=glob, max_results=max_results,
|
|
222
|
+
context_lines=context_lines, case_insensitive=case_insensitive,
|
|
219
223
|
)
|
|
220
224
|
except (OSError, RuntimeError, ValueError) as exc:
|
|
221
225
|
return GrepResult(error=f"Error searching path '{path or '.'}': {exc}", matches=[])
|
|
@@ -226,7 +230,12 @@ class CodingLocalShellBackend(LocalShellBackend):
|
|
|
226
230
|
matches.append({"path": result_path, "line": item["line"], "text": item["text"]})
|
|
227
231
|
return GrepResult(matches=matches)
|
|
228
232
|
|
|
229
|
-
def glob(
|
|
233
|
+
def glob(
|
|
234
|
+
self,
|
|
235
|
+
pattern: str,
|
|
236
|
+
path: str | None = None,
|
|
237
|
+
max_results: int = 1000,
|
|
238
|
+
) -> Any:
|
|
230
239
|
"""Find files with the required native Rust engine."""
|
|
231
240
|
from datetime import datetime
|
|
232
241
|
|
|
@@ -244,6 +253,8 @@ class CodingLocalShellBackend(LocalShellBackend):
|
|
|
244
253
|
)
|
|
245
254
|
matches = []
|
|
246
255
|
for item in payload["matches"]:
|
|
256
|
+
if len(matches) >= max_results:
|
|
257
|
+
break
|
|
247
258
|
result_path = self._native_result_path(base_path, item["path"])
|
|
248
259
|
if result_path is None:
|
|
249
260
|
continue
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Resolve model-facing tool exclusions for the coding harness."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from collections.abc import Iterable
|
|
6
6
|
|
|
7
|
-
_DEFAULT_EXCLUDES = frozenset({"ls", "grep"})
|
|
7
|
+
_DEFAULT_EXCLUDES = frozenset({"ls", "glob", "grep"})
|
|
8
8
|
_DEFAULT_READONLY_EXCLUDES = frozenset(
|
|
9
9
|
{
|
|
10
10
|
"execute",
|
|
@@ -20,22 +20,23 @@ def apply_harness_exclusions(
|
|
|
20
20
|
readonly: bool = False,
|
|
21
21
|
excluded_tools: Iterable[str] | None = None,
|
|
22
22
|
) -> frozenset[str]:
|
|
23
|
-
"""
|
|
23
|
+
"""Return the tools that should be hidden from model requests.
|
|
24
24
|
|
|
25
|
-
``ls``
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
``ls`` is excluded by default because ``execute`` can run the project's
|
|
26
|
+
native directory commands. Read-only mode additionally excludes ``execute``,
|
|
27
|
+
``write_file``, and ``edit_file``.
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
``model_spec`` is used only to disable deepagents' built-in general-purpose
|
|
30
|
+
subagent. Tool exclusions are applied by Synapse request middleware instead
|
|
31
|
+
of deepagents' process-global harness registry because that registry unions
|
|
32
|
+
exclusions and cannot re-enable a tool such as ``grep`` later in the same
|
|
33
|
+
process.
|
|
31
34
|
"""
|
|
32
35
|
names = set(_DEFAULT_EXCLUDES)
|
|
33
36
|
names.update(excluded_tools or [])
|
|
34
37
|
if readonly:
|
|
35
38
|
names |= set(_DEFAULT_READONLY_EXCLUDES)
|
|
36
39
|
excluded = frozenset(n.strip() for n in names if n and n.strip())
|
|
37
|
-
if not excluded:
|
|
38
|
-
return frozenset()
|
|
39
40
|
|
|
40
41
|
from deepagents import (
|
|
41
42
|
GeneralPurposeSubagentProfile,
|
|
@@ -43,12 +44,12 @@ def apply_harness_exclusions(
|
|
|
43
44
|
register_harness_profile,
|
|
44
45
|
)
|
|
45
46
|
|
|
47
|
+
# Tool exclusions are request-local middleware in ``build_coding_agent``.
|
|
48
|
+
# Do not register them here: deepagents merges profile exclusions globally,
|
|
49
|
+
# so a readonly agent would otherwise make later writable agents readonly too.
|
|
46
50
|
profile = HarnessProfile(
|
|
47
|
-
excluded_tools=excluded,
|
|
48
51
|
general_purpose_subagent=GeneralPurposeSubagentProfile(enabled=False),
|
|
49
52
|
)
|
|
50
|
-
# Model-level and provider-level keys so both string specs and prebuilt
|
|
51
|
-
# BaseChatModel resolution paths can match.
|
|
52
53
|
register_harness_profile(model_spec, profile)
|
|
53
54
|
if ":" in model_spec:
|
|
54
55
|
provider = model_spec.split(":", 1)[0]
|
|
@@ -696,6 +696,17 @@ _COMPACT_TOOL_DESCRIPTIONS: dict[str, str] = {
|
|
|
696
696
|
"Always read a file before editing it. "
|
|
697
697
|
"Supports images, audio, video, and PDF via multimodal reads."
|
|
698
698
|
),
|
|
699
|
+
"grep": (
|
|
700
|
+
"Search workspace files with a regular expression and return matching paths, line "
|
|
701
|
+
"numbers, and text. Examples: pattern='TODO|FIXME', pattern='(?i)error', or "
|
|
702
|
+
"pattern='def\\s+name' with glob='**/*.py'. Escape regex metacharacters when "
|
|
703
|
+
"searching for literal text."
|
|
704
|
+
),
|
|
705
|
+
"glob": (
|
|
706
|
+
"Find workspace files and directories matching a glob pattern. Supports *, **, and ?. "
|
|
707
|
+
"Examples: '**/*.py' for Python files, 'src/**/*.ts' for TypeScript under src, and "
|
|
708
|
+
"'README?.md' for one-character filename variants."
|
|
709
|
+
),
|
|
699
710
|
}
|
|
700
711
|
|
|
701
712
|
|
|
@@ -104,10 +104,21 @@ class _Rule:
|
|
|
104
104
|
|
|
105
105
|
|
|
106
106
|
_BUILTIN_DENY_PATTERNS = (".git/",)
|
|
107
|
+
_DEFAULT_IGNORE_PATTERNS = (
|
|
108
|
+
"target/",
|
|
109
|
+
".venv/",
|
|
110
|
+
".node_modules/",
|
|
111
|
+
"node_modules/",
|
|
112
|
+
"__pycache__/",
|
|
113
|
+
)
|
|
107
114
|
_BUILTIN_DENY_RULES = tuple(
|
|
108
115
|
_Rule(regex=_gitignore_pattern_to_regex(pattern), negate=False, raw=pattern)
|
|
109
116
|
for pattern in _BUILTIN_DENY_PATTERNS
|
|
110
117
|
)
|
|
118
|
+
_DEFAULT_IGNORE_RULES = tuple(
|
|
119
|
+
_Rule(regex=_gitignore_pattern_to_regex(pattern), negate=False, raw=pattern)
|
|
120
|
+
for pattern in _DEFAULT_IGNORE_PATTERNS
|
|
121
|
+
)
|
|
111
122
|
|
|
112
123
|
|
|
113
124
|
class ToolIgnoreMatcher:
|
|
@@ -196,15 +207,11 @@ class ToolIgnoreMatcher:
|
|
|
196
207
|
return False
|
|
197
208
|
if any(rule.regex.match(rel) for rule in _BUILTIN_DENY_RULES):
|
|
198
209
|
return True
|
|
199
|
-
|
|
200
|
-
return False
|
|
201
|
-
ignored = False
|
|
202
|
-
matched = False
|
|
210
|
+
ignored = any(rule.regex.match(rel) for rule in _DEFAULT_IGNORE_RULES)
|
|
203
211
|
for rule in self._rules:
|
|
204
212
|
if rule.regex.match(rel):
|
|
205
|
-
matched = True
|
|
206
213
|
ignored = not rule.negate
|
|
207
|
-
return ignored
|
|
214
|
+
return ignored
|
|
208
215
|
|
|
209
216
|
|
|
210
217
|
def relative_to_root(path: str | Path, root: Path) -> str:
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""Custom tools for the coding agent."""
|
|
2
|
+
|
|
3
|
+
from synapse.tools.filesystem_search import build_filesystem_search_tools
|
|
4
|
+
from synapse.tools.session_tools import build_session_tools, build_tool_result_reader_tool
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"build_filesystem_search_tools",
|
|
8
|
+
"build_session_tools",
|
|
9
|
+
"build_tool_result_reader_tool",
|
|
10
|
+
]
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"""Model-facing filesystem search tools with stable, Synapse-owned schemas."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any, Literal
|
|
6
|
+
|
|
7
|
+
from langchain_core.tools import tool
|
|
8
|
+
from pydantic import BaseModel, Field
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class FindFilesInput(BaseModel):
|
|
12
|
+
"""Arguments for the workspace path-pattern search tool."""
|
|
13
|
+
|
|
14
|
+
pattern: str = Field(description="Glob pattern, such as '**/*.py' or 'README?.md'.")
|
|
15
|
+
path: str | None = Field(
|
|
16
|
+
default=None,
|
|
17
|
+
description="Workspace directory to search. Omit to search the workspace root.",
|
|
18
|
+
)
|
|
19
|
+
max_results: int = Field(
|
|
20
|
+
default=200,
|
|
21
|
+
ge=1,
|
|
22
|
+
le=1000,
|
|
23
|
+
description="Maximum number of matching paths to return from the search backend.",
|
|
24
|
+
)
|
|
25
|
+
head_limit: int = Field(
|
|
26
|
+
default=0,
|
|
27
|
+
ge=0,
|
|
28
|
+
le=1000,
|
|
29
|
+
description="Maximum entries to return to the model (0 = use max_results).",
|
|
30
|
+
)
|
|
31
|
+
offset: int = Field(
|
|
32
|
+
default=0,
|
|
33
|
+
ge=0,
|
|
34
|
+
description="Skip first N entries before applying head_limit (pagination).",
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class SearchFilesInput(BaseModel):
|
|
39
|
+
"""Arguments for the workspace regular-expression content search tool."""
|
|
40
|
+
|
|
41
|
+
pattern: str = Field(
|
|
42
|
+
description="Regular expression to search for. Use escaped metacharacters for literal text."
|
|
43
|
+
)
|
|
44
|
+
path: str | None = Field(
|
|
45
|
+
default=None,
|
|
46
|
+
description="Workspace file or directory to search. Omit to search the workspace root.",
|
|
47
|
+
)
|
|
48
|
+
glob: str | None = Field(
|
|
49
|
+
default=None,
|
|
50
|
+
description="Optional glob filter, such as '**/*.py' or 'src/**/*.ts'.",
|
|
51
|
+
)
|
|
52
|
+
output_mode: Literal["files_with_matches", "content", "count"] = Field(
|
|
53
|
+
default="files_with_matches",
|
|
54
|
+
description="Return matching file paths, matching lines, or a count for each file.",
|
|
55
|
+
)
|
|
56
|
+
max_results: int = Field(
|
|
57
|
+
default=200,
|
|
58
|
+
ge=1,
|
|
59
|
+
le=1000,
|
|
60
|
+
description="Maximum number of matching lines to return from the search backend.",
|
|
61
|
+
)
|
|
62
|
+
head_limit: int = Field(
|
|
63
|
+
default=0,
|
|
64
|
+
ge=0,
|
|
65
|
+
le=1000,
|
|
66
|
+
description="Maximum entries to return to the model (0 = use max_results).",
|
|
67
|
+
)
|
|
68
|
+
offset: int = Field(
|
|
69
|
+
default=0,
|
|
70
|
+
ge=0,
|
|
71
|
+
description="Skip first N entries before applying head_limit (pagination).",
|
|
72
|
+
)
|
|
73
|
+
context_lines: int = Field(
|
|
74
|
+
default=0,
|
|
75
|
+
ge=0,
|
|
76
|
+
le=10,
|
|
77
|
+
description="Number of context lines to include before and after each match.",
|
|
78
|
+
)
|
|
79
|
+
case_insensitive: bool = Field(
|
|
80
|
+
default=False,
|
|
81
|
+
description="Enable case-insensitive search.",
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def build_filesystem_search_tools(backend: Any) -> list[Any]:
|
|
86
|
+
"""Create schema-controlled search tools backed by ``CodingLocalShellBackend``."""
|
|
87
|
+
|
|
88
|
+
@tool("find_files", args_schema=FindFilesInput)
|
|
89
|
+
def find_files(
|
|
90
|
+
*,
|
|
91
|
+
pattern: str,
|
|
92
|
+
path: str | None = None,
|
|
93
|
+
max_results: int = 200,
|
|
94
|
+
head_limit: int = 0,
|
|
95
|
+
offset: int = 0,
|
|
96
|
+
) -> str:
|
|
97
|
+
"""Find workspace files and directories by glob pattern."""
|
|
98
|
+
result = backend.glob(pattern=pattern, path=path, max_results=max_results + 1)
|
|
99
|
+
error = getattr(result, "error", None)
|
|
100
|
+
if error:
|
|
101
|
+
return str(error)
|
|
102
|
+
all_matches = list(getattr(result, "matches", []) or [])
|
|
103
|
+
display_limit = head_limit if head_limit > 0 else max_results
|
|
104
|
+
paginated = all_matches[offset : offset + display_limit]
|
|
105
|
+
if not paginated:
|
|
106
|
+
return "No paths matched."
|
|
107
|
+
lines = []
|
|
108
|
+
for item in paginated:
|
|
109
|
+
item_path = item.get("path", "") if isinstance(item, dict) else str(item)
|
|
110
|
+
is_dir = item.get("is_dir", False) if isinstance(item, dict) else False
|
|
111
|
+
lines.append(f"{item_path}{'/' if is_dir else ''}")
|
|
112
|
+
suffix = "\n[Results truncated]" if len(all_matches) > offset + len(paginated) else ""
|
|
113
|
+
return "\n".join(lines) + suffix
|
|
114
|
+
|
|
115
|
+
@tool("search_files", args_schema=SearchFilesInput)
|
|
116
|
+
def search_files(
|
|
117
|
+
*,
|
|
118
|
+
pattern: str,
|
|
119
|
+
path: str | None = None,
|
|
120
|
+
glob: str | None = None,
|
|
121
|
+
output_mode: Literal["files_with_matches", "content", "count"] = "files_with_matches",
|
|
122
|
+
max_results: int = 200,
|
|
123
|
+
head_limit: int = 0,
|
|
124
|
+
offset: int = 0,
|
|
125
|
+
context_lines: int = 0,
|
|
126
|
+
case_insensitive: bool = False,
|
|
127
|
+
) -> str:
|
|
128
|
+
"""Search workspace files with a regular expression."""
|
|
129
|
+
result = backend.grep(
|
|
130
|
+
pattern=pattern,
|
|
131
|
+
path=path,
|
|
132
|
+
glob=glob,
|
|
133
|
+
max_results=max_results + 1 + offset,
|
|
134
|
+
context_lines=context_lines,
|
|
135
|
+
case_insensitive=case_insensitive,
|
|
136
|
+
)
|
|
137
|
+
error = getattr(result, "error", None)
|
|
138
|
+
if error:
|
|
139
|
+
return str(error)
|
|
140
|
+
all_matches = list(getattr(result, "matches", []) or [])
|
|
141
|
+
display_limit = head_limit if head_limit > 0 else max_results
|
|
142
|
+
paginated = all_matches[offset : offset + display_limit]
|
|
143
|
+
if not paginated:
|
|
144
|
+
return "No matches found."
|
|
145
|
+
suffix = "\n[Results truncated]" if len(all_matches) > offset + len(paginated) else ""
|
|
146
|
+
if output_mode == "content":
|
|
147
|
+
content = "\n".join(
|
|
148
|
+
f"{item['path']}:{item['line']}: {item['text']}" for item in paginated
|
|
149
|
+
)
|
|
150
|
+
return content + suffix
|
|
151
|
+
grouped: dict[str, int] = {}
|
|
152
|
+
for item in paginated:
|
|
153
|
+
grouped[item["path"]] = grouped.get(item["path"], 0) + 1
|
|
154
|
+
if output_mode == "count":
|
|
155
|
+
content = "\n".join(
|
|
156
|
+
f"{item_path}: {count}" for item_path, count in grouped.items()
|
|
157
|
+
)
|
|
158
|
+
else:
|
|
159
|
+
content = "\n".join(grouped)
|
|
160
|
+
return content + suffix
|
|
161
|
+
|
|
162
|
+
return [find_files, search_files]
|
|
@@ -24,7 +24,7 @@ def test_build_system_prompt_includes_workspace(tmp_path: Path):
|
|
|
24
24
|
or "Virtual filesystem" in text
|
|
25
25
|
or "\u8d44\u6df1\u8f6f\u4ef6\u5de5\u7a0b Agent" in text
|
|
26
26
|
)
|
|
27
|
-
assert "
|
|
27
|
+
assert "用中文思考和推理" in text
|
|
28
28
|
assert "Current workspace" in text
|
|
29
29
|
|
|
30
30
|
|
|
@@ -118,7 +118,41 @@ def test_build_coding_agent_wires_create_deep_agent(tmp_path: Path):
|
|
|
118
118
|
assert kwargs["model"] is fake_model
|
|
119
119
|
assert kwargs["backend"] is not None
|
|
120
120
|
assert kwargs["checkpointer"] is not None
|
|
121
|
-
|
|
121
|
+
search_tools = {
|
|
122
|
+
tool.name: tool
|
|
123
|
+
for tool in kwargs["tools"]
|
|
124
|
+
if tool.name in {"find_files", "search_files"}
|
|
125
|
+
}
|
|
126
|
+
assert set(search_tools) == {"find_files", "search_files"}
|
|
127
|
+
assert search_tools["search_files"].tool_call_schema.model_json_schema()["properties"][
|
|
128
|
+
"pattern"
|
|
129
|
+
]["description"].startswith("Regular expression")
|
|
130
|
+
exclusion = next(
|
|
131
|
+
middleware
|
|
132
|
+
for middleware in (kwargs.get("middleware") or [])
|
|
133
|
+
if type(middleware).__name__ == "exclude_tools"
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
class _Request:
|
|
137
|
+
def __init__(self, tools): # noqa: ANN001
|
|
138
|
+
self.tools = tools
|
|
139
|
+
|
|
140
|
+
def override(self, **changes): # noqa: ANN003
|
|
141
|
+
return _Request(changes.get("tools", self.tools))
|
|
142
|
+
|
|
143
|
+
ls_tool = MagicMock(name="ls_tool")
|
|
144
|
+
ls_tool.name = "ls"
|
|
145
|
+
glob_tool = MagicMock(name="glob_tool")
|
|
146
|
+
glob_tool.name = "glob"
|
|
147
|
+
grep_tool = MagicMock(name="grep_tool")
|
|
148
|
+
grep_tool.name = "grep"
|
|
149
|
+
find_files_tool = MagicMock(name="find_files_tool")
|
|
150
|
+
find_files_tool.name = "find_files"
|
|
151
|
+
search_files_tool = MagicMock(name="search_files_tool")
|
|
152
|
+
search_files_tool.name = "search_files"
|
|
153
|
+
request = _Request([ls_tool, glob_tool, grep_tool, find_files_tool, search_files_tool])
|
|
154
|
+
filtered = exclusion.wrap_model_call(request, lambda current: current)
|
|
155
|
+
assert [tool.name for tool in filtered.tools] == ["find_files", "search_files"]
|
|
122
156
|
model_retries = [
|
|
123
157
|
middleware
|
|
124
158
|
for middleware in (kwargs.get("middleware") or [])
|
|
@@ -570,11 +570,18 @@ def test_fs_permissions_and_harness(tmp_path: Path):
|
|
|
570
570
|
assert perms is not None
|
|
571
571
|
excluded = apply_harness_exclusions("openai:demo")
|
|
572
572
|
assert "ls" in excluded
|
|
573
|
+
assert "glob" in excluded
|
|
573
574
|
assert "grep" in excluded
|
|
574
575
|
excluded = apply_harness_exclusions("openai:demo", readonly=True)
|
|
575
576
|
assert "write_file" in excluded
|
|
576
577
|
assert "execute" in excluded
|
|
577
578
|
|
|
579
|
+
from deepagents.profiles.harness.harness_profiles import _get_harness_profile
|
|
580
|
+
|
|
581
|
+
profile = _get_harness_profile("openai:demo")
|
|
582
|
+
assert profile is not None
|
|
583
|
+
assert profile.excluded_tools == frozenset()
|
|
584
|
+
|
|
578
585
|
|
|
579
586
|
def test_default_subagents_optional_models(tmp_path: Path):
|
|
580
587
|
del tmp_path
|