From 2d3c15e48bfd13f29003b954ffc59d6491fbbea4 Mon Sep 17 00:00:00 2001 From: Benjamin Toby Date: Tue, 27 Oct 2026 17:41:46 +0100 Subject: [PATCH] Open a bot's own files from a workspace conversation A workspace run saves to the bot's own folder unless it picks the workspace's, but a file chip in a workspace conversation only looked in the workspace's folder, so those refs rendered as dead text. The chip now sends both ids and the single-file lookup also searches the bot's own folder for a user who reaches that bot. Co-Authored-By: Claude Opus 5.5 --- AGENTS.md | 2 +- .../admin/bots/[bot_id]/(partials)/file-ref-chip.tsx | 7 +++++-- src/pages/api/admin/bots/files.ts | 12 +++++++++++- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 01b9d46..56e45aa 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -169,7 +169,7 @@ Set in Settings > Environment (super admin), not `.env`. `envs` (private; encryp ### Bot files and folders - Files live on the data volume, not on computers: `DATA_DIR/bots/` and `DATA_DIR/workspaces/`. Catalog `bot_files`, bytes in private `media` (`bot-file`) written by `recordBotFile`. Reach via `grabStorageScopes`; paths via `resolveBotPath` (no absolute, `..`, NUL, symlink escape); quota checked by `assertStorageRoom`. -- Tools in `src/harness/tools/storage/` (every run). `attach` puts a file on the reply. `grabConversationFiles` must list the **whole** folder tree, or nested `[file:ID]` refs render dead. +- Tools in `src/harness/tools/storage/` (every run). `attach` puts a file on the reply. `grabConversationFiles` must list the **whole** folder tree, or nested `[file:ID]` refs render dead. A workspace run saves to the bot's own folder unless it picks the workspace's, so a chip in a workspace conversation looks up both (`api/admin/bots/files?file_id=` with `bot_id` and `workspace_id`). - `import_file` copies from a computer through the sandbox's streaming `GET /v1/file/download`, **never through its shell** (`/v1/shell/exec` caps output at ~30K chars and silently truncated imports). Size read first, `change_policy=abort`, length checked. - Ingestion: chunks + embeddings into `bot_file_chunks` / `bot_file_vectors` (vec0), worked by `src/file-ingest/`; without an embedding model search falls back to words and says so. sqlite-vec limits: metadata columns are NOT NULL; side-car columns can't be filtered with `MATCH` (filter in code). **Never pass `--vector` to `bunx bun-sqlite schema` in `entrypoint.sh`** (wipes vectors on boot). Changing `AppData.EmbeddingDimensions` needs a manual `--vector` run and a re-ingest. - **Foreign keys are off per connection** unless `enableForeignKeys` ran (only `src/server.ts` does). Scripts never fire `ON DELETE CASCADE`, so **any helper that deletes a parent row must delete its children explicitly** (as `deleteBotFile`, `purgeStorage`, `deleteSkill` do). A leftover child fails the next `bun run db:schema` with a foreign key violation. diff --git a/src/pages/admin/bots/[bot_id]/(partials)/file-ref-chip.tsx b/src/pages/admin/bots/[bot_id]/(partials)/file-ref-chip.tsx index 23a368a..45de9fb 100644 --- a/src/pages/admin/bots/[bot_id]/(partials)/file-ref-chip.tsx +++ b/src/pages/admin/bots/[bot_id]/(partials)/file-ref-chip.tsx @@ -27,10 +27,13 @@ function fetchFile({ if (cached) return cached; - const query = new URLSearchParams({ file_id: String(file_id) }); + /** + * Both ids in a workspace: a bot working there saves to its own folder + * unless it picks the workspace's, and the chip has to find either. + */ + const query = new URLSearchParams({ file_id: String(file_id), bot_id: String(bot_id) }); if (workspace_id) query.set("workspace_id", String(workspace_id)); - else query.set("bot_id", String(bot_id)); const pending = fetchApi<{}, APIResponseObject>( `/api/admin/bots/files?${query.toString()}`, diff --git a/src/pages/api/admin/bots/files.ts b/src/pages/api/admin/bots/files.ts index 87545b3..bbeded2 100644 --- a/src/pages/api/admin/bots/files.ts +++ b/src/pages/api/admin/bots/files.ts @@ -56,7 +56,17 @@ export const handler: BunextAPIRouteHandler