From a8f1c5a69f7e6f6fb61df0fce33f798c976c3a37 Mon Sep 17 00:00:00 2001 From: Dan Tasse <105866+dantasse@users.noreply.github.com> Date: Tue, 30 Jun 2026 09:27:21 -0400 Subject: [PATCH] feat: add skill to work with branches better (#3596) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Agents seemed to have trouble finding the right calls to work with branches (create, list, delete) and passing the right params to get it to work. We probably don't need a big skill to get it on the right track but a little nudge seems helpful. Doing a couple simple tasks, it saved about half the time and tokens, so feels worthwhile. Created with the Claude skills creator, hence the "skill.md in a bare folder" organization - happy to move it if that's not the standard anymore. ``` Benchmark results (3 evals, with-skill vs baseline): ┌────────────────┬────────────┬────────────────────┐ │ Metric │ With skill │ Without skill │ ├────────────────┼────────────┼────────────────────┤ │ Pass rate │ 3/3 (100%) │ 3/3 (100%) │ ├────────────────┼────────────┼────────────────────┤ │ Avg time │ 51s │ 142s (2.8× slower) │ ├────────────────┼────────────┼────────────────────┤ │ Avg tokens │ 19,305 │ 36,513 (47% more) │ ├────────────────┼────────────┼────────────────────┤ │ Avg tool calls │ 5.7 │ 26 (4.5× more) │ └────────────────┴────────────┴────────────────────┘ ``` --- .agents/skills/lancedb-branch-ops/SKILL.md | 137 +++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 .agents/skills/lancedb-branch-ops/SKILL.md diff --git a/.agents/skills/lancedb-branch-ops/SKILL.md b/.agents/skills/lancedb-branch-ops/SKILL.md new file mode 100644 index 000000000..cf020ad19 --- /dev/null +++ b/.agents/skills/lancedb-branch-ops/SKILL.md @@ -0,0 +1,137 @@ +--- +name: lancedb-branch-ops +description: Branch management for LanceDB tables via the REST API. Use this skill whenever someone wants to create, delete, list, or switch branches on a LanceDB table — or needs to make sure a write (metadata update, index build, etc.) lands on a specific branch instead of main. Invoke it even without the word "branch" if context makes clear they want an experimental copy of a table, want to isolate changes, or want to confirm a mutation didn't touch main. Covers: branches/list, branches/create, branches/delete, and passing "branch" in describe/update_field_metadata/create_index to target a non-main version. +--- + +## Goal + +Manage branches on a LanceDB table: list what exists, create new ones, delete stale ones, and direct read/write operations at a specific branch without touching main. + +## Step 0: Establish the connection + +Use the `lancedb-connect` skill to resolve the base URL and auth headers (`x-api-key`, `x-lancedb-database`). Skip this only if the connection is already known from the current conversation. + +All examples below use `{base_url}` — substitute the resolved endpoint and include the auth headers on every request. + +## The branch model (important) + +LanceDB branches are named snapshots that diverge from the table's current state at creation time. There is **no checkout command** — you never switch the whole table to a branch. Instead, you **pass `"branch": ""` in the request body** of any operation to target that branch. Omitting the key (or sending an empty body) always targets main. + +`branches/list` returns only non-main branches. Main always exists and is not listed. + +## List branches + +```http +POST {base_url}/v1/table/{table_id}/branches/list +Content-Type: application/json + +{} +``` + +Response: +```json +{ + "branches": { + "experiment-reindex": {"parentVersion": 1, "createAt": 1782506085, "manifestSize": 1029} + } +} +``` + +If `branches` is `{}`, the table has no branches besides main. + +## Create a branch + +```http +POST {base_url}/v1/table/{table_id}/branches/create +Content-Type: application/json + +{"name": "experiment-reindex"} +``` + +HTTP 200 with `{}` body = success. The branch is created off the table's current state on main. + +Verify by calling `branches/list` and confirming the new name appears. + +## Delete a branch + +```http +POST {base_url}/v1/table/{table_id}/branches/delete +Content-Type: application/json + +{"name": "stale-2024"} +``` + +HTTP 200 with `{}` body = success. Only the branch pointer is removed — main and all row data remain intact. + +Verify by calling `branches/list` (name gone) and `describe` with no branch param (main still responds). + +## Operate on a specific branch + +Pass `"branch": ""` in the body of any operation to scope it to that branch: + +**Read schema on a branch:** +```http +POST {base_url}/v1/table/{table_id}/describe +Content-Type: application/json + +{"branch": "wip-branch"} +``` + +**Write metadata to a branch (not main):** +```http +POST {base_url}/v1/table/{table_id}/update_field_metadata +Content-Type: application/json + +{ + "branch": "wip-branch", + "updates": [ + { + "path": "category", + "metadata": {"lancedb:description": "Product category label."}, + "replace": false + } + ] +} +``` + +**Build an index on a branch:** +```http +POST {base_url}/v1/table/{table_id}/create_index +Content-Type: application/json + +{ + "branch": "wip-branch", + "column": "category", + "index_type": "BTREE" +} +``` + +## Verifying isolation + +After writing to a branch, always confirm the change did NOT land on main: + +```bash +# Should show the new metadata +curl -s -X POST {base_url}/v1/table/{table_id}/describe \ + -H "x-api-key: " -H "x-lancedb-database: " \ + -H "content-type: application/json" \ + -d '{"branch": "wip-branch"}' + +# Should NOT show the new metadata +curl -s -X POST {base_url}/v1/table/{table_id}/describe \ + -H "x-api-key: " -H "x-lancedb-database: " \ + -H "content-type: application/json" \ + -d '{}' +``` + +## Quick reference + +| Goal | Endpoint | Body | +|------|----------|------| +| List all branches | `branches/list` | `{}` | +| Create a branch | `branches/create` | `{"name": "..."}` | +| Delete a branch | `branches/delete` | `{"name": "..."}` | +| Read schema on branch | `describe` | `{"branch": "..."}` | +| Write metadata on branch | `update_field_metadata` | `{"branch": "...", "updates": [...]}` | +| Build index on branch | `create_index` | `{"branch": "...", "column": ..., "index_type": ...}` | +| Target main (default) | any endpoint | omit `"branch"` key |