bathys 0.8.0__tar.gz → 0.9.0__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.
- {bathys-0.8.0 → bathys-0.9.0}/.remember/logs/memory-2026-09-09.log +41 -0
- {bathys-0.8.0 → bathys-0.9.0}/CHANGELOG.md +14 -0
- {bathys-0.8.0 → bathys-0.9.0}/PKG-INFO +4 -4
- {bathys-0.8.0 → bathys-0.9.0}/README.md +3 -3
- bathys-0.9.0/docs/product/ideas-borrowed.md +69 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/product/roadmap.md +1 -0
- {bathys-0.8.0 → bathys-0.9.0}/npm/bathys-mcp/.remember/logs/memory-2026-09-09.log +17 -0
- {bathys-0.8.0 → bathys-0.9.0}/pyproject.toml +1 -1
- {bathys-0.8.0 → bathys-0.9.0}/src/bathys/__init__.py +1 -1
- {bathys-0.8.0 → bathys-0.9.0}/src/bathys/core.py +54 -4
- {bathys-0.8.0 → bathys-0.9.0}/src/bathys/crawler.py +44 -3
- {bathys-0.8.0 → bathys-0.9.0}/src/bathys/server.py +6 -1
- {bathys-0.8.0 → bathys-0.9.0}/.github/workflows/ci.yml +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/.gitignore +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/.remember/.gitignore +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/.remember/logs/hook-errors.log +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/.remember/logs/memory-2026-09-06.log +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/.remember/logs/memory-2026-09-07.log +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/.remember/logs/memory-2026-09-08.log +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/.remember/tmp/case-divergence +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/.remember/tmp/no-transcript-notice +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/.remember/tmp/post-tool-ran +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/.remember/tmp/session-slug +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/Dockerfile +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/LICENSE +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/THIRD_PARTY_NOTICES.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/agents/HARNESS-DROPIN.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/agents/bathys-researcher.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/agents/skills/bathys-deep-dive/SKILL.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/agents/skills/bathys-source-audit/SKILL.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/adr/0001-python-crawl4ai.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/adr/0002-pin-mcp-sdk-v1.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/adr/0003-self-managed-searxng.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/adr/0004-bm25-distillation.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/adr/0005-cache-raw-before-distill.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/adr/0006-three-tool-string-surface.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/architecture/data-flow.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/architecture/overview.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/architecture/pipeline.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/assets/banner.svg +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/contracts/config.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/contracts/mcp-tools.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/contracts/module-contracts.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/contracts/output-format.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/getting-started/cases.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/getting-started/configure.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/getting-started/install.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/getting-started/integrate.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/index.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/integrations/claude-code.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/integrations/cursor.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/integrations/generic-mcp.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/integrations/overview.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/integrations/zcode.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/meta/glossary.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/meta/style-guide.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/operations/metrics.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/operations/runbook.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/product/api-engine-initiative.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/product/charter.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/product/competitive.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/product/features.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/product/mind-initiative.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/docs/product/ocr-initiative.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/gpu-llm-analysis-2026.html +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/gpu-llm-multiagent-2026.html +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/install.sh +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/integrations/README.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/integrations/hermes/README.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/integrations/hermes/install.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/integrations/pi/README.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/integrations/pi/assets/bathys-rules.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/integrations/zcode/README.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/npm/bathys-mcp/.remember/.gitignore +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/npm/bathys-mcp/.remember/logs/hook-errors.log +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/npm/bathys-mcp/.remember/logs/memory-2026-09-08.log +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/npm/bathys-mcp/.remember/tmp/no-transcript-notice +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/npm/bathys-mcp/.remember/tmp/post-tool-ran +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/npm/bathys-mcp/README.md +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/npm/bathys-mcp/bin/cli.js +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/npm/bathys-mcp/bin/postinstall.js +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/npm/bathys-mcp/package.json +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/scripts/acceptance_v02.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/scripts/batch_check.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/scripts/metrics_report.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/scripts/smoke.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/scripts/stdio_check.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/src/bathys/batch.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/src/bathys/cache.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/src/bathys/compose.yaml +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/src/bathys/config.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/src/bathys/distill.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/src/bathys/doctor.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/src/bathys/installer.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/src/bathys/searx.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/src/bathys/searxng-settings.yml +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/src/bathys/services.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/tests/test_batch.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/tests/test_cache.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/tests/test_config.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/tests/test_core.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/tests/test_distill.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/tests/test_installer.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/tests/test_searx.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/tests/test_v04.py +0 -0
- {bathys-0.8.0 → bathys-0.9.0}/uv.lock +0 -0
|
@@ -140,3 +140,44 @@
|
|
|
140
140
|
13:14:06 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
141
141
|
13:14:28 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
142
142
|
13:14:43 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
143
|
+
13:15:04 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
144
|
+
13:15:20 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
145
|
+
13:36:02 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
146
|
+
13:36:14 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
147
|
+
13:44:58 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
148
|
+
13:45:07 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
149
|
+
13:45:15 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
150
|
+
13:45:28 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
151
|
+
13:45:46 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
152
|
+
13:46:06 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
153
|
+
13:46:18 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
154
|
+
13:46:27 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
155
|
+
13:46:38 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
156
|
+
13:46:47 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
157
|
+
13:46:56 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
158
|
+
13:47:04 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
159
|
+
13:47:14 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
160
|
+
13:47:14 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
161
|
+
13:47:31 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
162
|
+
13:47:41 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
163
|
+
13:47:51 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
164
|
+
13:48:02 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
165
|
+
13:48:11 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
166
|
+
13:48:20 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
167
|
+
13:48:30 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
168
|
+
13:48:40 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
169
|
+
13:48:52 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
170
|
+
13:49:00 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
171
|
+
13:49:11 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
172
|
+
13:49:11 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
173
|
+
13:49:22 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
174
|
+
13:49:32 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
175
|
+
13:49:43 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
176
|
+
13:49:53 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
177
|
+
13:50:05 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
178
|
+
13:50:13 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
179
|
+
13:50:28 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
180
|
+
13:50:39 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
181
|
+
13:50:50 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
182
|
+
13:51:03 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
183
|
+
13:51:16 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/.remember
|
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
Формат: Keep a Changelog; версии — semver. Дата — дата выпуска версии.
|
|
4
4
|
|
|
5
|
+
## [0.9.0] — 2026-09-09
|
|
6
|
+
|
|
7
|
+
Тема: «Borrowed Ideas» — три фичи, заимствованные из pi-web-access (реализация наша; разведка самого источника проведена живьём через Bathys).
|
|
8
|
+
|
|
9
|
+
### Добавлено
|
|
10
|
+
|
|
11
|
+
- **`find` в `read_url`** — точный поиск по кэшу сырца без сети (заимствовано из `get_search_content`/`findText`): счётчики совпадений, позиции и контекст; live: 25 совпадений «self-attention» по кэшу PDF за 0.0 с. Работает и по PDF-кэшу.
|
|
12
|
+
- **PDF text-layer в HTTP-ярусе** (`pymupdf`, локально, без ML/облака; заимствовано из их PDF-обработки): PDF-URL читается первым ярусом, `content-type: application/pdf` → текст → обычная дистилляция. Live: «Attention Is All You Need» (2.2 МБ) → 1489 симв. под запрос за 1.1 с. Сканы без текстового слоя — честный отказ (OCR-инициатива остаётся paused); отдельные PDF-ошибки не эскалируют в браузер (`_FinalTierError`) — браузер на PDF всё равно падает с «Download is starting».
|
|
13
|
+
- **Типизация fallback-причин F-102** (заимствовано из их `fallbackOn`): captcha/suspended весят ×3 (липкое состояние), timeout ×1, прочее ×2 — капчевые движки исключаются из fallback-наборов быстрее.
|
|
14
|
+
|
|
15
|
+
### Исправлено
|
|
16
|
+
|
|
17
|
+
- JS-shell-детектор больше не срабатывает на PDF/извлечённых страницах (пустой raw-html по дизайну ≠ оболочка) — ранее это маскировало PDF-результат ошибкой браузера.
|
|
18
|
+
|
|
5
19
|
## [0.8.0] — 2026-09-09
|
|
6
20
|
|
|
7
21
|
Тема: «Engine Orchestration» — вердикт архкома №4 + безключевая оркестрация движков.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: bathys
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
Summary: Unified local deep-research search service for AI agents — one pipeline (search → extraction → query distillation → cache), zero cloud quotas. MCP stdio server with native harness integration (bathys install).
|
|
5
5
|
Project-URL: Homepage, https://github.com/Korrnals/bathys
|
|
6
6
|
Project-URL: Repository, https://github.com/Korrnals/bathys
|
|
@@ -33,7 +33,7 @@ Description-Content-Type: text/markdown
|
|
|
33
33
|
Сонар находит координаты, батискаф ныряет за полными текстами, дистиллятор поднимает на палубу только то, что отвечает на вопрос.
|
|
34
34
|
|
|
35
35
|

|
|
36
|
-

|
|
37
37
|

|
|
38
38
|

|
|
39
39
|
|
|
@@ -171,7 +171,7 @@ Bathys — stdio MCP-сервер: блок `mcpServers` один и тот же
|
|
|
171
171
|
|---|---|
|
|
172
172
|
| `deep_research(query, max_sources=3, …)` | ищет, параллельно читает топ-источники, возвращает слитый дистиллят под запрос. Первый вызов для любого ресёрч-вопроса. |
|
|
173
173
|
| `web_search(query, max_results=8, …)` | ранжированный список ссылок со сниппетами без содержимого страниц; `as_json=true` — чистый JSON для программ. |
|
|
174
|
-
| `read_url(url, query=None,
|
|
174
|
+
| `read_url(url, query=None, find=None)` | читает страницу (включая текстовые PDF); с `query` — релевантные пассажи; с `find` — точный поиск по кэшу сырца без сети. |
|
|
175
175
|
| `read_urls(urls, query=None, total_chars=12000)` | пакетно читает до 10 известных страниц; бюджет делится между успешными, сбой страницы — одна строка, не сорванный вызов. |
|
|
176
176
|
|
|
177
177
|
Поиск сужается общими фильтрами `time_range`, `category`, `engines`, `language`. Живой футер ответа показывает сжатие и кэш: `[bathys: 41 raw hits, top 3 considered · dove 3 pages · 35669 ch fetched → 7508 ch returned · 3.2s]`.
|
|
@@ -210,7 +210,7 @@ Bathys — stdio MCP-сервер: блок `mcpServers` один и тот же
|
|
|
210
210
|
|
|
211
211
|
## 📍 Статус
|
|
212
212
|
|
|
213
|
-
**0.
|
|
213
|
+
**0.9.0.** Выпускная история: v0.2 «Качество выдачи» (ретраи, здоровье движков), v0.3 «Паритет с Tavily» (`read_urls`, JSON-режим), v0.4 «Эксплуатация» (robots-этика, метрики, `bathys-doctor`), v0.5 «Identity & Harness» (репозиционирование, промпты, субагент), v0.6 «Native Install» (`bathys install`), v0.7 «Ship & Setup» (двухъярусное извлечение, `bathys setup`, однострочник, uninstall) — итоги в [CHANGELOG.md](CHANGELOG.md).
|
|
214
214
|
|
|
215
215
|
Репозиторий: `github.com/Korrnals/bathys`. Пакет опубликован: [PyPI `bathys`](https://pypi.org/project/bathys/) (pip install), однострочник установки — выше. До 1.0: публикация npm-обёртки `bathys-mcp` и первый прогон Docker-образа; CI (matrix 3.10–3.12 + shellcheck) уже в репозитории.
|
|
216
216
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
Сонар находит координаты, батискаф ныряет за полными текстами, дистиллятор поднимает на палубу только то, что отвечает на вопрос.
|
|
8
8
|
|
|
9
9
|

|
|
10
|
-

|
|
11
11
|

|
|
12
12
|

|
|
13
13
|
|
|
@@ -145,7 +145,7 @@ Bathys — stdio MCP-сервер: блок `mcpServers` один и тот же
|
|
|
145
145
|
|---|---|
|
|
146
146
|
| `deep_research(query, max_sources=3, …)` | ищет, параллельно читает топ-источники, возвращает слитый дистиллят под запрос. Первый вызов для любого ресёрч-вопроса. |
|
|
147
147
|
| `web_search(query, max_results=8, …)` | ранжированный список ссылок со сниппетами без содержимого страниц; `as_json=true` — чистый JSON для программ. |
|
|
148
|
-
| `read_url(url, query=None,
|
|
148
|
+
| `read_url(url, query=None, find=None)` | читает страницу (включая текстовые PDF); с `query` — релевантные пассажи; с `find` — точный поиск по кэшу сырца без сети. |
|
|
149
149
|
| `read_urls(urls, query=None, total_chars=12000)` | пакетно читает до 10 известных страниц; бюджет делится между успешными, сбой страницы — одна строка, не сорванный вызов. |
|
|
150
150
|
|
|
151
151
|
Поиск сужается общими фильтрами `time_range`, `category`, `engines`, `language`. Живой футер ответа показывает сжатие и кэш: `[bathys: 41 raw hits, top 3 considered · dove 3 pages · 35669 ch fetched → 7508 ch returned · 3.2s]`.
|
|
@@ -184,7 +184,7 @@ Bathys — stdio MCP-сервер: блок `mcpServers` один и тот же
|
|
|
184
184
|
|
|
185
185
|
## 📍 Статус
|
|
186
186
|
|
|
187
|
-
**0.
|
|
187
|
+
**0.9.0.** Выпускная история: v0.2 «Качество выдачи» (ретраи, здоровье движков), v0.3 «Паритет с Tavily» (`read_urls`, JSON-режим), v0.4 «Эксплуатация» (robots-этика, метрики, `bathys-doctor`), v0.5 «Identity & Harness» (репозиционирование, промпты, субагент), v0.6 «Native Install» (`bathys install`), v0.7 «Ship & Setup» (двухъярусное извлечение, `bathys setup`, однострочник, uninstall) — итоги в [CHANGELOG.md](CHANGELOG.md).
|
|
188
188
|
|
|
189
189
|
Репозиторий: `github.com/Korrnals/bathys`. Пакет опубликован: [PyPI `bathys`](https://pypi.org/project/bathys/) (pip install), однострочник установки — выше. До 1.0: публикация npm-обёртки `bathys-mcp` и первый прогон Docker-образа; CI (matrix 3.10–3.12 + shellcheck) уже в репозитории.
|
|
190
190
|
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Заимствованные идеи: pi-web-access → Bathys
|
|
2
|
+
|
|
3
|
+
| Поле | Значение |
|
|
4
|
+
|---|---|
|
|
5
|
+
| Источник | [pi-web-access](https://github.com/nicobailon/pi-web-access) (Pi coding agent extension, 1399★, активен 2026-09) — разведано живьём через Bathys 2026-09-09 |
|
|
6
|
+
| Принцип | Реализация всегда наша; заимствуются **проверенные продуктовой практикой** решения. Pi — Extension для агента (TypeScript, полный системный доступ), Bathys — единый локальный поисковый сервис (MCP, слой данных). Контексты разные — переносим только то, что усиливает наш конвейер, не ломая хартию (без LLM внутри, без облака по умолчанию). |
|
|
7
|
+
| Статус | Кандидаты в роадмап; приоритизация ниже |
|
|
8
|
+
|
|
9
|
+
## Что переносим (сильные идеи, ранжировано)
|
|
10
|
+
|
|
11
|
+
### 1. `source_check` — верификация утверждения как machine-readable артефакт ★★★
|
|
12
|
+
|
|
13
|
+
У них: `source_check({claim, queries?, fetchContent?, domainFilter?})` → артефакт: статус `supported | contradicted | unclear | missing-evidence`, цитаты пассажей с оффсетами, SHA-256 хэши контента, качество источников; **ошибки поиска/фетча остаются в артефекте, не выбрасываются молча**.
|
|
14
|
+
|
|
15
|
+
Почему нам: у Bathys уже есть промпт `bathys_source_audit` (текстовая стратегия) и скилл — но статус-вердикты у вызывающего агента остаются текстом, который модель может исказить. Детерминированная часть (сбор источников, пассажи с оффсетами, хэши, «1 источник vs 2 независимых») может считать **движок Bathys** — вердикты `supported/contradicted` по правилу «2 независимых домена» — а синтез остаётся агенту. Это углубление нашего же принципа «слой данных без LLM»: верификация фактуры детерминирована, интерпретация — у харнесса.
|
|
16
|
+
|
|
17
|
+
Реализация: новый инструмент `source_check` (5-й) ИЛИ расширение `read_urls` параметром `claim`; артефакт — наш строковый формат с блоками `[bathys: …]`-статистикой.
|
|
18
|
+
|
|
19
|
+
### 2. `get_search_content` — пагинация по кэшу с `findText` ★★★
|
|
20
|
+
|
|
21
|
+
У них: сохранённый контент извлекается позже по `responseId` с `offset/limit` или `findText` (exact/case-insensitive/fuzzy, кап 20k, счётчики совпадений и контекст).
|
|
22
|
+
|
|
23
|
+
Почему нам: у Bathys кэш сырца **уже есть** (до дистилляции — это наше преимущество), но агент может получить только повторный дистиллят. Дать `find_text(url, pattern)` — поиск по сырому кэшу без сети: «найди в той статье точную цитату про X». Дёшево (кэш уже лежит), идеально для аудита и точных цитат.
|
|
24
|
+
|
|
25
|
+
Реализация: параметр `find` в `read_url` при cache-HIT или отдельный инструмент; поиск по сырому тексту с контекстом ±N символов.
|
|
26
|
+
|
|
27
|
+
### 3. GitHub-специализация: клон вместо скрейпа ★★
|
|
28
|
+
|
|
29
|
+
У них: GitHub-URL → локальный `git clone` (кэш на сессию, >350MB → API-вид); PR/issue → приоритизированный markdown-документ (статус, чеки, ревью, комменты, `gh`-CLI) вместо HTML-скрейпа.
|
|
30
|
+
|
|
31
|
+
Почему нам: наш HTTP-ярус на GitHub получает HTML-мусор, браузерный — тяжёлый. Спец-обработчик GitHub-URL (детект по хосту) → `gh api` для PR/issues (структура, а не парсинг) и README+дерево для репо — это **та же двухъярусная философия, но ярус-1 специализируется по типу URL**. `gh` уже есть в системе; без `gh` — фолбэк на HTTP-ярус.
|
|
32
|
+
|
|
33
|
+
Реализация: в `crawler._fetch_http` — редирект на GitHub-ветку (детект: github.com/{owner}/{repo}[/pull|/issues/|N]).
|
|
34
|
+
|
|
35
|
+
### 4. PDF → Markdown-конверсия ★★
|
|
36
|
+
|
|
37
|
+
У них: PDF-URL → конверсия и сохранение в temp-каталог (агент читает секции `read`-ом, не грузя весь документ в контекст); три движка: datalab (layout-aware), gemini (LLM), unpdf (локально, без ключа).
|
|
38
|
+
|
|
39
|
+
Почему нам: OCR-инициатива у нас **приостановлена** (VLM = GPU-боль), но unpdf-путь — это **локальная конверсия текстовых PDF без ML** (`pip install pymupdf` уже был в плане OCR-инициативы как text-layer). Наш двухъярусный HTTP-ярус сейчас на PDF просто падает («unsupported content-type» — сам видел в коде). Текстовый PDF без ML — честное закрытие 80% PDF-кейса без разморозки OCR.
|
|
40
|
+
|
|
41
|
+
Реализация: детект `content-type: application/pdf` в HTTP-ярусе → pymupdf → текст в тот же конвейер дистилляции. Сканы — честный отказ с указанием на OCR-инициативу.
|
|
42
|
+
|
|
43
|
+
### 5. Routing/fallback-конфигурация ★ (у нас уже частично есть)
|
|
44
|
+
|
|
45
|
+
У них: `searchRouting: {providers: [...], fallbackOn: [transient, quota, network, invalid-response]}` — типизированные причины фолбэка; `provider: "all"` — параллельный мульти-поиск; `proxy` per-call.
|
|
46
|
+
|
|
47
|
+
Что берём: (а) **типизация причин фолбэка** — наш F-101 ретраится по «пустой выдаче», но не различает `captcha` vs `timeout` vs `quota` на уровне retry-решения (unresponsive_engines это содержит! — парсить причину); (б) `provider: "all"`-режим для `web_search` — параллельный опрос всех активных движков с дедупликацией (у SearXNG это уже есть в `!format=json` — нам нужно просто НЕ передавать engines и объединить) — **дешёво, у нас почти есть**.
|
|
48
|
+
|
|
49
|
+
Не берём: их 25+ облачных провайдеров (против нашей хартии), browser-cookies Gemini Web (приватность-риск, у нас robots-этика), curator-UI (UI = Not-doing).
|
|
50
|
+
|
|
51
|
+
## Чего НЕ заимствуем (и почему — зафиксировано)
|
|
52
|
+
|
|
53
|
+
| Их фича | Почему нет |
|
|
54
|
+
|---|---|
|
|
55
|
+
| Video understanding (YouTube/Gemini/frames) | Требует облачной VLM (Gemini) — против «ноль облака по умолчанию»; локального аналога без GPU нет |
|
|
56
|
+
| 25+ облачных поисковых провайдеров | Наша ценность — оркестрация локального SearXNG; облако — только опциональные ключи (archcom #4) |
|
|
57
|
+
| Browser-cookie авторизация (Gemini Web) | Приватность-антипаттерн для нашего позиционирования |
|
|
58
|
+
| Curator-UI (браузерный) | UI = Not-doing хартии |
|
|
59
|
+
| LLM-суммаризация результатов | «LLM внутри нет» — синтез у вызывающего агента |
|
|
60
|
+
|
|
61
|
+
## Приоритизация для роадмапа
|
|
62
|
+
|
|
63
|
+
| # | Фича | Сложность | Версия-кандидат |
|
|
64
|
+
|---|---|---|---|
|
|
65
|
+
| 1 | `find`/`get_search_content` по кэшу сырца | S (кэш уже есть) | v0.9 |
|
|
66
|
+
| 2 | PDF text-layer в HTTP-ярусе (pymupdf) | S–M | v0.9 |
|
|
67
|
+
| 3 | Типизация причин фолбэка + «all»-режим | S | v0.9 |
|
|
68
|
+
| 4 | GitHub-специализация (`gh api`) | M | v0.9/v1.0 |
|
|
69
|
+
| 5 | `source_check`-инструмент с детерминированными вердиктами | M–L | v1.0 (входит в паритет с Tavily-классом) |
|
|
@@ -119,6 +119,7 @@ Chromium и SearXNG тяжёлый (порядка гигабайта) — до
|
|
|
119
119
|
## Кандидаты (рассматриваются)
|
|
120
120
|
|
|
121
121
|
- **Лёгкий семантический слой (re-ranker)** (v0.3+) — статус: предложение; спайк одобрен председателем 2026-09-06; интеграция — отдельное решение архкома по критериям гейта в [mind-initiative.md](mind-initiative.md).
|
|
122
|
+
- **Заимствованные фичи из pi-web-access** (v0.9+) — разведано 2026-09-09 через живой Bathys; переносим 5 идей (кэш-find, PDF text-layer, типизация fallback-причин, GitHub-специализация, source_check), отклонены видео-VLM/облачные/cookies-UI — приоритеты в [ideas-borrowed.md](ideas-borrowed.md).
|
|
122
123
|
- **API-движки метапоиска** (v0.8) — статус: **утверждена владельцем 2026-09-09**, материалы собраны е2е; план и чеклист — [api-engine-initiative.md](api-engine-initiative.md). Оркестрация готовых API-движков SearXNG (braveapi/exaapi), свой движок — только по триггеру.
|
|
123
124
|
- **OCR-чтение PDF, сканов и скриншотов** (v0.3+) — статус: **приостановлена** (решение мейнтейнера 2026-09-06: приоритет — доступность на любом CPU-железе); возврат — по триггерам §8 в [ocr-initiative.md](ocr-initiative.md).
|
|
124
125
|
|
|
@@ -42,3 +42,20 @@
|
|
|
42
42
|
13:11:12 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp/.remember
|
|
43
43
|
13:11:12 [hook] WARNING: no session dir for this project: /var/home/abyss/.distrobox/ubuntu/home/.claude/projects/-var-home-abyss-LABs-MCP-deepreserch-npm-bathys-mcp (slug of /var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp). Memory cannot save until it matches a directory under /var/home/abyss/.distrobox/ubuntu/home/.claude/projects/
|
|
44
44
|
13:11:21 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp/.remember
|
|
45
|
+
13:32:15 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp/.remember
|
|
46
|
+
13:32:25 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp/.remember
|
|
47
|
+
13:32:25 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp/.remember
|
|
48
|
+
13:32:35 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp/.remember
|
|
49
|
+
13:32:46 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp/.remember
|
|
50
|
+
13:32:58 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp/.remember
|
|
51
|
+
13:33:07 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp/.remember
|
|
52
|
+
13:33:19 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp/.remember
|
|
53
|
+
13:33:30 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp/.remember
|
|
54
|
+
13:33:39 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp/.remember
|
|
55
|
+
13:33:48 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp/.remember
|
|
56
|
+
13:34:57 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp/.remember
|
|
57
|
+
13:35:07 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp/.remember
|
|
58
|
+
13:35:17 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp/.remember
|
|
59
|
+
13:35:39 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp/.remember
|
|
60
|
+
13:35:51 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp/.remember
|
|
61
|
+
13:44:45 [hook] post-tool: PROJECT_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp PIPELINE_DIR=/var/home/abyss/.distrobox/ubuntu/home/.zcode/cli/plugins/cache/claude-plugins-official/remember/0.20.0 PYTHON=python3 REMEMBER_DIR=/var/home/abyss/LABs/MCP/deepreserch/npm/bathys-mcp/.remember
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "bathys"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.9.0"
|
|
8
8
|
description = "Unified local deep-research search service for AI agents — one pipeline (search → extraction → query distillation → cache), zero cloud quotas. MCP stdio server with native harness integration (bathys install)."
|
|
9
9
|
keywords = ["mcp", "deep-research", "search", "web-search", "ai-agents", "llm", "local-first", "distillation", "searxng", "crawl4ai"]
|
|
10
10
|
classifiers = [
|
|
@@ -4,6 +4,7 @@ so scripts and tests can drive it without MCP framing."""
|
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
6
|
import asyncio
|
|
7
|
+
import re
|
|
7
8
|
import time
|
|
8
9
|
from dataclasses import dataclass
|
|
9
10
|
|
|
@@ -152,10 +153,21 @@ class Engine:
|
|
|
152
153
|
self._search_ts = time.monotonic()
|
|
153
154
|
|
|
154
155
|
def _record_health(self, outcome: searx.SearchOutcome) -> None:
|
|
155
|
-
"""F-102: consecutive-failure streak per engine; any hit resets it.
|
|
156
|
+
"""F-102: consecutive-failure streak per engine; any hit resets it.
|
|
157
|
+
v0.9: failure reasons are now TYPED (borrowed from pi-web-access's
|
|
158
|
+
fallbackOn design) — captcha engines get a longer memory than timeout
|
|
159
|
+
engines, because captchas don't heal in seconds."""
|
|
156
160
|
for e in outcome.unresponsive:
|
|
157
|
-
|
|
158
|
-
|
|
161
|
+
parts = e.split(":", 1)
|
|
162
|
+
name = parts[0]
|
|
163
|
+
reason = (parts[1] if len(parts) > 1 else "").lower()
|
|
164
|
+
if "captcha" in reason or "suspended" in reason:
|
|
165
|
+
weight = 3 # captcha: sticky condition, counts triple
|
|
166
|
+
elif "timeout" in reason:
|
|
167
|
+
weight = 1 # timeout: transient, counts as-is
|
|
168
|
+
else:
|
|
169
|
+
weight = 2 # quota/network/unknown
|
|
170
|
+
self._engine_fails[name] = self._engine_fails.get(name, 0) + weight
|
|
159
171
|
for h in outcome.hits:
|
|
160
172
|
for name in h.engines:
|
|
161
173
|
self._engine_fails.pop(name, None)
|
|
@@ -331,8 +343,46 @@ class Engine:
|
|
|
331
343
|
distilled = distill.passages(slim, query, max_chars)
|
|
332
344
|
return ReadResult(page=page, distilled=distilled, cache_hit=hit)
|
|
333
345
|
|
|
346
|
+
def _find_in_cache(self, url: str, pattern: str, *, limit: int = 3,
|
|
347
|
+
context: int = 160) -> str:
|
|
348
|
+
"""find-text over the cached RAW page (borrowed from pi-web-access's
|
|
349
|
+
get_search_content/findText): exact substring search, no network,
|
|
350
|
+
match counters and local context. Cache miss -> honest error."""
|
|
351
|
+
pk = Cache.key("page", url)
|
|
352
|
+
got, stored = self.cache.get(pk)
|
|
353
|
+
if not got:
|
|
354
|
+
return f"[bathys: find — нет кэша для {url}; сначала read_url]"
|
|
355
|
+
if "error" in stored:
|
|
356
|
+
return f"[bathys: find — в кэше ошибка: {stored['error']}]"
|
|
357
|
+
text = stored.get("text", "")
|
|
358
|
+
low, pl = text.lower(), pattern.lower()
|
|
359
|
+
positions: list[int] = []
|
|
360
|
+
i = low.find(pl)
|
|
361
|
+
while i != -1 and len(positions) < 50:
|
|
362
|
+
positions.append(i)
|
|
363
|
+
i = low.find(pl, i + 1)
|
|
364
|
+
if not positions:
|
|
365
|
+
return (f"[bathys: find '{pattern}' — 0 совпадений в кэше "
|
|
366
|
+
f"({len(text)} ch); попробуй read_url с query]")
|
|
367
|
+
total = len(positions)
|
|
368
|
+
shown = positions[:limit]
|
|
369
|
+
blocks = []
|
|
370
|
+
for n, pos in enumerate(shown, 1):
|
|
371
|
+
lo = max(0, pos - context)
|
|
372
|
+
hi = min(len(text), pos + len(pattern) + context)
|
|
373
|
+
frag = ("…" if lo else "") + text[lo:hi] + ("…" if hi < len(text) else "")
|
|
374
|
+
frag = re.sub(r"\s+", " ", frag)
|
|
375
|
+
blocks.append(f"{n}. @{pos}: …{frag}…")
|
|
376
|
+
return (f"[bathys: find '{pattern}' — {total} совпадений(я), показано {len(shown)} "
|
|
377
|
+
f"(кэш сырца, без сети)\n" + "\n".join(blocks))
|
|
378
|
+
|
|
334
379
|
async def read(self, url: str, *, query: str | None = None, max_chars: int = 8000,
|
|
335
|
-
refresh: bool = False) -> str:
|
|
380
|
+
refresh: bool = False, find: str | None = None) -> str:
|
|
381
|
+
if find is not None:
|
|
382
|
+
out = self._find_in_cache(url, find)
|
|
383
|
+
self._log_metrics("read_url", cache="HIT", chars_in=0,
|
|
384
|
+
chars_out=len(out), secs=0.0, url=url)
|
|
385
|
+
return out
|
|
336
386
|
started = time.monotonic()
|
|
337
387
|
try:
|
|
338
388
|
res = await self._read(url, query=query, max_chars=max_chars, refresh=refresh)
|
|
@@ -54,6 +54,10 @@ _COMMENT_RE = re.compile(r"<!--.*?-->", re.S)
|
|
|
54
54
|
_TAG_RE = re.compile(r"<[^>]+>")
|
|
55
55
|
_TITLE_RE = re.compile(r"<title\b[^>]*>(.*?)</title>", re.S | re.I)
|
|
56
56
|
_WS_RE = re.compile(r"\s+")
|
|
57
|
+
class _FinalTierError(RuntimeError):
|
|
58
|
+
"""Tier-1 error that must NOT escalate to the browser tier."""
|
|
59
|
+
|
|
60
|
+
|
|
57
61
|
_APP_ROOT_RE = re.compile(
|
|
58
62
|
r"<body[^>]*>\s*(<div[^>]*id=[\"']?(app|root|__next|__nuxt)[\"']?[^>]*>\s*"
|
|
59
63
|
r"(</div>)?\s*</body>)", re.I)
|
|
@@ -81,6 +85,23 @@ def _looks_like_js_shell(html: str, text: str) -> bool:
|
|
|
81
85
|
return len(text) < 200
|
|
82
86
|
|
|
83
87
|
|
|
88
|
+
def _pdf_text(content: bytes) -> str | None:
|
|
89
|
+
"""Extract the text layer from PDF bytes; None when there is no text."""
|
|
90
|
+
try:
|
|
91
|
+
import pymupdf # optional dependency, lazy import
|
|
92
|
+
except ImportError:
|
|
93
|
+
raise _FinalTierError(
|
|
94
|
+
"crawl failed: PDF support needs `pip install pymupdf` (local, no ML)")
|
|
95
|
+
try:
|
|
96
|
+
doc = pymupdf.open(stream=content, filetype="pdf")
|
|
97
|
+
parts = [page.get_text() for page in doc]
|
|
98
|
+
doc.close()
|
|
99
|
+
except Exception as e:
|
|
100
|
+
raise RuntimeError(f"crawl failed: pdf parse error ({e.__class__.__name__})")
|
|
101
|
+
text = "\n\n".join(parts).strip()
|
|
102
|
+
return text if len(text) >= 40 else None # <40 chars => likely a scan
|
|
103
|
+
|
|
104
|
+
|
|
84
105
|
class Crawler:
|
|
85
106
|
"""Extraction facade. One shared browser at most, started lazily."""
|
|
86
107
|
|
|
@@ -161,8 +182,22 @@ class Crawler:
|
|
|
161
182
|
ctype = resp.headers.get("content-type", "")
|
|
162
183
|
if resp.status_code >= 400:
|
|
163
184
|
raise RuntimeError(f"crawl failed: http {resp.status_code}")
|
|
185
|
+
if "pdf" in ctype or url.lower().endswith(".pdf"):
|
|
186
|
+
# PDF text layer (v0.9, borrowed from pi-web-access's PDF handling):
|
|
187
|
+
# local extraction via pymupdf — no ML, no cloud, no OCR. Scanned
|
|
188
|
+
# PDFs (no text layer) fail honestly and stay out of scope until
|
|
189
|
+
# the paused OCR initiative is revived.
|
|
190
|
+
text = _pdf_text(resp.content)
|
|
191
|
+
if text is None:
|
|
192
|
+
raise _FinalTierError(
|
|
193
|
+
"crawl failed: PDF has no text layer (scanned?) — OCR initiative is paused")
|
|
194
|
+
return (
|
|
195
|
+
Page(url=str(resp.url), status=resp.status_code, title="",
|
|
196
|
+
text=text, raw_chars=len(resp.content), tier="http-pdf"),
|
|
197
|
+
"",
|
|
198
|
+
)
|
|
164
199
|
if "html" not in ctype and "xml" not in ctype and ctype:
|
|
165
|
-
# non-HTML (
|
|
200
|
+
# non-HTML (json/etc) — not tier-1 material
|
|
166
201
|
raise RuntimeError(f"crawl failed: unsupported content-type {ctype.split(';')[0]}")
|
|
167
202
|
html = resp.text
|
|
168
203
|
title_m = _TITLE_RE.search(html)
|
|
@@ -183,14 +218,20 @@ class Crawler:
|
|
|
183
218
|
if mode == "off":
|
|
184
219
|
page, _ = await self._fetch_http(url, http)
|
|
185
220
|
return page
|
|
186
|
-
# auto: try tier 1, escalate to tier 2 on JS-shell or failure
|
|
221
|
+
# auto: try tier 1, escalate to tier 2 on JS-shell or failure.
|
|
222
|
+
# PDF errors are FINAL (final): a headless browser on a PDF just hits
|
|
223
|
+
# "Download is starting" — escalating would mask the honest message.
|
|
187
224
|
try:
|
|
188
225
|
page, html = await self._fetch_http(url, http)
|
|
226
|
+
except _FinalTierError:
|
|
227
|
+
raise
|
|
189
228
|
except RuntimeError:
|
|
190
229
|
if mode == "auto":
|
|
191
230
|
return await self._fetch_browser(url)
|
|
192
231
|
raise
|
|
193
|
-
|
|
232
|
+
# PDF/extracted-content pages return empty raw html by design —
|
|
233
|
+
# that is NOT a JS shell; skip the heuristic and return as-is.
|
|
234
|
+
if page.tier != "http" or not _looks_like_js_shell(html, page.text):
|
|
194
235
|
return page
|
|
195
236
|
return await self._fetch_browser(url)
|
|
196
237
|
|
|
@@ -174,6 +174,7 @@ async def read_url(
|
|
|
174
174
|
query: str | None = None,
|
|
175
175
|
max_chars: int = 8000,
|
|
176
176
|
refresh: bool = False,
|
|
177
|
+
find: str | None = None,
|
|
177
178
|
ctx: Context = None,
|
|
178
179
|
) -> str:
|
|
179
180
|
"""Read one web page; return its main content as clean, budgeted markdown.
|
|
@@ -187,8 +188,12 @@ async def read_url(
|
|
|
187
188
|
query: optional focus; return only passages relevant to it
|
|
188
189
|
max_chars: output character budget (300-50000)
|
|
189
190
|
refresh: ignore cache and re-fetch the page
|
|
191
|
+
find: search the cached RAW text for this exact substring (case-insensitive):
|
|
192
|
+
returns matches with counters and context, no network needed. Requires
|
|
193
|
+
the page to have been read before; combine with query for first reads.
|
|
190
194
|
"""
|
|
191
|
-
return await _engine(ctx).read(url, query=query, max_chars=max_chars,
|
|
195
|
+
return await _engine(ctx).read(url, query=query, max_chars=max_chars,
|
|
196
|
+
refresh=refresh, find=find)
|
|
192
197
|
|
|
193
198
|
|
|
194
199
|
@mcp.tool(annotations=ToolAnnotations(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|