Appearance
Search API (Hybrid) ​
Coleo exposes two search surfaces:
- General hybrid search — SQLite FTS (keyword) + Qdrant (semantic) over tasks, bugs, arms, and indexed docs.
- Status history search — Qdrant semantic search over arm status reports / completions with keyword boost and filters.
General hybrid search ​
POST /api/search
json
{
"query": "authentication issues",
"types": ["task", "bug"],
"limit": 20,
"offset": 0,
"minScore": 0.1,
"keywordWeight": 0.5,
"semanticWeight": 0.5,
"filters": { "priority": "high" }
}Response includes per-result keywordScore, semanticScore, and combined score.
If Qdrant/embeddings fail, search degrades to keyword-only (semanticUsed: false).
Related:
| Method | Path | Purpose |
|---|---|---|
| GET | /api/search/suggestions?q= | Title suggestions |
| POST | /api/search/index | Upsert document into the project's Qdrant search-index-<projectKey> collection |
Implementation: src/api/routes/search.ts
Tests: src/api/routes/__tests__/search.test.ts
Status history hybrid search ​
POST /api/status-history/search
json
{
"query": "problems with database migrations",
"filters": {
"arm_ids": ["arm-alpha"],
"event_types": ["status_report", "task_completion"],
"from": "2026-07-01T00:00:00Z",
"to": "2026-07-10T23:59:59Z",
"task_id": "phase28g-d4c3d1",
"classification": "development"
},
"limit": 20,
"keywordWeight": 0.35,
"semanticWeight": 0.65,
"include_context": true
}Response:
json
{
"results": [
{
"event": { "id": "...", "type": "status_report", "title": "...", "content": "..." },
"score": 0.84,
"keywordScore": 0.66,
"semanticScore": 0.91,
"highlights": ["... migration ..."]
}
],
"total": 1,
"query": "problems with database migrations",
"semanticUsed": true,
"query_time_ms": 42
}| Method | Path | Purpose |
|---|---|---|
| GET | /api/status-history/stats?period=week | Collection health / point count |
| GET | /api/status-history/by-arm/:armId | Filtered list for one arm |
| POST | /api/status-history/index | Manual / backfill index |
Implementation: src/api/routes/status-history.ts
Pipeline: src/vector/indexing-pipeline.ts
Collection: status-history (see STATUS_HISTORY_CONFIG)
Weights (hybrid ranking) ​
Combined score:
score = keywordScore * keywordWeight_norm + semanticScore * semanticWeight_normWeights are normalized to sum to 1. Defaults:
- General search: 0.5 / 0.5
- Status history: 0.35 keyword / 0.65 semantic
Set semanticWeight: 0 for pure keyword; keywordWeight: 0 for pure semantic.
Verification ​
bash
bun test src/api/routes/__tests__/search.test.ts
bun test src/api/routes/__tests__/status-history.test.tsLive Qdrant + embeddings (optional):
bash
docker compose up -d qdrant
bun run test:qdrant
bun run test:embeddingRetention policy ​
Status-history points in Qdrant are purged by event type:
| Type | Default | Env override |
|---|---|---|
task_completion, task_created, discovery, bug_report | forever | COLEO_STATUS_HISTORY_RETENTION_<TYPE>=forever |
status_report, task_updated | 90 days | e.g. COLEO_STATUS_HISTORY_RETENTION_STATUS_REPORT=60 |
arm_event (heartbeats-like) | 7 days | COLEO_STATUS_HISTORY_RETENTION_ARM_EVENT=7 |
bash
# Dry-run plan
bun run retention:status-history -- --dry-run
# Apply deletes in Qdrant
bun run retention:status-historyImplementation: src/vector/retention.ts, src/scripts/status-history-retention.ts
Backfill existing status reports ​
Import rows from SQLite status_reports into the project's Qdrant status-history-<projectKey> collection (embeds via configured embedding provider):
bash
# Preview
bun run backfill:status-history -- --dry-run --limit 20
# Apply
bun run backfill:status-history
# Another project (the DB must match that project's Coleo directory)
COLEO_PROJECT_DIR=/path/to/project COLEO_DIR=/path/to/project/.coleo bun run backfill:status-historyIds are deterministic (status-report-<reportId>) so re-runs upsert safely.
Note: CLI coleo status-reports backfill imports .project/status-*.md into SQLite. bun run backfill:status-history indexes SQLite → Qdrant.
MCP tools (brain/arms) ​
Registered on the Coleo MCP server (src/mcp/server.ts):
| Tool | Backend |
|---|---|
search | POST /api/search — hybrid keyword + semantic over tasks/bugs/arms/index |
search_status_history | POST /api/status-history/search — hybrid over status history collection |
Example arm call shape (status history):
json
{
"query": "previous attempts at database migration",
"filters": {
"arm_ids": ["arm-alpha"],
"event_types": ["status_report", "task_completion"],
"days_back": 30
},
"limit": 10
}Dependencies ​
- Embeddings: embeddings.md
- Qdrant: qdrant.md
