refactor(sense-generator): extract prompts to prompt.md templates
Each role's prompt is now a separate markdown file with {{mustache}} placeholders,
loaded at module init and interpolated at runtime.
小橘 🍊(NEKO Team)
This commit is contained in:
parent
516a28533a
commit
a811660a33
@ -1,8 +1,14 @@
|
|||||||
import { createCursorRole } from "@uncaged/nerve-workflow-utils";
|
import { createCursorRole } from "@uncaged/nerve-workflow-utils";
|
||||||
|
import { readFileSync } from "node:fs";
|
||||||
|
import { join, dirname } from "node:path";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
import { resolveDashScopeProvider, NERVE_ROOT, SENSES_DIR } from "../shared.js";
|
import { resolveDashScopeProvider, NERVE_ROOT, SENSES_DIR } from "../shared.js";
|
||||||
import { coderMetaSchema } from "../types.js";
|
import { coderMetaSchema } from "../types.js";
|
||||||
import type { SenseMeta } from "../types.js";
|
import type { SenseMeta } from "../types.js";
|
||||||
|
|
||||||
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
|
const PROMPT = readFileSync(join(__dirname, "prompt.md"), "utf-8");
|
||||||
|
|
||||||
export async function buildCoderRole() {
|
export async function buildCoderRole() {
|
||||||
const provider = await resolveDashScopeProvider();
|
const provider = await resolveDashScopeProvider();
|
||||||
if (provider === null) {
|
if (provider === null) {
|
||||||
@ -12,19 +18,10 @@ export async function buildCoderRole() {
|
|||||||
cwd: NERVE_ROOT,
|
cwd: NERVE_ROOT,
|
||||||
mode: "default",
|
mode: "default",
|
||||||
prompt: async (threadId) =>
|
prompt: async (threadId) =>
|
||||||
`Read the workflow thread for the planner's sense design: \`nerve thread ${threadId}\`
|
PROMPT
|
||||||
|
.replace("{{threadId}}", threadId)
|
||||||
Implement the sense. Create exactly:
|
.replace("{{sensesDir}}", SENSES_DIR)
|
||||||
1. The sense directory under ${SENSES_DIR}/<sense-name>/
|
.replace("{{nerveRoot}}", NERVE_ROOT),
|
||||||
2. index.js — export async function compute(db, _peers), import schema from "./schema.ts"
|
extract: { provider, schema: coderMetaSchema },
|
||||||
3. schema.ts — drizzle-orm/sqlite-core
|
|
||||||
4. migrations/0001_init.sql — must match schema.ts
|
|
||||||
5. Update ${NERVE_ROOT}/nerve.yaml — add sense config + reflex entry
|
|
||||||
|
|
||||||
Follow the patterns from existing senses. Create all files now.`,
|
|
||||||
extract: {
|
|
||||||
provider,
|
|
||||||
schema: coderMetaSchema,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
10
workflows/sense-generator/roles/coder/prompt.md
Normal file
10
workflows/sense-generator/roles/coder/prompt.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Read the workflow thread for the planner's sense design: `nerve thread {{threadId}}`
|
||||||
|
|
||||||
|
Implement the sense. Create exactly:
|
||||||
|
1. The sense directory under {{sensesDir}}/<sense-name>/
|
||||||
|
2. index.js — export async function compute(db, _peers), import schema from "./schema.ts"
|
||||||
|
3. schema.ts — drizzle-orm/sqlite-core
|
||||||
|
4. migrations/0001_init.sql — must match schema.ts
|
||||||
|
5. Update {{nerveRoot}}/nerve.yaml — add sense config + reflex entry
|
||||||
|
|
||||||
|
Follow the patterns from existing senses. Create all files now.
|
||||||
@ -1,8 +1,13 @@
|
|||||||
import { createCursorRole } from "@uncaged/nerve-workflow-utils";
|
import { createCursorRole } from "@uncaged/nerve-workflow-utils";
|
||||||
|
import { readFileSync } from "node:fs";
|
||||||
|
import { join, dirname } from "node:path";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
import { resolveDashScopeProvider, buildSenseExamples, getNerveYaml, NERVE_ROOT } from "../shared.js";
|
import { resolveDashScopeProvider, buildSenseExamples, getNerveYaml, NERVE_ROOT } from "../shared.js";
|
||||||
import { plannerMetaSchema } from "../types.js";
|
import { plannerMetaSchema } from "../types.js";
|
||||||
import type { SenseMeta } from "../types.js";
|
import type { SenseMeta } from "../types.js";
|
||||||
|
|
||||||
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
|
const PROMPT = readFileSync(join(__dirname, "prompt.md"), "utf-8");
|
||||||
const senseExamples = buildSenseExamples();
|
const senseExamples = buildSenseExamples();
|
||||||
const nerveYaml = getNerveYaml();
|
const nerveYaml = getNerveYaml();
|
||||||
|
|
||||||
@ -15,30 +20,10 @@ export async function buildPlannerRole() {
|
|||||||
cwd: NERVE_ROOT,
|
cwd: NERVE_ROOT,
|
||||||
mode: "ask",
|
mode: "ask",
|
||||||
prompt: async (threadId) =>
|
prompt: async (threadId) =>
|
||||||
`You are planning a new Nerve sense.
|
PROMPT
|
||||||
|
.replace("{{threadId}}", threadId)
|
||||||
Read the workflow thread for the user's request: \`nerve thread ${threadId}\`
|
.replace("{{senseExamples}}", senseExamples)
|
||||||
|
.replace("{{nerveYaml}}", nerveYaml),
|
||||||
Pick a good kebab-case name for this sense. Produce a PLAN (not code) in markdown:
|
extract: { provider, schema: plannerMetaSchema },
|
||||||
|
|
||||||
## Sense Design
|
|
||||||
### Name — kebab-case
|
|
||||||
### Fields — name, type (integer/real/text), description
|
|
||||||
### Compute Logic — step-by-step, specific Node.js APIs or shell commands
|
|
||||||
### Trigger Config — group, interval, throttle, timeout
|
|
||||||
|
|
||||||
Reference senses:
|
|
||||||
${senseExamples}
|
|
||||||
|
|
||||||
Current nerve.yaml:
|
|
||||||
\`\`\`yaml
|
|
||||||
${nerveYaml}
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
Output ONLY the plan. Be precise and implementation-ready.`,
|
|
||||||
extract: {
|
|
||||||
provider,
|
|
||||||
schema: plannerMetaSchema,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
21
workflows/sense-generator/roles/planner/prompt.md
Normal file
21
workflows/sense-generator/roles/planner/prompt.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
You are planning a new Nerve sense.
|
||||||
|
|
||||||
|
Read the workflow thread for the user's request: `nerve thread {{threadId}}`
|
||||||
|
|
||||||
|
Pick a good kebab-case name for this sense. Produce a PLAN (not code) in markdown:
|
||||||
|
|
||||||
|
## Sense Design
|
||||||
|
### Name — kebab-case
|
||||||
|
### Fields — name, type (integer/real/text), description
|
||||||
|
### Compute Logic — step-by-step, specific Node.js APIs or shell commands
|
||||||
|
### Trigger Config — group, interval, throttle, timeout
|
||||||
|
|
||||||
|
Reference senses:
|
||||||
|
{{senseExamples}}
|
||||||
|
|
||||||
|
Current nerve.yaml:
|
||||||
|
```yaml
|
||||||
|
{{nerveYaml}}
|
||||||
|
```
|
||||||
|
|
||||||
|
Output ONLY the plan. Be precise and implementation-ready.
|
||||||
Loading…
x
Reference in New Issue
Block a user