feat: track chat file associations with chat_file_links on chats (#23537)

Needed by #23833

Adds a `chat_file_links` association table to track which files are
associated with each chat.

- `AppendChatFileIDs` query links a file to a chat with deduplication
- `GetChatFileMetadataByIDs` query returns lightweight file metadata by
IDs
- Tool-created files (e.g. `propose_plan`) are linked to the chat after
insert
- User-uploaded files are linked to the chat when the referencing
message is sent
- Single-chat GET endpoint hydrates `files: ChatFileMetadata[]` on the
response

> 🤖 Created by Coder Agents and massaged into shape by a human.
This commit is contained in:
Cian Johnston
2026-04-07 12:05:29 +01:00
committed by GitHub
parent beb99c17de
commit d5a1792f07
26 changed files with 1175 additions and 60 deletions
+24 -2
View File
@@ -134,6 +134,12 @@ edited message onward, truncating any messages that followed it.
|-----------|-------------------|----------|----------------------------------|
| `content` | `ChatInputPart[]` | yes | The replacement message content. |
The response is an `EditChatMessageResponse` with the edited `message`
and an optional `warnings` array. When file references in the edited
content cannot be linked (e.g. the per-chat file cap is reached), the
edit still succeeds and the `warnings` array describes which files
were not linked.
### Stream updates
`GET /api/experimental/chats/{chat}/stream`
@@ -201,7 +207,9 @@ Each event is a JSON object with `kind` and `chat` fields:
`GET /api/experimental/chats`
Returns all chats owned by the authenticated user.
Returns all chats owned by the authenticated user. The `files` field is
populated on `POST /chats` and `GET /chats/{id}`. Other endpoints that
return a `Chat` object omit it.
| Query parameter | Type | Required | Description |
|-----------------|----------|----------|------------------------------------------------------------------|
@@ -212,7 +220,17 @@ Returns all chats owned by the authenticated user.
`GET /api/experimental/chats/{chat}`
Returns the `Chat` object (metadata only, no messages).
Returns the `Chat` object (metadata only, no messages). The response
includes a `files` field (`ChatFileMetadata[]`) containing metadata for
files that have been successfully linked to the chat. File linking is
best-effort; if linking fails, the file remains in message content but
will be absent from this field.
When file linking is skipped (e.g. the per-chat file cap is reached),
`POST /chats` includes a `warnings` array on the `Chat` response and
`POST /chats/{chat}/messages` includes a `warnings` array on the
`CreateChatMessageResponse`. The `warnings` field is `omitempty` and
absent when all files are linked successfully.
### Get chat messages
@@ -295,6 +313,10 @@ file, use `GET /api/experimental/chats/files/{file}`.
Supported formats: PNG, JPEG, GIF, WebP (up to 10 MB). The server
validates actual file content regardless of the declared `Content-Type`.
Files referenced in messages are automatically linked to the chat and
appear in the `files` field on subsequent
`GET /api/experimental/chats/{chat}` responses.
## Chat statuses
| Status | Meaning |