---
title: "Presets"
description: "Give the model only the tools one job needs, or let a model pick them for each conversation."
canonical_url: "https://github-tools.com/presets"
---
# Presets

> Give the model only the tools one job needs, or let a model pick them for each conversation.

## Overview

A preset in GitHub tools is a named list of tools for one job, such as reviewing pull requests or triaging issues. Without one, the model gets all 97 tools and reads every definition on every request. With one, it only sees the tools it can use for that job, and an agent also gets a system prompt written for it.

<preset-picker>



</preset-picker>

Pick one preset, combine a few, or let a decision model choose the tools from what the user asks.

## Configure

Set `preset` where you create the tools or the agent:

```ts [review.ts]
import { createGithubTools } from '@github-tools/sdk'

const tools = createGithubTools({ preset: 'code-review' })
// 28 tools: pull requests, reviews, diffs, blame, checks, and 9 writes such as createPullRequestReview
```

<table>
<thead>
  <tr>
    <th>
      Preset
    </th>
    
    <th>
      Tools
    </th>
    
    <th>
      Writes
    </th>
    
    <th>
      For
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        repo-explorer
      </code>
    </td>
    
    <td>
      39
    </td>
    
    <td>
      0
    </td>
    
    <td>
      Read-only questions about code, history, pull requests, issues, discussions, gists, workflows and releases
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        code-review
      </code>
    </td>
    
    <td>
      28
    </td>
    
    <td>
      9
    </td>
    
    <td>
      Reviewing pull requests: diffs, files, blame and checks, then reviews, comments, thread replies and commit statuses
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        issue-triage
      </code>
    </td>
    
    <td>
      32
    </td>
    
    <td>
      16
    </td>
    
    <td>
      Labeling, assigning, commenting on, reacting to, closing, reopening and creating issues, with milestones and sub-issues
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ci-ops
      </code>
    </td>
    
    <td>
      21
    </td>
    
    <td>
      4
    </td>
    
    <td>
      Diagnosing failed GitHub Actions runs, triggering, cancelling or re-running workflows, and reporting commit statuses
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        security-audit
      </code>
    </td>
    
    <td>
      32
    </td>
    
    <td>
      3
    </td>
    
    <td>
      Reading code, CI logs and code scanning, Dependabot and secret scanning alerts, then reporting findings as issues
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        release-manager
      </code>
    </td>
    
    <td>
      24
    </td>
    
    <td>
      4
    </td>
    
    <td>
      Comparing tags, summarizing changes, and creating, editing or deleting releases
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        discussion-moderator
      </code>
    </td>
    
    <td>
      11
    </td>
    
    <td>
      2
    </td>
    
    <td>
      Reading and answering Discussions, and linking related issues
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        notification-inbox
      </code>
    </td>
    
    <td>
      11
    </td>
    
    <td>
      1
    </td>
    
    <td>
      Triaging the user's notification inbox. Needs a user token, see <a href="https://github-tools.com/auth#permissions-per-preset">
        Auth
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pr-author
      </code>
    </td>
    
    <td>
      23
    </td>
    
    <td>
      9
    </td>
    
    <td>
      Branching, editing files, opening a pull request, keeping its branch up to date and answering its review threads
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        maintainer
      </code>
    </td>
    
    <td>
      97
    </td>
    
    <td>
      48
    </td>
    
    <td>
      Everything, the same as omitting <code>
        preset
      </code>
    </td>
  </tr>
</tbody>
</table>

Every preset includes five core read tools, so a task never stalls on context: `getRepository`, `getFileContent`, `getRepositoryTree`, `searchCode` and `listCommits`. `code-review`, `issue-triage` and `pr-author` also include `getCollaboratorPermission`, so the agent can check whether the person asking may push before it acts for them.

## Combine presets

When one agent spans two jobs, pass an array. The tools are merged, and `createGithubAgent` merges the system prompts:

```ts [triage-and-review.ts]
const tools = createGithubTools({ preset: ['code-review', 'issue-triage'] })
```

Start from the smallest preset that does the job.

## Let the agent pick tools

When one agent takes open-ended requests, no fixed preset fits them all. `preset: 'auto'` asks the [decision model](https://github-tools.com/approval#let-a-model-decide) which tools the conversation's first request needs, and lists only those:

```ts [agent.ts]
import { createGithubAgent } from '@github-tools/sdk'

const agent = createGithubAgent({
  model: 'anthropic/claude-opus-5.5',
  preset: 'auto',
})

await agent.generate({ prompt: 'Why is CI failing on main?' })
// lists the core read tools plus the CI tools this request needs
```

The agent lists the core read tools, plus up to 8 others that the decision model rates at least 0.5.

The rest of the catalog stays reachable through one extra tool, `callGithubTool`. The model passes a tool's `name` and its arguments as `input`, or leaves out `input` to read the tool's schema first. The call goes through the named tool's approval and overrides.

### Pick tools with generateText or streamText

Without `createGithubAgent`, call `selectTools` yourself once per conversation and pass the result as `activeTools`:

```ts [stream.ts]
import { createGithubTools, selectTools } from '@github-tools/sdk'
import { streamText } from 'ai'

const activeTools = await selectTools(messages)

const result = streamText({
  model: 'anthropic/claude-opus-5.5',
  tools: createGithubTools(),
  activeTools,
  messages,
})
```

`selectTools` takes the same `evaluation` options as a second argument.

### Keep the prompt cache across requests

Providers that cache prompts, such as Anthropic, cache from the start: tool definitions first, then the system prompt and the conversation. When the tool list changes between two requests, the provider writes the whole conversation to its cache again, which costs more than reading it.

So `preset: 'auto'` picks tools once, on the conversation's first request, and keeps them for the rest of it. That's `evaluation.scope: 'session'`, the default. A later request that needs another tool reaches it through `callGithubTool`, which doesn't change the list. Set `scope: 'turn'` to pick again for each new request.

`createGithubAgent` keeps its picks in memory, so on serverless another instance decides again and can pick differently. Pass `evaluation.store` to keep them in your own storage:

```ts [agent.ts]
import { createGithubAgent } from '@github-tools/sdk'
import { kv } from './kv'

const agent = createGithubAgent({
  model: 'anthropic/claude-opus-5.5',
  preset: 'auto',
  evaluation: {
    store: {
      get: key => kv.get<string[]>(key),
      set: (key, value) => kv.set(key, value, { ex: 60 * 60 * 24 }),
    },
  },
})
```

### Route to presets instead

Routing to presets gives each request a whole job's tools and that job's system prompt, instead of single tools. Set `evaluation.selection: 'presets'`, and the agent picks up to 2 presets rated at least 0.7 for each request. When none qualifies, or the decision call fails, it uses the read-only `repo-explorer`, so a vague request never gets write tools.

The agent routes each new request again, so the tool list, and with it the prompt cache, can change between requests.

With `generateText` or `streamText`, `selectPresets(messages)` returns the presets to pass to `createGithubTools({ preset })`.

### Adjust the selection

<table>
<thead>
  <tr>
    <th>
      <code>
        evaluation
      </code>
      
       option
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      What it does
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        selection
      </code>
    </td>
    
    <td>
      <code>
        'tools'
      </code>
    </td>
    
    <td>
      <code>
        'presets'
      </code>
      
       routes to presets instead of single tools
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        scope
      </code>
    </td>
    
    <td>
      <code>
        'session'
      </code>
      
      , or <code>
        'turn'
      </code>
      
       for presets on <code>
        createGithubAgent
      </code>
    </td>
    
    <td>
      Pick once per conversation, or for each request
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        minToolProbability
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      Lowest rating for a tool to be listed
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        maxTools
      </code>
    </td>
    
    <td>
      <code>
        8
      </code>
    </td>
    
    <td>
      Tools listed beyond the core read tools
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        minPresetProbability
      </code>
    </td>
    
    <td>
      <code>
        0.7
      </code>
    </td>
    
    <td>
      Lowest rating for a preset, with <code>
        selection: 'presets'
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        maxPresets
      </code>
    </td>
    
    <td>
      <code>
        2
      </code>
    </td>
    
    <td>
      Presets combined, with <code>
        selection: 'presets'
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        store
      </code>
    </td>
    
    <td>
      In memory
    </td>
    
    <td>
      <code>
        { get, set }
      </code>
      
       storage for <code>
        createGithubAgent
      </code>
      
      's picks
    </td>
  </tr>
</tbody>
</table>

`model` and `providerOptions` are shared with `requireApproval: 'auto'`, see [Approval](https://github-tools.com/approval#let-a-model-decide).

## FAQ

<accordion>
<accordion-item label="Where are the exact tool lists?">

`PRESET_TOOLS` exports the tools of each preset, and `CORE_READ_TOOLS` the five core read tools. [Auth](https://github-tools.com/auth#permissions-per-preset) lists the token permissions each preset needs.

</accordion-item>

<accordion-item label="Should one agent combine presets, or should I use several agents?">

When an assistant has several distinct roles, give each role its own agent and preset, and have a manager agent hand requests to them. Combine presets when a single job needs both.

</accordion-item>

<accordion-item label="What if the decision call fails?">

If the decision call fails, `preset: 'auto'` falls back to the read-only `repo-explorer` tools and logs an [`EVALUATION_FAILED`](https://github-tools.com/errors) warning. Routing to presets also falls back to `repo-explorer`.

</accordion-item>

<accordion-item label="How does a call through callGithubTool look in approval requests?">

Approval requests and UI parts show it as `callGithubTool`, with the GitHub tool in `input.name` and its arguments in `input.input`.

</accordion-item>

<accordion-item label="Do different agents share stored picks?">

No, agents configured differently don't share picks, because the keys come from the request and the routing settings.

</accordion-item>

<accordion-item label="Can routing pick maintainer?">

No, routing to presets never picks `maintainer`, so it never exposes the whole catalog.

</accordion-item>

<accordion-item label="Why does scope: 'session' throw with selection: 'presets'?">

Routing to presets has no `callGithubTool`, so `createGithubAgent` can't keep presets for a whole session: the combination throws [`SESSION_SCOPE_NEEDS_TOOL_SELECTION`](https://github-tools.com/errors). The eve extension accepts both, because it defers the other tools.

</accordion-item>

<accordion-item label="Does preset: 'auto' work outside the AI SDK agent?">

The [eve extension](https://github-tools.com/integrations/eve) supports `preset: 'auto'`, [TanStack AI](https://github-tools.com/integrations/tanstack-ai) supports it for routing to presets only, and `createDurableGithubAgent` doesn't accept it. The eve extension defers unlisted tools behind its own search, and keeps its picks in the session, ignoring `store`.

</accordion-item>

<accordion-item label="Which versions do I need?">

`preset: 'auto'` needs `ai` 7.0.105 or later.

</accordion-item>
</accordion>


## Sitemap

See the full [sitemap](https://github-tools.com/sitemap.md) for all pages.
