abelworkflow 1.0.0-rc.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -8
- package/extensions/pi-gpt-responses-compat/index.ts +1 -1
- package/lib/cli/args.mjs +2 -2
- package/lib/cli/main.mjs +39 -41
- package/lib/cli/prompts.mjs +16 -29
- package/lib/installer/assets.mjs +13 -15
- package/lib/installer/install.mjs +18 -32
- package/lib/installer/state.mjs +0 -19
- package/lib/providers/claude.mjs +23 -214
- package/lib/providers/codex.mjs +7 -7
- package/lib/providers/pi.mjs +273 -58
- package/lib/providers/skills.mjs +29 -88
- package/lib/templates/workflow/AGENTS.md +10 -10
- package/lib/templates/workflow/commands/abel-design.md +175 -0
- package/lib/templates/workflow/commands/abel-implement.md +64 -46
- package/lib/templates/workflow/commands/abel-init.md +2 -4
- package/package.json +1 -7
- package/skills/grok-search/.env.example +3 -3
- package/skills/grok-search/SKILL.md +1 -1
- package/skills/grok-search/defaults.json +1 -1
- package/skills/prompt-enhancer/SKILL.md +2 -27
- package/lib/installer/render.mjs +0 -46
- package/lib/templates/workflow/commands/abel-plan.md +0 -82
- package/lib/templates/workflow/commands/abel-research.md +0 -126
- package/skills/prompt-enhancer/.env.example +0 -12
- package/skills/prompt-enhancer/ADVANCED.md +0 -103
- package/skills/prompt-enhancer/requirements.txt +0 -1
- package/skills/prompt-enhancer/scripts/_dotenv.py +0 -32
- package/skills/prompt-enhancer/scripts/enhance.py +0 -144
- package/skills/prompt-enhancer/scripts/prompt_enhancer_entry.py +0 -238
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: abel-plan
|
|
3
|
-
description: Refine approved change into a zero-decision executable plan.
|
|
4
|
-
category: abel
|
|
5
|
-
tags: [abel, plan, PBT]
|
|
6
|
-
argument-hint: [change_name]
|
|
7
|
-
---
|
|
8
|
-
<!-- ABEL:START -->
|
|
9
|
-
**Guardrails**
|
|
10
|
-
- Strictly adhere to **OpenSpec** rules when writing **standardized spec-structured projects**.
|
|
11
|
-
- The goal of this phase is to eliminate ALL decision points from the task flow—implementation should be pure mechanical execution.
|
|
12
|
-
- Do not proceed to implementation until every ambiguity is resolved and every constraint is explicitly documented.
|
|
13
|
-
- Every requirement must have Property-Based Testing (PBT) properties defined—focus on invariants, not just example-based tests.
|
|
14
|
-
- If constraints cannot be fully specified, escalate back to the user or return to the research phase rather than making assumptions.
|
|
15
|
-
- Refer to `openspec/AGENTS.md` for additional conventions; run `openspec update` if the file is missing.
|
|
16
|
-
|
|
17
|
-
**Skill Integration**: See `Stage Skill Matrix` (Plan column)
|
|
18
|
-
|
|
19
|
-
**FORBIDDEN**: Direct implementation code generation
|
|
20
|
-
|
|
21
|
-
**Steps**
|
|
22
|
-
1. Run `openspec view` to display all **Active Changes**, then confirm with the user which change folder (`<change_name>`) they wish to refine into a zero-decision plan.
|
|
23
|
-
|
|
24
|
-
2. Navigate to `openspec/changes/<change_name>/` and review existing artifacts:
|
|
25
|
-
- Check `openspec status --change <change_name>` for artifact completion
|
|
26
|
-
- Use `openspec instructions specs --change <change_name>` for specs guidance
|
|
27
|
-
|
|
28
|
-
3. **Implementation Analysis**: Perform systematic analysis to derive a plan. If the proposal has 3+ interconnected requirements, first break it down into components, identify dependencies, evaluate architectural trade-offs, and surface potential conflicts. Then invoke `/context7-auto-research` to validate framework/library choices:
|
|
29
|
-
```
|
|
30
|
-
/context7-auto-research: "For each technology mentioned in change <change_name>, retrieve official documentation patterns and best practices."
|
|
31
|
-
```
|
|
32
|
-
Produce a consolidated, constraint-complete plan and list any missing constraints as questions to the user.
|
|
33
|
-
|
|
34
|
-
4. **Uncertainty Elimination Audit**: Invoke skills to detect and eliminate remaining ambiguities:
|
|
35
|
-
```
|
|
36
|
-
# First, validate against existing codebase patterns
|
|
37
|
-
{{CODEBASE_RETRIEVAL_PATTERN_AUDIT}}
|
|
38
|
-
# Then audit for ambiguities directly and list them explicitly
|
|
39
|
-
Review change <change_name> for decision points that remain unspecified. For each: [AMBIGUITY] <description> → [REQUIRED CONSTRAINT] <what must be specified>.
|
|
40
|
-
Identify implicit assumptions in change <change_name>. For each: [ASSUMPTION] <description> → [EXPLICIT CONSTRAINT NEEDED] <concrete specification>.
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
**Anti-Pattern Detection** (flag and reject):
|
|
44
|
-
- Information collection without decision boundaries (e.g., "JWT vs OAuth2 vs session—all viable")
|
|
45
|
-
- Technical comparisons without selection criteria
|
|
46
|
-
- Deferred decisions marked as "to be determined during implementation"
|
|
47
|
-
|
|
48
|
-
**Target Pattern** (required for approval):
|
|
49
|
-
- Explicit technology choices with parameters (e.g., "JWT with accessToken TTL=15min, refreshToken TTL=7days")
|
|
50
|
-
- Concrete algorithm selections with configurations (e.g., "bcrypt with cost factor=12")
|
|
51
|
-
- Precise behavioral rules (e.g., "Lock account for 30min after 5 failed login attempts")
|
|
52
|
-
|
|
53
|
-
Iterate with user until ALL ambiguities are resolved into explicit constraints.
|
|
54
|
-
|
|
55
|
-
5. **PBT Property Extraction**: Invoke skills to derive testable invariants:
|
|
56
|
-
```
|
|
57
|
-
"Extract Property-Based Testing properties from change <change_name>. For each requirement: [INVARIANT] <must always hold> → [FALSIFICATION STRATEGY] <how to generate counterexamples>."
|
|
58
|
-
"Define system properties for change <change_name>: [PROPERTY] <name> | [DEFINITION] <formal description> | [BOUNDARY CONDITIONS] <edge cases> | [COUNTEREXAMPLE GENERATION] <approach>."
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
**PBT Property Categories to Extract**:
|
|
62
|
-
- **Commutativity/Associativity**: Order-independent operations
|
|
63
|
-
- **Idempotency**: Repeated operations yield same result
|
|
64
|
-
- **Round-trip**: Encode→Decode returns original
|
|
65
|
-
- **Invariant Preservation**: State constraints maintained across operations
|
|
66
|
-
- **Monotonicity**: Ordering guarantees (e.g., timestamps always increase)
|
|
67
|
-
- **Bounds**: Value ranges, size limits, rate constraints
|
|
68
|
-
|
|
69
|
-
**Reference**
|
|
70
|
-
- Use `openspec show <change_name> --json --deltas-only` to inspect proposal structure when validation fails.
|
|
71
|
-
- Use `openspec list --specs` to check for conflicts with existing specifications.
|
|
72
|
-
- Search existing patterns with `rg -n "INVARIANT:|PROPERTY:|Constraint:" openspec/` before defining new ones.
|
|
73
|
-
- For complex proposals, consider running steps 2-4 iteratively on sub-components.
|
|
74
|
-
- Ask the user directly for ANY ambiguity—do not assume or guess.
|
|
75
|
-
|
|
76
|
-
**Exit Criteria**
|
|
77
|
-
A proposal is ready to exit the Plan phase only when:
|
|
78
|
-
- [ ] Zero ambiguities remain (verified by step 4 audit)
|
|
79
|
-
- [ ] All PBT properties documented with falsification strategies
|
|
80
|
-
- [ ] `openspec validate <change_name> --strict` returns zero issues
|
|
81
|
-
- [ ] User has explicitly approved all constraint decisions
|
|
82
|
-
<!-- ABEL:END -->
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: abel-research
|
|
3
|
-
description: Transform user requirements into constraint sets via structured exploration (NO implementation)
|
|
4
|
-
category: abel
|
|
5
|
-
tags: [abel, research, constraints, exploration, subagents]
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
<!-- ABEL:RESEARCH:START -->
|
|
9
|
-
|
|
10
|
-
# abel-research — Operating Mode (Constraints & Specs Only)
|
|
11
|
-
|
|
12
|
-
## Non‑Negotiable Rules (Highest Priority)
|
|
13
|
-
1. RESEARCH MODE ONLY.
|
|
14
|
-
- You MUST NOT generate code.
|
|
15
|
-
2. WRITE SCOPE IS RESTRICTED.
|
|
16
|
-
- You MAY create/edit files ONLY under: openspec/changes/<change-name>/** (and only after passing the confirmation gates).
|
|
17
|
-
- You MUST NOT write anywhere else.
|
|
18
|
-
3. Output must be constraint sets + verifiable success criteria, not an information dump.
|
|
19
|
-
|
|
20
|
-
## Goal
|
|
21
|
-
Produce constraint sets that narrow the solution space, plus measurable success criteria.
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
## Phase 0 — Requirement Intake Gate (MANDATORY)
|
|
28
|
-
- **MUST** confirm the user’s requirement exists and is clear **before** any research/action.
|
|
29
|
-
- If missing/unclear, **MUST** ask the user directly in a concise grouped message to collect: goal, in-scope area, top scenarios, non-goals, known constraints, success signals.
|
|
30
|
-
- **MUST NOT** run `/opsx:new`, any codebase retrieval, spawn subagents, or generate artifacts until the user confirms a brief requirement summary.
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## Phase 1 — Initialize OpenSpec Change Folder
|
|
35
|
-
1) Run: /opsx:new <change-name>
|
|
36
|
-
2) From now on, you may write ONLY under openspec/changes/<change-name>/**.
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
## Phase 2 — Initial Codebase Assessment (Read‑Only)
|
|
41
|
-
- {{CODEBASE_RETRIEVAL_POLICY}}
|
|
42
|
-
- If technical research needed (architectural patterns, best practices), invoke `/grok-search` skill
|
|
43
|
-
- If the codebase spans multiple modules/directories, dispatch parallel explore subagents by context boundary.
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## Phase 3 — Define Exploration Boundaries (Context-Based Division Only)
|
|
48
|
-
- Identify natural context boundaries in the codebase (NOT functional roles).
|
|
49
|
-
- Example divisions:
|
|
50
|
-
* Subagent 1: User domain code (user models, user services, user UI)
|
|
51
|
-
* Subagent 2: Authentication & authorization code (auth middleware, session, tokens)
|
|
52
|
-
* Subagent 3: Configuration & infrastructure (configs, deployments, build scripts)
|
|
53
|
-
- Each boundary should be self-contained: no cross-communication needed between subagents.
|
|
54
|
-
- Define exploration scope and expected output for each subagent.
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
## Phase 4 — Subagent Output Template (MANDATORY JSON)
|
|
59
|
-
All explore subagents MUST return valid JSON using this schema:
|
|
60
|
-
{
|
|
61
|
-
"module_name": "字符串 - 所探索的上下文边界",
|
|
62
|
-
"existing_structures": ["发现的关键结构/模式列表"],
|
|
63
|
-
"existing_conventions": ["当前使用的约定/标准列表"],
|
|
64
|
-
"constraints_discovered": ["限制解决方案空间的硬约束列表"],
|
|
65
|
-
"open_questions": ["需要用户输入的歧义问题列表"],
|
|
66
|
-
"dependencies": ["对其他模块/系统的依赖列表"],
|
|
67
|
-
"risks": ["潜在风险或阻碍列表"],
|
|
68
|
-
"success_criteria_hints": ["指示成功的可观察行为列表"]
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## Phase 5 — Parallel Subagent Dispatch
|
|
74
|
-
- Monitor subagent execution and collect structured reports.
|
|
75
|
-
- For each boundary, spawn an Explore subagent with:
|
|
76
|
-
- {{CODEBASE_RETRIEVAL_MANDATORY_RULE}}
|
|
77
|
-
- Clear scope
|
|
78
|
-
- self-contained with independent output
|
|
79
|
-
- Required output template (from Phase 4)
|
|
80
|
-
- If boundary involves 3+ interconnected components, require explicit step-by-step dependency analysis
|
|
81
|
-
- Clear success criteria: complete analysis of assigned boundary
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
---
|
|
85
|
-
|
|
86
|
-
## Phase 6 — Aggregate & Synthesize
|
|
87
|
-
- Collect all subagent JSON outputs.
|
|
88
|
-
- Merge findings into unified constraint sets:
|
|
89
|
-
* **Hard constraints**: Technical limitations, existing patterns that cannot be violated.
|
|
90
|
-
* **Soft constraints**: Conventions, preferences, style guides.
|
|
91
|
-
* **Dependencies**: Cross-module relationships that affect implementation order.
|
|
92
|
-
* **Risks**: Potential blockers that need mitigation.
|
|
93
|
-
- Identify **open questions** from all reports that require user clarification.
|
|
94
|
-
- Synthesize **success criteria** from scenario hints across all contexts.
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
## Phase 7 — User Interaction for Ambiguity Resolution
|
|
99
|
-
- Compile prioritized list of open questions from aggregated reports.
|
|
100
|
-
- Present questions directly to the user in a concise grouped message:
|
|
101
|
-
* Group related questions together.
|
|
102
|
-
* Provide context for each question.
|
|
103
|
-
* Suggest default answers when applicable.
|
|
104
|
-
- Capture user responses as additional constraints.
|
|
105
|
-
- Update constraint sets with confirmed decisions.
|
|
106
|
-
|
|
107
|
-
---
|
|
108
|
-
|
|
109
|
-
## Phase 8 — Generate OpenSpec Artifacts
|
|
110
|
-
- Transform finalized constraint sets into OpenSpec proposal/specs/design/tasks.
|
|
111
|
-
- Every requirement MUST have a verifiable scenario and success criteria.
|
|
112
|
-
- Keep all writes inside openspec/changes/<change-name>/**.
|
|
113
|
-
|
|
114
|
-
## Reference
|
|
115
|
-
- Review existing constraints: `rg -n "Constraint:|MUST|MUST NOT" openspec/specs`
|
|
116
|
-
- {{CODEBASE_RETRIEVAL_STRUCTURE_REFERENCE}}
|
|
117
|
-
|
|
118
|
-
- Check prior research outputs: `ls openspec/changes/*/`
|
|
119
|
-
- OpenSpec CLI commands:
|
|
120
|
-
- `openspec view` - Interactive dashboard to browse changes
|
|
121
|
-
- `openspec list --changes` - List all active changes
|
|
122
|
-
- `openspec status --change <name>` - Check artifact completion status
|
|
123
|
-
- `openspec instructions proposal --change <name>` - Get proposal instructions
|
|
124
|
-
- Validate subagent outputs conform to template before aggregation.
|
|
125
|
-
- Ask the user directly for ANY ambiguity—do not assume or guess.
|
|
126
|
-
<!-- ABEL:RESEARCH:END -->
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
# Prompt Enhancer CLI configuration
|
|
2
|
-
# Copy this file to .env and fill in the values you want to use.
|
|
3
|
-
|
|
4
|
-
# Optional: third-party OpenAI-compatible base URL
|
|
5
|
-
PE_API_URL=
|
|
6
|
-
|
|
7
|
-
# Optional: third-party OpenAI-compatible API key
|
|
8
|
-
PE_API_KEY=
|
|
9
|
-
|
|
10
|
-
# Optional: model name for the third-party endpoint
|
|
11
|
-
# Leave all three fields blank to use the current agent directly.
|
|
12
|
-
PE_MODEL=
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
# Advanced Usage
|
|
2
|
-
|
|
3
|
-
## Using the Python Script Directly
|
|
4
|
-
|
|
5
|
-
Use the bootstrap entrypoint from the installed skill directory:
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
# Assuming third-party config is already set in <SKILL_DIR>/.env or the environment
|
|
9
|
-
python "<SKILL_DIR>/scripts/prompt_enhancer_entry.py" "your prompt here"
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
`prompt_enhancer_entry.py` is the canonical entrypoint. It creates or reuses a skill-local virtual environment and then runs `scripts/enhance.py`.
|
|
13
|
-
If `PE_API_URL`, `PE_API_KEY`, and `PE_MODEL` are not all present, do not call the script; rewrite the prompt directly with the current agent instead.
|
|
14
|
-
|
|
15
|
-
## Environment Variables
|
|
16
|
-
|
|
17
|
-
| Variable | Description | Default |
|
|
18
|
-
|----------|-------------|---------|
|
|
19
|
-
| `PE_API_URL` | Third-party OpenAI-compatible base URL | - |
|
|
20
|
-
| `PE_API_KEY` | Third-party OpenAI-compatible API key | - |
|
|
21
|
-
| `PE_MODEL` | Model to use on the third-party endpoint | - |
|
|
22
|
-
| `PE_DEBUG` | Print bootstrap and fallback diagnostics to `stderr` | `0` |
|
|
23
|
-
| `PROMPT_ENHANCER_VENV_DIR` | Override the skill-local venv path | `skills/prompt-enhancer/.venv` |
|
|
24
|
-
| `PROMPT_ENHANCER_PYTHON` | Python version/spec for `uv venv --python` | - |
|
|
25
|
-
| `AGENTS_SKILLS_PYTHON` | Absolute path to fallback/bootstrap Python | - |
|
|
26
|
-
|
|
27
|
-
## Local `.env`
|
|
28
|
-
|
|
29
|
-
The CLI loads `<SKILL_DIR>/.env` automatically if present:
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
cp "<SKILL_DIR>/.env.example" "<SKILL_DIR>/.env"
|
|
33
|
-
python "<SKILL_DIR>/scripts/prompt_enhancer_entry.py" "your prompt here"
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## Integration with Other Tools
|
|
37
|
-
|
|
38
|
-
The enhanced prompt is written to `stdout`. Usage or debug diagnostics stay on `stderr`, and bootstrap/fallback diagnostics are only emitted when `PE_DEBUG=1`.
|
|
39
|
-
|
|
40
|
-
### Piping Output
|
|
41
|
-
|
|
42
|
-
Assuming `PE_API_URL`, `PE_API_KEY`, and `PE_MODEL` are already configured:
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
# Pipe to clipboard (macOS)
|
|
46
|
-
python "<SKILL_DIR>/scripts/prompt_enhancer_entry.py" "my prompt" | pbcopy
|
|
47
|
-
|
|
48
|
-
# Pipe to file
|
|
49
|
-
python "<SKILL_DIR>/scripts/prompt_enhancer_entry.py" "my prompt" > enhanced.md
|
|
50
|
-
|
|
51
|
-
# Chain with other commands
|
|
52
|
-
python "<SKILL_DIR>/scripts/prompt_enhancer_entry.py" "my prompt" | claude -p
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### In Shell Scripts
|
|
56
|
-
|
|
57
|
-
Assuming the environment is already configured:
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
#!/bin/bash
|
|
61
|
-
ENHANCED=$(python "$HOME/.agents/skills/prompt-enhancer/scripts/prompt_enhancer_entry.py" "$1")
|
|
62
|
-
echo "$ENHANCED"
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
## Manual Enhancement (Current Agent)
|
|
66
|
-
|
|
67
|
-
If the user does not provide `url`, `apiKey`, and `model`, use the current agent directly and apply the enhancement principles:
|
|
68
|
-
|
|
69
|
-
1. Read the user's prompt
|
|
70
|
-
2. Apply the template from [TEMPLATE.md](TEMPLATE.md)
|
|
71
|
-
3. Preserve every explicit user constraint
|
|
72
|
-
4. Use placeholders for unknown context instead of inventing requirements
|
|
73
|
-
5. Structure the output with:
|
|
74
|
-
- Context section
|
|
75
|
-
- Objective section
|
|
76
|
-
- Step-by-step instructions
|
|
77
|
-
- Constraints
|
|
78
|
-
|
|
79
|
-
## Troubleshooting
|
|
80
|
-
|
|
81
|
-
### Script Not Found
|
|
82
|
-
Verify the canonical entrypoint exists:
|
|
83
|
-
```bash
|
|
84
|
-
ls "$HOME/.agents/skills/prompt-enhancer/scripts/prompt_enhancer_entry.py"
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### Permission Denied
|
|
88
|
-
Run it through Python instead of executing the file directly:
|
|
89
|
-
```bash
|
|
90
|
-
python "$HOME/.agents/skills/prompt-enhancer/scripts/prompt_enhancer_entry.py" "your prompt here"
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
### Show Usage
|
|
94
|
-
Run the entrypoint without a prompt to print usage information:
|
|
95
|
-
```bash
|
|
96
|
-
python "$HOME/.agents/skills/prompt-enhancer/scripts/prompt_enhancer_entry.py"
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### Missing Third-Party Config
|
|
100
|
-
The script requires `PE_API_URL`, `PE_API_KEY`, and `PE_MODEL`. If any field is missing, skip the script and use the current agent directly.
|
|
101
|
-
|
|
102
|
-
### Debug Fallbacks
|
|
103
|
-
Set `PE_DEBUG=1` to show dependency-install or configuration diagnostics on `stderr`.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
openai>=1.30,<2
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"""Shared .env loader for Prompt Enhancer scripts."""
|
|
2
|
-
|
|
3
|
-
import os
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def load_dotenv() -> bool:
|
|
8
|
-
env_path = Path(__file__).resolve().parent.parent / ".env"
|
|
9
|
-
if not env_path.exists():
|
|
10
|
-
return False
|
|
11
|
-
try:
|
|
12
|
-
seen_keys = set()
|
|
13
|
-
with open(env_path, "r", encoding="utf-8") as f:
|
|
14
|
-
for line in f:
|
|
15
|
-
line = line.strip()
|
|
16
|
-
if not line or line.startswith("#") or "=" not in line:
|
|
17
|
-
continue
|
|
18
|
-
key, _, value = line.partition("=")
|
|
19
|
-
key = key.strip()
|
|
20
|
-
value = value.strip()
|
|
21
|
-
if (value.startswith('"') and value.endswith('"')) or (
|
|
22
|
-
value.startswith("'") and value.endswith("'")
|
|
23
|
-
):
|
|
24
|
-
value = value[1:-1]
|
|
25
|
-
if not key or key in seen_keys:
|
|
26
|
-
continue
|
|
27
|
-
seen_keys.add(key)
|
|
28
|
-
if not os.environ.get(key):
|
|
29
|
-
os.environ[key] = value
|
|
30
|
-
return True
|
|
31
|
-
except IOError:
|
|
32
|
-
return False
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Prompt Enhancer CLI for OpenAI-compatible endpoints."""
|
|
3
|
-
|
|
4
|
-
import argparse
|
|
5
|
-
import os
|
|
6
|
-
import sys
|
|
7
|
-
from typing import Tuple
|
|
8
|
-
|
|
9
|
-
from _dotenv import load_dotenv
|
|
10
|
-
|
|
11
|
-
load_dotenv()
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
SYSTEM_PROMPT = """
|
|
15
|
-
You are an expert Prompt Engineer for Coding Agents (Claude Code, Codex, Gemini CLI).
|
|
16
|
-
Your goal is to rewrite the user's raw input into a structured, high-context prompt that maximizes the agent's effectiveness.
|
|
17
|
-
|
|
18
|
-
Guidelines:
|
|
19
|
-
1. Structure: Use a clear Markdown structure with headers.
|
|
20
|
-
2. Chain of Thought: Explicitly ask the agent to "Think step-by-step" or "Analyze the file structure first".
|
|
21
|
-
3. Context: If the user's prompt is vague, add placeholders like "[Insert relevant file(s)]" or "[Specify tech stack]" in the rewritten prompt, or simply infer them if obvious.
|
|
22
|
-
4. Format:
|
|
23
|
-
- Context: What is the current state? What files are involved?
|
|
24
|
-
- Objective: What exactly should be done?
|
|
25
|
-
- Constraints: specific libraries, coding styles, or "no placeholders".
|
|
26
|
-
- Response Format: e.g., "Return only the code block" or "Explain step-by-step".
|
|
27
|
-
|
|
28
|
-
Output Template:
|
|
29
|
-
|
|
30
|
-
# Context
|
|
31
|
-
[Refined context description]
|
|
32
|
-
|
|
33
|
-
# Objective
|
|
34
|
-
[Precise task definition]
|
|
35
|
-
|
|
36
|
-
# Step-by-Step Instructions
|
|
37
|
-
1. [Step 1]
|
|
38
|
-
2. [Step 2]
|
|
39
|
-
...
|
|
40
|
-
|
|
41
|
-
# Constraints
|
|
42
|
-
- [Constraint 1]
|
|
43
|
-
- [Constraint 2]
|
|
44
|
-
"""
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def parse_args() -> argparse.Namespace:
|
|
48
|
-
parser = argparse.ArgumentParser(
|
|
49
|
-
prog="prompt_enhancer_entry.py",
|
|
50
|
-
description="Enhance a prompt through a third-party OpenAI-compatible API.",
|
|
51
|
-
)
|
|
52
|
-
parser.add_argument("--url", dest="api_url", help="Third-party OpenAI-compatible base URL.")
|
|
53
|
-
parser.add_argument("--api-key", dest="api_key", help="Third-party OpenAI-compatible API key.")
|
|
54
|
-
parser.add_argument("--model", help="Model name on the third-party endpoint.")
|
|
55
|
-
parser.add_argument("--prompt", help="Prompt text to enhance.")
|
|
56
|
-
parser.add_argument("prompt_parts", nargs="*", help=argparse.SUPPRESS)
|
|
57
|
-
return parser.parse_args()
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def debug_enabled() -> bool:
|
|
61
|
-
value = os.environ.get("PE_DEBUG", "")
|
|
62
|
-
return value.strip().lower() in {"1", "true", "yes", "on"}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def resolve_prompt(args: argparse.Namespace) -> str:
|
|
66
|
-
prompt = args.prompt.strip() if args.prompt else ""
|
|
67
|
-
if prompt:
|
|
68
|
-
return prompt
|
|
69
|
-
joined = " ".join(args.prompt_parts).strip()
|
|
70
|
-
if joined:
|
|
71
|
-
return joined
|
|
72
|
-
raise ValueError("Missing prompt. Pass --prompt \"...\" or a positional prompt.")
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
def resolve_config(args: argparse.Namespace) -> Tuple[str, str, str]:
|
|
76
|
-
api_url = (args.api_url or os.environ.get("PE_API_URL", "")).strip()
|
|
77
|
-
api_key = (args.api_key or os.environ.get("PE_API_KEY", "")).strip()
|
|
78
|
-
model = (args.model or os.environ.get("PE_MODEL", "")).strip()
|
|
79
|
-
|
|
80
|
-
missing = []
|
|
81
|
-
if not api_url:
|
|
82
|
-
missing.append("url")
|
|
83
|
-
if not api_key:
|
|
84
|
-
missing.append("apiKey")
|
|
85
|
-
if not model:
|
|
86
|
-
missing.append("model")
|
|
87
|
-
if missing:
|
|
88
|
-
raise ValueError(
|
|
89
|
-
"Missing third-party OpenAI-compatible config: "
|
|
90
|
-
+ ", ".join(missing)
|
|
91
|
-
+ ". If these fields are unavailable, use the current agent directly."
|
|
92
|
-
)
|
|
93
|
-
return api_url, api_key, model
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
def _extract_response_text(response) -> str:
|
|
97
|
-
content = response.choices[0].message.content
|
|
98
|
-
if isinstance(content, str):
|
|
99
|
-
return content
|
|
100
|
-
if content is None:
|
|
101
|
-
raise RuntimeError("The provider returned an empty response.")
|
|
102
|
-
return str(content)
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
def enhance_with_openai(prompt: str, api_key: str, model: str, api_url: str = "") -> str:
|
|
106
|
-
try:
|
|
107
|
-
from openai import OpenAI
|
|
108
|
-
except ImportError:
|
|
109
|
-
raise RuntimeError("Missing dependency: openai. Install dependencies for the configured provider.") from None
|
|
110
|
-
|
|
111
|
-
kwargs = {"api_key": api_key}
|
|
112
|
-
if api_url:
|
|
113
|
-
kwargs["base_url"] = api_url
|
|
114
|
-
client = OpenAI(**kwargs)
|
|
115
|
-
response = client.chat.completions.create(
|
|
116
|
-
model=model,
|
|
117
|
-
messages=[
|
|
118
|
-
{"role": "system", "content": SYSTEM_PROMPT},
|
|
119
|
-
{"role": "user", "content": prompt},
|
|
120
|
-
],
|
|
121
|
-
)
|
|
122
|
-
return _extract_response_text(response)
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
def main() -> None:
|
|
126
|
-
try:
|
|
127
|
-
args = parse_args()
|
|
128
|
-
prompt = resolve_prompt(args)
|
|
129
|
-
api_url, api_key, model = resolve_config(args)
|
|
130
|
-
print(enhance_with_openai(prompt, api_key, model, api_url))
|
|
131
|
-
except Exception as exc:
|
|
132
|
-
if debug_enabled():
|
|
133
|
-
print(f"Error: {exc}", file=sys.stderr)
|
|
134
|
-
else:
|
|
135
|
-
msg = str(exc)
|
|
136
|
-
if "Missing third-party OpenAI-compatible config" in msg:
|
|
137
|
-
print("Missing API configuration. Use the current agent directly instead, or set PE_API_URL, PE_API_KEY, PE_MODEL.", file=sys.stderr)
|
|
138
|
-
else:
|
|
139
|
-
print(msg, file=sys.stderr)
|
|
140
|
-
sys.exit(1)
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if __name__ == "__main__":
|
|
144
|
-
main()
|