Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 83992a71cd |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@united-workforce/cli",
|
"name": "@united-workforce/cli",
|
||||||
"version": "0.2.0",
|
"version": "0.1.1",
|
||||||
"files": [
|
"files": [
|
||||||
"src",
|
"src",
|
||||||
"dist",
|
"dist",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@united-workforce/util",
|
"name": "@united-workforce/util",
|
||||||
"version": "0.1.2",
|
"version": "0.1.1",
|
||||||
"files": [
|
"files": [
|
||||||
"src",
|
"src",
|
||||||
"dist",
|
"dist",
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export {
|
|||||||
validateFrontmatter,
|
validateFrontmatter,
|
||||||
} from "./frontmatter-markdown/index.js";
|
} from "./frontmatter-markdown/index.js";
|
||||||
export { createLogger } from "./logger.js";
|
export { createLogger } from "./logger.js";
|
||||||
|
export { generateModeratorReference } from "./moderator-reference.js";
|
||||||
export type {
|
export type {
|
||||||
CreateProcessLoggerOptions,
|
CreateProcessLoggerOptions,
|
||||||
ProcessLogFn,
|
ProcessLogFn,
|
||||||
@@ -35,3 +35,4 @@ export { extractUlidTimestamp, generateUlid } from "./ulid.js";
|
|||||||
export { generateUsageReference } from "./usage-reference.js";
|
export { generateUsageReference } from "./usage-reference.js";
|
||||||
export { VERSION } from "./version.js";
|
export { VERSION } from "./version.js";
|
||||||
export { generateWorkflowAuthoringReference } from "./workflow-authoring-reference.js";
|
export { generateWorkflowAuthoringReference } from "./workflow-authoring-reference.js";
|
||||||
|
export { generateYamlReference } from "./yaml-reference.js";
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
export function generateModeratorReference(): string {
|
||||||
|
return `# Moderator Reference
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The moderator is the workflow engine's routing component. It evaluates the directed graph defined in the workflow YAML to determine the next role (or \`$END\`) after each step — with zero LLM cost.
|
||||||
|
|
||||||
|
## Status-Based Routing
|
||||||
|
|
||||||
|
The moderator uses **status-based routing**: it inspects the previous step's extracted output (specifically the \`$status\` field) and looks up the corresponding edge in the graph.
|
||||||
|
|
||||||
|
### Graph Structure
|
||||||
|
|
||||||
|
The graph is a nested map: \`Record<Role | "$START", Record<Status, Target>>\`. Each role maps its possible \`$status\` values to a target with a \`role\` and \`prompt\`:
|
||||||
|
|
||||||
|
\`\`\`yaml
|
||||||
|
graph:
|
||||||
|
$START:
|
||||||
|
new: { role: planner, prompt: "Analyze the issue." }
|
||||||
|
resume: { role: planner, prompt: "Review the previous run output and continue." }
|
||||||
|
planner:
|
||||||
|
ready: { role: developer, prompt: "Implement the plan (CAS hash: {{{plan}}})." }
|
||||||
|
insufficient_info: { role: $END, prompt: "Not enough info." }
|
||||||
|
developer:
|
||||||
|
done: { role: reviewer, prompt: "Review branch {{{branch}}} at {{{worktree}}}." }
|
||||||
|
failed: { role: $END, prompt: "Developer failed: {{{reason}}}." }
|
||||||
|
reviewer:
|
||||||
|
approved: { role: tester, prompt: "Run tests on {{{branch}}} at {{{worktree}}}." }
|
||||||
|
rejected: { role: developer, prompt: "Fix issues: {{{comments}}}." }
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
### Routing Algorithm
|
||||||
|
|
||||||
|
1. Look up \`graph[lastRole]\` to get the status map for the current role
|
||||||
|
2. Look up \`statusMap[lastOutput.$status]\` to get the target
|
||||||
|
3. If target role is \`$END\`, mark thread as completed
|
||||||
|
4. Otherwise, render the edge prompt (Mustache templates with \`{{{field}}}\` from output) and spawn the next agent
|
||||||
|
|
||||||
|
### Edge Prompts and Mustache Templates
|
||||||
|
|
||||||
|
Edge prompts use triple-brace Mustache syntax (\`{{{field}}}\`) to interpolate values from the previous step's output into the next agent's task prompt. This passes structured data (branch names, file paths, CAS hashes) between roles without manual wiring.
|
||||||
|
|
||||||
|
## Special Nodes
|
||||||
|
|
||||||
|
- \`$START\` — entry point; uses status keys \`new\` (first start) and \`resume\` (resuming a completed thread)
|
||||||
|
- \`$END\` — terminal node; thread completes when reached and is moved to history
|
||||||
|
|
||||||
|
## Integration with Steps
|
||||||
|
|
||||||
|
Each \`uwf thread exec\` cycle:
|
||||||
|
1. Moderator reads the thread's head step output
|
||||||
|
2. Looks up \`graph[lastRole][output.$status]\` to pick the next role
|
||||||
|
3. If next is \`$END\`, marks thread as completed
|
||||||
|
4. Otherwise, renders the edge prompt and spawns the agent for the selected role
|
||||||
|
5. Extract pipeline parses agent output → new step node → append to CAS chain
|
||||||
|
`;
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
export function generateYamlReference(): string {
|
||||||
|
return `# Workflow YAML Schema Reference
|
||||||
|
|
||||||
|
## Top-Level Structure
|
||||||
|
|
||||||
|
A workflow YAML file defines the complete workflow specification:
|
||||||
|
|
||||||
|
\`\`\`yaml
|
||||||
|
name: solve-issue # verb-first kebab-case identifier
|
||||||
|
description: "..." # human-readable description
|
||||||
|
|
||||||
|
roles: # named actors in the workflow
|
||||||
|
planner:
|
||||||
|
description: "Analyzes issue and outputs a plan"
|
||||||
|
goal: "You are a planning agent."
|
||||||
|
capabilities:
|
||||||
|
- issue-analysis
|
||||||
|
- planning
|
||||||
|
procedure: |
|
||||||
|
1. Read the issue
|
||||||
|
2. Produce a test spec
|
||||||
|
output: "Output the plan summary. Set $status to ready or insufficient_info."
|
||||||
|
frontmatter: # JSON Schema for structured output (drives routing)
|
||||||
|
oneOf:
|
||||||
|
- properties:
|
||||||
|
$status: { const: ready }
|
||||||
|
plan: { type: string }
|
||||||
|
required: [$status, plan]
|
||||||
|
- properties:
|
||||||
|
$status: { const: insufficient_info }
|
||||||
|
required: [$status]
|
||||||
|
|
||||||
|
graph: # status-based routing (nested map)
|
||||||
|
$START:
|
||||||
|
new: { role: planner, prompt: "Analyze the issue." }
|
||||||
|
resume: { role: planner, prompt: "Review the previous run output and continue." }
|
||||||
|
planner:
|
||||||
|
ready: { role: developer, prompt: "Implement plan {{{plan}}}." }
|
||||||
|
insufficient_info: { role: $END, prompt: "Not enough info." }
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
## roles
|
||||||
|
|
||||||
|
Each role defines an actor in the workflow:
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|-------|------|-------------|
|
||||||
|
| \`description\` | string | Short description of the role's purpose |
|
||||||
|
| \`goal\` | string | System-level goal statement for the agent |
|
||||||
|
| \`capabilities\` | string[] | Tags describing what the role can do |
|
||||||
|
| \`procedure\` | string | Step-by-step instructions for the agent |
|
||||||
|
| \`output\` | string | Description of expected output format |
|
||||||
|
| \`frontmatter\` | JSON Schema | Defines the structured output the agent must produce |
|
||||||
|
|
||||||
|
### frontmatter
|
||||||
|
|
||||||
|
The \`frontmatter\` field is a standard JSON Schema object. The extract pipeline validates agent output against it. Key conventions:
|
||||||
|
- \`$status\` field drives routing decisions in the graph
|
||||||
|
- Use \`const\` or \`enum\` to constrain status values
|
||||||
|
- Use \`oneOf\` to define multiple valid output shapes (one per status)
|
||||||
|
- All \`required\` fields must appear in the agent's frontmatter output
|
||||||
|
|
||||||
|
## graph
|
||||||
|
|
||||||
|
The graph is a nested map defining status-based routing:
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
Record<Role | "$START", Record<Status, { role: string, prompt: string }>>
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
| Level | Key | Value |
|
||||||
|
|-------|-----|-------|
|
||||||
|
| Outer | Role name or \`$START\` | Status map for that role |
|
||||||
|
| Inner | \`$status\` value | Target: \`{ role, prompt }\` |
|
||||||
|
|
||||||
|
### Special Nodes
|
||||||
|
- \`$START\` — entry point; uses status keys \`new\` (first start) and \`resume\` (resuming a completed thread)
|
||||||
|
- \`$END\` — terminal node; thread completes when reached
|
||||||
|
|
||||||
|
### Edge Prompts
|
||||||
|
Prompts use triple-brace Mustache templates (\`{{{field}}}\`) to interpolate values from the previous step's output. Example: \`"Implement plan {{{plan}}} in repo {{{repoPath}}}."\`
|
||||||
|
`;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user