[go: up one dir, main page]

Frameworks
Create a complete GitHub agent in 3 files with eve — defineDynamic registers all 42 tools, with durable human-in-the-loop approval (always, once, predicates).

eve is Vercel's filesystem-first agent framework: an agent is a folder with instructions, a model config, and tools. With @github-tools/sdk/eve, that folder becomes a complete GitHub agent in 3 files — all 42 tools registered from a single file, with durable human-in-the-loop approval that actually pauses the session until a person approves.

There are two ways to add the tools to an eve agent: importing @github-tools/sdk/eve directly (below), or mounting them as an eve extension via @github-tools/eve-extension. Both are supported today — the extension is the direction this integration is moving toward and will become the recommended way to add GitHub tools to an eve agent.

Add GitHub tools to an eve agent

The whole agent

Three files. That's the entire thing:

You are a GitHub assistant. Use the GitHub tools to inspect repos, PRs, and issues.
Ask before merging or closing anything destructive.

Run it:

Terminal
npx eve dev

You now have a GitHub agent that can read repos, review PRs, triage issues, and manage CI — with every write operation gated behind durable approval by default. The full example lives in examples/eve-agent/ (or pnpm dev:eve-agent from the monorepo root).

Install

Add eve and ai v7 (required peer of eve v0.19+) alongside the SDK:

pnpm add @github-tools/sdk eve ai zod

Ensure ai resolves to v7 — eve v0.19+ is not compatible with AI SDK v6. You still need GITHUB_TOKEN (or pass token explicitly). See Installation.

For Vercel Connect, use connectGithubTools from @github-tools/sdk/connect/eve — it mints the token lazily. Do not top-level await getToken(...) in agent/tools/ modules.

One file, all tools

createGithubTools() returns a defineDynamic value: eve resolves the tool set on session.started, so a single default export registers every tool. Scope and gate as needed:

agent/tools/github.ts
import { createGithubTools } from '@github-tools/sdk/eve'

export default createGithubTools({
  preset: ['code-review', 'issue-triage'],
  requireApproval: {
    mergePullRequest: true,
    createIssue: 'once',
    addPullRequestComment: false,
    createOrUpdateFile: ({ toolInput }) => toolInput?.owner !== 'vercel-labs',
  },
})

Map keys become tool names — the model sees listPullRequests, createIssue, and so on (same names as the AI SDK package). There is no automatic file-slug prefix when returning a tool map.

Durable approval, done right

This is eve's headline advantage over the boolean needsApproval on the AI SDK and Workflow paths: approval pauses the session durably until a human responds, and policies are expressive:

ValueMaps toBehavior
true / 'always'always()Require approval on every call
false / 'never'never()Skip approval
'once'once()Approve once per session, then auto-allow
predicatecustom ApprovalInput-dependent gate (toolInput, session context)
always() / once() / never()passthroughImport helpers from eve/tools/approval

Default (no requireApproval): all write tools → always(). Unlisted write tools keep the always() fail-safe default. Read tools never require approval.

For durable HITL with the standard boolean/per-tool config, use durable Workflow agents with WorkflowAgent. See also Control write safety for the AI SDK surface.

Cherry-pick one tool per file

For the filesystem-native eve layout, import individual factories:

agent/tools/list_pull_requests.ts
import { listPullRequests } from '@github-tools/sdk/eve'

export default listPullRequests()

Each factory returns a defineTool value. The filename slug becomes the tool name when exported alone.

Presets and options

All presets (code-review, issue-triage, repo-explorer, ci-ops, maintainer) work with createGithubTools. Options mirror the AI SDK surface:

OptionDescription
tokenGitHub PAT (defaults to GITHUB_TOKEN)
presetSingle preset or array to merge
requireApprovalGlobal, per-tool, or predicate approval (eve)
overridesPer-tool description, approval, toModelOutput, outputSchema
author / committer / coAuthorsCommit attribution for file/merge tools

High-volume read tools (listPullRequestFiles, getCommit, getFileContent) include conservative default toModelOutput projections — full payloads still reach channels; the model sees trimmed diffs/content.

Idempotency

eve replays completed steps but re-runs steps interrupted mid-execution:

ToolIdempotency
createOrUpdateFileNatural when content + sha unchanged
closeIssueNatural when already closed
createBranchNatural when branch exists at same SHA
addIssueComment, createIssue, mergePullRequest, …Not idempotent

Gate non-idempotent writes behind always() or once() where replay safety matters.

eve vs AI SDK vs Workflow SDK

AI SDKeveWorkflow SDK
Import@github-tools/sdk@github-tools/sdk/eve@github-tools/sdk/workflow
Tool registrationcreateGithubTools() objectdefineDynamic in agent/tools/createGithubTools() in workflow
Approvalboolean needsApprovalalways / once / predicatesboolean needsApproval (durable pause)
Durabilityin-processeve session (filesystem-first)"use workflow" steps

Vercel Connect

Skip GITHUB_TOKEN entirely and mint the token from a Connect connector — connectGithubTools derives scopes from preset and fetches the token lazily inside each tool call:

agent/agent.ts
import { defineAgent } from 'eve'

export default defineAgent({
  model: 'anthropic/claude-sonnet-5',
  // TODO(eve-connect-bundle): remove when eve externalizes transitive @vercel/connect
  build: {
    externalDependencies: ['@vercel/connect'],
  },
})
agent/tools/github.ts
import { connectGithubTools } from '@github-tools/sdk/connect/eve'

export default connectGithubTools('github/my-connector', {
  preset: 'maintainer',
})

See Vercel Connect for the connector setup checklist and multi-tenant scoping.

eve extension

@github-tools/eve-extension packages the same tools as a mountable eve extension instead of importing @github-tools/sdk/eve directly into agent/tools/. This is the recommended direction going forward — the direct @github-tools/sdk/eve import above keeps working and isn't going away, but new agents should prefer the extension:

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

export default githubExtension({
  connector: 'github/my-connector', // or token: process.env.GITHUB_TOKEN
  preset: 'code-review',
  requireApproval: {
    addPullRequestComment: ({ toolInput }) => toolInput?.owner !== 'vercel-labs',
  },
})

code-review is used here (rather than maintainer) because it pairs cleanly with a Connect connector — maintainer and repo-explorer include gist tools, and GitHub only grants gist access to user access tokens, never the installation tokens Connect mints, so gist calls 403 over Connect (see Tokens & Auth). The requireApproval predicate above is also a real gate, not a no-op: write tools already require approval by always() by default, so { mergePullRequest: true } would change nothing — a predicate is what actually narrows or loosens the default.

Tools are exposed to the model as <namespace>__<toolName>, where <namespace> comes from the mount file's name — agent/extensions/github.ts yields github__listPullRequests, github__createIssue, and so on. Not yet published to npm; see examples/eve-extension-agent and packages/github-tools-eve-extension to build and consume it from the workspace.

Once published, this extension will become the primary, recommended way to add GitHub tools to an eve agent; @github-tools/sdk/eve remains supported for direct imports.

External references