Skip to content

Commit 98672aa

Browse files
Add rfspec plugin: multi-model spec generation via /rfspec command
Sends user prompt directly to Opus 4.6 (max), GPT-5.4 (xhigh), and Gemini 3.1 Pro (high) in parallel -- each at its maximum reasoning tier. Presents competing responses and lets the user pick or synthesize. Includes a skill that teaches the agent the full workflow: when to invoke rfspec, how to evaluate and compare results, how to synthesize, and where to save the final spec.
1 parent 2c0bfc4 commit 98672aa

File tree

9 files changed

+313
-0
lines changed

9 files changed

+313
-0
lines changed

.factory-plugin/marketplace.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@
2323
"description": "Core Skills for essential functionalities and integrations",
2424
"source": "./plugins/core",
2525
"category": "core"
26+
},
27+
{
28+
"name": "rfspec",
29+
"description": "Request for Spec: fan out a prompt to multiple AI models in parallel and pick or synthesize the best implementation spec",
30+
"source": "./plugins/rfspec",
31+
"category": "productivity"
2632
}
2733
]
2834
}

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ Skills for continuous learning and improvement.
4848
- `frontend-design` - Build web apps, websites, HTML pages with good design
4949
- `browser-navigation` - Browser automation with agent-browser
5050

51+
### rfspec
52+
53+
Fan out a prompt to multiple AI models in parallel and pick or synthesize the best result.
54+
55+
**Skills:**
56+
57+
- `rfspec` - Multi-model spec generation and synthesis workflow
58+
- `/rfspec` - Send a prompt to Opus 4.6, GPT-5.4, and Gemini 3.1 Pro simultaneously and compare results
59+
5160
## Plugin Structure
5261

5362
Each plugin follows the Factory plugin format:
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"name": "rfspec",
3+
"description": "Request for Spec: fan out a prompt to multiple AI models in parallel and pick or synthesize the best implementation spec",
4+
"version": "1.0.0",
5+
"author": {
6+
"name": "Andy Taylor",
7+
"email": "andrew.taylor@factory.ai"
8+
}
9+
}

plugins/rfspec/README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# rfspec
2+
3+
Request for Spec -- fan out a prompt to multiple AI models in parallel and choose or synthesize the best result.
4+
5+
## What it does
6+
7+
`/rfspec` sends your prompt to three models simultaneously (Claude Opus 4.6, GPT-5.4, Gemini 3.1 Pro), each at its maximum reasoning tier. The results are presented side-by-side so you can pick the strongest one or synthesize a combination. No prescriptive system prompt is injected -- the models bring their own reasoning to your request.
8+
9+
## Usage
10+
11+
```
12+
/rfspec <describe what you want to build>
13+
```
14+
15+
Example:
16+
17+
```
18+
/rfspec add a dark mode toggle to the settings page with persistent user preference
19+
```
20+
21+
The command will:
22+
23+
1. Send the prompt to all three models in parallel via `droid exec`, each at its maximum reasoning tier (Opus: max, GPT-5.4: xhigh, Gemini: high)
24+
2. Collect and display each model's response (Options A, B, C)
25+
3. Ask you to pick one as-is or synthesize the best parts
26+
4. Save the chosen result to `specs/active/YYYY-MM-DD-<slug>.md`
27+
28+
## Requirements
29+
30+
- **droid CLI** -- must be installed and authenticated
31+
- **jq** -- for JSON parsing (`brew install jq` on macOS)
32+
- Access to at least one of the three models. Models that fail are skipped gracefully; the command only errors if all three fail.

plugins/rfspec/commands/rfspec

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/usr/bin/env bash
2+
exec "$(dirname "$0")/../skills/rfspec/scripts/run.sh" "$@"
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
---
2+
name: rfspec
3+
version: 1.2.0
4+
description: |
5+
Multi-model spec generation and synthesis. Use when the user wants to:
6+
- Get competing proposals from different AI models
7+
- Compare approaches to a problem from different perspectives
8+
- Synthesize the best parts of several proposals into one spec
9+
Keywords: rfspec, competing specs, multi-model, compare approaches,
10+
multiple perspectives, request for spec, fan out, model comparison.
11+
NOT for: single-model generation, code review, or running tests.
12+
---
13+
14+
# rfspec -- Request for Spec
15+
16+
Fan out a prompt to multiple models, compare their responses, and help the user pick or synthesize the best result.
17+
18+
## Quick Reference
19+
20+
| Task | Action |
21+
|------|--------|
22+
| Generate competing specs | `/rfspec <prompt>` |
23+
| Pick one result | Select via AskUser after comparison |
24+
| Synthesize results | Combine strongest elements when user chooses synthesis |
25+
| Save final spec | Write to `specs/active/YYYY-MM-DD-<slug>.md` |
26+
27+
## Workflow
28+
29+
1. Run `/rfspec <user's prompt>` -- fires parallel model calls, returns labeled options (A, B, C).
30+
2. Evaluate the results -- see [references/evaluation-guide.md](references/evaluation-guide.md).
31+
3. Present the choice to the user via AskUser.
32+
4. Save the selected or synthesized result.
33+
34+
## Saving
35+
36+
Save the final result (picked or synthesized) to:
37+
38+
```
39+
specs/active/YYYY-MM-DD-<slug>.md
40+
```
41+
42+
Where `<slug>` is a short kebab-case name derived from the topic.
43+
44+
## Pitfalls
45+
46+
- Don't summarize each option individually -- compare them against each other.
47+
- Don't concatenate when synthesizing -- resolve contradictions and produce a coherent document.
48+
- If all options are rejected, gather feedback and re-run with a refined prompt.
49+
50+
## Verification
51+
52+
After saving a spec:
53+
54+
1. Confirm the file exists at the expected path.
55+
2. Verify it contains the selected or synthesized content.
56+
3. Report the saved path to the user.
57+
58+
## Examples
59+
60+
Example 1: User wants competing specs
61+
User says: "Get me specs from multiple models for adding a dark mode toggle"
62+
Actions:
63+
64+
1. Run `/rfspec add a dark mode toggle to the settings page with persistent user preference`
65+
2. Read Options A, B, C
66+
3. Compare: "Option A uses CSS variables with a React context, Option B uses Tailwind's dark class with localStorage, Option C uses a theme provider with system preference detection."
67+
4. Present choice via AskUser
68+
Result: User picks Option B, saved to `specs/active/2026-03-06-dark-mode-toggle.md`
69+
70+
Example 2: User wants synthesis
71+
User says: "rfspec this: refactor the auth module to use JWT"
72+
Actions:
73+
74+
1. Run `/rfspec refactor the auth module to use JWT`
75+
2. Compare results, noting Option A has better token rotation but Option C has cleaner middleware
76+
3. User selects "Synthesize"
77+
4. Combine Option A's rotation logic with Option C's middleware structure
78+
Result: Synthesized spec saved to `specs/active/2026-03-06-auth-jwt-refactor.md`
79+
80+
Example 3: All options rejected
81+
User says: "None of these work, they all miss the caching layer"
82+
Actions:
83+
84+
1. Ask what's missing -- user explains the Redis caching requirement
85+
2. Offer to re-run: `/rfspec refactor auth module to use JWT with Redis session caching`
86+
Result: New round of specs generated with caching addressed
87+
88+
## References
89+
90+
- [references/evaluation-guide.md](references/evaluation-guide.md) -- how to compare, synthesize, and handle rejection
91+
- [references/troubleshooting.md](references/troubleshooting.md) -- error codes and fixes
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Evaluation Guide
2+
3+
How to compare and evaluate competing model responses.
4+
5+
## Comparing Options
6+
7+
When results come back from `/rfspec`:
8+
9+
1. **Read all options** before responding. Understand each approach fully.
10+
2. **Identify meaningful differences** -- not cosmetic ones. Focus on:
11+
- Architectural choices (patterns, libraries, data flow)
12+
- Scope differences (what each included or excluded)
13+
- Risk areas (where one flagged something the others missed)
14+
- Concrete vs. vague (which named actual files, functions, steps)
15+
3. **Write a brief comparison** -- 2-4 sentences per option covering strengths and gaps. Compare, don't summarize.
16+
4. **Present the choice** using AskUser:
17+
- Use Option A as-is
18+
- Use Option B as-is
19+
- Use Option C as-is
20+
- Synthesize a refined version combining the best of all three
21+
- None of these work
22+
23+
## Synthesizing
24+
25+
If the user picks synthesis:
26+
27+
1. Start from the strongest option as the base.
28+
2. Pull in specific elements from the others -- name what you're taking and why.
29+
3. Resolve contradictions (don't concatenate).
30+
4. The final result should read as a single coherent document, not a patchwork.
31+
32+
## Handling Rejection
33+
34+
If the user rejects all options:
35+
36+
1. Ask what's missing or wrong.
37+
2. Incorporate their feedback into a refined prompt.
38+
3. Offer to re-run `/rfspec` with the updated prompt.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Troubleshooting
2+
3+
## All three models failed
4+
5+
```
6+
Error: All three models failed. Check that your droid CLI is authenticated...
7+
```
8+
9+
**Cause:** droid CLI not authenticated or models unavailable.
10+
**Solution:** Run `droid` interactively to verify auth, then retry.
11+
12+
## jq not installed
13+
14+
```
15+
Error: jq is required but not installed.
16+
```
17+
18+
**Cause:** jq not on PATH.
19+
**Solution:** `brew install jq` (macOS) or `apt-get install jq` (Linux).
20+
21+
## One or two models failed
22+
23+
```
24+
Note: The following models encountered errors: Opus 4.6
25+
```
26+
27+
**Cause:** Specific model unavailable or rate-limited.
28+
**Solution:** This is handled gracefully -- compare the options that did return. No action needed unless the failed model was critical.
29+
30+
## Command not found
31+
32+
```
33+
/rfspec: command not found
34+
```
35+
36+
**Cause:** Plugin not installed.
37+
**Solution:** Install via `/plugins` UI or `droid plugin install rfspec@factory-plugins --scope user`.
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
# ── guard: dependencies ──────────────────────────────────────────────
5+
command -v jq >/dev/null 2>&1 || { echo "Error: jq is required but not installed. Install it with: brew install jq"; exit 1; }
6+
command -v droid >/dev/null 2>&1 || { echo "Error: droid CLI is required but not found on PATH."; exit 1; }
7+
8+
PROMPT="$*"
9+
10+
if [ -z "$PROMPT" ]; then
11+
echo "Usage: /rfspec <your prompt>"
12+
echo ""
13+
echo "Sends your prompt to three models in parallel (Opus, GPT, Gemini),"
14+
echo "then lets you pick the best spec or synthesize a combination."
15+
exit 1
16+
fi
17+
18+
# ── prompt ────────────────────────────────────────────────────────────
19+
TMPDIR=$(mktemp -d)
20+
trap 'rm -rf "$TMPDIR"' EXIT
21+
22+
echo "$PROMPT" > "$TMPDIR/prompt.md"
23+
24+
# ── models (id, label, max reasoning) ────────────────────────────────
25+
MODEL_A="claude-opus-4-6"; LABEL_A="Opus 4.6"; RE_A="max"
26+
MODEL_B="gpt-5.4"; LABEL_B="GPT-5.4"; RE_B="xhigh"
27+
MODEL_C="gemini-3.1-pro-preview"; LABEL_C="Gemini 3.1 Pro"; RE_C="high"
28+
29+
# ── fire all three in parallel ───────────────────────────────────────
30+
droid exec -m "$MODEL_A" -r "$RE_A" -f "$TMPDIR/prompt.md" -o json 2>/dev/null > "$TMPDIR/a.json" &
31+
PID_A=$!
32+
droid exec -m "$MODEL_B" -r "$RE_B" -f "$TMPDIR/prompt.md" -o json 2>/dev/null > "$TMPDIR/b.json" &
33+
PID_B=$!
34+
droid exec -m "$MODEL_C" -r "$RE_C" -f "$TMPDIR/prompt.md" -o json 2>/dev/null > "$TMPDIR/c.json" &
35+
PID_C=$!
36+
37+
FAIL=""
38+
wait $PID_A 2>/dev/null || FAIL="${FAIL}${LABEL_A} "
39+
wait $PID_B 2>/dev/null || FAIL="${FAIL}${LABEL_B} "
40+
wait $PID_C 2>/dev/null || FAIL="${FAIL}${LABEL_C} "
41+
42+
# ── extract results ──────────────────────────────────────────────────
43+
extract() {
44+
local file="$1"
45+
if [ -s "$file" ]; then
46+
jq -r '.result // empty' "$file" 2>/dev/null || cat "$file"
47+
fi
48+
}
49+
50+
RESULT_A=$(extract "$TMPDIR/a.json")
51+
RESULT_B=$(extract "$TMPDIR/b.json")
52+
RESULT_C=$(extract "$TMPDIR/c.json")
53+
54+
# ── present results ──────────────────────────────────────────────────
55+
echo "=== RFSPEC RESULTS ==="
56+
echo ""
57+
echo "User request: ${PROMPT}"
58+
echo ""
59+
60+
[ -n "$RESULT_A" ] && printf '### Option A -- %s\n\n%s\n\n' "$LABEL_A" "$RESULT_A"
61+
[ -n "$RESULT_B" ] && printf '### Option B -- %s\n\n%s\n\n' "$LABEL_B" "$RESULT_B"
62+
[ -n "$RESULT_C" ] && printf '### Option C -- %s\n\n%s\n\n' "$LABEL_C" "$RESULT_C"
63+
64+
if [ -n "$FAIL" ]; then
65+
echo "Note: The following models encountered errors: ${FAIL}"
66+
echo ""
67+
fi
68+
69+
SUCCESS=0
70+
[ -n "$RESULT_A" ] && SUCCESS=$((SUCCESS + 1))
71+
[ -n "$RESULT_B" ] && SUCCESS=$((SUCCESS + 1))
72+
[ -n "$RESULT_C" ] && SUCCESS=$((SUCCESS + 1))
73+
74+
if [ "$SUCCESS" -eq 0 ]; then
75+
echo "Error: All three models failed. Check that your droid CLI is authenticated"
76+
echo "and the models (${MODEL_A}, ${MODEL_B}, ${MODEL_C}) are available."
77+
exit 1
78+
fi
79+
80+
echo "=== AGENT INSTRUCTIONS ==="
81+
echo "Analyze the specs above. Provide a brief comparison of each model's"
82+
echo "strengths and weaknesses. Then use the AskUser tool to offer:"
83+
echo "- Use Option A (${LABEL_A}) as-is"
84+
echo "- Use Option B (${LABEL_B}) as-is"
85+
echo "- Use Option C (${LABEL_C}) as-is"
86+
echo "- Synthesize a refined spec combining the best of all three"
87+
echo "- No -- none of these work (explain why)"
88+
echo "If the user picks synthesis, combine the strongest elements and save"
89+
echo "to specs/active/YYYY-MM-DD-<slug>.md. If rejected, gather feedback."

0 commit comments

Comments
 (0)