seamless-rag 0.1.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.
- seamless_rag-0.1.0/.claude/commands/autorun.md +243 -0
- seamless_rag-0.1.0/.claude/settings.json +52 -0
- seamless_rag-0.1.0/.claude/skills/seamless-rag/SKILL.md +200 -0
- seamless_rag-0.1.0/.claude/skills/text-to-sql/SKILL.md +158 -0
- seamless_rag-0.1.0/.env.example +55 -0
- seamless_rag-0.1.0/.github/workflows/docs.yml +33 -0
- seamless_rag-0.1.0/.gitignore +35 -0
- seamless_rag-0.1.0/CLAUDE.md +177 -0
- seamless_rag-0.1.0/CONTRIBUTING.md +75 -0
- seamless_rag-0.1.0/Dockerfile +21 -0
- seamless_rag-0.1.0/JUDGES_TESTING_GUIDE.md +219 -0
- seamless_rag-0.1.0/LICENSE +201 -0
- seamless_rag-0.1.0/Makefile +65 -0
- seamless_rag-0.1.0/PKG-INFO +369 -0
- seamless_rag-0.1.0/README.md +299 -0
- seamless_rag-0.1.0/docker-compose.test.yml +15 -0
- seamless_rag-0.1.0/docker-compose.yml +33 -0
- seamless_rag-0.1.0/docs/ARCHITECTURE.md +112 -0
- seamless_rag-0.1.0/docs/BENCHMARK_REAL_DATA.md +159 -0
- seamless_rag-0.1.0/docs/CLI_TEST_REPORT.md +103 -0
- seamless_rag-0.1.0/docs/api-reference.md +190 -0
- seamless_rag-0.1.0/docs/assets/architecture.svg +89 -0
- seamless_rag-0.1.0/docs/assets/badge-mariadb.svg +23 -0
- seamless_rag-0.1.0/docs/assets/demo.gif +0 -0
- seamless_rag-0.1.0/docs/assets/demo.mp4 +0 -0
- seamless_rag-0.1.0/docs/assets/logo.svg +30 -0
- seamless_rag-0.1.0/docs/assets/mariadb-logo.svg +25 -0
- seamless_rag-0.1.0/docs/assets/toon-comparison.svg +48 -0
- seamless_rag-0.1.0/docs/contributing.md +76 -0
- seamless_rag-0.1.0/docs/getting-started.md +153 -0
- seamless_rag-0.1.0/docs/index.md +95 -0
- seamless_rag-0.1.0/docs/internal/HANDOFF.md +62 -0
- seamless_rag-0.1.0/docs/internal/JUDGES_TESTING_GUIDE.md +121 -0
- seamless_rag-0.1.0/docs/internal/SPECIFICATION.md +101 -0
- seamless_rag-0.1.0/docs/internal/TODO.md +129 -0
- seamless_rag-0.1.0/docs/judges-testing-guide.md +219 -0
- seamless_rag-0.1.0/docs/providers.md +121 -0
- seamless_rag-0.1.0/docs/toon-format.md +124 -0
- seamless_rag-0.1.0/environment.yml +9 -0
- seamless_rag-0.1.0/eval/analyze.py +62 -0
- seamless_rag-0.1.0/eval/harness.py +270 -0
- seamless_rag-0.1.0/mkdocs.yml +48 -0
- seamless_rag-0.1.0/pyproject.toml +125 -0
- seamless_rag-0.1.0/scripts/demo.py +134 -0
- seamless_rag-0.1.0/scripts/demo.tape +119 -0
- seamless_rag-0.1.0/scripts/record_demo.sh +50 -0
- seamless_rag-0.1.0/scripts/score.py +235 -0
- seamless_rag-0.1.0/src/seamless_rag/__init__.py +7 -0
- seamless_rag-0.1.0/src/seamless_rag/benchmark/__init__.py +1 -0
- seamless_rag-0.1.0/src/seamless_rag/benchmark/compare.py +63 -0
- seamless_rag-0.1.0/src/seamless_rag/cli.py +447 -0
- seamless_rag-0.1.0/src/seamless_rag/config.py +43 -0
- seamless_rag-0.1.0/src/seamless_rag/core.py +210 -0
- seamless_rag-0.1.0/src/seamless_rag/llm/__init__.py +30 -0
- seamless_rag-0.1.0/src/seamless_rag/llm/factory.py +76 -0
- seamless_rag-0.1.0/src/seamless_rag/llm/gemini.py +45 -0
- seamless_rag-0.1.0/src/seamless_rag/llm/ollama.py +57 -0
- seamless_rag-0.1.0/src/seamless_rag/llm/openai_provider.py +39 -0
- seamless_rag-0.1.0/src/seamless_rag/llm/protocol.py +26 -0
- seamless_rag-0.1.0/src/seamless_rag/pipeline/__init__.py +1 -0
- seamless_rag-0.1.0/src/seamless_rag/pipeline/embedder.py +232 -0
- seamless_rag-0.1.0/src/seamless_rag/pipeline/rag.py +181 -0
- seamless_rag-0.1.0/src/seamless_rag/pipeline/retrieval.py +142 -0
- seamless_rag-0.1.0/src/seamless_rag/providers/__init__.py +1 -0
- seamless_rag-0.1.0/src/seamless_rag/providers/factory.py +95 -0
- seamless_rag-0.1.0/src/seamless_rag/providers/gemini.py +78 -0
- seamless_rag-0.1.0/src/seamless_rag/providers/ollama.py +70 -0
- seamless_rag-0.1.0/src/seamless_rag/providers/openai_provider.py +67 -0
- seamless_rag-0.1.0/src/seamless_rag/providers/protocol.py +34 -0
- seamless_rag-0.1.0/src/seamless_rag/providers/sentence_transformers.py +29 -0
- seamless_rag-0.1.0/src/seamless_rag/storage/__init__.py +5 -0
- seamless_rag-0.1.0/src/seamless_rag/storage/mariadb.py +476 -0
- seamless_rag-0.1.0/src/seamless_rag/storage/protocol.py +65 -0
- seamless_rag-0.1.0/src/seamless_rag/toon/__init__.py +5 -0
- seamless_rag-0.1.0/src/seamless_rag/toon/encoder.py +786 -0
- seamless_rag-0.1.0/src/seamless_rag/web.py +526 -0
- seamless_rag-0.1.0/tests/__init__.py +0 -0
- seamless_rag-0.1.0/tests/conftest.py +81 -0
- seamless_rag-0.1.0/tests/eval/__init__.py +0 -0
- seamless_rag-0.1.0/tests/eval/conftest.py +18 -0
- seamless_rag-0.1.0/tests/eval/golden_datasets/rag_eval_set.json +314 -0
- seamless_rag-0.1.0/tests/eval/test_retrieval_quality.py +105 -0
- seamless_rag-0.1.0/tests/fixtures/sample_documents.json +206 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/decode/arrays-nested.json +217 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/decode/arrays-primitive.json +127 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/decode/arrays-tabular.json +85 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/decode/blank-lines.json +153 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/decode/delimiters.json +246 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/decode/indentation-errors.json +184 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/decode/numbers.json +175 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/decode/objects.json +265 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/decode/path-expansion.json +173 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/decode/primitives.json +158 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/decode/root-form.json +17 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/decode/validation-errors.json +83 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/decode/whitespace.json +61 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/encode/arrays-nested.json +105 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/encode/arrays-objects.json +158 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/encode/arrays-primitive.json +103 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/encode/arrays-tabular.json +73 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/encode/delimiters.json +253 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/encode/key-folding.json +218 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/encode/objects.json +220 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/encode/primitives.json +251 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/encode/whitespace.json +44 -0
- seamless_rag-0.1.0/tests/fixtures/toon_spec/fixtures.schema.json +117 -0
- seamless_rag-0.1.0/tests/integration/__init__.py +0 -0
- seamless_rag-0.1.0/tests/integration/conftest.py +143 -0
- seamless_rag-0.1.0/tests/integration/test_providers_e2e.py +137 -0
- seamless_rag-0.1.0/tests/integration/test_rag_end_to_end.py +61 -0
- seamless_rag-0.1.0/tests/integration/test_vector_operations.py +167 -0
- seamless_rag-0.1.0/tests/unit/__init__.py +0 -0
- seamless_rag-0.1.0/tests/unit/__snapshots__/test_toon_snapshots.ambr +43 -0
- seamless_rag-0.1.0/tests/unit/conftest.py +125 -0
- seamless_rag-0.1.0/tests/unit/test_auto_embedder.py +272 -0
- seamless_rag-0.1.0/tests/unit/test_cli.py +143 -0
- seamless_rag-0.1.0/tests/unit/test_core_facade.py +204 -0
- seamless_rag-0.1.0/tests/unit/test_embedding_provider.py +105 -0
- seamless_rag-0.1.0/tests/unit/test_llm_provider.py +215 -0
- seamless_rag-0.1.0/tests/unit/test_provider_factory.py +113 -0
- seamless_rag-0.1.0/tests/unit/test_rag_pipeline.py +92 -0
- seamless_rag-0.1.0/tests/unit/test_rag_with_llm.py +79 -0
- seamless_rag-0.1.0/tests/unit/test_token_benchmark.py +87 -0
- seamless_rag-0.1.0/tests/unit/test_toon_encoder.py +266 -0
- seamless_rag-0.1.0/tests/unit/test_toon_properties.py +175 -0
- seamless_rag-0.1.0/tests/unit/test_toon_snapshots.py +46 -0
- seamless_rag-0.1.0/tests/unit/test_toon_spec_fixtures.py +92 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# Seamless-RAG Autonomous Development Loop
|
|
2
|
+
|
|
3
|
+
You are an autonomous agent building a championship-winning RAG toolkit for the MariaDB Hackathon MY 2026. Execute this loop INDEFINITELY until the user explicitly stops you with Ctrl+C.
|
|
4
|
+
|
|
5
|
+
**NEVER stop to ask the user anything. NEVER say "shall I continue". Just keep going.**
|
|
6
|
+
|
|
7
|
+
## Startup Checklist
|
|
8
|
+
|
|
9
|
+
1. Run `conda run -n seamless-rag python -m pytest tests/unit --co -q 2>&1 | tail -3` to verify env works
|
|
10
|
+
2. Run `conda run -n seamless-rag python scripts/score.py` to see current dashboard
|
|
11
|
+
3. Read `TODO.md` for what needs doing
|
|
12
|
+
4. Read `docs/SPECIFICATION.md` for current state
|
|
13
|
+
5. Begin the main loop at Phase 1
|
|
14
|
+
|
|
15
|
+
## Main Loop (repeat forever)
|
|
16
|
+
|
|
17
|
+
### Phase 1: ASSESS — What's the next task?
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
conda run -n seamless-rag python scripts/score.py
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Read `TODO.md`. Pick the **first unchecked item** in priority order.
|
|
24
|
+
If all are checked, look for quality improvements (coverage gaps, flaky tests, missing edge cases, docs).
|
|
25
|
+
|
|
26
|
+
### Phase 2: RESEARCH — Understand before coding
|
|
27
|
+
|
|
28
|
+
**RULE: Never guess. Always verify. Use these tools:**
|
|
29
|
+
|
|
30
|
+
**For understanding a library API or TOON spec detail:**
|
|
31
|
+
```
|
|
32
|
+
Use Agent tool with subagent_type="Explore" to search the reference code:
|
|
33
|
+
prompt: "Find how the TypeScript TOON encoder handles tabular arrays.
|
|
34
|
+
Look in /Users/sunfl/Documents/study/MSrag/references/p0-core/toon-official/packages/toon/src/encode/"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**For current best practices or library docs:**
|
|
38
|
+
```
|
|
39
|
+
Use WebSearch tool:
|
|
40
|
+
query: "mariadb-connector-python array.array vector insert example 2026"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**For complex technical questions requiring deep research:**
|
|
44
|
+
```
|
|
45
|
+
Use Agent tool (general-purpose, background):
|
|
46
|
+
prompt: "Research how to implement exponential backoff retry in Python for a database
|
|
47
|
+
polling loop. Find production-grade patterns. Return code examples."
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**For reading specific documentation pages:**
|
|
51
|
+
```
|
|
52
|
+
Use WebFetch tool:
|
|
53
|
+
url: "https://mariadb.com/kb/en/vector-overview/"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**For multi-faceted investigation (spawn a team):**
|
|
57
|
+
```
|
|
58
|
+
Launch multiple Agent tools in parallel:
|
|
59
|
+
Agent 1: "Research TOON v3 spec Section 7.2 quoting rules by reading /references/p0-core/toon-spec/SPEC.md"
|
|
60
|
+
Agent 2: "Search web for Python regex patterns for TOON numeric detection"
|
|
61
|
+
Agent 3: "Read the TypeScript reference encoder at /references/p0-core/toon-official/packages/toon/src/encode/primitives.ts"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Phase 3: IMPLEMENT — TDD cycle
|
|
65
|
+
|
|
66
|
+
1. **Read the failing test** carefully — understand exactly what it expects
|
|
67
|
+
2. **Read reference code** if the implementation requires specific API knowledge
|
|
68
|
+
3. **Write the minimum code** to pass the test
|
|
69
|
+
4. **Let the PostToolUse hook** run tests automatically after each edit
|
|
70
|
+
5. If tests pass: move to next failing test
|
|
71
|
+
6. If tests fail: read the error, fix the implementation (NOT the test)
|
|
72
|
+
7. Repeat until all tests in the current component pass
|
|
73
|
+
|
|
74
|
+
### Phase 4: VERIFY — Broader checks
|
|
75
|
+
|
|
76
|
+
After a component passes its unit tests:
|
|
77
|
+
```bash
|
|
78
|
+
conda run -n seamless-rag python -m pytest tests/unit -v --tb=short # all unit tests
|
|
79
|
+
conda run -n seamless-rag ruff check src/seamless_rag/ # lint
|
|
80
|
+
conda run -n seamless-rag python scripts/score.py # score dashboard
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Phase 5: CODEX REVIEW — Quality gate
|
|
84
|
+
|
|
85
|
+
**Before any commit of a new feature or significant refactor, get a Codex review:**
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
Use Agent tool with subagent_type="codex:codex-rescue":
|
|
89
|
+
prompt: "Review the TOON v3 tabular encoder implementation at
|
|
90
|
+
/Users/sunfl/Documents/study/MSrag/workspace/src/seamless_rag/toon/encoder.py
|
|
91
|
+
|
|
92
|
+
Check for:
|
|
93
|
+
1. Correctness against TOON v3 spec (quoting rules, escape sequences, number canonicalization)
|
|
94
|
+
2. Edge cases: null, empty string, commas in values, newlines, unicode, negative zero
|
|
95
|
+
3. Code quality: type hints, readability, no unnecessary complexity
|
|
96
|
+
4. Performance: no quadratic algorithms for large datasets
|
|
97
|
+
|
|
98
|
+
Rate the code A/B/C/D and list specific issues to fix."
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Fix ALL issues Codex identifies before committing.** If Codex rates B or lower on critical code (TOON encoder, RAG engine), iterate until it's an A.
|
|
102
|
+
|
|
103
|
+
### Phase 6: COMMIT & DOCUMENT
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# Stage specific files (NEVER git add . or git add -A)
|
|
107
|
+
git add src/seamless_rag/toon/encoder.py tests/unit/test_toon_encoder.py
|
|
108
|
+
|
|
109
|
+
# Atomic commit with conventional prefix
|
|
110
|
+
git commit -m "feat: implement TOON v3 tabular encoder with value quoting and number canonicalization"
|
|
111
|
+
|
|
112
|
+
# Push
|
|
113
|
+
git push origin main
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Then update live docs:
|
|
117
|
+
- Mark the item as `[x]` in `TODO.md`
|
|
118
|
+
- Update `docs/SPECIFICATION.md` with what's now implemented
|
|
119
|
+
- Update `docs/HANDOFF.md` milestones
|
|
120
|
+
|
|
121
|
+
### Phase 7: ANTI-IDLE & RETRY — Never get stuck, never stop
|
|
122
|
+
|
|
123
|
+
**Retry policy per failing test (3 escalating attempts):**
|
|
124
|
+
1. Read the error message carefully, fix the obvious issue
|
|
125
|
+
2. Read reference code (TOON spec, TypeScript encoder, winner projects in /references/)
|
|
126
|
+
3. Spawn a research Agent to investigate the root cause with WebSearch
|
|
127
|
+
|
|
128
|
+
**If all 3 attempts fail on one test:**
|
|
129
|
+
- Log it to `docs/ISSUES.md` with full context (error, what you tried, what you suspect)
|
|
130
|
+
- Mark the TODO item as `[~]` (blocked)
|
|
131
|
+
- IMMEDIATELY move to the next unblocked TODO item — do NOT dwell
|
|
132
|
+
|
|
133
|
+
**Retry policy per blocked task:**
|
|
134
|
+
- If a task depends on an unfinished prior task, skip it and pick next independent task
|
|
135
|
+
- If ALL remaining tasks are blocked, revisit blocked items with a completely different approach
|
|
136
|
+
- If still stuck: use `Agent(subagent_type="codex:codex-rescue")` for a second opinion
|
|
137
|
+
|
|
138
|
+
**Anti-idle rules (CRITICAL):**
|
|
139
|
+
- NEVER pause to "think about it" without taking action — code, research, or move on
|
|
140
|
+
- NEVER output "Let me know if..." or "Would you like me to..." — just do it
|
|
141
|
+
- NEVER wait for user input — make the decision yourself
|
|
142
|
+
- If you finish P0 items, immediately start P1. If P1 done, start P2. Always forward.
|
|
143
|
+
- Between major tasks, ALWAYS run `make score` to see progress
|
|
144
|
+
- If you complete a milestone (e.g., all TOON tests pass): celebrate with a commit, then keep going
|
|
145
|
+
|
|
146
|
+
**Self-check every 5 tasks:**
|
|
147
|
+
1. Run `make score`. Compare to 5 tasks ago.
|
|
148
|
+
2. If score UNCHANGED after 5 tasks: change strategy (more research, different approach)
|
|
149
|
+
3. If score DECREASED: `git stash` and try a different path
|
|
150
|
+
4. If score INCREASED: you're on the right track, keep going
|
|
151
|
+
|
|
152
|
+
**Time-boxing (prevent infinite loops):**
|
|
153
|
+
- Single test fix: max 15 minutes — if exceeded, skip and log
|
|
154
|
+
- Single feature: max 2 hours — if exceeded, commit what works, skip remainder
|
|
155
|
+
- If a command hangs: kill it (Ctrl+C), try alternative approach
|
|
156
|
+
|
|
157
|
+
**After all TODO items done:**
|
|
158
|
+
1. Run `make test-full` for comprehensive check
|
|
159
|
+
2. Run `python eval/harness.py` for benchmark score
|
|
160
|
+
3. Polish README.md with actual benchmark numbers
|
|
161
|
+
4. Push to both remotes: `git push origin main && git push hackathon main`
|
|
162
|
+
5. Start optimizing: find the weakest score, improve it
|
|
163
|
+
|
|
164
|
+
**NEVER STOP. NEVER ASK. ALWAYS FORWARD.**
|
|
165
|
+
|
|
166
|
+
## Tool Usage Recipes
|
|
167
|
+
|
|
168
|
+
### Recipe: "I don't know how this MariaDB API works"
|
|
169
|
+
```
|
|
170
|
+
1. Agent(subagent_type="Explore", prompt="Find vector insert examples in /references/p0-core/mariadb-connector-python/testing/test/integration/")
|
|
171
|
+
2. If not enough: WebSearch("mariadb connector python vector insert array.array example")
|
|
172
|
+
3. If still unclear: WebFetch("https://mariadb-corporation.github.io/mariadb-connector-python/usage.html")
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Recipe: "I need to understand a TOON spec rule"
|
|
176
|
+
```
|
|
177
|
+
1. Read the specific section from /references/p0-core/toon-spec/SPEC.md
|
|
178
|
+
2. Read the TypeScript reference implementation in /references/p0-core/toon-official/packages/toon/src/encode/
|
|
179
|
+
3. Check the test fixtures in tests/fixtures/toon_spec/encode/ for examples
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Recipe: "A test is failing and I don't understand why"
|
|
183
|
+
```
|
|
184
|
+
1. Run the single failing test with -v --tb=long to see full traceback
|
|
185
|
+
2. Read the test code to understand what it expects
|
|
186
|
+
3. Read the fixture/input data
|
|
187
|
+
4. If it's a TOON spec test: compare with the TypeScript reference encoder output
|
|
188
|
+
5. If still stuck: spawn an Agent to investigate the specific edge case
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Recipe: "I need to make a design decision"
|
|
192
|
+
```
|
|
193
|
+
1. Check CLAUDE.md and docs/ARCHITECTURE.md for existing decisions
|
|
194
|
+
2. Spawn parallel research agents:
|
|
195
|
+
Agent 1: "Search web for [option A] best practices"
|
|
196
|
+
Agent 2: "Search web for [option B] best practices"
|
|
197
|
+
Agent 3: "Check how the YT semantic search winner handled this in /references/p1-reference/yt-semantic-search-winner/"
|
|
198
|
+
3. Compare findings against the 5 judge directives
|
|
199
|
+
4. Choose the option, document in docs/ARCHITECTURE.md
|
|
200
|
+
5. Proceed — do NOT ask the user
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Recipe: "Integration test needs Docker MariaDB"
|
|
204
|
+
```bash
|
|
205
|
+
# Start test MariaDB
|
|
206
|
+
docker compose -f docker-compose.test.yml up -d --wait
|
|
207
|
+
# Run integration tests
|
|
208
|
+
conda run -n seamless-rag python -m pytest tests/integration -v --tb=short
|
|
209
|
+
# Clean up
|
|
210
|
+
docker compose -f docker-compose.test.yml down -v
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Recipe: "Final delivery push to hackathon remote"
|
|
214
|
+
```bash
|
|
215
|
+
# Ensure all tests pass
|
|
216
|
+
conda run -n seamless-rag python -m pytest tests/ -v --tb=short -m "not eval"
|
|
217
|
+
# Push to personal
|
|
218
|
+
git push origin main
|
|
219
|
+
# Push to hackathon
|
|
220
|
+
git push hackathon main
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Quality Gates
|
|
224
|
+
|
|
225
|
+
Before marking any feature "done":
|
|
226
|
+
- [ ] All related unit tests pass (not just the new ones)
|
|
227
|
+
- [ ] `ruff check` passes on changed files
|
|
228
|
+
- [ ] `make score` shows improvement or no regression
|
|
229
|
+
- [ ] Codex review is A-grade (for critical components)
|
|
230
|
+
- [ ] Commit is atomic with conventional message prefix
|
|
231
|
+
- [ ] `docs/SPECIFICATION.md` and `TODO.md` are updated
|
|
232
|
+
|
|
233
|
+
## Completion Criteria (the project is "done" when ALL are true)
|
|
234
|
+
|
|
235
|
+
1. `make score` → 100% unit + 100% spec + 95%+ props
|
|
236
|
+
2. `make test-full` → all pass including Docker integration
|
|
237
|
+
3. `python eval/harness.py` → composite score >= 80
|
|
238
|
+
4. `docker compose up -d && conda run -n seamless-rag seamless-rag ask "test question"` → works end-to-end
|
|
239
|
+
5. README.md → judge-ready with architecture, benchmarks, quick start
|
|
240
|
+
6. JUDGES_TESTING_GUIDE.md → exists with 4 evaluation tiers
|
|
241
|
+
7. All critical code Codex-reviewed at A grade
|
|
242
|
+
8. Pushed to both `origin` and `hackathon` remotes
|
|
243
|
+
9. `docs/HANDOFF.md` → all milestones marked complete
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(conda run -n seamless-rag *)",
|
|
5
|
+
"Bash(docker compose *)",
|
|
6
|
+
"Bash(make *)",
|
|
7
|
+
"Bash(git *)",
|
|
8
|
+
"Bash(gh *)",
|
|
9
|
+
"Bash(pip install *)",
|
|
10
|
+
"Bash(python -m pytest *)",
|
|
11
|
+
"Bash(python eval/*)",
|
|
12
|
+
"Bash(python scripts/*)",
|
|
13
|
+
"Bash(ruff *)",
|
|
14
|
+
"WebSearch",
|
|
15
|
+
"WebFetch(domain:mariadb.org)",
|
|
16
|
+
"WebFetch(domain:toonformat.dev)",
|
|
17
|
+
"WebFetch(domain:github.com)",
|
|
18
|
+
"WebFetch(domain:pypi.org)",
|
|
19
|
+
"WebFetch(domain:docs.python.org)",
|
|
20
|
+
"WebFetch(domain:mariadb.com)",
|
|
21
|
+
"WebFetch(domain:mariadb-corporation.github.io)",
|
|
22
|
+
"WebFetch(domain:huggingface.co)",
|
|
23
|
+
"WebFetch(domain:sdk.vercel.ai)"
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
"hooks": {
|
|
27
|
+
"PostToolUse": [
|
|
28
|
+
{
|
|
29
|
+
"matcher": "Edit|Write",
|
|
30
|
+
"hooks": [
|
|
31
|
+
{
|
|
32
|
+
"type": "command",
|
|
33
|
+
"command": "cd \"$CLAUDE_PROJECT_DIR\" && INPUT=$(cat); FILE=$(echo \"$INPUT\" | jq -r '.tool_input.file_path // empty' 2>/dev/null); MOD=$(basename \"$(dirname \"$FILE\")\"); if echo \"$FILE\" | grep -q 'src/seamless_rag/toon'; then conda run -n seamless-rag python -m pytest tests/unit/test_toon_encoder.py tests/unit/test_toon_properties.py -x -q --tb=line --no-header 2>&1 | tail -10; elif echo \"$FILE\" | grep -q 'src/seamless_rag/benchmark'; then conda run -n seamless-rag python -m pytest tests/unit/test_token_benchmark.py -x -q --tb=line --no-header 2>&1 | tail -10; elif echo \"$FILE\" | grep -q 'src/seamless_rag/pipeline'; then conda run -n seamless-rag python -m pytest tests/unit/test_rag_pipeline.py -x -q --tb=line --no-header 2>&1 | tail -10; elif echo \"$FILE\" | grep -q 'src/seamless_rag/providers'; then conda run -n seamless-rag python -m pytest tests/unit/test_embedding_provider.py -x -q --tb=line --no-header -m 'not slow' 2>&1 | tail -10; elif echo \"$FILE\" | grep -q 'tests/'; then conda run -n seamless-rag python -m pytest \"$FILE\" -x -q --tb=line --no-header 2>&1 | tail -10; else conda run -n seamless-rag python -m pytest tests/unit -x -q --tb=line --no-header -m 'not slow' -o addopts= 2>&1 | tail -10; fi",
|
|
34
|
+
"timeout": 30000
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"PreToolUse": [
|
|
40
|
+
{
|
|
41
|
+
"matcher": "Bash",
|
|
42
|
+
"hooks": [
|
|
43
|
+
{
|
|
44
|
+
"type": "command",
|
|
45
|
+
"command": "INPUT=$(cat); CMD=$(echo \"$INPUT\" | jq -r '.tool_input.command // empty' 2>/dev/null); if echo \"$CMD\" | grep -q 'git commit'; then cd \"$CLAUDE_PROJECT_DIR\" && conda run -n seamless-rag python -m pytest tests/unit -x -q --tb=no 2>&1 | tail -3; fi; exit 0",
|
|
46
|
+
"timeout": 30000
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: seamless-rag
|
|
3
|
+
description: "Work with the Seamless-RAG toolkit — MariaDB vector search, TOON encoding, auto-embedding, and RAG queries. Use this skill when the user works in the seamless-rag project, asks about MariaDB vector operations, TOON format encoding, embedding providers, or RAG pipeline tasks. Also trigger when the user wants to query databases via vector search, convert data to TOON format, or manage MariaDB embedding workflows."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Seamless-RAG Agent Skill
|
|
7
|
+
|
|
8
|
+
Seamless-RAG is a **thin bridging layer** between MariaDB and LLMs/agents. It does NOT replace SQL — it complements it with vector search for semantic queries, and provides TOON format for token-efficient data consumption.
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
Agent (intent, strategy, judgment)
|
|
12
|
+
↕ CLI / Python API
|
|
13
|
+
Seamless-RAG (embed rows, vector search, format as TOON)
|
|
14
|
+
↕ mariadb-connector-python
|
|
15
|
+
MariaDB (store, index, execute SQL + VEC_DISTANCE)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## When to Use What
|
|
19
|
+
|
|
20
|
+
- **Precise query** ("Q3 revenue > 1M", aggregations, JOINs): use the **text-to-sql** skill → generates SQL → `export()` → TOON
|
|
21
|
+
- **Semantic query** ("find similar products"): `rag.ask(question)` for vector search
|
|
22
|
+
- **Hybrid** ("waterproof watches under $50"): `rag.ask(question, where="price < 50")`
|
|
23
|
+
- **Any SQL result → LLM**: always use `export()` to convert to TOON before feeding to LLM
|
|
24
|
+
|
|
25
|
+
> **Routing rule**: if the user's question involves numbers, aggregations, GROUP BY, or exact filters → route to `text-to-sql` skill. If it's fuzzy/semantic → use `ask`. If both → use `ask --where`.
|
|
26
|
+
|
|
27
|
+
## Reading TOON Format
|
|
28
|
+
|
|
29
|
+
When you receive TOON output from seamless-rag tools, read it like this:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
[N,]{col1,col2,col3}: ← header: N rows, column names in order
|
|
33
|
+
val1,val2,val3 ← row 1: values match column positions
|
|
34
|
+
val4,val5,val6 ← row 2
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Example — this TOON:**
|
|
38
|
+
```
|
|
39
|
+
[3,]{id,name,price,in_stock}:
|
|
40
|
+
1,Widget,29.99,true
|
|
41
|
+
2,"Smith, John",19.99,false
|
|
42
|
+
3,Gizmo,null,true
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Means the same as this JSON:**
|
|
46
|
+
```json
|
|
47
|
+
[{"id":1,"name":"Widget","price":29.99,"in_stock":true},
|
|
48
|
+
{"id":2,"name":"Smith, John","price":19.99,"in_stock":false},
|
|
49
|
+
{"id":3,"name":"Gizmo","price":null,"in_stock":true}]
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**TOON rules:**
|
|
53
|
+
- Header `[N,]{...}:` tells you row count and column names
|
|
54
|
+
- Each indented line is one row, values in column order
|
|
55
|
+
- `null` = no value, `true`/`false` = booleans
|
|
56
|
+
- Quoted values (`"Smith, John"`) contain commas or special characters
|
|
57
|
+
- Unquoted values are plain text, numbers, or booleans
|
|
58
|
+
- Numbers are canonical: no scientific notation, no trailing zeros
|
|
59
|
+
|
|
60
|
+
**Why TOON over JSON**: 10-55% fewer tokens vs compact JSON for structured data. Field names appear once in the header instead of repeating per row. Savings are highest with many rows and short values.
|
|
61
|
+
|
|
62
|
+
## Project Location
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
/Users/sunfl/Documents/study/MSrag/workspace/
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Conda env**: `seamless-rag` — always prefix commands with `conda run -n seamless-rag`.
|
|
69
|
+
|
|
70
|
+
## CLI Commands
|
|
71
|
+
|
|
72
|
+
Global options: `--host`, `--port`, `--user`, `--password`, `--database`, `--provider`, `--model`, `--log-level`
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# Core: data already in MariaDB → add vectors
|
|
76
|
+
seamless-rag init # VECTOR columns + HNSW index
|
|
77
|
+
seamless-rag embed [--table chunks] [--column content] # Bulk-embed single column
|
|
78
|
+
seamless-rag embed --table products --columns "name,category,price" # Multi-column embed
|
|
79
|
+
seamless-rag watch [--table chunks] [--columns "name,desc"] # Auto-embed new inserts
|
|
80
|
+
|
|
81
|
+
# Query
|
|
82
|
+
seamless-rag ask "question" [--top-k 5] [--where "price<50"] [--mmr] [--context-window 1]
|
|
83
|
+
seamless-rag export "SELECT ... FROM ..." # Any SQL → TOON format
|
|
84
|
+
|
|
85
|
+
# Tools
|
|
86
|
+
seamless-rag benchmark [--rows 50] [--cols 6] # JSON vs TOON comparison
|
|
87
|
+
seamless-rag web [--port 7860] [--share] # Gradio web UI (localhost-only by default)
|
|
88
|
+
seamless-rag demo # End-to-end demo
|
|
89
|
+
seamless-rag ingest <path> [--chunk-size 500] [--overlap 50] # Load text files for testing
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Python API
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
from seamless_rag import SeamlessRAG
|
|
96
|
+
|
|
97
|
+
with SeamlessRAG(host="127.0.0.1", database="seamless_rag") as rag:
|
|
98
|
+
rag.init() # create schema
|
|
99
|
+
|
|
100
|
+
# Single-column embed (default)
|
|
101
|
+
rag.embed_table("articles", text_column="content")
|
|
102
|
+
|
|
103
|
+
# Multi-column embed — richer semantics
|
|
104
|
+
rag.embed_table("products", text_column=["name", "category", "price"])
|
|
105
|
+
# Internally: "Widget — Tools — 29.99" → searches match name AND price
|
|
106
|
+
|
|
107
|
+
# Semantic search with hybrid filter
|
|
108
|
+
result = rag.ask("waterproof watches", top_k=5, where="price < 500", mmr=True)
|
|
109
|
+
# result.answer : str — LLM answer
|
|
110
|
+
# result.context_toon : str — TOON context (feed to next LLM call)
|
|
111
|
+
# result.savings_pct : float — token savings vs compact JSON
|
|
112
|
+
# result.sources : list[dict] — raw results
|
|
113
|
+
|
|
114
|
+
# SQL → TOON (for precise queries, agent tools)
|
|
115
|
+
toon = rag.export("SELECT region, SUM(revenue) FROM sales GROUP BY region")
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## TOON Encoder (standalone)
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
from seamless_rag.toon.encoder import encode_tabular
|
|
122
|
+
|
|
123
|
+
toon = encode_tabular([
|
|
124
|
+
{"id": 1, "name": "Alice", "score": 95},
|
|
125
|
+
{"id": 2, "name": "Bob", "score": 87},
|
|
126
|
+
])
|
|
127
|
+
# → [2,]{id,name,score}:
|
|
128
|
+
# 1,Alice,95
|
|
129
|
+
# 2,Bob,87
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Provider Configuration
|
|
133
|
+
|
|
134
|
+
| Variable | Default | Options |
|
|
135
|
+
|----------|---------|---------|
|
|
136
|
+
| `EMBEDDING_PROVIDER` | `sentence-transformers` | `sentence-transformers`, `gemini`, `openai`, `ollama` |
|
|
137
|
+
| `EMBEDDING_MODEL` | `all-MiniLM-L6-v2` | Model name for chosen provider |
|
|
138
|
+
| `LLM_PROVIDER` | `ollama` | `ollama`, `gemini`, `openai` |
|
|
139
|
+
| `LLM_MODEL` | `qwen3:8b` | Model name for chosen provider |
|
|
140
|
+
| `EMBEDDING_API_KEY` | (empty) | Required for gemini/openai embedding |
|
|
141
|
+
| `LLM_API_KEY` | (empty) | Required for gemini LLM |
|
|
142
|
+
| `OPENAI_API_KEY` | (empty) | Required for openai LLM |
|
|
143
|
+
| `LLM_BASE_URL` | (empty) | Custom Ollama endpoint |
|
|
144
|
+
| `SEAMLESS_WEB_USER` | (empty) | Web UI auth username (required for --share) |
|
|
145
|
+
| `SEAMLESS_WEB_PASSWORD` | (empty) | Web UI auth password (required for --share) |
|
|
146
|
+
|
|
147
|
+
## Security
|
|
148
|
+
|
|
149
|
+
- **SQL injection prevention**: WHERE filters validated via sqlglot AST — blocks writes, DDL, subqueries, dangerous functions
|
|
150
|
+
- **Web UI**: localhost-only by default; `--share` requires auth env vars
|
|
151
|
+
- **LLM**: context truncated to 20K chars; retry with jitter for transient errors
|
|
152
|
+
|
|
153
|
+
## Testing
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
conda run -n seamless-rag make test-all # lint + unit + spec (no Docker)
|
|
157
|
+
conda run -n seamless-rag make test-full # includes integration
|
|
158
|
+
conda run -n seamless-rag make score # quality dashboard
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
538/538 tests passing (100%). TOON spec: 166/166.
|
|
162
|
+
|
|
163
|
+
## Agent Workflow Patterns
|
|
164
|
+
|
|
165
|
+
### Pattern 1: SQL results as agent context
|
|
166
|
+
```python
|
|
167
|
+
# Agent generates SQL, seamless-rag formats as TOON
|
|
168
|
+
toon = rag.export("SELECT product, revenue, margin FROM sales WHERE quarter='Q3'")
|
|
169
|
+
# Feed toon to next LLM call — 60% fewer tokens than JSON
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Pattern 2: Semantic search on text columns
|
|
173
|
+
```python
|
|
174
|
+
# When the question is fuzzy, not expressible as SQL
|
|
175
|
+
result = rag.ask("products customers complained about", top_k=10, mmr=True)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Pattern 3: Hybrid filter + semantic
|
|
179
|
+
```python
|
|
180
|
+
# Combine SQL precision with vector semantics
|
|
181
|
+
result = rag.ask("reliable laptops", where="price < 1000 AND category = 'electronics'")
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Pattern 4: Multi-column embedding for rich search
|
|
185
|
+
```python
|
|
186
|
+
# Embed multiple columns for searches that span fields
|
|
187
|
+
rag.embed_table("products", text_column=["name", "category", "price", "rating"])
|
|
188
|
+
# Internal: "Widget — Tools — 29.99 — 4.5"
|
|
189
|
+
# Now "cheap high-rated tools" matches on ALL fields, not just description
|
|
190
|
+
result = rag.ask("cheap high-rated tools", where="price < 50")
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Pattern 5: Multi-step agent with accumulated TOON context
|
|
194
|
+
```python
|
|
195
|
+
# Each step: query DB → TOON → feed to LLM → next decision
|
|
196
|
+
# TOON saves 15-30% per step, compounding over 20 steps
|
|
197
|
+
step1 = rag.export("SELECT region, SUM(revenue) FROM sales GROUP BY region")
|
|
198
|
+
# LLM analyzes, decides to drill into worst region
|
|
199
|
+
step2 = rag.export("SELECT product, units FROM sales WHERE region='EMEA' AND quarter='Q3'")
|
|
200
|
+
```
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: text-to-sql
|
|
3
|
+
description: "Convert natural language questions into SQL, execute against MariaDB, and return results in TOON format. Use when the user asks a data question that needs a precise SQL query — revenue reports, aggregations, filtered lookups, JOINs — rather than semantic/vector search. Works with any MariaDB database the user has access to."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Text-to-SQL Agent Skill
|
|
7
|
+
|
|
8
|
+
Turn natural language into SQL → execute → return TOON-formatted results.
|
|
9
|
+
|
|
10
|
+
This skill is the **precise query** complement to `seamless-rag ask` (semantic search). Use this when the user's question maps to exact SQL — numbers, aggregations, filters, JOINs.
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
User: "What's the average rating of comedy movies from the 2000s?"
|
|
14
|
+
↓
|
|
15
|
+
Agent: inspect schema → generate SQL → execute via seamless-rag export → TOON result
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## When to Use This vs `seamless-rag ask`
|
|
19
|
+
|
|
20
|
+
| Signal | Use text-to-sql | Use `seamless-rag ask` |
|
|
21
|
+
|--------|----------------|----------------------|
|
|
22
|
+
| Numbers, aggregations | "average revenue", "count of", "top 10 by" | - |
|
|
23
|
+
| Exact filters | "where price > 100", "in Q3 2025" | - |
|
|
24
|
+
| JOINs, GROUP BY | "revenue by region" | - |
|
|
25
|
+
| Fuzzy / semantic | - | "movies similar to Inception" |
|
|
26
|
+
| Hybrid | Generate SQL with WHERE, pass to `ask --where` | `ask "query" --where "price < 50"` |
|
|
27
|
+
|
|
28
|
+
## Workflow
|
|
29
|
+
|
|
30
|
+
### Step 1: Discover schema
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# List databases
|
|
34
|
+
conda run -n seamless-rag python -c "
|
|
35
|
+
import mariadb
|
|
36
|
+
conn = mariadb.connect(host='127.0.0.1', port=3306, user='root', password='seamless')
|
|
37
|
+
cur = conn.cursor()
|
|
38
|
+
cur.execute('SHOW DATABASES')
|
|
39
|
+
for row in cur: print(row[0])
|
|
40
|
+
cur.close(); conn.close()
|
|
41
|
+
"
|
|
42
|
+
|
|
43
|
+
# List tables in a database
|
|
44
|
+
conda run -n seamless-rag python -c "
|
|
45
|
+
import mariadb
|
|
46
|
+
conn = mariadb.connect(host='127.0.0.1', port=3306, user='root', password='seamless', database='DATABASE_NAME')
|
|
47
|
+
cur = conn.cursor()
|
|
48
|
+
cur.execute('SHOW TABLES')
|
|
49
|
+
for row in cur: print(row[0])
|
|
50
|
+
cur.close(); conn.close()
|
|
51
|
+
"
|
|
52
|
+
|
|
53
|
+
# Get table schema
|
|
54
|
+
conda run -n seamless-rag python -c "
|
|
55
|
+
import mariadb
|
|
56
|
+
conn = mariadb.connect(host='127.0.0.1', port=3306, user='root', password='seamless', database='DATABASE_NAME')
|
|
57
|
+
cur = conn.cursor()
|
|
58
|
+
cur.execute('DESCRIBE TABLE_NAME')
|
|
59
|
+
for row in cur: print(f'{row[0]:20s} {row[1]:20s} {row[2] or \"\"}')
|
|
60
|
+
cur.close(); conn.close()
|
|
61
|
+
"
|
|
62
|
+
|
|
63
|
+
# Sample data (first 3 rows)
|
|
64
|
+
conda run -n seamless-rag seamless-rag --database DATABASE_NAME export "SELECT * FROM TABLE_NAME LIMIT 3"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Step 2: Generate SQL
|
|
68
|
+
|
|
69
|
+
Given the schema, write a SELECT query. Rules:
|
|
70
|
+
- **SELECT only** — never generate INSERT, UPDATE, DELETE, DROP, ALTER
|
|
71
|
+
- **Use LIMIT** — always add LIMIT unless the user asks for "all"
|
|
72
|
+
- **Validate column names** against the schema — don't guess
|
|
73
|
+
- **Use aliases** for readability: `AVG(price) AS avg_price`
|
|
74
|
+
- **MariaDB dialect** — use `LIMIT` not `TOP`, backtick identifiers if needed
|
|
75
|
+
|
|
76
|
+
### Step 3: Execute and return TOON
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
conda run -n seamless-rag seamless-rag --database DATABASE_NAME export "YOUR_SQL_HERE"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The `export` command:
|
|
83
|
+
- Validates the SQL (rejects writes/DDL via sqlglot AST parsing)
|
|
84
|
+
- Executes the query
|
|
85
|
+
- Converts results to TOON tabular format
|
|
86
|
+
- Prints to stdout
|
|
87
|
+
|
|
88
|
+
### Step 4: Present results
|
|
89
|
+
|
|
90
|
+
Show the TOON output directly. If the user needs analysis, feed the TOON to your next reasoning step — it's already token-efficient.
|
|
91
|
+
|
|
92
|
+
## Examples
|
|
93
|
+
|
|
94
|
+
### Simple aggregation
|
|
95
|
+
```
|
|
96
|
+
User: "What genres have the highest average rating?"
|
|
97
|
+
|
|
98
|
+
→ Schema check: movielens.top_movies has (id, title, genres, year, avg_rating, num_ratings, tags)
|
|
99
|
+
|
|
100
|
+
→ SQL: SELECT genres, ROUND(AVG(avg_rating), 2) AS avg_score, COUNT(*) AS count
|
|
101
|
+
FROM top_movies GROUP BY genres ORDER BY avg_score DESC LIMIT 10
|
|
102
|
+
|
|
103
|
+
→ Execute: seamless-rag --database movielens export "SELECT genres, ..."
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Filtered lookup
|
|
107
|
+
```
|
|
108
|
+
User: "Show me high-risk restaurant violations in 94110"
|
|
109
|
+
|
|
110
|
+
→ Schema check: restaurant.violations has (id, business_name, ..., postal_code, ..., risk_category)
|
|
111
|
+
|
|
112
|
+
→ SQL: SELECT business_name, violation_description, inspection_score
|
|
113
|
+
FROM violations WHERE risk_category = 'High Risk' AND postal_code = '94110'
|
|
114
|
+
ORDER BY inspection_score ASC LIMIT 20
|
|
115
|
+
|
|
116
|
+
→ Execute: seamless-rag --database restaurant export "SELECT ..."
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Multi-table JOIN
|
|
120
|
+
```
|
|
121
|
+
User: "Which documents have the most chunks?"
|
|
122
|
+
|
|
123
|
+
→ SQL: SELECT d.title, COUNT(c.id) AS chunk_count
|
|
124
|
+
FROM documents d JOIN chunks c ON c.document_id = d.id
|
|
125
|
+
GROUP BY d.id ORDER BY chunk_count DESC LIMIT 10
|
|
126
|
+
|
|
127
|
+
→ Execute: seamless-rag --database seamless_rag export "SELECT ..."
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Available Databases
|
|
131
|
+
|
|
132
|
+
Check what's available by running `SHOW DATABASES`. Common ones in this project:
|
|
133
|
+
|
|
134
|
+
| Database | Tables | Description |
|
|
135
|
+
|----------|--------|-------------|
|
|
136
|
+
| `seamless_rag` | documents, chunks | Default RAG database (demo data) |
|
|
137
|
+
| `movielens` | movies, top_movies | 9.7K movies with ratings and tags |
|
|
138
|
+
| `restaurant` | inspections, violations | 54K SF restaurant health inspections |
|
|
139
|
+
|
|
140
|
+
## Security
|
|
141
|
+
|
|
142
|
+
The `seamless-rag export` command validates all SQL via sqlglot AST parsing:
|
|
143
|
+
- Only SELECT queries are allowed
|
|
144
|
+
- INSERT/UPDATE/DELETE/DROP/ALTER are blocked
|
|
145
|
+
- Subqueries with writes are blocked
|
|
146
|
+
- Dangerous functions (SLEEP, BENCHMARK, LOAD_FILE) are blocked
|
|
147
|
+
|
|
148
|
+
This means you can safely pass user-influenced queries through `export`.
|
|
149
|
+
|
|
150
|
+
## Connection Config
|
|
151
|
+
|
|
152
|
+
Default connection (from `.env` or CLI flags):
|
|
153
|
+
- Host: `127.0.0.1`
|
|
154
|
+
- Port: `3306`
|
|
155
|
+
- User: `root`
|
|
156
|
+
- Password: `seamless`
|
|
157
|
+
|
|
158
|
+
Override with: `seamless-rag --host X --port Y --user Z --password W --database DB export "SQL"`
|