Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ Recoverable conditions come back as payload fields —
`query_parse_error`, `query_too_broad`, `truncated`, `regex_incompatible`, `regex_invalid`,
`no_content_atom`, `zero_width_only_atoms`, `commit_not_indexed` — rather than errors, so
an agent can react without a failed tool call. `regex_invalid` is distinct from
`regex_incompatible`: the latter means Python `re` (not Postgres) rejected an otherwise-valid
`regex_incompatible`: the latter means Python `regex` (not Postgres) rejected an otherwise-valid
pattern and only degrades highlighting; `regex_invalid` means Postgres rejected the pattern
outright and the query did not run. Pagination rides the same envelope as
`next_cursor`, and the semantic tool adds its own status fields (`semantic_enabled`,
Expand Down
2 changes: 1 addition & 1 deletion app/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ The MCP server Databricks App: a FastMCP streamable-HTTP service exposing the in

### Working In This Directory
- **The engine is a process-scoped module singleton, not lifespan-owned.** A FastMCP `lifespan` re-enters once per MCP session; building the engine there would re-pay Lakebase cold start and open N×5 pools. `get_engine()` in `main.py` is the only builder; the lifespan only references it and never disposes (that is `atexit`'s job).
- **Blocking work runs off the event loop.** Every tool body goes through `_dispatch` → `anyio.to_thread.run_sync` under `_DB_LIMITER` (sized to the 5-conn pool). Never run SQL or the Python `re` rescan inline in an async handler.
- **Blocking work runs off the event loop.** Every tool body goes through `_dispatch` → `anyio.to_thread.run_sync` under `_DB_LIMITER` (sized to the 5-conn pool). Never run SQL or the Python `regex` rescan inline in an async handler.
- **Recoverable conditions are payload fields, never exceptions**: `truncated`, `query_too_broad`, `query_parse_error`, `regex_incompatible`, `regex_invalid`, `no_content_atom`, `zero_width_only_atoms`, `semantic_schema_missing`. Only genuinely unexpected faults reach `_dispatch`, which logs the traceback and re-raises. Envelope keys are additive and permanent — agents depend on them; never remove or reshape one.
- **`clamp_limit` gates every caller-supplied limit** (`<=0` → `row_limit`, `> max` → `max_row_limit`) before it reaches a builder.
- `main.py` aliases `service.*` builders (`_search_code_payload = service.search_code_payload`); tests monkeypatching collaborators must patch `service.*`, since function globals resolve in the defining module.
Expand Down
5 changes: 3 additions & 2 deletions webui/frontend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ npm run build # tsc -b && vite build -> dist/
```

`dist/` is committed to the repo (see the root `.gitignore` negation) because DABs source sync
respects `.gitignore`, and CI does not run a Node build step for v1 — `webui/main.py` serves
respects `.gitignore`, and production deploy does not require Node — `webui/main.py` serves
this directory directly via `SPAStaticFiles`. **Rebuild and commit `dist/` whenever `src/`
changes**; CI's `webui` job enforces dist freshness via `make webui-verify-dist`.
changes**; CI's `webui` job runs a Node build step (`make webui-verify-dist`) purely to enforce
that the committed `dist/` matches `src/`, not to produce a deploy artifact.

## Test

Expand Down
Loading