Skip to content

feat: create a prompt variation from the content of an add - #953

Open
ctawiah wants to merge 1 commit into
ctawiah/share-variation-selection-1e8afrom
ctawiah/create-variations-1e8a
Open

ctawiah wants to merge 1 commit into
ctawiah/share-variation-selection-1e8afrom
ctawiah/create-variations-1e8a

Conversation

@ctawiah

@ctawiah ctawiah commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Context

sync prompts add can only start syncing a variation that exists in LaunchDarkly. The only command that creates a variation is link, which needs an external prompt file. This PR lets an add create a variation in an existing config from its content. The create, adopt, and refuse rules are the same as for a tool or skill. The next PR adds the flags.

What changes

  • create.Input gets the model config key. A variation create needs the content and the model config key. The name is optional, and comes from the key by default.
  • The content is read with the body rules of a variation file. For an agent config, it is the instructions. For a completion config, it is role blocks such as <system>...</system>, or plain text as one system message. local.ParsePromptBody is exported for this.
  • These checks run before any request:
    • the content flag and blank values
    • at most one --key, and no project-key/config-key/variation-key arguments with a create
    • the create rules for the key
    • every missing flag without a terminal: variation creation requires --project, --config-key, --key, and --model-config-key without interactive input
  • These checks run before any write:
    • no local file and no sync.lock row
    • the config exists, and the content parses for its mode
    • the model config exists
    • no archived variation holds the key
  • The config can already have the variation. If the prompt matches, and the name and the model config key match when passed, add starts syncing it through the existing add. The model config version, the model settings, and the tools and skills are not compared. So a variation whose model config has a newer version can still be adopted. Otherwise add stops and changes nothing.
  • A create uses the latest version of the model config, as link does. It writes the file with upsert: true and no ref, and runs the same steps as a tool create.

With the flags of the next PR, against a stand-in for the LaunchDarkly API:

$ ldcli sync prompts add --project demo --config-key summary --key brief --model-config-key claude \
    --name "Brief summary" --content "$(printf '<system>Be brief.</system>\n<user>{{ticket}}</user>')" --yes --no-input -o plaintext
Prompts
  created   demo/summary/brief   new

1 applied.
Note: Created .launchdarkly/demo/configs/summary/brief.prompt.md.

The new file:

---
formatVersion: 1
upsert: true
mode: completion
key: brief
name: Brief summary
modelConfigKey: claude
modelConfigVersion: 2
model:
  custom: {}
  modelName: claude-sonnet
  parameters: {}
---

<system>
Be brief.
</system>

<user>
{{ticket}}
</user>

Design notes

  • runCreate now has one driver, createResource, and one builder for each kind: createAttachment and createVariation. The driver plans in memory, asks, writes, applies the plan of the one resource, and removes the file after a definite failure. A builder gives it the reviewed row and the write. adopt is shared too.
  • link and the create build the new variation with one create.NewVariation.
  • As for a skill, the model config and name questions come after the config read, so an adopt asks nothing that it ignores. Without a terminal, all four flags are required.
  • The content is parsed with the mode of the config before the model config read. So a bad role block reads only the config.
  • The reviewed row comes from planResource with the new variation in memory. The variation has a model config version, so the model canonicalization of the plan does not change it. The row that the apply reads from the new file is therefore the same.

Review focus

  • Is the adopt comparison right? The prompt is always compared, and the name and the model config key only when passed.
  • Does the archived-key check run before any write?
  • Does the shared driver keep the tool and skill creates as they were?

Verification

  • go test ./... and golangci-lint run (v2.9.0) pass. Every tool and skill create test passes without edits after the driver split.
  • New tests through Runner.Run:
    • an agent create, pinned to the latest model config
    • completion creates from role blocks and from plain text
    • a create that leaves other pending changes alone
    • an adopt with a newer model config version
    • refusals for the prompt, the name, and the model config key
    • the archived key, a missing model config, and a rejected create that removes its file
    • every flag error with no request, and a role-block error that reads only the config
  • TestCreateRefusesTheKeyOfAnArchivedVariation fails without the archived check.
  • create/prompt_test.go covers the error for missing flags, both content modes, and the adopt comparison.
  • I built ldcli and ran the flag-only scripts of the sync commands and of link against a stand-in for the LaunchDarkly API. Their output is the same as before this PR. The next PR has the manual checks of the variation create.

Related changes

This stack builds on #937 to #941, which are merged.

  1. fix: exclude expanded tools from prompt diffs #957: Exclude expanded tools from prompt diffs (ctawiah/fix-prompt-tool-diff-5b1c)
  2. fix: plan a tool or skill row when a variation newly references it #945: Plan a tool or skill row when a variation newly references it (ctawiah/plan-referenced-attachments-1e8a)
  3. feat: keep unused tools and skills, and detach any resource kind #946: Keep unused tools and skills, and detach any resource kind (ctawiah/keep-unused-attachments-1e8a)
  4. feat: add tools and skills from LaunchDarkly #947: Add tools and skills from LaunchDarkly (ctawiah/add-attachments-1e8a)
  5. feat: route sync, add, and detach by scope #948: Route sync, add, and detach by scope (ctawiah/route-scopes-1e8a)
  6. feat: add the sync all, sync tools, and sync skills commands #949: Add the sync all, sync tools, and sync skills commands (ctawiah/scope-commands-1e8a)
  7. feat: create a tool or a skill from the content of an add #950: Create a tool or a skill from the content of an add (ctawiah/create-attachments-1e8a)
  8. feat: add the create flags of sync tools add and sync skills add #951: Add the create flags of sync tools add and sync skills add (ctawiah/create-attachment-flags-1e8a)
  9. refactor: share the selection of a new variation, and check any kind before an add #952: Share the selection of a new variation, and check any kind before an add (ctawiah/share-variation-selection-1e8a)
  10. This PR: create a prompt variation from the content of an add (ctawiah/create-variations-1e8a)
  11. feat: add the create flags of sync prompts add #954: Add the create flags of sync prompts add (ctawiah/create-variation-flags-1e8a)

Note

Overview
sync prompts add can create a new prompt variation from flags (content, model config, optional name) in an existing AI config, using the same create / adopt / refuse behavior as tools and skills.

Create validation moves to shared create.Input with ModelConfigKey and Check(kind syncdomain.Kind). --content is parsed like a variation file (ParsePromptBody is exported): agent instructions vs completion role blocks or plain text. runCreate splits into createVariation and createAttachment, with a shared createResource / adopt path. Existing remote variations with matching prompt (and optional name / model config key) start syncing without mutation; mismatches and archived keys are rejected before writes. link builds variations via create.NewVariation.

Reviewed by Cursor Bugbot for commit 4e53008. Bugbot is set up for automated code reviews on this repo. Configure here.

@ctawiah
ctawiah added this pull request to stack #955 October 22, 2026 22:19
@cursor
cursor Bot force-pushed the ctawiah/create-variations-1e8a branch from 083d37a to 7320951 Compare October 23, 2026 00:13
@ctawiah
ctawiah removed this pull request from stack #955 October 23, 2026 00:15
@ctawiah
ctawiah added this pull request to stack #960 October 23, 2026 00:16
@ctawiah
ctawiah marked this pull request as ready for review October 23, 2026 14:12
@ctawiah
ctawiah requested a review from a team as a code owner October 23, 2026 14:12
@ctawiah
ctawiah requested review from nieblara and nkester-ld and removed request for a team October 23, 2026 14:12
@cursor
cursor Bot force-pushed the ctawiah/create-variations-1e8a branch from 7320951 to b7a258a Compare October 23, 2026 14:27
@cursor
cursor Bot force-pushed the ctawiah/create-variations-1e8a branch 2 times, most recently from 9e3ebfd to e561178 Compare October 23, 2026 14:44
@cursor
cursor Bot force-pushed the ctawiah/create-variations-1e8a branch 2 times, most recently from 0c269d2 to 266321b Compare October 23, 2026 17:07
@cursor
cursor Bot force-pushed the ctawiah/create-variations-1e8a branch from 266321b to 07f03a7 Compare October 23, 2026 21:17
@cursor
cursor Bot force-pushed the ctawiah/create-variations-1e8a branch from 07f03a7 to 28a23d3 Compare October 23, 2026 21:26
An add of prompt variations can now carry the content of a new
variation: its prompt, its model config key, and its name. The prompt is
read with the body rules of a variation file, so it is the instructions
of an agent config, or the role blocks of a completion config, where
plain text is one system message.

A create needs a config that exists. It uses the latest version of the
model config, as link does, and refuses the key of an archived variation.
If the config has the variation with the prompt, name, and model config
key that the user passed, add starts syncing it through the existing
add. If one of them differs, add stops and changes nothing.

The create runs the same steps as a tool or skill create, so runCreate
now has one driver and one builder for each kind. The driver plans the
create in memory, asks for confirmation, writes the file, applies the
plan of the new resource, and removes the file after a definite failure.
link and add build the new variation with the same NewVariation. The
command flags come in the next change.
@cursor
cursor Bot force-pushed the ctawiah/create-variations-1e8a branch from 28a23d3 to 4e53008 Compare October 23, 2026 21:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant