Workflow Introspection Nodes
Applies to: ChengOS v0.2.0+ | Last verified: 2026-09-25 | Source:
crates/cheng-nodes/src/nodes/builtin/tools
Workflows looking at workflows. tools/workflow_inspect lists and searches the workflows on the
instance, including finding every workflow that contains a given node type. tools/import_workflow
brings a workflow definition in. tools/get_execution_trace reads back what a past run did, at three
depths — a summary, the tool calls, or the bounded detail — so an agent can diagnose a failure without
pulling the whole trace. tools/read_artifact fetches the content behind an artifact reference.
Workflow Inspector — tools/workflow_inspect
Read-only query for workflow definitions, node schemas, and execution status. list_workflows=list template workflows (is_template=true, name/tag filter, deterministic sort_by, pagination), find_workflows_by_node_type=list template workflows that contain an exact node_type (reverse lookup, created_at desc), get_workflow=get workflow details (view=both for legacy-compatible output, summary for compact planning data, full for import definition), list_node_types=list node types (compact node_type/name/category by default for low-token scanning, verbose=true adds description/version/is_tool_node; optional node_filter fuzzy match + category_filter), get_node_schema=get node input/output schema (alias describe_node_type; compact=true returns only top-level input/output field-name arrays), list_ports=compact port shape (name/type/required) without full schema, find_replacements=given invalid node_types return valid candidates and explains when a queried type already exists, validate_workflow=validate a draft definition (nodes/edges) or a saved workflow_id against live node schemas and return a structured ValidationReport (read-only, never persists), get_execution=query execution status and node outputs by execution_id (execution_node_filter/node_status_filter opt into enhanced per-node records + matched_count), list_executions=list execution history for a workflow (requires workflow_id)
Inputs
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
mode | enum | — | manual | Execution mode: Manual=user fills parameters, Llm=LLM auto-fills parameters. Control: select. Options: manual, llm |
action | string | — | "" | Operation type: list_workflows (deterministic sort via sort_by) / find_workflows_by_node_type (template workflows containing an exact node_type) / get_workflow (view=both/summary/full) / list_node_types (compact node_type/name/category by default, verbose=true for full detail; supports node_filter/category_filter, returns categories when unfiltered) / get_node_schema (alias describe_node_type; compact=true returns only input/output field names) / list_ports (compact port shape) / find_replacements (suggest valid node types and explains existing types) / validate_workflow (validate a draft definition or a saved workflow_id against live schemas) / get_execution (supports execution_node_filter/node_status_filter) / list_executions. Control: select. Options: list_workflows (模板工作流列表), find_workflows_by_node_type (按节点类型查工作流), get_workflow (获取工作流), list_node_types (节点类型列表), get_node_schema (获取节点模式), list_ports (列出端口), find_replacements (查找替换候选), validate_workflow (验证工作流), get_execution (获取执行), list_executions (执行历史) |
workflow_id | string | — | null | Workflow UUID (required for get_workflow) |
view | enum | — | both | get_workflow only: both (default, legacy-compatible response) / summary (compact agentSummary plus metadata) / full (import-compatible definition plus metadata). Control: select. Options: both (保留 agentSummary、definition 和旧版顶层副本,完全兼容现有调用方。), summary (仅返回紧凑的 agentSummary 和工作流元数据。), full (仅返回可导入的 definition 和工作流元数据。) |
name_filter | string | — | null | Workflow name filter (optional for list_workflows, fuzzy match) |
tag_filter | string | — | null | Workflow tag filter (optional for list_workflows, exact match) |
limit | integer | — | 50 | Max return count (default 50, max 200) |
offset | integer | — | 0 | Pagination offset (default 0) |
node_type | string | — | null | Node type ID (required for get_node_schema, e.g. agent/llm) |
compact | boolean | — | false | get_node_schema only: when true, input_schema and output_schema are arrays of top-level field names instead of full JSON Schema. Use this first when you only need port names; leave false (default) for types, required fields, and nested constraints. Control: switch |
category_filter | string | — | null | Node category filter (optional for list_node_types) |
node_filter | string | — | null | Fuzzy node filter for list_node_types (matches node_type/name/description, case-insensitive, e.g. 'chat') |
node_types | array | — | null | Node types to find replacement candidates for (required for find_replacements, e.g. ["io/chat_input"]) |
execution_id | string | — | null | Execution UUID (required for get_execution) |
definition | object | — | null | Draft graph to validate for validate_workflow: an object with camelCase nodes[] (nodeId, nodeType) and edges[] (sourceNode, sourcePort, targetNode, targetPort). Supply exactly one of definition or workflow_id. |
verbose | boolean | — | false | list_node_types verbosity. Default (false) returns only node_type/name/category per item (compact, low token cost for scanning all node types). Set verbose=true to also return description/version/is_tool_node. Use get_node_schema/list_ports for full detail on a specific node. Does not change filtering, totals, pagination, categories, candidates, or hints. Control: switch |
sort_by | enum | — | null | Sort order for list_workflows / find_workflows_by_node_type: created_at (desc, default) / updated_at (desc) / name (asc, case-insensitive) / node_count (desc). Every mode has a stable workflow-ID tie-break. Control: select. Options: created_at (创建时间降序(最新在前)——默认排序。), updated_at (更新时间降序(最近改动在前)。), name (名称升序,大小写无关。), node_count (节点数量降序。) |
execution_node_filter | string | — | null | get_execution only: case-sensitive substring match on execution node IDs. Distinct from node_filter (which fuzzily filters registered node types). Supplying this opts into enhanced per-node records + matched_count. |
node_status_filter | enum | — | null | get_execution only: keep nodes in this state (waiting/ready/running/completed/failed/skipped). Combined with execution_node_filter using AND. Supplying this opts into enhanced per-node records + matched_count. Control: select. Options: waiting, ready, running, completed, failed, skipped |
Outputs
| Field | Type | Description |
|---|---|---|
status | string | Operation status: ok / not_found / error |
data | any | Query result (JSON format) |
count | integer | Current page result count |
total | integer | Total count (after filtering, before pagination) |
categories | array | Sorted, deduplicated node categories (list_node_types without filters). data still holds the node array. |
candidates | any | Up to five ranked replacement candidates when a node_filter matches nothing |
hint | string | Actionable hint for the agent |
truncated | boolean | True when the current page was truncated by limit. Call again with offset=next_offset to continue. |
next_offset | integer | Next pagination offset to use when truncated=true. |
error | string | Error message |
Import Workflow — tools/import_workflow
Register a workflow as a file-managed workflow in the current workspace. Two modes: (1) structured create — pass name + nodes[] (each with a unique 'key' and 'nodeType') + edges[] (sourceKey/sourcePort/targetKey/targetPort); the tool validates against live node schemas, generates all UUIDs, and imports only if valid. (2) legacy import — pass canonical V1 'content'. Never mix 'content' with structured fields. Filesystem write success is NOT import success — only this call's result is authoritative.
Inputs
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
workflow_key | string | ✅ | — | Stable lowercase kebab-case key for this workflow's folder |
name | string | — | — | Structured create: workflow display name (do not combine with 'content') |
description | string | — | — | Structured create: optional workflow description |
nodes | array | — | — | Structured create: nodes[] each with a unique 'key', 'nodeType', optional 'name'/'position'/'config'. IDs are generated by the tool. |
edges | array | — | — | Structured create: edges[] each with sourceKey, sourcePort, targetKey, targetPort |
content | string | — | — | Legacy import: canonical V1 workflow.json content (do not combine with structured fields) |
Outputs
| Field | Type | Description |
|---|---|---|
workflow_id | string | Resolved workflow id on success. |
outcome | string | created, updated, or unchanged on success. |
source_path | string | Stored source path on success. |
node_ids | any | Structured mode: generated node ids by temporary key. |
validation | any | Structured mode: the full validation report (errors + warnings). |
warnings | array<string> | Non-fatal advisories. |
error_code | string | Stable error code on failure. |
error | string | Error message; null on success. |
Get Execution Trace — tools/get_execution_trace
Read a previous turn's execution record by trace_key (legacy in-process trace) or archive_ref (durable execution archive) for LLM on-demand viewing
Inputs
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
trace_key | string | — | null | Trace retrieval key from conversation history summary (format: session_id:turn). Optional when archive_ref is provided. |
archive_ref | string | — | null | Opaque durable execution-archive reference, taken from the execution_record marker in conversation history |
mode | string | — | null | Query mode: 'summary' (counts and tool names), 'tool_calls' (per-step calls, ids, statuses, arguments), or 'detail' (adds bounded result payloads). Ask 'which tools did you use' with tool_calls. |
Outputs
| Field | Type | Description |
|---|---|---|
content | string | Execution record content (empty string if not found) |
found | boolean | Whether the corresponding execution record was found |
unavailable_reason | string | Explicit unavailability state when found=false: not_available, expired, or forbidden. An unavailable record does NOT mean no tools were called. |
Read Artifact — tools/read_artifact
Read a bounded byte/line window of a text artifact by reference. Accepts only an artifact reference — never a raw file path — and returns continuation info for paged reads. For a source-snapshot artifact, pass snapshot_path to read one manifest-addressed text file.
Inputs
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
artifact | object (port) | — | null | Artifact reference to read (the only accepted source). Connection port, not a form field. |
start_byte | integer | — | 0 | Byte offset to start reading from |
max_bytes | integer | — | 16384 | Maximum bytes to read in this window (default 16 KiB, hard cap 1 MiB) |
start_line | integer | — | null | 1-based start line (enables line mode) |
max_lines | integer | — | null | Maximum lines to read in line mode |
snapshot_path | string | — | null | Source-relative manifest path of one text file inside a source snapshot (e.g. 'src/main.py'). Only valid when the artifact is a source snapshot. |
Outputs
| Field | Type | Description |
|---|---|---|
content | string | Bounded plain-text content of this window |
source_artifact | object | Artifact that was read |
bytes_read | integer | Bytes Read |
total_bytes | integer | Total Bytes |
truncated | boolean | Whether more content exists beyond this window |
next_offset | integer | Byte offset for the next paged read (byte mode, when truncated) |
warning | string | Non-sensitive advisory about this read |
error | string | Error message; null on success. |