mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
feat: auto-archive inactive chats with audit trail (#24642)
Adds a background job in `dbpurge` that periodically archives chats inactive beyond a configurable threshold. Each archived root chat gets a background audit entry tagged `chat_auto_archive`. Disabled by default. * New `AutoArchiveInactiveChats` SQL query with LATERAL last-activity subquery and partial index on archive candidates * `site_configs`-backed `auto_archive_days` setting with admin-only PUT, any-authenticated-user GET * Cascade archive via `root_chat_id`; pinned chats and active threads exempt * Root-only audit dispatch on detached context, matching manual archive (`patchChat`) behavior * 11 subtests covering disabled no-op, boundary, deleted messages, child activity, pinned exemption, multi-owner, idempotency, and batch pagination PR #24643 adds per-owner digest notifications. PR #24704 adds the requisite UI controls. > 🤖
This commit is contained in:
@@ -326,8 +326,38 @@ appear in the `files` field on subsequent
|
||||
|
||||
| Status | Meaning |
|
||||
|-------------------|------------------------------------------------------------------------------|
|
||||
| `waiting` | No pending work (newly created, finished, or interrupted). |
|
||||
| `waiting` | Idle. Newly created, finished successfully, or interrupted. |
|
||||
| `pending` | Queued for processing. |
|
||||
| `running` | Agent is actively working. |
|
||||
| `paused` | Agent is paused (for example, waiting for user input). |
|
||||
| `completed` | Agent finished and the task is complete. |
|
||||
| `error` | Agent encountered an error. |
|
||||
| `requires_action` | Agent invoked a client-provided tool and needs the result before continuing. |
|
||||
|
||||
## Configuration
|
||||
|
||||
Deployment-wide chat settings are read and written under
|
||||
`/api/experimental/chats/config/*`. Reading config requires authentication; writing requires
|
||||
deployment-admin privileges.
|
||||
|
||||
### Auto-archive window
|
||||
|
||||
Chats whose newest non-deleted message is older than
|
||||
`auto_archive_days` are automatically archived by a background job.
|
||||
Pinned chats and chats belonging to a still-active thread are
|
||||
exempt. `0` disables the feature; the default is 90.
|
||||
|
||||
```sh
|
||||
# Read
|
||||
curl -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
|
||||
https://coder.example.com/api/experimental/chats/config/auto-archive-days
|
||||
# { "auto_archive_days": 90 }
|
||||
|
||||
# Update
|
||||
curl -X PUT -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"auto_archive_days": 60}' \
|
||||
https://coder.example.com/api/experimental/chats/config/auto-archive-days
|
||||
```
|
||||
|
||||
Accepted range: `0` to `3650` (~10 years).
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
# Conversation Auto-Archive
|
||||
|
||||
Coder Agents automatically archives long-inactive conversations so they
|
||||
drop out of active chat lists without any user intervention. Archived
|
||||
conversations are still visible (and can be unarchived) until they age
|
||||
out of the separate retention window, at which point they are purged.
|
||||
|
||||
## How it works
|
||||
|
||||
A background process runs approximately every 10 minutes. On each tick
|
||||
it scans the chat database for root conversations whose most recent
|
||||
non-deleted message is older than the configured auto-archive window
|
||||
and flips them from "active" to "archived". Cascaded children (chats
|
||||
linked into a larger conversation via `root_chat_id`) are archived
|
||||
alongside their parent so the conversation stays coherent.
|
||||
|
||||
Activity is defined as the most recent non-deleted message in the
|
||||
conversation family, counting messages from every role. Root chats
|
||||
whose status indicates ongoing work (`running`, `pending`, `paused`,
|
||||
or `requires_action`) are never selected for auto-archiving.
|
||||
Children inherit their root's archival decision.
|
||||
|
||||
Pinned root conversations (those with a non-zero pin order) are never
|
||||
selected for auto-archiving. Children are archived alongside their
|
||||
root regardless of individual pin status. Admins and users who want
|
||||
to retain a conversation long after its last message should pin the
|
||||
root.
|
||||
|
||||
## Interaction with retention
|
||||
|
||||
Auto-archive and deletion are two independent controls:
|
||||
|
||||
| Control | What it does | Default |
|
||||
|---------------------|---------------------------------------------------------------------------|-------------------|
|
||||
| Auto-archive window | Moves inactive chats to the archived state | 0 days (disabled) |
|
||||
| Retention window | Deletes chats that have been archived long enough and orphaned chat files | 30 days |
|
||||
|
||||
A conversation needs to be inactive for `auto_archive_days`, then
|
||||
archived for `retention_days`, before it is deleted. The two windows
|
||||
stack additively. With auto-archive disabled by default, inactive
|
||||
chats are never auto-archived; once an admin opts in by setting a
|
||||
non-zero `auto_archive_days`, a conversation lives for at least
|
||||
`auto_archive_days + retention_days` from its last message before it
|
||||
is permanently removed.
|
||||
|
||||
Auto-archive (like manual archive) resets the per-chat retention
|
||||
clock, so the full `retention_days` runs from the tick that archived
|
||||
the chat, not from its last message.
|
||||
|
||||
Setting either value to `0` disables that step. Setting
|
||||
`auto_archive_days` to `0` means inactive chats are never
|
||||
auto-archived (users still archive manually). Setting
|
||||
`retention_days` to `0` means archived chats are kept indefinitely.
|
||||
|
||||
## Configuration
|
||||
|
||||
The auto-archive window is stored as the
|
||||
`agents_chat_auto_archive_days` key in the `site_configs` table.
|
||||
The default is `0` (disabled); set to a positive number of days to
|
||||
enable auto-archiving.
|
||||
|
||||
Use the admin API to read or update the value:
|
||||
|
||||
GET /api/experimental/chats/config/auto-archive-days
|
||||
PUT /api/experimental/chats/config/auto-archive-days
|
||||
|
||||
## Rollout advice
|
||||
|
||||
Auto-archive is disabled by default, so upgrading to a release that
|
||||
includes this feature will not archive any existing chats until an
|
||||
admin opts in. The first tick after enabling auto-archive on a
|
||||
deployment with a long history will process up to 1,000 root chats
|
||||
(and their children). If your deployment has a large backlog, the
|
||||
initial rollout will span many ticks. This is intentional and avoids
|
||||
stalling the rest of `dbpurge` during the first run. To disable,
|
||||
set `auto_archive_days` back to `0`.
|
||||
|
||||
## Audit trail
|
||||
|
||||
Each auto-archived root chat produces an audit log entry with the
|
||||
background subsystem tag `chat_auto_archive`. Cascaded children are
|
||||
not audited individually. The audit entry records the chat ID, owner
|
||||
ID, and organization ID, and the diff shows `archived` flipping from
|
||||
`false` to `true`.
|
||||
@@ -4,6 +4,10 @@ Coder Agents automatically cleans up old conversation data to manage database
|
||||
growth. Archived conversations and their associated files are periodically
|
||||
purged based on a configurable retention period.
|
||||
|
||||
Conversations become eligible for purging only after they are archived. Old
|
||||
conversations can be archived manually, or automatically. See
|
||||
[Auto-Archive](./chat-auto-archive.md) for how the two controls interact.
|
||||
|
||||
## How it works
|
||||
|
||||
A background process runs approximately every 10 minutes to remove expired
|
||||
|
||||
Reference in New Issue
Block a user