docs: teach agents workflow schema discovery
This commit is contained in:
@@ -69,5 +69,8 @@ wf run trace <run_id> --from 0 --limit 25
|
|||||||
- Do not use planning-session specs or implementation plans as user-facing runtime guidance.
|
- Do not use planning-session specs or implementation plans as user-facing runtime guidance.
|
||||||
- Do not confuse draft shape with raw plan shape: drafts use `steps/routes/use`;
|
- Do not confuse draft shape with raw plan shape: drafts use `steps/routes/use`;
|
||||||
raw plans use `nodes/edges/node`.
|
raw plans use `nodes/edges/node`.
|
||||||
- `wf schema` is currently only an empty command group; do not rely on it for
|
- Use `wf schema` to list workflow document/component shapes.
|
||||||
workflow plan shape until subcommands exist.
|
- Use `wf schema draft`, `wf schema raw`, or `wf schema <Component>` for compact
|
||||||
|
JSON guidance before authoring.
|
||||||
|
- Add `--verbose` only when a complete JSON Schema document is required; it may
|
||||||
|
be large.
|
||||||
|
|||||||
@@ -3,6 +3,16 @@
|
|||||||
Use direct plan import only when you already have a complete workflow plan. For
|
Use direct plan import only when you already have a complete workflow plan. For
|
||||||
interactive authoring, prefer draft workspaces and focused edit commands.
|
interactive authoring, prefer draft workspaces and focused edit commands.
|
||||||
|
|
||||||
|
Before writing a plan, inspect the current public shape:
|
||||||
|
|
||||||
|
wf schema raw
|
||||||
|
wf schema NodeUse
|
||||||
|
wf schema InputPathBinding
|
||||||
|
wf schema OutputBinding
|
||||||
|
|
||||||
|
Use `wf schema raw --verbose` only when the complete validation schema is
|
||||||
|
required.
|
||||||
|
|
||||||
## Command Path
|
## Command Path
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -3,6 +3,11 @@
|
|||||||
Use draft workspaces for iterative workflow authoring. They are mutable and
|
Use draft workspaces for iterative workflow authoring. They are mutable and
|
||||||
revisioned; artifacts are immutable and versioned.
|
revisioned; artifacts are immutable and versioned.
|
||||||
|
|
||||||
|
Before writing or patching a draft, inspect the current public shape:
|
||||||
|
|
||||||
|
wf schema draft
|
||||||
|
wf schema DraftUseStep
|
||||||
|
|
||||||
## Draft Shape
|
## Draft Shape
|
||||||
|
|
||||||
A draft has:
|
A draft has:
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ from wf_api.models import RawWorkflowPlan
|
|||||||
from wf_artifacts.drafts.models import WorkflowDraft
|
from wf_artifacts.drafts.models import WorkflowDraft
|
||||||
from wf_core.models.workflow import Workflow
|
from wf_core.models.workflow import Workflow
|
||||||
|
|
||||||
|
|
||||||
JsonObject: TypeAlias = dict[str, Any]
|
JsonObject: TypeAlias = dict[str, Any]
|
||||||
SCHEMA_DIALECT = Draft202012Validator.META_SCHEMA["$id"]
|
SCHEMA_DIALECT = Draft202012Validator.META_SCHEMA["$id"]
|
||||||
ROOT_MODELS: dict[str, type[Any]] = {
|
ROOT_MODELS: dict[str, type[Any]] = {
|
||||||
@@ -63,7 +62,11 @@ class SchemaCatalog:
|
|||||||
def entry(self, name: str) -> SchemaEntry:
|
def entry(self, name: str) -> SchemaEntry:
|
||||||
canonical = self.resolve(name)
|
canonical = self.resolve(name)
|
||||||
schema = self.schema(canonical)
|
schema = self.schema(canonical)
|
||||||
aliases = tuple(sorted(alias for alias, target in self.aliases.items() if target == canonical))
|
aliases = tuple(
|
||||||
|
sorted(
|
||||||
|
alias for alias, target in self.aliases.items() if target == canonical
|
||||||
|
)
|
||||||
|
)
|
||||||
return SchemaEntry(
|
return SchemaEntry(
|
||||||
name=canonical,
|
name=canonical,
|
||||||
aliases=aliases,
|
aliases=aliases,
|
||||||
@@ -145,8 +148,7 @@ def _compact_node(schema: object, related: set[str]) -> object:
|
|||||||
properties = schema.get("properties")
|
properties = schema.get("properties")
|
||||||
if isinstance(properties, dict):
|
if isinstance(properties, dict):
|
||||||
result["properties"] = {
|
result["properties"] = {
|
||||||
name: _compact_node(value, related)
|
name: _compact_node(value, related) for name, value in properties.items()
|
||||||
for name, value in properties.items()
|
|
||||||
}
|
}
|
||||||
if "items" in schema:
|
if "items" in schema:
|
||||||
result["items"] = _compact_node(schema["items"], related)
|
result["items"] = _compact_node(schema["items"], related)
|
||||||
@@ -157,7 +159,9 @@ def _compact_node(schema: object, related: set[str]) -> object:
|
|||||||
result["one_of"] = [_compact_node(branch, related) for branch in branches]
|
result["one_of"] = [_compact_node(branch, related) for branch in branches]
|
||||||
break
|
break
|
||||||
discriminator = schema.get("discriminator")
|
discriminator = schema.get("discriminator")
|
||||||
if isinstance(discriminator, dict) and isinstance(discriminator.get("propertyName"), str):
|
if isinstance(discriminator, dict) and isinstance(
|
||||||
|
discriminator.get("propertyName"), str
|
||||||
|
):
|
||||||
result["discriminator"] = discriminator["propertyName"]
|
result["discriminator"] = discriminator["propertyName"]
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,11 @@ from jsonschema import Draft202012Validator
|
|||||||
from typer.testing import CliRunner
|
from typer.testing import CliRunner
|
||||||
|
|
||||||
from wf_cli.app import app
|
from wf_cli.app import app
|
||||||
|
from wf_cli.schema_catalog import (
|
||||||
|
compact_schema_outline,
|
||||||
|
schema_catalog,
|
||||||
|
verbose_schema_document,
|
||||||
|
)
|
||||||
|
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
@@ -112,9 +116,6 @@ def test_schema_unknown_name_fails_with_suggestion() -> None:
|
|||||||
assert "NodeUse" in result.output
|
assert "NodeUse" in result.output
|
||||||
|
|
||||||
|
|
||||||
from wf_cli.schema_catalog import schema_catalog
|
|
||||||
|
|
||||||
|
|
||||||
def test_schema_catalog_resolves_aliases_and_components() -> None:
|
def test_schema_catalog_resolves_aliases_and_components() -> None:
|
||||||
catalog = schema_catalog()
|
catalog = schema_catalog()
|
||||||
|
|
||||||
@@ -125,9 +126,6 @@ def test_schema_catalog_resolves_aliases_and_components() -> None:
|
|||||||
assert catalog.entry("NodeUse").kind == "definition"
|
assert catalog.entry("NodeUse").kind == "definition"
|
||||||
|
|
||||||
|
|
||||||
from wf_cli.schema_catalog import compact_schema_outline, verbose_schema_document
|
|
||||||
|
|
||||||
|
|
||||||
def test_compact_outline_replaces_local_refs_with_names() -> None:
|
def test_compact_outline_replaces_local_refs_with_names() -> None:
|
||||||
payload = compact_schema_outline("NodeUse")
|
payload = compact_schema_outline("NodeUse")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user