Skip to content

refactor: remove legacy live-read and injected-history chat context paths#26585

Merged
kylecarbs merged 6 commits into
mainfrom
refactor/remove-legacy-chat-context
Jun 23, 2026
Merged

refactor: remove legacy live-read and injected-history chat context paths#26585
kylecarbs merged 6 commits into
mainfrom
refactor/remove-legacy-chat-context

Conversation

@kylecarbs

Copy link
Copy Markdown
Member

This PR makes the agent-pushed pinned snapshot (chat_context_resources) the sole source of workspace context for chats, completing the "Release 5" cleanup. It removes legacy mechanisms now superseded by the snapshot that agents push over dRPC (PushContextState) and refresh via chat-context/refresh.

Removed:

  • Live-read at turn time. MCP tool discovery, skill live-body reads, and the instruction/skill history fallback that dialed the workspace on every turn.
  • Context injected as message history. The persist_workspace_context generation action and its decision-loop guard.
  • The legacy write path. POST/DELETE /api/v2/workspaceagents/me/experimental/chat-context, the agentsdk AddChatContext/ClearChatContext methods, and the CLI one-shot writer.
  • The chats.last_injected_context column and all of its plumbing (migration 000529, queries, db2sdk, dbauthz, audit table, and the frontend ContextUsageIndicator fallback).

Subagent context inheritance no longer copies parent context messages; children now hydrate the parent's pinned chat_context_resources on create, which yields an identical pin for the same workspace and agent.

What stays (still served by the live agent connection, not the snapshot): read_skill_file supporting-file reads, read_skill supporting-file listing, and MCP tool execution.

Note

Migration 000529 drops chats.last_injected_context and recreates the chats_expanded view without it. The down migration restores both.

Decision log (D1-D5)
  • D1 (subagent inheritance): Re-point inheritance from the legacy message copy to a pinned hydrate. Children call hydrateChatContextOnCreate instead of copying parent context messages.
  • D2 (persist_workspace_context): Remove the generation action entirely along with the decision-loop guard it existed to satisfy, since context is never injected into history anymore.
  • D3 (legacy HTTP + CLI): Remove the experimental chat-context POST/DELETE endpoints, the agentsdk methods, and the CLI one-shot. The dRPC push + chat-context/refresh replace them.
  • D4 (frontend fallback): Remove the last_injected_context fallback in ContextUsageIndicator; pinned resources are the sole source.
  • D5 (sequencing): Ship as a single PR rather than a stacked pair.

Coder Agents generated on behalf of @kylecarbs.

…aths

Make the agent-pushed pinned snapshot (chat_context_resources) the sole
source of workspace context for chats. Removes:

- Live-read paths that dial the workspace for skills, MCP, and
  instructions at turn time (MCP discovery, skill live-body reads, and
  the instruction/skill history fallback).
- The context-injected-as-message-history mechanism, including the
  persist_workspace_context generation action and its loop guard.
- The legacy POST/DELETE /chat-context HTTP endpoints, the agentsdk
  AddChatContext/ClearChatContext methods, and the CLI one-shot writer.
- The chats.last_injected_context column and all of its plumbing
  (migration 000529, queries, db2sdk, dbauthz, audit table, frontend).

Subagent context inheritance now hydrates pinned chat_context_resources
on child create instead of copying parent context messages.
@github-actions

Copy link
Copy Markdown

Docs preview

📖 View docs preview for docs/admin/security/audit-logs.md

@datadog-coder

This comment has been minimized.

…imeout

Follow-up to the legacy live-read/injected-history removal so test-go-pg
passes and API-created chats keep first-turn workspace context.

Production:
- Pin a chat to its bound agent's pushed snapshot on the first turn when it
  is still unpinned (ensureChatContextPinnedOnFirstTurn). API-created chats
  carry no agent at create (hydrateChatContextOnCreate is a no-op) and bind
  lazily on the first turn, so without this the first turn read empty pinned
  context whenever the agent pushed before the chat existed. The hook reuses
  the create-path hydration: idempotent (only NULL-hash chats), snapshot-gated
  (no empty stamping), and leaves dirtied chats for the refresh endpoint.
  persistBuildAgentBinding stays passive (rebind-only), honoring the #26438
  contract that the create/push path owns first-time pinning.
- Widen planPathLookupTimeout to defaultDialTimeout + 5s. Removing live-read
  removed connection warming, so the plan-path resolver now does the first
  cold dial; the old 5s budget was smaller than the 30s dial timeout and was
  cut off. Resolve the plan-path block in the parallel turn-prep phase so the
  cold dial overlaps with other work instead of blocking sequentially.

Tests:
- Delete tests of removed live MCP discovery (slow-agent wait, mid-turn
  discovery, retry-after-empty) and their now-orphaned helpers.
- Rewrite the AI-gateway and plan-mode tests to seed pinned context instead
  of mocking live ContextConfig/ListMCPTools, keeping their original intent
  (API-key preservation; plan/ask MCP tool visibility).

Coder Agents generated on behalf of @kylecarbs.
Add TestEnsureChatContextPinnedOnFirstTurn covering the lazy-bind
pinning path that hydrates a chat's pinned context from its agent's
snapshot on the first turn after binding. This is the mechanism that
makes a workspace created mid-turn pin its context on the next turn:
the agent's push cannot hydrate a chat that is not yet bound to it,
and binding stays rebind-only.

Asserts it pins when bound and unpinned with a snapshot present, skips
when already pinned, and skips when agentless.

Coder Agents generated on behalf of @kylecarbs.
Replace the misleading createParentChatWithInheritedContext helper, which
seeded legacy message-part context that the pinned-only system now ignores,
with createWorkspaceBoundParentChat. It binds the parent to a workspace agent
that has pushed a snapshot, so CreateChat pins the parent at create.

Rewrite the subagent spawn test to assert the spawned child inherits the
parent's pinned chat_context_resources verbatim (same source, content hash,
body, and aggregate hash). The child shares the parent's agent and hydrates the
same snapshot on create, so context is reproduced without copying it through
chat history. It still asserts the child is created in computer_use mode.

Coder Agents generated on behalf of @kylecarbs.
@kylecarbs kylecarbs marked this pull request as ready for review June 23, 2026 00:47
Restore AgentChatContextSentinelPath, removed along with contextparts.go, as
the canonical value of the legacy skill-only context-file sentinel. The
chatopenai chain-mode test hardcodes this path and documents the sync against
the constant via a comment, since that test package does not import chatd.
Restore that comment too.

Coder Agents generated on behalf of @kylecarbs.
Replace the positional agentID/serverName/toolName/toolDescription arguments
with an agentMCPToolContext struct so call sites are self-documenting.

Coder Agents generated on behalf of @kylecarbs.
@kylecarbs kylecarbs merged commit cd56ab9 into main Jun 23, 2026
35 of 37 checks passed
@kylecarbs kylecarbs deleted the refactor/remove-legacy-chat-context branch June 23, 2026 01:26
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 23, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants