You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(operator): harden AI suggester prompt with worked examples
Rewrite the rule-suggester system prompt around the actual single-rule output
shape (llmSuggestedRule): one transform_type, one rule per request. The
previous prompt described the types accurately but gave the model no concrete
examples to anchor the decision between move / copy / glob / regex.
New prompt adds:
- Explicit response-shape template with field-level "for move or copy" /
"for glob or regex" guidance.
- Default rules for destination_branch ("main") and commit_strategy
("pull_request" unless clearly a direct commit).
- Four worked Input/Output examples — one per transform type — using
realistic paths (mflix-java-spring prefix rename, mflix README copy,
agg/python glob with ${relative_path}, tutorials/v2 regex with named
captures).
Also exports the prompt as services.SuggestRuleSystemPrompt and wires it
into cmd/test-llm so the smoke test exercises the exact prompt writers hit
via the UI. Verified end-to-end against the Grove Foundry APIM gateway:
claude-haiku-4-5 now correctly picks "glob" with ${relative_path} for a
.py-in-directory example (previously chose "move" with the exact file path).
Copy file name to clipboardExpand all lines: cmd/test-llm/main.go
+9-4Lines changed: 9 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -83,13 +83,18 @@ func main() {
83
83
}
84
84
}
85
85
86
-
// 3. GenerateJSON with the real rule-suggester system prompt.
87
-
systemPrompt:=`You are an expert in GitHub Copier workflow configuration. Given a source→target file transformation example, return a JSON object with fields: transform_type ("move"|"copy"|"glob"|"regex"), transform_from, transform_to, pattern, transform_template, name, destination_repo, destination_branch, commit_strategy, explanation. Prefer the simplest transform type that works.`
systemPrompt:=`You are an expert in GitHub Copier workflow configuration. You generate concise, correct YAML rules that match a single source→target file transformation example.
119
+
// SuggestRuleSystemPrompt is the system prompt used by the AI rule suggester.
120
+
// Exported so cmd/test-llm can exercise the real prompt end-to-end against
121
+
// the configured provider (same prompt writers will hit via the UI).
122
+
constSuggestRuleSystemPrompt=`You are a configuration generator for GitHub Copier workflows.
123
+
124
+
Given a single source→target file transformation example, output ONLY a valid JSON object — no markdown, no prose outside the JSON. Generate ONE rule describing ONE transformation.
125
+
126
+
Transform types (prefer the simplest that works — move > copy > glob > regex):
127
+
- "move" — rename a directory prefix. Matches any file under transform_from; replaces the prefix with transform_to. Use when the source and target share the subpath below the renamed prefix.
128
+
- "copy" — rename ONE exact file. Use when the example is a specific file pair, not a pattern.
129
+
- "glob" — wildcards in pattern (e.g. "dir/**/*.ext"). Use "${relative_path}" in transform_template to preserve subdir structure after the matched prefix.
130
+
- "regex" — Go RE2 regex with named captures (e.g. "(?P<name>.+)"). Use ONLY when move/copy/glob cannot express the rename.
131
+
132
+
Response shape (omit fields that don't apply to the chosen transform_type):
"explanation": "one sentence describing what this rule does"
144
+
}
145
+
146
+
Rules:
147
+
- destination_branch defaults to "main"; commit_strategy defaults to "pull_request" (use "direct" only if the user's intent is clearly a direct commit).
148
+
- If the user did not provide a target repo, use a placeholder like "org/target-repo" so the writer can fill it in.
149
+
- name should be short and kebab-case, derived from the source directory or file.
150
+
- The rule MUST produce the user's target path when applied to their source path. Verify the logic before responding.
151
+
152
+
Examples
122
153
123
-
The copier supports 4 transform types (pick the simplest that works):
124
-
- move: { from: "prefix/path", to: "new/prefix" } — renames a directory prefix. Matches any file under "from" and replaces the prefix with "to".
125
-
- copy: { from: "exact/file.md", to: "new/file.md" } — renames one exact file. Use only when source is a single specific file.
126
-
- glob: { pattern: "dir/**/*.ext", transform: "new/${relative_path}" } — matches files by glob pattern. Use "${relative_path}" to preserve subdirectory structure.
127
-
- regex: { pattern: "dir/(?P<name>.+)\\.ext", transform: "new/${name}.ext" } — uses Go regex with named capture groups. Use ONLY when move/copy/glob are insufficient.
Output: {"name":"mflix-java-spring-server","destination_repo":"mongodb/sample-app-java-mflix","destination_branch":"main","commit_strategy":"pull_request","transform_type":"move","transform_from":"mflix/server/java-spring","transform_to":"server","explanation":"Renames the mflix/server/java-spring prefix to server when copying into the target repo."}
Output: {"name":"mflix-readme","destination_repo":"mongodb/sample-app-java-mflix","destination_branch":"main","commit_strategy":"pull_request","transform_type":"copy","transform_from":"mflix/README-JAVA-SPRING.md","transform_to":"README.md","explanation":"Copies one specific README file and renames it in the destination."}
Output: {"name":"agg-python","destination_repo":"org/shared-examples","destination_branch":"main","commit_strategy":"pull_request","transform_type":"glob","pattern":"agg/python/**/*.py","transform_template":"shared/python/${relative_path}","explanation":"Matches any .py file under agg/python and preserves the subdirectory structure under shared/python."}
140
162
141
-
IMPORTANT: The generated rule MUST produce the user's target file when applied to their source file. Test your logic mentally before responding.`
Output: {"name":"tutorials-versioned","destination_repo":"org/docs-site","destination_branch":"main","commit_strategy":"pull_request","transform_type":"regex","pattern":"tutorials/v(?P<ver>[0-9]+)/(?P<slug>.+)\\.mdx","transform_template":"docs/${slug}-v${ver}.mdx","explanation":"Extracts version and slug from the source path and rebuilds the target filename with the version as a suffix."}`
142
165
166
+
// askLLMForRule sends a structured prompt to the LLM and parses the JSON response.
0 commit comments