skills
This commit is contained in:
@@ -0,0 +1,29 @@
|
|||||||
|
# Workflow Skill Docs Mirror Implementation Plan
|
||||||
|
|
||||||
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||||
|
|
||||||
|
**Goal:** Add a repo-local `wf-workflow` skill with agent-facing references and expose those same skill files through the MCP documentation source.
|
||||||
|
|
||||||
|
**Architecture:** `docs/` remains project-facing documentation. `skills/wf-workflow/` becomes a self-contained agent-facing operating manual with distilled references. `src/wf_mcp/documentation.py` exposes the skill files as documentation resources under `wf://skills/...` without changing existing `wf://docs/...` resources.
|
||||||
|
|
||||||
|
**Tech Stack:** Markdown skills, `wf_mcp.documentation`, `wf_platform.DocumentationResource`, pytest.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
- [ ] Add a failing docs resource test for `wf://skills/wf-workflow/SKILL.md` and one reference.
|
||||||
|
- [ ] Create `skills/wf-workflow/SKILL.md`.
|
||||||
|
- [ ] Create `skills/wf-workflow/references/workflow-lifecycle.md`.
|
||||||
|
- [ ] Create `skills/wf-workflow/references/capabilities-and-wrappers.md`.
|
||||||
|
- [ ] Create `skills/wf-workflow/references/draft-workspaces.md`.
|
||||||
|
- [ ] Create `skills/wf-workflow/references/troubleshooting.md`.
|
||||||
|
- [ ] Update `src/wf_mcp/documentation.py` to load the skill files as resources.
|
||||||
|
- [ ] Verify focused docs tests and lint.
|
||||||
|
|
||||||
|
## Guardrails
|
||||||
|
|
||||||
|
- Do not replace the existing `skills/wf-cli` skill.
|
||||||
|
- Do not make `SKILL.md` a link-only file.
|
||||||
|
- Do not symlink skill references to `docs/`; checked-in distilled files are more portable.
|
||||||
|
- Do not remove existing `wf://docs/...` resources.
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
---
|
||||||
|
name: wf-workflow
|
||||||
|
description: Use when an agent needs to discover workflow capabilities, create or patch draft workspaces, save workflow or wrapper artifacts, deploy, run, resume, debug, or troubleshoot workflows in this repository.
|
||||||
|
---
|
||||||
|
|
||||||
|
# wf Workflow
|
||||||
|
|
||||||
|
Use this skill for the workflow lifecycle, regardless of front door:
|
||||||
|
|
||||||
|
- MCP tools exposed by `wf.workflow.*`
|
||||||
|
- repo-local `wf` CLI commands
|
||||||
|
- future `wf_api` callers
|
||||||
|
|
||||||
|
Prefer small discovery calls, draft workspaces, validation, and bounded trace
|
||||||
|
reads. Do not write raw workflow plans unless the user explicitly asks for the
|
||||||
|
low-level escape hatch.
|
||||||
|
|
||||||
|
## Workflow Lifecycle
|
||||||
|
|
||||||
|
1. Discover sources with `wf.admin.list_sources` or `wf cap list`.
|
||||||
|
2. Discover workflow-ready capabilities with `wf.workflow.list_capabilities`.
|
||||||
|
3. Inspect one candidate with `wf.workflow.inspect_capability`.
|
||||||
|
4. Create a patchable draft workspace with
|
||||||
|
`wf.workflow.create_draft_workspace_from_capability`.
|
||||||
|
5. Patch targeted fields with focused helpers or JSON Patch.
|
||||||
|
6. Validate with `wf.workflow.validate_draft_workspace`.
|
||||||
|
7. Save with `wf.workflow.create_artifact_from_workspace` or
|
||||||
|
`wf.workflow.create_wrapper_from_workspace`.
|
||||||
|
8. Save a deployment with `wf.workflow.save_deployment`.
|
||||||
|
9. Validate with `wf.workflow.validate_deployment`.
|
||||||
|
10. Run with `wf.workflow.run_deployment`.
|
||||||
|
11. Inspect stopped runs with `wf.workflow.inspect_run`; read bounded trace
|
||||||
|
slices only when debugging.
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
- Use workflow capabilities, not raw MCP tools, when building graphs.
|
||||||
|
- Treat wrapper hints as scaffolding, not semantic truth.
|
||||||
|
- Use draft workspaces for iterative authoring; avoid rewriting full drafts.
|
||||||
|
- Use explicit source bindings at deployment time.
|
||||||
|
- Keep traces bounded with `trace_range`.
|
||||||
|
- Do not expect a newly saved workflow to become a new MCP tool mid-session.
|
||||||
|
- For MCP content blocks, add explicit extraction/wrapper steps instead of
|
||||||
|
pretending `content` is always plain text.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
Read only the reference needed for the current task. Start with a small preview
|
||||||
|
or search hit, then open the relevant section; do not dump every reference into
|
||||||
|
context.
|
||||||
|
|
||||||
|
Useful patterns:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# PowerShell preview
|
||||||
|
Get-Content skills/wf-workflow/references/workflow-lifecycle.md -TotalCount 40
|
||||||
|
|
||||||
|
# Targeted search
|
||||||
|
rg -n "trace|resume|binding_missing|wrapper_hints" skills/wf-workflow/references
|
||||||
|
```
|
||||||
|
|
||||||
|
- `references/workflow-lifecycle.md`: end-to-end lifecycle and tool order.
|
||||||
|
- `references/capabilities-and-wrappers.md`: raw capability vs workflow
|
||||||
|
capability, wrapper artifacts, and content-block handling.
|
||||||
|
- `references/draft-workspaces.md`: draft shape, mappings, patches, and save
|
||||||
|
path.
|
||||||
|
- `references/troubleshooting.md`: missing source/capability, unrunnable
|
||||||
|
deployment, run/trace issues.
|
||||||
|
|
||||||
|
For shell-first workflows, also use the existing `wf-cli` skill.
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
# Capabilities And Wrappers Reference
|
||||||
|
|
||||||
|
Use this when deciding whether to call a capability directly, wrap it, or place
|
||||||
|
it in a workflow.
|
||||||
|
|
||||||
|
## Core Split
|
||||||
|
|
||||||
|
```text
|
||||||
|
raw MCP tool != workflow capability
|
||||||
|
```
|
||||||
|
|
||||||
|
A raw MCP tool may be callable and still be awkward for workflows. Workflow
|
||||||
|
capabilities are graph-facing contracts with schemas and outcomes.
|
||||||
|
|
||||||
|
## Discovery Order
|
||||||
|
|
||||||
|
1. Use `wf.admin.list_sources` to understand owners.
|
||||||
|
2. Use `wf.workflow.list_capabilities` for graph-ready capabilities.
|
||||||
|
3. Use `wf.workflow.inspect_capability` for one full contract.
|
||||||
|
4. Use `wf.workflow.call_capability` to test a single workflow-facing contract.
|
||||||
|
|
||||||
|
## Wrapper Artifacts
|
||||||
|
|
||||||
|
Use a wrapper artifact when the raw provider shape needs normalization:
|
||||||
|
|
||||||
|
- provider status strings should become workflow outcomes
|
||||||
|
- raw envelopes should be narrowed
|
||||||
|
- `isError` or error blocks need explicit outcome routing
|
||||||
|
- provider inputs are too broad or unstable for graph use
|
||||||
|
|
||||||
|
Saved wrappers appear as workflow capabilities under source id `workflow`, with
|
||||||
|
names like `workflow.echo_wrapper.v1`.
|
||||||
|
|
||||||
|
## Wrapper Hints
|
||||||
|
|
||||||
|
`inspect_capability` returns `wrapper_hints`. Treat them as authoring
|
||||||
|
scaffolding:
|
||||||
|
|
||||||
|
- `confidence=high`: simple shape, likely safe to validate first
|
||||||
|
- `confidence=medium`: usable but review candidates
|
||||||
|
- `confidence=low`: patch missing decisions before saving
|
||||||
|
|
||||||
|
`next_actions` is guidance, not validation authority.
|
||||||
|
|
||||||
|
## MCP Content Blocks
|
||||||
|
|
||||||
|
MCP tools often return `content: [{type, text, ...}]`. Do not map this list
|
||||||
|
into a string state field. Filter/extract text explicitly, or write a wrapper
|
||||||
|
that decides what content types are acceptable.
|
||||||
|
|
||||||
|
If a result exposes a convenience `text` field, inspect the capability schema
|
||||||
|
and wrapper hints before using it. Do not assume every content block is text.
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
# Draft Workspaces Reference
|
||||||
|
|
||||||
|
Use draft workspaces for iterative workflow authoring. They are mutable and
|
||||||
|
revisioned; artifacts are immutable and versioned.
|
||||||
|
|
||||||
|
## Draft Shape
|
||||||
|
|
||||||
|
A draft has:
|
||||||
|
|
||||||
|
- `name`
|
||||||
|
- `input_schema`
|
||||||
|
- `state_schema`
|
||||||
|
- `output_schema`
|
||||||
|
- `start`
|
||||||
|
- `steps`
|
||||||
|
- `routes`
|
||||||
|
- optional top-level `output`
|
||||||
|
|
||||||
|
`steps` are keyed by stable ids. `routes` map outcomes to another step id or
|
||||||
|
`__end__`.
|
||||||
|
|
||||||
|
## Mapping Rules
|
||||||
|
|
||||||
|
Step input bindings read graph values into node-local input:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"target": { "root": "local", "parts": ["text"] },
|
||||||
|
"path": { "root": "input", "parts": ["text"] }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Step output bindings write node-local output into workflow state:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"source": { "root": "local", "parts": ["echoed"] },
|
||||||
|
"target": { "root": "state", "parts": ["echoed"] }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Top-level workflow output uses `path` / `target`, not step-level
|
||||||
|
`source` / `target`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"path": { "root": "state", "parts": ["echoed"] },
|
||||||
|
"target": { "root": "local", "parts": ["echoed"] }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Workspace Flow
|
||||||
|
|
||||||
|
1. Create workspace from capability.
|
||||||
|
2. Get workspace with `include_draft=true` before patching.
|
||||||
|
3. Patch with current `revision`.
|
||||||
|
4. Validate workspace.
|
||||||
|
5. Save artifact or wrapper from workspace.
|
||||||
|
|
||||||
|
If a patch returns `revision_conflict`, fetch the workspace again and retry
|
||||||
|
against the latest revision.
|
||||||
|
|
||||||
|
## Focused Helpers
|
||||||
|
|
||||||
|
Prefer focused helpers over JSON Patch for common edits:
|
||||||
|
|
||||||
|
- `set_draft_name`
|
||||||
|
- `set_draft_route`
|
||||||
|
- `set_step_input_map`
|
||||||
|
- `set_step_output_map`
|
||||||
|
|
||||||
|
Use JSON Patch for structural edits the helpers do not cover.
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# Workflow Troubleshooting Reference
|
||||||
|
|
||||||
|
Use this when a source, capability, artifact, deployment, or run is missing,
|
||||||
|
unrunnable, or surprising.
|
||||||
|
|
||||||
|
## Missing Capability
|
||||||
|
|
||||||
|
Check in this order:
|
||||||
|
|
||||||
|
1. `wf.admin.list_sources`
|
||||||
|
2. `wf.admin.inspect_source`
|
||||||
|
3. `wf.workflow.list_capabilities`
|
||||||
|
4. `wf.workflow.inspect_capability`
|
||||||
|
|
||||||
|
Remember: MCP control tools are not workflow capabilities. They appear in
|
||||||
|
MCP `tools/list`, not `wf.workflow.list_capabilities`.
|
||||||
|
|
||||||
|
## Unrunnable Deployment
|
||||||
|
|
||||||
|
Run `validate_deployment` before `run_deployment`.
|
||||||
|
|
||||||
|
Common diagnostics:
|
||||||
|
|
||||||
|
- `binding_missing`: deployment lacks a logical-to-concrete source binding.
|
||||||
|
- `source_missing`: bound concrete source does not exist or is disabled.
|
||||||
|
- `capability_missing`: required node/reducer is not available.
|
||||||
|
- `schema_changed`: saved snapshot no longer matches current source.
|
||||||
|
- `source_unreachable`: live check could not contact an upstream source.
|
||||||
|
|
||||||
|
Use `live_check=true` only when you intentionally want to contact upstream
|
||||||
|
sources. It may spawn stdio servers or perform network I/O.
|
||||||
|
|
||||||
|
## Run Debugging
|
||||||
|
|
||||||
|
If a run fails:
|
||||||
|
|
||||||
|
1. Read `status`, `error`, `diagnostics`, and `trace_count`.
|
||||||
|
2. Use `inspect_run` for stored summary.
|
||||||
|
3. Use `read_run_trace` with a bounded range.
|
||||||
|
|
||||||
|
Do not request full traces unless the user explicitly asks and the trace is
|
||||||
|
known to be small.
|
||||||
|
|
||||||
|
## Harness Problems
|
||||||
|
|
||||||
|
Some LLM harnesses do not refresh `tools/list` mid-session. Do not rely on new
|
||||||
|
saved workflows becoming new tools. Use `run_deployment` and `call_capability`
|
||||||
|
instead.
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# Workflow Lifecycle Reference
|
||||||
|
|
||||||
|
Use this when an agent needs to go from available capabilities to a saved,
|
||||||
|
validated, runnable deployment.
|
||||||
|
|
||||||
|
## Primary Path
|
||||||
|
|
||||||
|
1. List sources.
|
||||||
|
- MCP: `wf.admin.list_sources`
|
||||||
|
- CLI: `wf cap list --format ids`
|
||||||
|
2. List workflow capabilities.
|
||||||
|
- MCP: `wf.workflow.list_capabilities`
|
||||||
|
- CLI: `wf cap list`
|
||||||
|
3. Inspect one capability.
|
||||||
|
- MCP: `wf.workflow.inspect_capability`
|
||||||
|
- CLI: `wf cap inspect <name>`
|
||||||
|
4. Bootstrap a draft workspace.
|
||||||
|
- MCP: `wf.workflow.create_draft_workspace_from_capability`
|
||||||
|
- CLI: `wf draft create-from-capability <workspace_id> <capability>`
|
||||||
|
5. Inspect/patch/validate the workspace until valid.
|
||||||
|
- Prefer focused helpers when available.
|
||||||
|
- Use JSON Patch only for general edits.
|
||||||
|
6. Save an artifact.
|
||||||
|
- Full workflow: `create_artifact_from_workspace`
|
||||||
|
- Reusable wrapper: `create_wrapper_from_workspace`
|
||||||
|
7. Save and validate a deployment.
|
||||||
|
8. Run the deployment.
|
||||||
|
9. Inspect the run summary first; read bounded traces only when needed.
|
||||||
|
|
||||||
|
## Object Model
|
||||||
|
|
||||||
|
- **Source**: owner of capabilities, such as `wf.std` or `everything.default`.
|
||||||
|
- **Workflow capability**: graph-ready `NodeSpec` or saved wrapper artifact.
|
||||||
|
- **Artifact**: immutable saved workflow or wrapper.
|
||||||
|
- **Deployment**: mutable binding from artifact version to concrete sources.
|
||||||
|
- **Run**: durable stopped execution record with status, output, and trace count.
|
||||||
|
|
||||||
|
## Result Handling
|
||||||
|
|
||||||
|
`run_deployment` returns compact status by default. Capture `run_id` even for
|
||||||
|
completed or failed runs. Use:
|
||||||
|
|
||||||
|
- `inspect_run` for compact stored result.
|
||||||
|
- `read_run_trace` for explicit debug slices, for example
|
||||||
|
`{"start": 0, "limit": 25}`.
|
||||||
|
- `resume_run` only for interrupted runs.
|
||||||
|
|
||||||
|
Do not ask for unbounded traces.
|
||||||
@@ -13,6 +13,7 @@ from wf_platform import (
|
|||||||
def build_local_documentation_source(repo_root: Path) -> CapabilitySource:
|
def build_local_documentation_source(repo_root: Path) -> CapabilitySource:
|
||||||
"""Load project manuals into a provider-neutral local documentation source."""
|
"""Load project manuals into a provider-neutral local documentation source."""
|
||||||
docs_dir = repo_root / "docs"
|
docs_dir = repo_root / "docs"
|
||||||
|
skills_dir = repo_root / "skills"
|
||||||
return build_documentation_source(
|
return build_documentation_source(
|
||||||
[
|
[
|
||||||
_markdown_resource(
|
_markdown_resource(
|
||||||
@@ -53,6 +54,50 @@ def build_local_documentation_source(repo_root: Path) -> CapabilitySource:
|
|||||||
title="Workflow Drafts",
|
title="Workflow Drafts",
|
||||||
description="Draft and workspace authoring model for workflows.",
|
description="Draft and workspace authoring model for workflows.",
|
||||||
),
|
),
|
||||||
|
_markdown_resource(
|
||||||
|
path=skills_dir / "wf-workflow" / "SKILL.md",
|
||||||
|
name="wf.skills.wf_workflow.skill",
|
||||||
|
uri="wf://skills/wf-workflow/SKILL.md",
|
||||||
|
title="wf-workflow Skill",
|
||||||
|
description="Agent-facing workflow lifecycle skill entrypoint.",
|
||||||
|
),
|
||||||
|
_markdown_resource(
|
||||||
|
path=skills_dir
|
||||||
|
/ "wf-workflow"
|
||||||
|
/ "references"
|
||||||
|
/ "workflow-lifecycle.md",
|
||||||
|
name="wf.skills.wf_workflow.workflow_lifecycle",
|
||||||
|
uri="wf://skills/wf-workflow/references/workflow-lifecycle.md",
|
||||||
|
title="wf-workflow Workflow Lifecycle Reference",
|
||||||
|
description="Agent-facing workflow lifecycle and tool order.",
|
||||||
|
),
|
||||||
|
_markdown_resource(
|
||||||
|
path=skills_dir
|
||||||
|
/ "wf-workflow"
|
||||||
|
/ "references"
|
||||||
|
/ "capabilities-and-wrappers.md",
|
||||||
|
name="wf.skills.wf_workflow.capabilities_and_wrappers",
|
||||||
|
uri=("wf://skills/wf-workflow/references/capabilities-and-wrappers.md"),
|
||||||
|
title="wf-workflow Capabilities And Wrappers Reference",
|
||||||
|
description=(
|
||||||
|
"Agent-facing raw capability, workflow capability, and "
|
||||||
|
"wrapper guidance."
|
||||||
|
),
|
||||||
|
),
|
||||||
|
_markdown_resource(
|
||||||
|
path=skills_dir / "wf-workflow" / "references" / "draft-workspaces.md",
|
||||||
|
name="wf.skills.wf_workflow.draft_workspaces",
|
||||||
|
uri="wf://skills/wf-workflow/references/draft-workspaces.md",
|
||||||
|
title="wf-workflow Draft Workspaces Reference",
|
||||||
|
description="Agent-facing draft workspace authoring guidance.",
|
||||||
|
),
|
||||||
|
_markdown_resource(
|
||||||
|
path=skills_dir / "wf-workflow" / "references" / "troubleshooting.md",
|
||||||
|
name="wf.skills.wf_workflow.troubleshooting",
|
||||||
|
uri="wf://skills/wf-workflow/references/troubleshooting.md",
|
||||||
|
title="wf-workflow Troubleshooting Reference",
|
||||||
|
description="Agent-facing workflow troubleshooting ladder.",
|
||||||
|
),
|
||||||
],
|
],
|
||||||
prompts=[
|
prompts=[
|
||||||
DocumentationPrompt(
|
DocumentationPrompt(
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ def test_server_exposes_platform_documentation_resources() -> None:
|
|||||||
assert "wf://docs/operator-manual" in uris
|
assert "wf://docs/operator-manual" in uris
|
||||||
assert "wf://docs/workflow-capabilities" in uris
|
assert "wf://docs/workflow-capabilities" in uris
|
||||||
assert "wf://docs/workflow-drafts" in uris
|
assert "wf://docs/workflow-drafts" in uris
|
||||||
|
assert "wf://skills/wf-workflow/SKILL.md" in uris
|
||||||
|
assert "wf://skills/wf-workflow/references/workflow-lifecycle.md" in uris
|
||||||
|
|
||||||
result = await client.read_resource("wf://docs/operator-manual")
|
result = await client.read_resource("wf://docs/operator-manual")
|
||||||
assert isinstance(result[0], mcp_types.TextResourceContents)
|
assert isinstance(result[0], mcp_types.TextResourceContents)
|
||||||
@@ -44,6 +46,13 @@ def test_server_exposes_platform_documentation_resources() -> None:
|
|||||||
or "Do not use `source` at top level" in drafts_result[0].text
|
or "Do not use `source` at top level" in drafts_result[0].text
|
||||||
)
|
)
|
||||||
|
|
||||||
|
skill_result = await client.read_resource(
|
||||||
|
"wf://skills/wf-workflow/SKILL.md"
|
||||||
|
)
|
||||||
|
assert isinstance(skill_result[0], mcp_types.TextResourceContents)
|
||||||
|
assert "name: wf-workflow" in skill_result[0].text
|
||||||
|
assert "Workflow Lifecycle" in skill_result[0].text
|
||||||
|
|
||||||
asyncio.run(run_proxy())
|
asyncio.run(run_proxy())
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user