Commit Graph

252 Commits

Author SHA1 Message Date
Tobi Lütke
de3a83a553
refactor: remove OR operator from lex queries
Simplify to just: terms, "phrases", and -negation
2026-02-18 22:17:52 -05:00
Tobi Lütke
77e4d8f378
refactor: remove single collection param, use collections array only
BREAKING: collection param removed from structured_search.
Use collections: ['name'] for single collection filter.
2026-02-18 22:16:15 -05:00
Tobi Lütke
efb39616e6
feat(lex): add query syntax for exact phrases, negation, and OR
Lex queries now support:
- "exact phrase" - quoted exact matching (no prefix)
- -term or -"phrase" - exclude from results
- term1 OR term2 - match either term

Semantic queries (vec/hyde) validate and reject these operators
with helpful error messages.

Examples:
  performance -sports     → matches "performance" excluding "sports"
  "machine learning"      → exact phrase match
  auth OR authentication  → matches either term
2026-02-18 22:14:09 -05:00
Tobi Lütke
d1ec31eab8
feat: add collections array filter + improve query writing docs
- structured_search now accepts collections[] for OR filtering
- Updated skill docs with detailed query writing guidance
- lex: 2-5 keywords, include synonyms, exact names
- vec: full natural language questions with context
- hyde: 50-100 word hypothetical answer passages
2026-02-18 22:09:24 -05:00
Tobi Lütke
6d6bdff09c
docs: simplify skill documentation 2026-02-18 22:00:24 -05:00
Tobi Lütke
19284ddb80
refactor(mcp): remove deprecated search tools, keep only structured_search
BREAKING CHANGE: MCP tools search, vector_search, deep_search removed.
Use structured_search with lex/vec/hyde queries instead.

- Remove search, vector_search, deep_search MCP tool registrations
- Update MCP instructions to focus on structured_search
- Update skill docs to reflect simplified API
- Rename test describes to reflect they test store functions
- CLI commands (qmd search, vsearch, query) unchanged for backwards compat
2026-02-18 21:50:25 -05:00
Tobi Lütke
db44e1a5bc
test: add comprehensive tests for structured search
32 tests covering:
- parseStructuredQuery parser (24 tests)
  - plain queries returning null
  - single/multiple prefixed queries
  - mixed plain + prefixed lines
  - error on multiple plain lines
  - whitespace handling
  - edge cases (colons in text, etc.)
- StructuredSubSearch type validation (3 tests)
- structuredSearch function basics (5 tests)
  - empty searches
  - no matches
  - limit/minScore options
2026-02-18 21:39:40 -05:00
Tobias Lütke
222dde153d
Merge pull request #220 from tobi/feat/structured-search
feat: add structured_search for LLM-provided query expansions
2026-02-18 22:36:20 -04:00
Tobi Lütke
8ebe5ab31b
feat(cli): add structured query syntax to qmd query
Lines prefixed with lex:, vec:, or hyde: route directly to
structured search, skipping automatic query expansion.

Examples:
  qmd query 'lex: CAP theorem'
  qmd query $'lex: keywords\nvec: natural language question'
  qmd query $'lex: terms\nvec: question\nhyde: hypothetical answer...'

Plain queries (single line, no prefix) still use automatic expansion.
Multiple plain lines without prefixes error with helpful message.

This lets CLI users leverage the same structured search as MCP,
useful when piping from scripts or when you know exactly what
query variations you want.
2026-02-18 19:58:41 -05:00
Tobi Lütke
bdec84a3e9
docs: use npm package name, clarify vec/hyde both use vector similarity 2026-02-18 19:34:08 -05:00
Tobi Lütke
0201710c2b
feat: add structured_search for LLM-provided query expansions
- New MCP tool: structured_search - lets capable LLMs provide their own
  lex/vec/hyde query variations instead of using local expansion model
- New REST endpoint: POST /search - same functionality without MCP protocol
- Updated skill docs to prioritize structured_search for LLM callers
- Added installation instructions for Claude Code, Desktop, and OpenClaw

Pipeline: lex→FTS, vec/hyde→batch embed, RRF fusion (first query 2x weight),
chunk + rerank, position-aware blending, dedup.

This is the recommended endpoint for capable LLMs - they generate better
query variations than the small local model, especially for domain-specific
or nuanced queries.
2026-02-18 19:05:49 -05:00
Tobi Lutke
648779a04d
fix(test): reset currentIndexName between test files
collections-config.test.ts set currentIndexName to "myindex" in its
last test but only restored env vars in afterEach — not the module
variable. Under bun test (single process), this leaked into mcp.test.ts,
causing it to look for myindex.yml instead of index.yml.

Fix: reset setConfigIndexName("index") in afterEach, and add defensive
reset in mcp.test.ts beforeAll.
2026-02-18 15:53:58 -04:00
Tobi Lutke
0697bc59d6
release: v1.0.7 2026-02-18 15:36:54 -04:00
Tobi Lutke
8cddbcb247
changelog: write 1.0.7 unreleased notes
LFM2 query expansion model, multiple collection filters,
XDG_CONFIG_HOME support, and JSON output fixes.
2026-02-18 15:36:31 -04:00
Tobias Lütke
4950f423cd
Merge pull request #200 from vincentkoc/vincentkoc-code/fix-cli-add-message 2026-02-18 08:43:15 -04:00
Tobias Lütke
e3b56959e3
Merge pull request #201 from vincentkoc/vincentkoc-code/chore-remove-no-lex-option 2026-02-18 08:42:57 -04:00
Tobias Lütke
67e2aab18c
Merge pull request #206 from tobi/liquidai-query-expansion 2026-02-18 08:42:01 -04:00
Tobias Lütke
b142be8cdc
Merge pull request #205 from tobi/mate/dataset-v3-improvements 2026-02-18 08:41:36 -04:00
Tobias Lütke
1a67e1a093
Merge pull request #208 from tobi/fix/json-output-and-index-paths 2026-02-17 20:27:49 -04:00
Tobi Lütke
1007b46fcc
fix: return empty JSON array when no search results with --json flag
Previously, 'qmd search --json' would output plain text 'No results found.'
when no matches were found, which is invalid JSON. Now it correctly outputs
an empty JSON array [] when using --json format.

Fixed in all search commands: search, vsearch, and query.
2026-02-17 10:46:31 -05:00
Tobi Lütke
00bcfbbd34
fix: resolve relative paths in --index flag to prevent malformed config paths
When using --index with relative paths like './index/my-project', the path was
stored directly as the config filename, resulting in paths like:
/home/user/.config/qmd/./index/my-project.yml

This caused 'no such file or directory' errors. Now relative paths are resolved
and normalized by replacing path separators with underscores.
2026-02-17 10:46:31 -05:00
Tobi Lütke
48f0917269
feat(finetune): hyde-first ordering, relative paths, structured format
Dataset improvements:
- Reorder output to put hyde first for better retrieval priming
- Convert absolute paths to relative paths in scripts
- Add convert_to_structured.py for structured data format
- Add qmd_expansion_v3_structured.jsonl with type/query objects
- Update schema.py with reorder_hyde_first() helper
- Verify data now validates hyde-first ordering

Training data regenerated with new ordering (100% validation success).
2026-02-17 06:31:35 -05:00
Tobi Lütke
57f7caa93b
feat: add LiquidAI LFM2 support for query expansion
Add training configuration and documentation for using LiquidAI's LFM2-1.2B
as an alternative base model for query expansion fine-tuning.

LFM2 benefits:
- 2x faster decode/prefill vs standard transformers
- Optimized for edge/on-device inference
- Good at agentic tasks, RAG, and data extraction

Changes:
- Add configs/sft_lfm2.yaml with LFM2-specific LoRA target modules
- Add jobs/sft_lfm2.py for HuggingFace Jobs training
- Update llm.ts with LFM2 GGUF model URIs
- Add documentation for LFM2 training workflow

LFM2 uses a hybrid architecture (convolutions + attention) requiring
different LoRA targets: q_proj, k_proj, v_proj, out_proj, in_proj, w1, w2, w3
2026-02-17 06:20:57 -05:00
Tobi Lütke
a282ce7a26
feat(finetune): improve query expansion dataset v3
Dataset improvements:
- fix_hyde.py: Replace generic template hyde entries with query-specific ones
  using GPT-4o-mini (removed 'comprehensive guide covers everything' pattern)
- fix_lex_filler.py: Remove filler words (overview, tutorial, guide, examples,
  documentation, best practices) that were padding rather than genuine search intent
- qmd_expansion_v3.jsonl: Improved dataset with 1,498 high-quality entries

Training data preparation:
- convert_to_chatml.py: Convert to ChatML format for LFM2.5 training
- verify_data.py: Validation script to ensure data quality
- train-lfm2/: Ready-to-use training data (90/10 train/val split)

Data quality metrics:
- 100% success rate (all entries properly formatted)
- Query length: 6-65 chars (avg: 29.3)
- Response length: 307-777 chars (avg: 539.5)
- All entries contain lex, vec, and hyde expansions
2026-02-17 06:19:59 -05:00
Vincent Koc
7fee9f904b chore(cli): remove unused no-lex flag from argument parser 2026-02-16 20:55:29 -08:00
Vincent Koc
e9b30bb821 fix(cli): use collection add command in empty collection hints 2026-02-16 20:51:54 -08:00
Tobi Lutke
640ac13cd0
fix: support multiple -c collection filters in search commands
Closes #191 (thanks @openclaw)
2026-02-16 14:03:53 -04:00
Tobi Lutke
8c2282c979
fix: respect XDG_CONFIG_HOME in collection config path
Closes #190 (thanks @openclaw)
2026-02-16 14:03:49 -04:00
Tobi Lutke
1781e7bf61
fix: pre-push hook writes to stderr, no interactive prompts
Git hooks can't rely on tty access. Remove all interactive
prompting — just validate and exit non-zero on failure.
2026-02-16 11:53:52 -04:00
Tobi Lutke
51c03d9445
release: v1.0.6 2026-02-16 09:08:34 -04:00
Tobi Lutke
63f3b68559
feat: show models in status, improve pre-push hook
- Move model info from --help to `qmd status` with live HuggingFace
  links derived from actual configured URIs
- Pre-push hook: handle non-interactive shells gracefully, resolve
  annotated tags correctly for CI checks
2026-02-16 09:08:28 -04:00
Tobi Lutke
8dd6cdcebf
fix: hide bun:sqlite import from tsc on Node.js builds
Concatenate the module specifier at runtime ('bun:' + 'sqlite') so tsc
doesn't try to resolve it during compilation on Node.js CI runners.
2026-02-16 08:56:02 -04:00
Tobi Lutke
6d399bc50a
release: v1.0.5 2026-02-16 08:47:23 -04:00
Tobi Lutke
e39848c030
chore: gitignore .claude/ 2026-02-16 08:47:20 -04:00
Tobi Lutke
614c8d6328
docs: write changelog for v1.0.5
Build now ships compiled JS, new release skill and tooling.
2026-02-16 08:46:46 -04:00
Tobi Lutke
7fb69a5ca2
feat: release skill with changelog-driven workflow and git hooks
- Add /release skill with full process: hook install, changelog
  validation, git history review, preview, and release execution
- Skill auto-populates [Unreleased] from git history when empty
- Install hook script symlinks pre-push for tag validation
- Register skills/ dir in .pi/settings.json for pi discovery
2026-02-16 08:46:10 -04:00
Tobi Lutke
09803a75b7
feat: compile to JS for npm, release system, full changelog
- Add tsc build step (tsconfig.build.json) so npm package ships
  compiled JS instead of raw TypeScript requiring tsx at runtime
- Update qmd wrapper and daemon spawn to use dist/qmd.js in
  production while keeping tsx for development
- Add self-installing pre-push hook validating v* tag pushes:
  package.json version match, changelog entry, CI status
- Add release.sh script that renames [Unreleased] to versioned
  entry, bumps package.json, commits, and tags
- Add extract-changelog.sh for cumulative GitHub release notes
- Update publish workflow with build step and GitHub release creation
- Flesh out CHANGELOG.md with full history from 0.1.0 through 1.0.0
  in Keep-a-Changelog format with PR/contributor attributions
- Add release standards and changelog guidelines to CLAUDE.md
2026-02-16 08:42:32 -04:00
Tobi Lutke
77c6eba159
fix: publish workflow bun test timeout and npm auth 2026-02-15 23:02:33 -04:00
Tobias Lütke
7acba1c451
Merge pull request #178 from tobi/release/v1.0.0
Release v1.0.0
2026-02-15 22:59:04 -04:00
Tobi Lutke
2780dfb5d0
fix: increase bun test timeout to 30s via CLI flag
The default 5s timeout is too short for CLI subprocess tests in CI.
2026-02-15 21:59:18 -04:00
Tobi Lutke
93f277c5e3
fix: MCP session support and cross-runtime test compat
- mcp.ts: add sessionIdGenerator to HTTP transport (fixes "stateless
  transport cannot be reused" error in CI)
- test-preload.ts: set 30s default timeout for bun test runner (matches
  vitest config, prevents CLI subprocess test timeouts)
- mcp.test.ts: use == null check instead of toBeUndefined for SQLite
  get() result (bun:sqlite returns null, better-sqlite3 returns undefined)
2026-02-15 21:54:25 -04:00
Tobi Lutke
edc9a87234
fix: correct test paths after moving to test/ directory
- cli.test.ts: fix qmdScript path from <root>/qmd.ts to <root>/src/qmd.ts
  (broke when tests moved from src/integration/ to test/)
- mcp.test.ts: forward Mcp-Session-Id header per MCP Streamable HTTP spec
2026-02-15 21:46:45 -04:00
Tobi Lutke
870d3aed3b
test: move all tests to flat test/ directory
No more src/models/ and src/integration/ subfolders to forget about.
All 9 test files live in test/, one command runs everything:

  npx vitest run test/
  bun test test/
2026-02-15 21:37:47 -04:00
Tobi Lutke
dcedfb5268
feat: cross-runtime SQLite compat layer (bun:sqlite + better-sqlite3)
Add src/db.ts that dynamically imports bun:sqlite under Bun and
better-sqlite3 under Node.js. Exports openDatabase(), loadSqliteVec(),
and a shared Database interface.

- sqlite-vec loading is now optional — FTS works without it, vector
  ops throw a clear error if unavailable
- CI tests both runtimes: Node 22/23 via vitest, Bun via bun test
- All 104 unit tests pass on both Node and Bun
2026-02-15 17:15:47 -04:00
Tobi Lutke
c685f7ac71
ci: switch from bun test to vitest on Node.js
All test files now use vitest + better-sqlite3 imports.
bun test can't load the better-sqlite3 native addon (symbol
error on Linux, segfault on macOS). Run vitest on Node 22/23.
2026-02-15 17:04:58 -04:00
Tobi Lutke
dc64166a2a
release: v1.0.0
Node.js compatibility, parallel embedding/reranking, flash attention,
GPU auto-detection, and restructured test suite.
2026-02-15 17:02:00 -04:00
Tobi Lutke
294fc76d9f
Merge remote-tracking branch 'origin/nodejs' 2026-02-15 16:58:48 -04:00
Tobi Lutke
9b89a51d10
test: split integration/model suites
Split test suites for explicit runtime execution.

- Move model-related tests under `src/models/*`.
- Move CLI/integration tests under `src/integration/*`.
- Add `src/store.helpers.unit.test.ts` for helper unit coverage.
- Add shared Vitest config with default timeout and suite organization.
- Remove legacy flat test files from `src/` root.
- Keep core test commands in scripts supporting unit/models/integration runs.
2026-02-15 16:57:13 -04:00
Tobi Lutke
4df5505bd6
Merge origin/nodejs: Node.js compat, perf improvements, vitest
Brings in Node.js compatibility (tsx, vitest), GPU auto-detection,
parallel embedding/reranking contexts, and flash attention support.
Preserves @tobilu/qmd package scope and publish config from main.
2026-02-15 16:52:30 -04:00
Tobi Lutke
b88c10bf83
docs: show bun/node install and package scope
Document both Node and Bun execution paths.
- Update install examples to `@tobilu/qmd` for npm and bun.
- Add npx/bunx one-off usage examples.
- Reflect Bun as first-class supported runtime in requirements.
2026-02-15 16:45:35 -04:00