Skip to content

Edit long instructions and skills safely ​

A Sales assistant's instructions often run to tens of thousands of characters, and its skills hold more. To change one rule, you don't need to read the whole text and send it all back. Read the part you need, change exactly the text you name, check the diff, and keep every earlier version within reach.

This works from Claude Code, Codex, or any MCP client connected to the MyChatBot plugin or to the Sales-Management MCP (sales_assistants domain). Every tool and parameter is in the Sales tools reference.

The loop ​

  1. Read the outline.
  2. Read only the part you change.
  3. Patch with dry_run and check the diff.
  4. Save the same patch with expected_version.
  5. Test the change in a private test chat.
  6. Restore the previous version if the result is worse.

1. Read the outline ​

assistant_view_instructions with just the assistant_id returns the outline, not the text: every markdown heading with its line range. It also returns the version to keep for step 4, the size of the text, and draft_pending, which says whether a builder draft exists.

json
{ "assistant_id": "123" }

2. Read only the part you change ​

Pass one of these:

  • section — a heading exactly as the outline lists it, such as "## Delivery";
  • start_line and end_line — up to 400 lines per call;
  • search — matching lines with a few lines of context around each.

To search only one part, add search to section or to start_line (with or without end_line).

3. Patch with a dry run ​

assistant_patch_instructions takes up to 20 edits and applies them in order:

EditWhat it does
{"op": "replace", "find": "…", "replace": "…"}Replaces the found text. An empty replace deletes it.
{"op": "insert_after", "find": "…", "text": "…"}Inserts text right after the found text. Start text with a line break to begin a new line.
{"op": "append", "text": "…"}Adds text on a new line at the end.
json
{
  "assistant_id": "123",
  "dry_run": true,
  "edits": [
    { "op": "replace", "find": "We ship in 2 days.", "replace": "We ship in 1 day." },
    { "op": "insert_after", "find": "Pay by card.", "text": "\nCash on delivery is also available." }
  ]
}

Every find must occur exactly once in the current text, character for character: spaces, line breaks, quotes, and letter case. If one doesn't match, or matches more than once, the whole call is refused and nothing changes. The error names the edit:

  • Not found: copy the text again from a fresh view. If a match differs only in letter case, quotes, or whitespace, the error says so.
  • Several matches: the error lists their line numbers. Add surrounding words to the find until it matches once.

Nothing is ever matched approximately.

A dry run returns the unified diff and a short summary of lines added and removed. Show it to whoever approves the change.

4. Save with expected_version ​

Send the same edits without dry_run, and pass the version from step 1 as expected_version. If someone saved the instructions in between, the call is refused with the current version: read again and redo the edits.

A saved patch goes through the same save as assistant_update_instructions: moderation, instruction history, and the voice-agent sync. It is live at once: an active assistant uses the new text in its next reply. The answer has the new version, the previous_version, and the diff. If moderation flags the new text, nothing is saved and, as with any flagged save, the assistant is switched off until someone switches it back on.

A pending builder draft can undo the change

The patch changes the live instructions, the ones the assistant uses now. If a builder draft is pending (draft_pending: true), it is kept, and the answer carries a warning. Accepting that draft later in the dashboard replaces the live text, this change included. Discard the draft, or make the same change in it.

5. Test the change ​

Re-run the conversation that prompted the change in a private test chat (test_chat_start, test_chat_send) or with your saved eval scenarios. See Testing and evals.

6. Restore a version ​

assistant_list_instruction_versions lists saved versions, newest first, and marks the one equal to the live text. Pass diff_history_id to see what changed since a version. Then preview a restore with assistant_restore_instructions and dry_run, and run it without.

Before a patch or a restore replaces the live text, the tool saves it as a version if it isn't one already, so you can undo the undo.

Skills ​

Skills use the same loop with their own tools: assistant_view_skill, assistant_patch_skill, assistant_list_skill_versions, and assistant_restore_skill.

  • assistant_view_skill returns the skill's name, slug, description, always-active flag, sort order, and version. A short skill comes back whole.
  • An edit of a skill's name, description, instructions, or always-active flag keeps the previous state as a version, whether it was made from the dashboard, Claude, or any other tool. A deleted skill keeps its last state too, unless it went with its deleted assistant.
  • assistant_restore_skill sets an existing skill back, or recreates a deleted one on its assistant, under its old ID when it's free.

When a call is refused ​

ErrorWhat happenedWhat to do
find_not_foundA find occurs nowhere. near_miss says if a match differs only in letter case, quotes, or whitespace.Copy the text exactly from a fresh view.
find_not_uniqueA find occurs more than once; match_lines lists where.Add surrounding text until it matches once.
version_conflictThe text changed since you read it.Read it again and redo the edits.
moderation_flaggedModeration flagged the new instructions. Nothing was saved, and the assistant was switched off, as with any flagged save.Change the flagged text, save, and switch the assistant back on.
empty_resultThe edits would leave the text empty.Use fewer deletions.
history_unavailableThe live instructions could not be saved as a version first, so nothing was written.Try again in a moment.
skill_history_unavailableSkill version history isn't set up yet, so skill patches and restores are refused.Try again later; a dry_run still works. Don't fall back to a full replacement you can't undo.
section_not_foundNo line is exactly that heading.Copy the heading from the outline.
history_not_foundThat history_id is not a saved version of this assistant.List the versions again.

See also ​