Repository navigation
feat(conversations): Name conversations after linked issues - #2218
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
BYK
left a comment
There was a problem hiding this comment.
Ideally it would detect anything listed here, assuming github: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/autolinked-references-and-urls
Also alternatives like:
- Let's fix issue 1583 on getsentry/junior
- Let's get PR 1234 fixed up
etc.
There was a problem hiding this comment.
@dcramer, about the question of this PR minting its own tokens: it did at first, but head 4498965 changes that. The title context hook now goes through the proxy.
- The GitHub
conversationTitleContexthook reads issues, PRs and commits throughctx.egress.fetch(operationsgithub.issue.get,github.pull.getandgithub.commit.get). It no longer callsissueInstallationTokenorgithubRequest. - Core builds that egress in
packages/junior/src/chat/plugins/conversation-title-context.tswithcreatePluginEgress. It runs as aconversation-titlesystem actor. That actor gets only installation grants, never user tokens, and it never starts authorization. - The host credential proxy picks the grant and adds the token. It reuses the shared installation lease, and egress policy and audit apply.
- Against
main, this PR's diff has noissueInstallationTokenorgithubRequestcalls.
The webhook route on main still mints installation tokens directly. It does this to read PR commit pages for commit classification and to add the "reviewing" reaction on feedback comments. That code is older than this PR. It has no Turn or credential context, so it never used egress. #2222 moves those calls into webhooks/installation-requests.ts. Its oxlint rules ban direct GitHub calls everywhere in the plugin except credential-support.ts and webhooks/. A possible follow-up is to route the webhook calls through egress as a system actor, the same way title context does.
#2218 first shipped a GitHub plugin hook that minted its own installation token and called `api.github.com` directly. That skipped Junior's credential proxy: egress policy, grant selection, the shared credential lease, and egress audit logs. Review caught it, and #2218 now reads through `ctx.egress`. This adds lint rules so the next one fails CI instead of relying on review. The rules are built-in oxlint rules, applied to `packages/junior-github/src`: - `no-restricted-imports` bans `githubRequest` and `issueInstallationToken` from `credential-support.js`. - `no-restricted-globals` bans `fetch`, and `no-restricted-properties` bans `globalThis.fetch`. The error tells the author to use `ctx.egress.fetch`. Only `credential-support.ts` and `webhooks/` may call GitHub directly. A webhook delivery has no Turn and no egress context. These rules work per file, so this PR also moves the direct GitHub calls out of `plugin.ts`: - The webhook commit-page and feedback-reaction requests move to `webhooks/installation-requests.ts`. - The `issueCredential` body moves to `issueGitHubCredential` in `credential-support.ts`. It needs an `IssueCredentialHookContext`, so other hooks cannot easily misuse it. The installation and user credential helpers are no longer exported. The rules live in the shared `packages/junior/.oxlintrc.json` with `**/junior-github/...` globs. I first tried a package config that extends the shared one, but oxlint 1.79 then fails to load the `anti-slop` JS plugin. The relative `jsPlugins` path does not resolve when the base config is in another directory. Override globs also resolve from the config's own directory, so the globs must use `**/junior-github`. Verification: - `pnpm lint`, `pnpm typecheck`, and the GitHub plugin tests (233) pass. - A probe file in `src/` that imports `issueInstallationToken` and `githubRequest` (direct and nested paths) and calls `fetch` and `globalThis.fetch` gets 8 errors. That is the same pattern as the original #2218 bypass. The new `webhooks/installation-requests.ts` passes. The rules only cover the GitHub plugin. Someone could still get around them, for example by re-exporting a function from another module. The rules are there to catch honest mistakes, not to enforce a security boundary. If #2218 merges first, this branch needs a rebase. Both change the imports in `plugin.ts`. <!-- junior-request-attribution:start --> via **BYK**. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:local%3Aweb%3A705d61c691f47edcb331770c --> -- [View Junior Session in Sentry](https://sentry.sentry.io/explore/conversations/local%3Aweb%3A705d61c691f47edcb331770c/?project=4510944073809921) <!-- junior-session-footer:end --> --------- Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com> Co-authored-by: BYK <burak.kaya@sentry.io>
Add a conversationTitleContext plugin hook. Core passes the first human message to plugins and gives the returned facts to the title model under Linked objects. The GitHub plugin reads the titles of linked issues and pull requests with a read-only token scoped to each repository. Co-Authored-By: BYK <burak.kaya@sentry.io>
…itles Detect issue, pull request, and commit references in the forms that GitHub autolinks, and in prose such as "issue 1583 on getsentry/junior" or "PR 1234". A reference without a repository uses the one repository that the message names, or else the configured github.repo. The title context hook now gets the plugin's config values for the Location. Co-Authored-By: BYK <burak.kaya@sentry.io>
Add the linked object instruction only when plugins return title context. Other title requests then match their eval recordings again, so evals such as the image edit case replay instead of running live. Co-Authored-By: BYK <burak.kaya@sentry.io>
The title context hook minted its own installation token and called GitHub directly. That skipped Junior's credential proxy: egress policy, grant selection, lease reuse, and audit telemetry. Core now gives the hook host-owned egress as a conversation-title system actor. The GitHub hook reads issues, pull requests, and commits through it. The system actor gets only installation grants, never user tokens, and title work never starts authorization. Reads reuse the shared installation lease, so title context no longer mints a token per object. Co-Authored-By: BYK <burak.kaya@sentry.io>
4498965 to
b2e632f
Compare
A conversation that starts with "Fix this " gets a vague title like "Verify Issue 1583 and Submit PR if Valid". The title model only sees the URL, so it can't tell what the issue is about.
This adds a provider-neutral
conversationTitleContextplugin hook. Before core generates a title from the first human message, it asks plugins for short facts about objects linked in that message. The title model sees those facts under "Linked objects", and the prompt tells it to name the object by number and title (for example,Fix #1583: Login fails on Safari).The GitHub plugin implements the hook. It finds up to 3 distinct issue, pull request, and commit references (URLs, GitHub autolinks such as
owner/repo#123, and prose such as "issue 1583 on getsentry/junior") and reads each title.The hook reads through host-owned credentialed egress (
ctx.egress), not a token it mints itself. Title work runs outside the Turn, so core gives it aconversation-titlesystem actor. Egress policy, grant selection, and audit telemetry apply. The system actor gets only installation grants, never user tokens, and title work never starts authorization. Reads reuse the shared installation lease, so no extra token is minted per object.The hook is optional and fails open. Core stops waiting after 5 seconds, ignores hooks that throw, and caps how many lines plugins can return and how long each line can be. If nothing comes back, titles are generated the same way as before. Dispatched runs, which have no human message, don't call the hook.
Note: titles from private repositories in the installation can now show up in conversation titles. Junior can already read and quote that content in replies in the same conversation, with the same installation-read grant.
The new lifecycle eval (
when the first message links a tracked issue…) needs a Roach recording. I couldn't record it locally without the write token, so it will record on its first CI run.via BYK.
--
View Junior Session in Sentry