You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[feature] Coding agents cannot show a pull request — add a Pulls panel, and make "don't fetch if nothing changed" true with GitHub conditional requests #401
The Coder can open a PR and then cannot show you one
Four GitHub tools exist (connectors/github.ts): github_workflow_runs, github_list_issues, github_read_issue, github_create_issue. There is no pull-request support anywhere — grep
for /pulls across workers/api/src returns nothing.
Worse than absent: the one place GitHub hands them over, we discard them. lib/github-issues.ts:107
with the comment "GitHub returns PRs from the issues endpoint too". Correct for an issues list,
and it means the data arrives and is dropped.
This matters because the Coder's safest mode produces exactly this artefact. The per-repo merge
policy (#314) has a pr setting: the agent does the work, opens a pull request and stops. That is
the mode a careful owner picks — and having picked it, the console can show them the issue that
started the work and the build that ran, but not the PR that is the actual output. They have to
leave for GitHub to see what their agent just produced.
The Coding tab already has the shape: Terminal · Issues · Builds. This is the missing fourth.
What to show
Per repo, the open PRs, and for each: number, title, author, draft flag, mergeable/conflicted,
review state (approved / changes requested / none), check status (which is already fetched for
Builds — fetchWorkflowRuns — so the two panels are reading the same runs from different angles),
branch, updated-at. Plus, and this is the one that closes the loop: which PR came from which
agent run, when a Pilot opened it.
Caching — and specifically "don't fetch if nothing changed"
There are TWO layers here and the repo has exactly one of them. Naming both, because the cheap one
is not the one that protects the rate limit.
Layer 1 — console → platform. Built, for builds only.routes/coding-repos.ts:293-300 merges a
durable KV history, computes a weak ETag over the result, and answers If-None-Match with a 304.
That is the pattern to copy verbatim; it saves bytes and re-renders.
Layer 2 — platform → GitHub. Not built, anywhere. Even the builds path fetches GitHub on every
poll and only then decides whether to send the client a 304. GitHub's own conditional requests are
the mechanism the request is asking for:
store the ETag GitHub returned, send it back as If-None-Match;
a 304 does not count against the rate limit — that is the entire point of it;
on 304, serve the cached copy and touch nothing else.
That is what makes "don't fetch if there were no changes" true rather than approximately true. It
matters here more than usual: /deployments documents an unauthenticated fallback on a shared
~60/hr IP budget, and issues-mode calls listIssues on every Loop iteration via nextIssue()
— today that is an unconditional GitHub round-trip per iteration, per repo.
Complementary, not a substitute: ?since= on issues and sort=updated&direction=desc on pulls
bound the payload; the ETag bounds the request.
Suggested shape
lib/github-prs.ts beside github-issues.ts — same auth path (App installation token, with
the same unauth fallback for public repos), same summary/detail split.
A conditional-fetch helper, shared by issues, PRs and builds: store {etag, payload, fetchedAt} in KV per (repo, resource), send If-None-Match, return the cached payload on 304.
One place, three consumers — and it retro-fixes the builds path's Layer-2 gap.
GET /:instanceId/coding/repos/:repoId/pulls mirroring /deployments, including the weak
ETag and 304 for Layer 1.
A Pulls panel in the Coding tab beside Issues and Builds.
github_list_pulls / github_read_pull tools (read scope) so the agent can answer "is my PR
green? did anyone review it?" without a browser. github_merge_pull is deliberately NOT proposed
here — merging is what the merge policy ([safety] Nothing decides whether an agent may merge to main — three unattended merges already happened #314) governs, and a tool that bypasses it would hand
the agent the authority that ticket exists to withhold.
Worth deciding
Does the PR panel show only PRs the agent opened, or all of them? All of them is more useful
and makes the panel a real view of the repo; agent-opened ones should be badged, since "did my
agent actually open it" is the question the board cannot answer today.
How stale may a cached list be when GitHub is unreachable? The builds path already answers
this well (durable KV history that survives retention and transient failure) and the same answer
probably applies.
The Coder can open a PR and then cannot show you one
Four GitHub tools exist (
connectors/github.ts):github_workflow_runs,github_list_issues,github_read_issue,github_create_issue. There is no pull-request support anywhere —grepfor
/pullsacrossworkers/api/srcreturns nothing.Worse than absent: the one place GitHub hands them over, we discard them.
lib/github-issues.ts:107with the comment "GitHub returns PRs from the issues endpoint too". Correct for an issues list,
and it means the data arrives and is dropped.
This matters because the Coder's safest mode produces exactly this artefact. The per-repo merge
policy (#314) has a
prsetting: the agent does the work, opens a pull request and stops. That isthe mode a careful owner picks — and having picked it, the console can show them the issue that
started the work and the build that ran, but not the PR that is the actual output. They have to
leave for GitHub to see what their agent just produced.
The Coding tab already has the shape: Terminal · Issues · Builds. This is the missing fourth.
What to show
Per repo, the open PRs, and for each: number, title, author, draft flag, mergeable/conflicted,
review state (approved / changes requested / none), check status (which is already fetched for
Builds —
fetchWorkflowRuns— so the two panels are reading the same runs from different angles),branch, updated-at. Plus, and this is the one that closes the loop: which PR came from which
agent run, when a Pilot opened it.
Caching — and specifically "don't fetch if nothing changed"
There are TWO layers here and the repo has exactly one of them. Naming both, because the cheap one
is not the one that protects the rate limit.
Layer 1 — console → platform. Built, for builds only.
routes/coding-repos.ts:293-300merges adurable KV history, computes a weak ETag over the result, and answers
If-None-Matchwith a 304.That is the pattern to copy verbatim; it saves bytes and re-renders.
Layer 2 — platform → GitHub. Not built, anywhere. Even the builds path fetches GitHub on every
poll and only then decides whether to send the client a 304. GitHub's own conditional requests are
the mechanism the request is asking for:
ETagGitHub returned, send it back asIf-None-Match;That is what makes "don't fetch if there were no changes" true rather than approximately true. It
matters here more than usual:
/deploymentsdocuments an unauthenticated fallback on a shared~60/hr IP budget, and issues-mode calls
listIssueson every Loop iteration vianextIssue()— today that is an unconditional GitHub round-trip per iteration, per repo.
Complementary, not a substitute:
?since=on issues andsort=updated&direction=descon pullsbound the payload; the ETag bounds the request.
Suggested shape
lib/github-prs.tsbesidegithub-issues.ts— same auth path (App installation token, withthe same unauth fallback for public repos), same summary/detail split.
{etag, payload, fetchedAt}in KV per (repo, resource), sendIf-None-Match, return the cached payload on 304.One place, three consumers — and it retro-fixes the builds path's Layer-2 gap.
GET /:instanceId/coding/repos/:repoId/pullsmirroring/deployments, including the weakETag and 304 for Layer 1.
Pullspanel in the Coding tab beside Issues and Builds.github_list_pulls/github_read_pulltools (read scope) so the agent can answer "is my PRgreen? did anyone review it?" without a browser.
github_merge_pullis deliberately NOT proposedhere — merging is what the merge policy ([safety] Nothing decides whether an agent may merge to main — three unattended merges already happened #314) governs, and a tool that bypasses it would hand
the agent the authority that ticket exists to withhold.
Worth deciding
and makes the panel a real view of the repo; agent-opened ones should be badged, since "did my
agent actually open it" is the question the board cannot answer today.
this well (durable KV history that survives retention and transient failure) and the same answer
probably applies.
Files:
workers/api/src/lib/github-issues.ts:103-122,workers/api/src/lib/connectors/github.ts:134-165,workers/api/src/routes/coding-repos.ts:264-305,workers/api/src/lib/build-history.ts.