| You are implementing Phase 2, Task 1: Deep LLM Layer — Claude API Integration
## Task Description
**Files:**
- Create: `sidecar/llm/deep.py`
- Create: `sidecar/tests/test_deep.py`
- Modify: `sidecar/pyproject.toml` (add `anthropic>=0.42` to dependencies)
**Implementation:**
Create `sidecar/llm/deep.py`:
```python
import anthropic
class DeepAnalyzer:
def __init__(
self,
api_key: str | None = None,
model: str = "claude-sonnet-4-20250514",
):
self.client = anthropic.AsyncAnthropic(api_key=api_key)
self.model = model
def build_prompt(self, running_summary: str, new_transcript: list[dict]) -> str:
lines = []
for entry in new_transcript:
label = "You" if entry["spk"] == "me" else "Them"
lines.append(f"{label}: {entry['text']}")
transcript_text = "\n".join(lines)
return f"""Analyze this meeting segment:
Full context summary: {running_summary}
New transcript since last analysis:
{transcript_text}
Provide:
1. Discussion trajectory - where is this heading?
2. 3 questions/objections the other party might raise next
3. Recommended talking points for each
4. Any risks or opportunities you notice
Be concise and actionable."""
def build_summary_prompt(self, previous_summary: str, new_transcript: list[dict]) -> str:
lines = []
for entry in new_transcript:
label = "You" if entry["spk"] == "me" else "Them"
lines.append(f"{label}: {entry['text']}")
transcript_text = "\n".join(lines)
return f"""Update this meeting summary with new content.
Previous summary: {previous_summary if previous_summary else "(meeting just started)"}
New transcript:
{transcript_text}
Write a concise updated summary (3-5 sentences) covering all key points discussed so far."""
async def analyze(self, running_summary: str, new_transcript: list[dict]) -> str:
prompt = self.build_prompt(running_summary, new_transcript)
message = await self.client.messages.create(
model=self.model,
max_tokens=500,
messages=[{"role": "user", "content": prompt}],
)
return message.content[0].text
async def summarize(self, previous_summary: str, new_transcript: list[dict]) -> str:
prompt = self.build_summary_prompt(previous_summary, new_transcript)
message = await self.client.messages.create(
model=self.model,
max_tokens=200,
messages=[{"role": "user", "content": prompt}],
)
return message.content[0].text
```
Create `sidecar/tests/test_deep.py`:
```python
import pytest
from unittest.mock import AsyncMock, MagicMock, patch
from llm.deep import DeepAnalyzer
class TestDeepAnalyzer:
def test_build_prompt(self):
analyzer = DeepAnalyzer(api_key="fake-key")
prompt = analyzer.build_prompt(
running_summary="Discussing Q2 budget cuts.",
new_transcript=[
{"spk": "them", "text": "We need to cut 20%."},
{"spk": "me", "text": "That's aggressive."},
],
)
assert "trajectory" in prompt.lower() or "heading" in prompt.lower()
assert "questions" in prompt.lower() or "objections" in prompt.lower()
assert "cut 20%" in prompt
assert "Q2 budget" in prompt
def test_build_summary_prompt(self):
analyzer = DeepAnalyzer(api_key="fake-key")
prompt = analyzer.build_summary_prompt(
previous_summary="Discussed hiring plans.",
new_transcript=[
{"spk": "them", "text": "Let's also talk about budget."},
],
)
assert "hiring plans" in prompt.lower()
assert "budget" in prompt.lower()
@pytest.mark.anyio
async def test_analyze_with_mock(self):
analyzer = DeepAnalyzer(api_key="fake-key")
mock_message = MagicMock()
mock_message.content = [MagicMock(text="1. Discussion heading toward budget cuts.\n2. They may ask about headcount.\n3. Prepare ROI data.")]
mock_client = MagicMock()
mock_client.messages = MagicMock()
mock_client.messages.create = AsyncMock(return_value=mock_message)
with patch.object(analyzer, "client", mock_client):
result = await analyzer.analyze(
running_summary="Q2 planning.",
new_transcript=[{"spk": "them", "text": "Cut costs."}],
)
assert isinstance(result, str)
assert len(result) > 0
@pytest.mark.anyio
async def test_summarize_with_mock(self):
analyzer = DeepAnalyzer(api_key="fake-key")
mock_message = MagicMock()
mock_message.content = [MagicMock(text="Discussed Q2 budget. Agreed to 15% cuts.")]
mock_client = MagicMock()
mock_client.messages = MagicMock()
mock_client.messages.create = AsyncMock(return_value=mock_message)
with patch.object(analyzer, "client", mock_client):
result = await analyzer.summarize(
previous_summary="",
new_transcript=[
{"spk": "them", "text": "Cut 15%."},
{"spk": "me", "text": "Agreed."},
],
)
assert isinstance(result, str)
assert len(result) > 0
```
**Steps:**
1. READ `sidecar/pyproject.toml` first, then add `"anthropic>=0.42"` to the dependencies list
2. Create the implementation and test files
3. Run `cd /Users/chris/projects/voiceScript/sidecar && uv sync --all-extras`
4. Run `uv run pytest tests/test_deep.py -v`
5. All 4 tests should PASS
6. Run full suite to check regressions: `uv run pytest tests/ -v --timeout=120`
7. Commit: `git add sidecar/llm/deep.py sidecar/tests/test_deep.py sidecar/pyproject.toml && git commit -m "feat: add Claude deep analyzer for strategic insights + predicted questions"`
Working directory: `/Users/chris/projects/voiceScript`
**IMPORTANT:** Preserve ALL existing pyproject.toml content when adding the new dependency. | 100% | subagents |
| Design a comprehensive anti-hallucination / cross-validation module for a Claude Code + Ollama + Windmill infrastructure. This is an architectural design task — produce a detailed, implementable plan.
## Context
The user has the following infrastructure:
- **Claude Code CLI** with Continuous Claude (32 agents, 109 skills, 30 hooks)
- **Ollama** on a remote PC (100.76.181.84:11434) with qwen3:14b and qwen3.5:27b
- **Windmill** workflow engine (localhost:8000) with PostgreSQL
- **MacBook** (100.121.64.48) as a lightweight service node with Windmill Worker
- **Memory system** with PostgreSQL + BGE embeddings for storing/recalling learnings
- **Hook architecture** supporting PreToolUse, PostToolUse, UserPromptSubmit, SessionStart, Stop events
## Available Tools (from research)
### Hallucination Detection Models:
1. **Bespoke-MiniCheck** (7B) — Available on Ollama (`ollama run bespoke-minicheck`), 77.4% F1, ~200ms. Non-commercial license.
2. **Vectara HHEM 2.1** — <600MB, runs on CPU, best-in-class F1, Apache 2.0
3. **LettuceDetect** — Token-level detection, ModernBERT-based, MIT, 79.2% F1
4. **Claude Citations API** — Built-in, 15% recall boost, standard pricing
### Existing Patterns to Reuse:
- `compiler-in-the-loop.ts` — PostToolUse hook that calls external LLM
- `memory-awareness.ts` — UserPromptSubmit hook that injects context
- `import-validator.ts` — PostToolUse validation with additionalContext
- `convomind/llm_client.py` — CircuitBreaker + SQLite cache + Ollama client
- `inforadar/llm.py` — Clean async Ollama client
- `embedding_service.py:418` — OllamaEmbeddingProvider
- `recall_learnings.py` / `store_learning.py` — Memory store/recall with dedup
## Design Requirements
1. **Accuracy first** — minimize false negatives (missed hallucinations)
2. **Opt-in per program** — each program/script can decide whether to use verification
3. **Economic** — prefer local models (Ollama, CPU models) over API calls
4. **Multi-layer** — different verification depth for different situations
5. **Integrate with existing infrastructure** — hooks, skills, Windmill, memory system
6. **Support both sync (inline) and async (background) verification**
## Architecture to Design
Design a module called `veritas` (or similar) with these layers:
### Layer 1: Prompt Engineering (always on, free)
- System prompt patterns that reduce hallucination
- "Permit uncertainty" and "cite sources" instructions
- Already partially exists in `claim-verification.md` rule
### Layer 2: Self-Consistency Check (local, cheap)
- Use Ollama qwen3:14b for quick cross-examination
- Generate a response, then ask a second model/prompt to verify key claims
- ~2-5 seconds overhead
### Layer 3: Dedicated Verification Models (local, accurate)
- Bespoke-MiniCheck on Ollama for claim-level fact checking
- Vectara HHEM 2.1 on CPU for NLI-based consistency scoring
- ~1-3 seconds overhead per claim
### Layer 4: Claude Citations API (for document-grounded tasks)
- When working with source documents, use Citations API
- Highest accuracy but costs tokens
### Integration Points:
1. **PostToolUse hook** — verify factual claims in tool outputs
2. **`/verify` skill** — on-demand verification of any text
3. **Windmill async job** — batch verification of documents/outputs
4. **Memory integration** — store verified/refuted facts for future recall
5. **Python SDK** — `from veritas import verify(text, context)` for any program
### Deployment:
- Core library: Python package at `~/tools/veritas/`
- Hook: TypeScript at `~/.claude/hooks/src/veritas-hook.ts`
- Skill: `~/.claude/skills/verify/SKILL.md`
- Windmill script: verification workflow
- Ollama model: bespoke-minicheck pre-pulled on PC
- HHEM model: pre-downloaded on MacBook (CPU inference)
## Deliverables
Produce a detailed architecture document covering:
1. System overview with ASCII diagram
2. Component specifications (each layer)
3. API design (Python SDK interface)
4. Integration specifications (hooks, skills, Windmill)
5. Deployment plan (what goes where)
6. Cost/performance analysis
7. Implementation order (what to build first)
Consider the HaluGate pattern (conditional routing — skip verification for creative/coding queries, full verification for factual queries) to save compute.
Think deeply about edge cases:
- What happens when Ollama PC is offline?
- How to handle verification timeout?
- How to avoid infinite verification loops?
- How to handle conflicting verification results?
- Cache strategy for repeated verifications? | 100% | subagents |
| You are fixing a critical issue: FTS5's default unicode61 tokenizer does not segment Chinese text into words, making Chinese BM25 search non-functional.
## The Problem
SQLite FTS5's `unicode61` tokenizer splits text by whitespace/punctuation. Chinese has no spaces between words, so "推荐用FastAPI写代码" becomes one giant token instead of ["推荐", "用", "FastAPI", "写", "代码"]. BM25 search for "FastAPI" works (it's surrounded by non-ASCII), but searching for "推荐" fails.
## The Solution
Use jieba for Chinese word segmentation. Register a custom SQLite function that segments text before FTS insertion and search.
### Step 1: Add jieba dependency
```bash
uv add jieba
```
### Step 2: Create tokenizer module
**src/wechatsync/db/tokenizer.py**:
```python
import jieba
import re
def segment_for_fts(text: str) -> str:
"""Segment Chinese text with jieba for FTS5 indexing.
Inserts spaces between Chinese words while preserving
non-Chinese tokens (English words, numbers, URLs).
"""
if not text:
return ""
# jieba.cut handles mixed Chinese/English well
words = jieba.cut(text, cut_all=False)
return " ".join(w.strip() for w in words if w.strip())
```
### Step 3: Register in SQLite connections
Modify **src/wechatsync/db/sqlite.py**:
- In both `init_db()` and `get_connection()`, after connecting:
```python
from wechatsync.db.tokenizer import segment_for_fts
conn.create_function("segment", 1, segment_for_fts)
```
### Step 4: Modify FTS triggers
In the SCHEMA DDL in sqlite.py, change the AFTER INSERT triggers to segment content:
```sql
-- Old:
CREATE TRIGGER IF NOT EXISTS messages_ai AFTER INSERT ON messages BEGIN
INSERT INTO messages_fts(rowid, content, sender_name)
VALUES (new.id, new.content, new.sender_name);
END;
-- New:
CREATE TRIGGER IF NOT EXISTS messages_ai AFTER INSERT ON messages BEGIN
INSERT INTO messages_fts(rowid, content, sender_name)
VALUES (new.id, segment(new.content), new.sender_name);
END;
-- Same for knowledge_fts trigger:
CREATE TRIGGER IF NOT EXISTS knowledge_ai AFTER INSERT ON knowledge_items BEGIN
INSERT INTO knowledge_fts(rowid, title, summary, tags)
VALUES (new.id, segment(new.title), segment(new.summary), new.tags);
END;
```
### Step 5: Segment search queries
Modify **src/wechatsync/search/engine.py** `bm25_search()`:
- Before passing query to FTS MATCH, segment it:
```python
from wechatsync.db.tokenizer import segment_for_fts
segmented_query = segment_for_fts(query)
```
- Use segmented_query in the MATCH clause
### Step 6: Write tests
**tests/test_tokenizer.py**:
- test_segment_chinese: "推荐用Cursor写代码" → segments with spaces, both "推荐" and "Cursor" are separate tokens
- test_segment_english: "FastAPI is great" → stays mostly the same
- test_segment_mixed: "张三推荐的Python框架" → Chinese words separated, "Python" preserved
- test_segment_empty: "" → ""
- test_segment_url: "看这个 https://example.com" → URL preserved
**tests/test_chinese_search.py**:
- test_chinese_fts_search: Insert Chinese message, search with Chinese keyword, verify found
- test_chinese_knowledge_search: Insert Chinese knowledge item, search with Chinese keyword, verify found
- test_mixed_language_search: Insert mixed Chinese/English, search in either language works
### Step 7: Verify existing tests still pass
Run full test suite: `uv run pytest tests/ -v`
### Step 8: Commit
```bash
git add -A && git commit -m "fix: add jieba Chinese tokenization for FTS5 search"
```
## Context
Project at /Users/chris/projects/weChat微信自动化/. 236 tests passing. Key files:
- src/wechatsync/db/sqlite.py — schema DDL + init_db/get_connection
- src/wechatsync/search/engine.py — bm25_search function
IMPORTANT: The trigger change means existing tests that create DBs will now need the segment function registered. Make sure init_db registers it. All test fixtures use init_db so they should get it automatically.
NOTE: jieba prints "Building prefix dict from the default dictionary..." on first use. You can suppress this with `jieba.setLogLevel(logging.WARNING)` in the tokenizer module.
Work from: /Users/chris/projects/weChat微信自动化/ | 100% | subagents |
| You are a top-tier LLM/SLM infrastructure researcher. Do comprehensive web research on the current state of Small Language Models (SLMs) for local/edge deployment in 2026. This is RESEARCH ONLY — do not write any code.
Search for and compile findings on:
1. **Top SLM models in 2026** (1B-10B parameters range):
- Qwen 3.5 variants (we already have qwen3.5:35b-a3b, qwen3.5:9b, qwen3.5:27b on Ollama)
- Phi-4/Phi-4-mini (Microsoft)
- Gemma 3 (Google)
- Llama 4 Scout/Maverick (Meta)
- SmolLM2 (Hugging Face)
- Any other notable SLMs released in 2025-2026
- Compare: quality, speed, VRAM usage, best use cases
2. **SLM routing/orchestration frameworks**:
- LLM routers (RouteLLM, Martian, etc.)
- When to use big model vs small model (cost/quality routing)
- Semantic Router, LiteLLM proxy, anything that helps route between local SLM and cloud API
- Model cascading patterns (try small first, escalate to big)
3. **Edge/local deployment patterns**:
- Ollama latest capabilities (tool calling, structured output, vision)
- vLLM for local serving
- llama.cpp / llama-cpp-python advances
- Quantization best practices (GGUF Q4/Q5/Q8, AWQ, GPTQ)
- Speculative decoding with small+large model pairs
4. **Practical SLM use cases that work well**:
- Text classification/routing
- Summarization
- Code completion (local)
- Embedding generation
- Structured data extraction (JSON mode)
- Tool calling / function calling
- RAG query rewriting
- What does NOT work well with SLMs (complex reasoning, long context, etc.)
5. **Industry patterns for hybrid local+cloud architectures**:
- Privacy-first routing (sensitive data → local, rest → cloud)
- Cost optimization (80% local, 20% cloud for hard queries)
- Latency optimization patterns
- Fallback/cascade architectures
Please provide detailed findings with specific model names, framework names, and links where possible. Focus on what's practical and production-ready, not just research papers. | 100% | subagents |
| Research the current working career page APIs for Netflix and Meta as of March 2026.
## Netflix
- The old Workday URL `https://netflix.wd1.myworkdayjobs.com/wday/cxs/netflix/jobs/jobs` returns 404
- Search the web for Netflix's current career page: jobs.netflix.com or similar
- Find the actual API endpoint or data source that powers their job search
- Test different URL patterns like:
- https://jobs.netflix.com/api/search
- https://explore.jobs.netflix.net/api/apply/v2/jobs
- Netflix might use a custom platform now, not Workday
- I need: endpoint URL, request method, parameters for searching "software engineer" jobs
## Meta
- metacareers.com blocks all non-browser HTTP requests with 400
- Look for alternative approaches that DON'T require Playwright:
- Does Meta have a public job API?
- Can we use the Facebook Graph API for job listings?
- Is there a jobs RSS feed?
- Can we scrape the server-rendered HTML with the right headers/cookies?
- Check if `www.metacareers.com/jobs?q=software+engineer` works with specific headers
- Try: curl with full browser headers including sec-fetch-site, sec-fetch-mode etc.
- Check if there's embedded JSON in the initial HTML response (like __RELAY_STORE__)
For both, I need the working endpoint, request format, and response structure. | 100% | subagents |
| Audit network exposure and authentication for the user's local services. Check:
1. **Listening ports** - run `lsof -i -P -n | grep LISTEN` to see what's listening and on what interfaces
2. **Firewall status** - check macOS firewall: `defaults read /Library/Preferences/com.apple.alf globalstate` or `/usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate`
3. **Tailscale status** - run `tailscale status` to check network isolation
4. **Service authentication**:
- Check Windmill docker-compose.yml for auth config
- Check Dashboard for auth/authentication mechanisms
- Check if any services have rate limiting disabled for localhost
- Check LibreChat auth config
5. **Docker port exposure** - check all running Docker containers and their port mappings: `docker ps --format "{{.Names}}\t{{.Ports}}"`
6. **SSH config** - check `~/.ssh/sshd_config` or system sshd_config for what address SSH listens on
Report:
- Services accessible from LAN (not just Tailscale)
- Services with no authentication
- Any rate limiting gaps
DO NOT modify any files. Research only. | 100% | subagents |
| Explore the claudeAutomation project to understand what existing infrastructure could support a desktop agent system. Look for:
1. **Skills system** - how are skills currently structured in ~/.claude/skills/ or continuous-claude?
2. **LLM Router** - how does llm-router/ work for routing to different models?
3. **Browser automation** - any existing browser scripts or patterns in docs/
4. **MCP servers** - what MCP integrations exist?
5. **Dashboard** - how does the dashboard work for task execution?
6. **Maintenance agent** - how does the maintenance agent orchestrate tasks?
7. **Any existing automation scripts** in scripts/ that do file manipulation, image processing, etc.
Focus on: what building blocks already exist that could be reused for a local desktop agent.
Search in:
- /Users/chris/projects/claudeAutomation/
- /Users/chris/.claude/
- /Users/chris/projects/claudeAutomation/docs/
- /Users/chris/projects/claudeAutomation/llm-router/
- /Users/chris/projects/claudeAutomation/dashboard/ | 100% | subagents |
| Audit all service configurations in ~/projects/claudeAutomation/ and ~/tools/ for port binding security. Check:
1. Docker compose files - are ports mapped to 0.0.0.0 or 127.0.0.1?
2. Any Python/Node servers - what address do they bind to?
3. Dashboard, MCP Permission, Infra Daemon configs
Search for:
- `docker-compose.yml` or `compose.yaml` files in ~/tools/windmill/, ~/tools/librechat/, ~/tools/continuous-claude/
- Port binding patterns: `0.0.0.0`, `bind`, `host`, `listen` in config files
- Python server configs with `host=` parameters
- Any `gateway.bind`, `server.host` type configs
For each service found, report:
- Service name
- Port
- Bind address (0.0.0.0 vs 127.0.0.1 vs other)
- Whether it's behind Tailscale or exposed to LAN
DO NOT modify any files. Research only. | 100% | subagents |
| I need to understand the current infrastructure for a "maintenance window" feature. Explore these areas in /Users/chris/projects/claudeAutomation/:
1. **infra-daemon/** — What does it currently do? What's in daemon.py, config.yaml, jobs/? What scheduling exists?
2. **LaunchAgents** — What launchd services exist at /Users/chris/Library/LaunchAgents/com.claude.* ?
3. **Session detection** — How could we detect if Claude Code is currently active? Check ~/.claude/ for session files, heartbeat mechanisms, or running processes.
4. **Existing automation** — Any scripts in scripts/ that do maintenance/health checks?
5. **Windmill** — Any existing scheduled tasks at ~/tools/windmill/?
Report a summary of what exists and what hooks are available for autonomous maintenance. | 100% | subagents |
| Research Cline (VS Code AI coding agent extension) session/chat history file format. I need:
1. Where Cline stores its session history files (likely in VS Code's extension storage)
2. File format (JSON, JSONL, SQLite, other?)
3. How user messages are distinguished from AI responses
4. Any metadata (timestamps, model, task IDs)
Search strategies:
- Check common VS Code extension storage paths: ~/.vscode/extensions/, ~/Library/Application Support/Code/
- Look for cline-related directories or files
- Search for "cline vscode session history" or "cline chat log format"
- Cline was previously called "Claude Dev" - check both names
- The extension stores task history locally
Return: file location, format details, parsing strategy, and any example content you can find. | 100% | subagents |