refactor(sense-generator): prompt.ts instead of prompt.md + mustache
Static imports, no runtime file reads, bundler friendly.
Removed mustache dependency.
小橘 🍊(NEKO Team)
This commit is contained in:
parent
a811660a33
commit
bc4ac8a5cc
@ -1,13 +1,8 @@
|
||||
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 { coderMetaSchema } 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");
|
||||
import { coderPrompt } from "./prompt.js";
|
||||
|
||||
export async function buildCoderRole() {
|
||||
const provider = await resolveDashScopeProvider();
|
||||
@ -17,11 +12,7 @@ export async function buildCoderRole() {
|
||||
return createCursorRole<SenseMeta["coder"]>({
|
||||
cwd: NERVE_ROOT,
|
||||
mode: "default",
|
||||
prompt: async (threadId) =>
|
||||
PROMPT
|
||||
.replace("{{threadId}}", threadId)
|
||||
.replace("{{sensesDir}}", SENSES_DIR)
|
||||
.replace("{{nerveRoot}}", NERVE_ROOT),
|
||||
prompt: async (threadId) => coderPrompt({ threadId, sensesDir: SENSES_DIR, nerveRoot: NERVE_ROOT }),
|
||||
extract: { provider, schema: coderMetaSchema },
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
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.
|
||||
16
workflows/sense-generator/roles/coder/prompt.ts
Normal file
16
workflows/sense-generator/roles/coder/prompt.ts
Normal file
@ -0,0 +1,16 @@
|
||||
export function coderPrompt(vars: {
|
||||
threadId: string;
|
||||
sensesDir: string;
|
||||
nerveRoot: string;
|
||||
}): string {
|
||||
return `Read the workflow thread for the planner's sense design: \`nerve thread ${vars.threadId}\`
|
||||
|
||||
Implement the sense. Create exactly:
|
||||
1. The sense directory under ${vars.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 ${vars.nerveRoot}/nerve.yaml — add sense config + reflex entry
|
||||
|
||||
Follow the patterns from existing senses. Create all files now.`;
|
||||
}
|
||||
@ -1,13 +1,9 @@
|
||||
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 { plannerMetaSchema } from "../types.js";
|
||||
import type { SenseMeta } from "../types.js";
|
||||
import { plannerPrompt } from "./prompt.js";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const PROMPT = readFileSync(join(__dirname, "prompt.md"), "utf-8");
|
||||
const senseExamples = buildSenseExamples();
|
||||
const nerveYaml = getNerveYaml();
|
||||
|
||||
@ -19,11 +15,7 @@ export async function buildPlannerRole() {
|
||||
return createCursorRole<SenseMeta["planner"]>({
|
||||
cwd: NERVE_ROOT,
|
||||
mode: "ask",
|
||||
prompt: async (threadId) =>
|
||||
PROMPT
|
||||
.replace("{{threadId}}", threadId)
|
||||
.replace("{{senseExamples}}", senseExamples)
|
||||
.replace("{{nerveYaml}}", nerveYaml),
|
||||
prompt: async (threadId) => plannerPrompt({ threadId, senseExamples, nerveYaml }),
|
||||
extract: { provider, schema: plannerMetaSchema },
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,21 +0,0 @@
|
||||
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.
|
||||
27
workflows/sense-generator/roles/planner/prompt.ts
Normal file
27
workflows/sense-generator/roles/planner/prompt.ts
Normal file
@ -0,0 +1,27 @@
|
||||
export function plannerPrompt(vars: {
|
||||
threadId: string;
|
||||
senseExamples: string;
|
||||
nerveYaml: string;
|
||||
}): string {
|
||||
return `You are planning a new Nerve sense.
|
||||
|
||||
Read the workflow thread for the user's request: \`nerve thread ${vars.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:
|
||||
${vars.senseExamples}
|
||||
|
||||
Current nerve.yaml:
|
||||
\`\`\`yaml
|
||||
${vars.nerveYaml}
|
||||
\`\`\`
|
||||
|
||||
Output ONLY the plan. Be precise and implementation-ready.`;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user