> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gourmand.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Edit Role

> Edit model role

export const ModelRecommendations = ({role = "all"}) => {
  const parseMarkdownLinks = text => {
    const regex = /\[([^\]]+)\]\(([^)]+)\)/g;
    const parts = [];
    let lastIndex = 0;
    let match;
    let key = 0;
    while ((match = regex.exec(text)) !== null) {
      if (match.index > lastIndex) {
        const beforeText = text.slice(lastIndex, match.index);
        if (beforeText) {
          parts.push(<span key={key++}>{beforeText}</span>);
        }
      }
      const [, linkText, url] = match;
      parts.push(<a key={key++} href={url} target="_blank" rel="noopener noreferrer" style={{
        color: "#0066cc",
        textDecoration: "underline"
      }}>
          {linkText}
        </a>);
      lastIndex = regex.lastIndex;
    }
    if (lastIndex < text.length) {
      const remainingText = text.slice(lastIndex);
      if (remainingText) {
        parts.push(<span key={key++}>{remainingText}</span>);
      }
    }
    return parts.length > 0 ? parts : text;
  };
  const modelRecs = {
    agent_plan: {
      open: ["[Qwen3 Coder (480B)](https://hub.gourmand.dev/openrouter/qwen3-coder)", "[Qwen3 Coder (30B)](https://hub.gourmand.dev/ollama/qwen3-coder-30b)", "[Devstral (27B)](https://hub.gourmand.dev/ollama/devstral)", "[Kimi K2 (1T)](https://hub.gourmand.dev/openrouter/kimi-k2)", "[gpt-oss (120B)](https://hub.gourmand.dev/openrouter/gpt-oss-120b)", "[gpt-oss (20B)](https://hub.gourmand.dev/ollama/gpt-oss-20b)", "[GLM 4.5 (355B)](https://hub.gourmand.dev/openrouter/glm-4-5)", "[GLM 4.5 Air (106B)](https://hub.gourmand.dev/openrouter/glm-4-5-air)"],
      closed: ["[Claude Opus 4.1](https://hub.gourmand.dev/anthropic/claude-4-1-opus)", "[Claude Sonnet 4](https://hub.gourmand.dev/anthropic/claude-4-sonnet)", "[GPT-5](https://hub.gourmand.dev/openai/gpt-5)", "[Gemini 2.5 Pro](https://hub.gourmand.dev/google/gemini-2.5-pro)"],
      notes: "Closed models are slightly better than open models"
    },
    chat_edit: {
      open: ["[Qwen3 Coder (480B)](https://hub.gourmand.dev/openrouter/qwen3-coder)", "[Qwen3 Coder (30B)](https://hub.gourmand.dev/ollama/qwen3-coder-30b)", "[gpt-oss (120B)](https://hub.gourmand.dev/openrouter/gpt-oss-120b)", "[gpt-oss (20B)](https://hub.gourmand.dev/ollama/gpt-oss-20b)"],
      closed: ["[Claude Opus 4.1](https://hub.gourmand.dev/anthropic/claude-4-1-opus)", "[Claude Sonnet 4](https://hub.gourmand.dev/anthropic/claude-4-sonnet)", "[GPT-5](https://hub.gourmand.dev/openai/gpt-5)", "[Gemini 2.5 Pro](https://hub.gourmand.dev/google/gemini-2.5-pro)"],
      notes: "Closed and open models have pretty similar performance"
    },
    autocomplete: {
      open: ["[QwenCoder2.5 (1.5B)](https://hub.gourmand.dev/ollama/qwen2.5-coder-1.5b)", "[QwenCoder2.5 (7B)](https://hub.gourmand.dev/ollama/qwen2.5-coder-7b)"],
      closed: ["[Codestral](https://hub.gourmand.dev/mistral/codestral)", "[Mercury Coder](https://hub.gourmand.dev/inception/mercury-coder)"],
      notes: "Closed models are slightly better than open models"
    },
    apply: {
      open: ["N/A"],
      closed: ["[Relace Instant Apply](https://hub.gourmand.dev/relace/instant-apply)", "[Morph Fast Apply](https://hub.gourmand.dev/morphllm/morph-v2)"],
      notes: "Open models are not good enough for this model role"
    },
    embed: {
      open: ["[Nomic Embed Text](https://hub.gourmand.dev/ollama/nomic-embed-text-latest)", "Qwen3 Embedding"],
      closed: ["[Voyage Code 3](https://hub.gourmand.dev/voyageai/voyage-code-3)", "[Morph Embeddings](https://hub.gourmand.dev/morphllm/morph-embedding-v2)", "Codestral Embed"],
      notes: "Closed models are slightly better than open models"
    },
    rerank: {
      open: ["zerank-1", "zerank-1-small", "Qwen3 Reranker"],
      closed: ["[Voyage Rerank 2.5](https://hub.gourmand.dev/voyageai/rerank-2-5)", "Relace Code Rerank", "[Morph Rerank](https://hub.gourmand.dev/morphllm/morph-rerank-v2)"],
      notes: "Open models are beginning to emerge for this model role"
    },
    next_edit: {
      open: ["[Instinct](https://hub.gourmand.dev/gobi/instinct)"],
      closed: ["[Mercury Coder](https://hub.gourmand.dev/inception/mercury-coder)"],
      notes: "Closed models are better than open models"
    }
  };
  let rolesToShow = [];
  if (!role || role === "all") {
    rolesToShow = Object.keys(modelRecs);
  } else {
    const key = role.toLowerCase().replace(/\s|\//g, "_").replace(/-/g, "_");
    if (modelRecs[key]) {
      rolesToShow = [key];
    }
  }
  if (rolesToShow.length === 0) {
    return <div>No recommendations found for role: {role}</div>;
  }
  return <table style={{
    width: "100%",
    borderCollapse: "collapse",
    marginTop: "1rem"
  }}>
      <thead>
        <tr>
          <th style={{
    textAlign: "left",
    borderBottom: "1px solid #ddd",
    padding: "8px"
  }}>
            Model role
          </th>
          <th style={{
    textAlign: "left",
    borderBottom: "1px solid #ddd",
    padding: "8px"
  }}>
            Best open models
          </th>
          <th style={{
    textAlign: "left",
    borderBottom: "1px solid #ddd",
    padding: "8px"
  }}>
            Best closed models
          </th>
          <th style={{
    textAlign: "left",
    borderBottom: "1px solid #ddd",
    padding: "8px"
  }}>
            Notes
          </th>
        </tr>
      </thead>
      <tbody>
        {rolesToShow.map(roleKey => {
    const rec = modelRecs[roleKey];
    if (!rec) return null;
    return <tr key={roleKey}>
              <td style={{
      fontWeight: 600,
      verticalAlign: "top",
      padding: "8px"
    }}>
                {roleKey.replace(/_/g, " ").replace(/\b\w/g, l => l.toUpperCase())}
              </td>
              <td style={{
      padding: "8px",
      verticalAlign: "top"
    }}>
                {rec.open.map((m, i) => <div key={i} style={{
      marginBottom: "4px"
    }}>
                    {parseMarkdownLinks(m)}
                  </div>)}
              </td>
              <td style={{
      padding: "8px",
      verticalAlign: "top"
    }}>
                {rec.closed.map((m, i) => <div key={i} style={{
      marginBottom: "4px"
    }}>
                    {parseMarkdownLinks(m)}
                  </div>)}
              </td>
              <td style={{
      padding: "8px",
      verticalAlign: "top"
    }}>
                {rec.notes}
              </td>
            </tr>;
  })}
      </tbody>
    </table>;
};

It's often useful to select a different model to respond to Edit instructions than for Chat instructions, as Edits are often more code-specific and may require less conversational readability.

In Gobi, you can add `edit` to a model's roles to specify that it can be used for Edit requests. If no edit models are specified, the selected `chat` model is used.

```yaml title="config.yaml" theme={null}
models:
  - name: Claude 4 Sonnet
    provider: anthropic
    model: claude-3-5-sonnet-latest
    apiKey: <YOUR_ANTHROPIC_API_KEY>
    roles:
      - edit
```

Explore edit models in [the hub](https://hub.gourmand.dev/explore/models?roles=edit). Generally, our recommendations for Edit overlap with recommendations for Chat.

## Model Recommendations

<ModelRecommendations role="chat_edit" />

## Prompt templating

You can customize the prompt template used for editing code by setting the `promptTemplates.edit` property in your model configuration. Gobi uses [Handlebars syntax](https://handlebarsjs.com/guide/) for templating.

Available variables for the edit template:

* `{{{userInput}}}` - The user's edit request/instruction
* `{{{language}}}` - The programming language of the code
* `{{{codeToEdit}}}` - The code that's being edited
* `{{{prefix}}}` - Content before the edit area
* `{{{suffix}}}` - Content after the edit area
* `{{{supportsCompletions}}}` - Whether the model supports completions API
* `{{{supportsPrefill}}}` - Whether the model supports prefill capability

Example:

```yaml theme={null}
models:
  - name: My Custom Edit Template
    provider: openai
    model: gpt-4o
    promptTemplates:
      edit: |
        `Here is the code before editing:
        \`\`\`{{{language}}}
        {{{codeToEdit}}}
        \`\`\`

        Here is the edit requested:
        "{{{userInput}}}"

        Here is the code after editing:`
```
