Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/eve-extension-token-provider.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@github-tools/eve-extension': minor
---

Accept an async token provider in the extension's `token` config (`string | (() => Promise<string>)`), matching the SDK's `GithubTokenInput`. Agents authenticating with a GitHub App can pass their installation-token minter directly instead of falling back to the `@github-tools/sdk/eve-runtime` subpath.
13 changes: 12 additions & 1 deletion apps/docs/content/docs/2.frameworks/1.eve-extension.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ export default githubExtension({

| Field | Type | Notes |
|---|---|---|
| `token` | `string?` | Falls back to `GITHUB_TOKEN` when omitted and `connector` is not set |
| `token` | `string \| (() => Promise<string>)` | PAT string, or an async provider for rotating tokens (e.g. a GitHub App installation token) — the same `GithubTokenInput` the SDK accepts; falls back to `GITHUB_TOKEN` when omitted and `connector` is not set |
| `connector` | `string \| (() => string \| Promise<string>)` | Vercel Connect connector name, or a resolver to pick one dynamically (e.g. per environment/tenant); takes priority over `token` |
| `connect` | `record?` | Passed through to `getToken` when `connector` is set |
| `preset` | preset name or array | `code-review`, `issue-triage`, `ci-ops`, `repo-explorer`, `security-audit`, `release-manager`, `discussion-moderator`, `notification-inbox`, `pr-author`, `maintainer`, see [Presets](/guide/presets) |
Expand All @@ -189,6 +189,17 @@ export default githubExtension({
| `overrides` | `record` | Per-tool `description` / `approval` / `toModelOutput` / `outputSchema` |
| `author` / `committer` / `coAuthors` | commit identity | Attribution for commit-creating tools, see [Commit Attribution](/guide/commit-attribution) |

The provider runs on every tool call, so short-lived tokens stay fresh:

```ts [agent/extensions/github.ts]
import githubExtension from '@github-tools/eve-extension'

export default githubExtension({
token: () => mintInstallationToken(),
preset: 'issue-triage',
})
```

## Durable multi-turn sessions

The extension registers each tool with an **authored inline** `execute` and `toModelOutput` that only close over a serializable tool `name`, then rebuilds session options from the extension config on every call via `@github-tools/sdk/eve-runtime`. Tools resolve on `step.started` so registration stays fresh across durable steps. That pattern survives multi-turn eve Workflow replay (see [#51](https://github.com/vercel-labs/github-tools/issues/51), [#99](https://github.com/vercel-labs/github-tools/issues/99)). Prefer this mount over the deprecated [`createGithubTools`](/deprecated/eve) / [`connectGithubTools`](/deprecated/eve) paths for Slack / multi-turn durable agents — those register tools from inside `node_modules` and are skipped on replay. Author `overrides.toModelOutput` inline in the agent; a function imported from a library will not get a durable descriptor.
Expand Down
2 changes: 2 additions & 0 deletions apps/docs/content/docs/4.guide/4.tokens-and-auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ import githubExtension from '@github-tools/eve-extension'
export default githubExtension({ connector: 'github/my-connector', preset: 'maintainer' })
```

For a GitHub App you manage yourself, pass `token: () => mintInstallationToken()` instead — same `GithubTokenInput` as the SDK.

(For the deprecated direct import, [`connectGithubTools` from `@github-tools/sdk/connect/eve`](/deprecated/eve#vercel-connect) still works the same way.)
::

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ Tools are exposed to the model as `<namespace>__<toolName>`: `agent/extensions/g

`token`, `connector`, `connect`, `preset`, `include`, `exclude`, `requireApproval`, `overrides`, `author`/`committer`/`coAuthors`, see `/frameworks/eve-extension#config-schema`.

`token` is `string | (() => Promise<string>)` (`GithubTokenInput`). Pass an async provider for rotating GitHub App installation tokens. Falls back to `GITHUB_TOKEN` when omitted; `connector` takes priority.

`include` **adds** to `preset` (union). Use it standalone for an exact set, or on top of a preset to add a missing tool. `exclude` **removes** tool names from the resolved set, use it to drop a couple of tools from a larger preset:

```ts
Expand Down
2 changes: 1 addition & 1 deletion packages/github-tools-eve-extension/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ extension/

| Field | Type | Notes |
|---|---|---|
| `token` | `string?` | Falls back to `GITHUB_TOKEN` when omitted and `connector` is not set |
| `token` | `string \| (() => Promise<string>)` (optional) | PAT string, or an async provider for rotating tokens (e.g. a GitHub App installation token) — the same `GithubTokenInput` the SDK accepts; falls back to `GITHUB_TOKEN` when omitted and `connector` is not set |
| `connector` | `string \| (() => string \| Promise<string>)` (optional) | Vercel Connect connector name, or a resolver to pick one dynamically (e.g. per environment/tenant); takes priority over `token` |
| `connect` | `record?` | Passed through to `getToken` when `connector` is set |
| `preset` | preset name or array | `code-review`, `issue-triage`, `ci-ops`, `repo-explorer`, `security-audit`, `release-manager`, `discussion-moderator`, `notification-inbox`, `pr-author`, `maintainer` |
Expand Down
14 changes: 11 additions & 3 deletions packages/github-tools-eve-extension/extension/extension.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { GithubTokenInput } from '@github-tools/sdk'
import type { GithubConnectorInput } from '@github-tools/sdk/connect'
import {
GITHUB_TOOL_NAMES,
Expand Down Expand Up @@ -32,8 +33,13 @@ export interface GithubExtensionContext {
* Declared as an interface (not only a Zod schema) so IDE hovers show JSDoc.
*/
export interface GithubExtensionConfig {
/** GitHub PAT. Falls back to `GITHUB_TOKEN` when omitted and `connector` is not set. */
token?: string
/**
* GitHub token: a PAT string, or a `() => Promise<string>` provider for
* tokens that rotate (a GitHub App installation token, a vault lease).
* Same input the SDK accepts. Falls back to `GITHUB_TOKEN` when omitted
* and `connector` is not set.
*/
token?: GithubTokenInput
/**
* Vercel Connect connector name (e.g. `github/my-connector`), or a
* `() => string | Promise<string>` resolver for picking one dynamically
Expand Down Expand Up @@ -91,7 +97,9 @@ const commitIdentitySchema = z.object({
})

const configSchema = z.object({
token: z.string().optional(),
token: z.custom<GithubTokenInput>(
value => typeof value === 'string' || typeof value === 'function',
).optional(),
connector: z.custom<GithubConnectorInput>(
value => typeof value === 'string' || typeof value === 'function',
).optional(),
Expand Down
Loading