Migrate Octokit calls to AI SDK tools
createGithubTools(options?)
Returns a record of AI SDK tools you can pass to generateText or streamText. All options are optional — the SDK reads GITHUB_TOKEN from your environment by default:
type GithubToolsOptions = {
token?: GithubTokenInput
requireApproval?: boolean | Partial<Record<GithubWriteToolName, boolean>>
overrides?: Partial<Record<string, ToolOverrides>>
preset?: GithubToolPreset | GithubToolPreset[]
author?: CommitIdentity
committer?: CommitIdentity
coAuthors?: CommitIdentity[]
}
type GithubTokenInput = string | (() => Promise<string>)
type CommitIdentity = {
name: string
email: string
}
type GithubToolPreset =
| 'code-review'
| 'issue-triage'
| 'repo-explorer'
| 'ci-ops'
| 'maintainer'
Minimal usage — reads GITHUB_TOKEN automatically:
import { createGithubTools } from '@github-tools/sdk'
const tools = createGithubTools()
With a preset and explicit token:
import { createGithubTools } from '@github-tools/sdk'
const tools = createGithubTools({
token: 'github_pat_xxxxxxxxxxxx',
preset: 'repo-explorer',
})
See Scope with presets for preset details and Control write safety for approval options.
Tool overrides
The overrides option lets you customize any AI SDK tool() property on a per-tool basis, keyed by tool name:
import { createGithubTools } from '@github-tools/sdk'
const tools = createGithubTools({
overrides: {
deleteGist: { needsApproval: false },
listIssues: { description: 'List bugs for the current sprint' },
},
})
import type { ToolOverrides } from '@github-tools/sdk'
Supported override properties:
| Property | Type | Description |
|---|---|---|
description | string | Custom tool description for the model |
title | string | Human-readable title |
strict | boolean | Strict mode for input generation |
needsApproval | boolean | function | Gate execution behind approval |
providerOptions | ProviderOptions | Provider-specific metadata |
onInputStart | function | Callback when argument streaming starts |
onInputDelta | function | Callback on each streaming delta |
onInputAvailable | function | Callback when full input is available |
toModelOutput | function | Custom mapping of tool result to model output |
Core properties (execute, inputSchema, outputSchema) cannot be overridden.
Commit attribution
The author, committer, and coAuthors options control how commits are attributed when using createOrUpdateFile or mergePullRequest:
import { createGithubTools } from '@github-tools/sdk'
const tools = createGithubTools({
token: 'github_pat_xxxxxxxxxxxx',
coAuthors: [
{ name: 'my-bot[bot]', email: '12345+my-bot[bot]@users.noreply.github.com' }
]
})
| Option | Type | Description |
|---|---|---|
author | CommitIdentity | The person who wrote the code. Falls back to the authenticated user. |
committer | CommitIdentity | The person who applied the commit. Falls back to the authenticated user. |
coAuthors | CommitIdentity[] | Additional contributors. Added as Co-authored-by trailers to commit messages. |
Commits made via the GitHub API are automatically signed by GitHub's web-flow key, passing branch protection rules that require signed commits.
See Commit attribution for detailed guidance.
createGithubAgent(options)
Returns a ToolLoopAgent with GitHub tools and system instructions pre-configured. The token is also auto-detected from GITHUB_TOKEN:
type GithubAgentOptions = {
model: string
token?: GithubTokenInput
preset?: GithubToolPreset | GithubToolPreset[]
requireApproval?: boolean | Partial<Record<GithubWriteToolName, boolean>>
system?: string
author?: CommitIdentity
committer?: CommitIdentity
coAuthors?: CommitIdentity[]
}
Use this when you want:
- reusable
.generate()/.stream()calls across multiple prompts - preset-aware system instructions without manual wiring
- a centralized agent definition shared across your codebase
import { createGithubAgent } from '@github-tools/sdk'
const agent = createGithubAgent({
model: 'anthropic/claude-sonnet-4.6',
preset: 'code-review',
system: 'You review PRs for security issues. Cite file paths and line numbers.',
})
createDurableGithubAgent(options)
Returns a WorkflowAgent for use inside a Vercel Workflow function ("use workflow"). Each LLM step and each GitHub tool invocation runs as a durable, retryable workflow step. Import from the workflow subpath:
import { createDurableGithubAgent } from '@github-tools/sdk/workflow'
Requires optional peer dependencies workflow and @ai-sdk/workflow — see Installation.
Options align with createGithubAgent (model, token, preset, requireApproval, instructions, additionalInstructions, stopWhen, temperature, and other agent options passed through). Write tools honor requireApproval via needsApproval — the workflow pauses until the user approves or denies.
import { createDurableGithubAgent } from '@github-tools/sdk/workflow'
import { getWritable } from 'workflow'
import type { ModelCallStreamPart, ModelMessage } from 'ai'
export async function githubAssistant(messages: ModelMessage[], token: string) {
'use workflow'
const agent = createDurableGithubAgent({
model: 'anthropic/claude-sonnet-4.6',
token,
preset: 'maintainer',
requireApproval: true,
})
const writable = getWritable<ModelCallStreamPart>()
await agent.stream({ messages, writable })
}
Conceptual overview: Durable workflows (Vercel Workflow).
createGithubTools(options) — eve
Returns a defineDynamic sentinel for eve's agent/tools/ directory. Import from @github-tools/sdk/eve:
import { createGithubTools } from '@github-tools/sdk/eve'
Requires optional peer dependencies eve and ai v7 — see Installation and eve agents.
import { createGithubTools } from '@github-tools/sdk/eve'
export default createGithubTools({
preset: 'code-review',
requireApproval: {
mergePullRequest: true,
createIssue: 'once',
addPullRequestComment: false,
},
})
type EveGithubToolsOptions = {
token?: GithubTokenInput
preset?: GithubToolPreset | GithubToolPreset[]
requireApproval?: boolean | Partial<Record<GithubWriteToolName, EveApprovalValue>>
overrides?: EveToolOverrides
author?: CommitIdentity
committer?: CommitIdentity
coAuthors?: CommitIdentity[]
}
type EveApprovalValue =
| boolean
| 'always'
| 'once'
| 'never'
| Approval // from eve/tools
Also exports individual eve tool factories (listPullRequests(), createIssue(), …) for one-tool-per-file layouts. Approval supports once, predicates, and eve helper passthrough — unlike the Workflow subpath, approval is enforced at runtime.
connectGithubTools(connector, options?)
Import from @github-tools/sdk/connect. Returns the same tool record as createGithubTools, backed by a Vercel Connect connector. Scopes are derived from preset unless overridden in connect.scopes:
import { connectGithubTools } from '@github-tools/sdk/connect'
const tools = connectGithubTools('github/my-connector', {
preset: 'code-review',
connect: {
installationId: 'inst_abc',
repositories: ['my-org/my-repo'],
},
})
type ConnectGithubToolsOptions = GithubToolsOptions & {
connect?: GithubConnectParams
}
type GithubConnectParams = Omit<ConnectTokenParams, 'subject'> & {
repositories?: string[]
}
subject is always { type: 'app' }. See Vercel Connect guide.
connectGithubTools(connector, options?) — eve
Import from @github-tools/sdk/connect/eve. Same as the AI SDK variant but returns a defineDynamic sentinel. Set build.externalDependencies: ['@vercel/connect'] in agent.ts until eve externalizes transitive Connect imports from workspace-linked packages (TODO(eve-connect-bundle)).
import { connectGithubTools } from '@github-tools/sdk/connect/eve'
export default connectGithubTools('github/my-connector', {
preset: 'maintainer',
})
connectGithubToken(connector, options?)
Returns a lazy GithubTokenInput backed by getToken. Use with createGithubTools when you only need the token provider:
import { connectGithubToken } from '@github-tools/sdk/connect'
import { createGithubTools } from '@github-tools/sdk'
const tools = createGithubTools({
preset: 'ci-ops',
token: connectGithubToken('github/my-connector', { preset: 'ci-ops' }),
})
Pass the same preset to connectGithubToken — it derives Connect scopes independently of the preset given to createGithubTools.
connectGithubScopesForPreset(preset?)
Returns Vercel Connect scope strings for a preset or combined presets. Without a preset, returns the union of all preset scopes.
resolveGithubToken(token?)
Resolves a GithubTokenInput (token string, async provider, or the process.env.GITHUB_TOKEN fallback) to a token string. Throws when no token is available.
createOctokit(token?)
Returns a configured @octokit/rest instance. Use this when you need lower-level GitHub API access or want to build custom tool factories:
import { createOctokit, resolveGithubToken } from '@github-tools/sdk'
const octokit = createOctokit(await resolveGithubToken())
const { data } = await octokit.repos.get({ owner: 'HugoRCD', repo: 'github-tools' })