Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ make validate-examples # validate all examples
- `loader.py` - YAML parsing with environment variable resolution (${VAR:-default}) and `!file` tag support
- `validator.py` - Cross-reference validation (agent names, routes, parallel groups)

- **expert/**: Conductor Expert knowledge base (opt-in, bundled docs)
- `loader.py` - Loads and caches bundled reference docs, wraps in `<conductor_knowledge>` tags
- `knowledge/` - Bundled markdown reference docs (yaml-schema.md, authoring.md, execution.md)

- **engine/**: Workflow execution orchestration
- `workflow.py` - Main `WorkflowEngine` class that orchestrates agent execution, parallel groups, for-each groups, and routing
- `context.py` - `WorkflowContext` manages accumulated agent outputs with three modes: accumulate, last_only, explicit
Expand Down Expand Up @@ -127,6 +131,7 @@ make validate-examples # validate all examples
- **Route evaluation**: First matching `when` condition wins; no `when` = always matches
- **Tool resolution**: `null` = all workflow tools, `[]` = none, `[list]` = subset
- **Reasoning effort**: `runtime.default_reasoning_effort` sets a workflow-wide default; per-agent `reasoning.effort` overrides it. Allowed values: `low`, `medium`, `high`, `xhigh`. Each provider translates the unified value to its native API (Copilot: `reasoning_effort` on the session, validated against the model's `supported_reasoning_efforts`; Claude: extended thinking with budget mapping low=2048, medium=8192, high=16384, xhigh=32768 tokens, with `temperature` coerced to 1.0 and `max_tokens` bumped to fit the budget). See `examples/reasoning-effort.yaml`.
- **Conductor Expert**: `runtime.conductor_expert: true` sets a workflow-wide default; per-agent `conductor_expert: true/false` overrides it (tri-state: `null` = inherit, `true` = enable, `false` = disable). When enabled, the bundled Conductor knowledge base (~70KB of YAML schema, execution model, and authoring patterns from `src/conductor/expert/knowledge/`) is prepended to the agent's prompt inside `<conductor_knowledge>` tags. Only applies to provider-backed agents (`type: agent` or default). See `examples/conductor-expert.yaml`.

## Tests Structure

Expand All @@ -138,6 +143,7 @@ Tests mirror source structure in `tests/`:
- `test_providers/` - Provider implementation tests
- `test_integration/` - Full workflow execution tests
- `test_gates/` - Human gate tests
- `test_expert/` - Conductor Expert knowledge base tests

Use `pytest.mark.performance` for performance tests (exclude with `-m "not performance"`).

Expand Down
81 changes: 81 additions & 0 deletions examples/conductor-expert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Conductor Expert Knowledge Base
#
# This example demonstrates the `conductor_expert` opt-in flag, which
# augments agent prompts with Conductor's bundled knowledge base. This
# gives agents deep understanding of Conductor's YAML schema, execution
# model, authoring patterns, and CLI commands — enabling them to
# evaluate, improve, debug, or generate Conductor workflows.
#
# The knowledge base is injected as a prompt preamble wrapped in
# <conductor_knowledge> tags, positioned after workspace instructions
# but before the agent's own prompt.
#
# Two levels of opt-in:
# 1. Per-agent: `conductor_expert: true` on an individual agent
# 2. Workflow-wide: `runtime.conductor_expert: true` (all agents)
#
# Per-agent `conductor_expert: false` can disable it even when the
# workflow-wide default is true.
#
# Usage:
# conductor run examples/conductor-expert.yaml \
# --input workflow_yaml="$(cat examples/simple-qa.yaml)"

workflow:
name: conductor-expert
description: Demonstrates Conductor Expert knowledge base injection
version: "1.0.0"
entry_point: reviewer

runtime:
provider: copilot

input:
workflow_yaml:
type: string
required: true
description: The YAML content of a Conductor workflow to review

agents:
- name: reviewer
description: Reviews a Conductor workflow for correctness and best practices
# This agent gets the full Conductor knowledge base injected
conductor_expert: true
prompt: |
Review the following Conductor workflow YAML for correctness,
best practices, and potential improvements.

Check for:
- Valid schema usage (field names, types, constraints)
- Appropriate context mode selection
- Route condition correctness
- Sensible failure modes for parallel/for-each groups
- Output schema design
- Missing route fallbacks or unbounded loops

Workflow YAML:
```yaml
{{ workflow.input.workflow_yaml }}
```

Provide a structured review with:
1. Issues found (with severity: error, warning, suggestion)
2. Recommended improvements
3. Overall assessment
output:
issues:
type: string
description: List of issues found with severity levels
improvements:
type: string
description: Recommended improvements
assessment:
type: string
description: Overall assessment of the workflow quality
routes:
- to: $end

output:
issues: "{{ reviewer.output.issues }}"
improvements: "{{ reviewer.output.improvements }}"
assessment: "{{ reviewer.output.assessment }}"
35 changes: 35 additions & 0 deletions plugins/conductor/skills/conductor/references/authoring.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ workflow:
max_agent_iterations: 50 # Max tool-use roundtrips per agent (1-500, optional)
max_session_seconds: 120 # Wall-clock timeout per agent session (optional)
default_reasoning_effort: medium # Workflow-wide reasoning effort: low, medium, high, xhigh (optional)
conductor_expert: true # Inject Conductor knowledge into all agents (default: false, optional)

input: # Define workflow inputs
param_name:
Expand Down Expand Up @@ -116,6 +117,10 @@ agents:
reasoning: # Override runtime.default_reasoning_effort (optional)
effort: high # low, medium, high, or xhigh

conductor_expert: true # Inject Conductor knowledge into this agent (optional, tri-state)
# null = inherit runtime.conductor_expert, true = force enable,
# false = force disable. Not allowed on script/human_gate/workflow.

routes: # Where to go next
- to: next_agent
```
Expand Down Expand Up @@ -148,6 +153,36 @@ agents:

See `examples/reasoning-effort.yaml` for a complete example.

### Conductor Expert Knowledge Base

`conductor_expert` enables opt-in injection of Conductor's bundled knowledge base (~70KB) into agent prompts. This gives agents deep understanding of the YAML schema, execution model, authoring patterns, and CLI commands — enabling them to evaluate, improve, debug, or generate Conductor workflows.

**Tri-state per-agent field:**
- `null` (default) — inherit from `runtime.conductor_expert`
- `true` — force enable, regardless of workflow default
- `false` — force disable, regardless of workflow default

**Workflow-wide default:** `runtime.conductor_expert: true` enables it for all provider-backed agents. Individual agents can override with `conductor_expert: false`.

Not allowed on `script`, `human_gate`, or `workflow` agent types. The knowledge is injected between workspace instructions and the agent prompt, wrapped in `<conductor_knowledge>` tags.

```yaml
workflow:
runtime:
conductor_expert: true # all agents get knowledge

agents:
- name: workflow_reviewer
conductor_expert: true # per-agent opt-in
prompt: "Review this workflow for correctness..."

- name: simple_agent
conductor_expert: false # opt out even when runtime default is true
prompt: "Do something simple."
```

See `examples/conductor-expert.yaml` for a complete example.

## Routing Patterns

### Linear
Expand Down
5 changes: 5 additions & 0 deletions plugins/conductor/skills/conductor/references/yaml-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ workflow:
max_agent_iterations: integer # Max tool-use roundtrips per agent (1-500, optional)
max_session_seconds: float # Wall-clock timeout per agent session in seconds (optional)
default_reasoning_effort: string # Workflow-wide reasoning/thinking effort: low, medium, high, xhigh (optional)
conductor_expert: boolean # Inject bundled Conductor knowledge into provider-backed agents (default: false)
mcp_servers: # MCP server configurations
<server_name>:
type: string # "stdio" (default), "http", or "sse"
Expand Down Expand Up @@ -152,6 +153,10 @@ agents:
reasoning:
effort: string # low, medium, high, or xhigh

# Conductor Expert knowledge base (optional, only on provider-backed agents)
# Tri-state: null = inherit runtime.conductor_expert, true = enable, false = disable
conductor_expert: boolean # Inject Conductor knowledge into this agent's prompt (optional)

# Per-agent retry policy (optional, not allowed for script, human_gate, or workflow agents)
retry:
max_attempts: integer # Max attempts including first (1-10, default: 1 = no retry)
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["src/conductor"]
artifacts = ["src/conductor/expert/knowledge/*.md"]
exclude = [
"src/conductor/web/frontend",
]
Expand Down
47 changes: 47 additions & 0 deletions src/conductor/config/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,29 @@ class AgentDef(BaseModel):
effort: high
"""

conductor_expert: bool | None = None
"""Opt-in to the Conductor Expert knowledge base for this agent.

When ``True``, the agent's prompt is augmented with Conductor's bundled
knowledge base covering the YAML schema, execution model, authoring
patterns, and CLI commands. This enables agents to evaluate, improve,
debug, or generate Conductor workflows with accurate, version-matched
knowledge.

- ``None`` (default): inherit from ``workflow.runtime.conductor_expert``
- ``True``: enable regardless of the workflow default
- ``False``: disable regardless of the workflow default

Only applies to provider-backed agents (type='agent' or None).

Example YAML::

agents:
- name: workflow_reviewer
conductor_expert: true
prompt: "Review this workflow for correctness..."
"""

@field_validator("timeout")
@classmethod
def validate_timeout(cls, v: int | None) -> int | None:
Expand All @@ -695,6 +718,8 @@ def validate_agent_type(self) -> AgentDef:
raise ValueError("human_gate agents cannot have 'max_depth'")
if self.reasoning is not None:
raise ValueError("human_gate agents cannot have 'reasoning'")
if self.conductor_expert is not None:
raise ValueError("human_gate agents cannot have 'conductor_expert'")
if self.timeout_seconds is not None:
raise ValueError("human_gate agents cannot have 'timeout_seconds'")
elif self.type == "script":
Expand Down Expand Up @@ -731,6 +756,8 @@ def validate_agent_type(self) -> AgentDef:
raise ValueError("script agents cannot have 'max_depth'")
if self.reasoning is not None:
raise ValueError("script agents cannot have 'reasoning'")
if self.conductor_expert is not None:
raise ValueError("script agents cannot have 'conductor_expert'")
if self.timeout_seconds is not None:
raise ValueError(
"script agents cannot have 'timeout_seconds' "
Expand Down Expand Up @@ -761,6 +788,8 @@ def validate_agent_type(self) -> AgentDef:
raise ValueError("workflow agents cannot have 'retry'")
if self.dialog is not None:
raise ValueError("workflow agents cannot have 'dialog'")
if self.conductor_expert is not None:
raise ValueError("workflow agents cannot have 'conductor_expert'")
if self.timeout_seconds is not None:
raise ValueError("workflow agents cannot have 'timeout_seconds'")
else:
Expand Down Expand Up @@ -918,6 +947,24 @@ class RuntimeConfig(BaseModel):
the request through to the SDK.
"""

conductor_expert: bool = False
"""Workflow-wide default for the Conductor Expert knowledge base.

When ``True``, all provider-backed agents in the workflow receive the
bundled Conductor knowledge base (YAML schema, execution model,
authoring patterns, CLI commands) prepended to their prompts.

Individual agents can override this with their own
``conductor_expert`` field (``True`` to force-enable, ``False`` to
force-disable).

Example YAML::

workflow:
runtime:
conductor_expert: true
"""


class WorkflowDef(BaseModel):
"""Top-level workflow configuration."""
Expand Down
5 changes: 5 additions & 0 deletions src/conductor/engine/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,13 +367,17 @@ def __init__(
# Workspace instructions preamble (inherited by sub-workflows)
self._instructions_preamble = instructions_preamble

# Conductor Expert default (workflow-level opt-in)
self._conductor_expert_default = config.workflow.runtime.conductor_expert

# For backward compatibility, create a default executor with single provider
# This is used when registry is None
if provider is not None:
self.executor = AgentExecutor(
provider,
workflow_tools=config.tools,
instructions_preamble=self._instructions_preamble,
conductor_expert_default=self._conductor_expert_default,
)
self.provider = provider # Keep for backward compatibility
else:
Expand Down Expand Up @@ -575,6 +579,7 @@ async def _get_executor_for_agent(self, agent: AgentDef) -> AgentExecutor:
provider,
workflow_tools=self.config.tools,
instructions_preamble=self._instructions_preamble,
conductor_expert_default=self._conductor_expert_default,
)
elif self.executor is not None:
# Single provider mode (backward compatibility)
Expand Down
48 changes: 42 additions & 6 deletions src/conductor/executor/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ def __init__(
provider: AgentProvider,
workflow_tools: list[str] | None = None,
instructions_preamble: str | None = None,
conductor_expert_default: bool = False,
) -> None:
"""Initialize the AgentExecutor.

Expand All @@ -106,10 +107,15 @@ def __init__(
workflow_tools: Tools defined at workflow level. Defaults to empty list.
instructions_preamble: Optional workspace instructions text to prepend
to every agent's rendered prompt.
conductor_expert_default: Workflow-level default for the Conductor
Expert knowledge base. When True, all agents executed by this
executor receive the knowledge base unless the agent explicitly
sets ``conductor_expert: false``.
"""
self.provider = provider
self.workflow_tools = workflow_tools or []
self.instructions_preamble = instructions_preamble
self._conductor_expert_default = conductor_expert_default
self.renderer = TemplateRenderer()

async def execute(
Expand Down Expand Up @@ -157,9 +163,10 @@ async def execute(
# Render prompt with context
rendered_prompt = self.renderer.render(agent.prompt, context)

# Prepend workspace instructions preamble if available
if self.instructions_preamble:
rendered_prompt = self.instructions_preamble + rendered_prompt
# Prepend prompt prefix (workspace instructions + optional expert knowledge)
prefix = self._build_prompt_prefix(agent)
if prefix:
rendered_prompt = prefix + rendered_prompt

# Append user guidance section if provided
if guidance_section:
Expand Down Expand Up @@ -245,12 +252,41 @@ def render_prompt(self, agent: AgentDef, context: dict[str, Any]) -> str:
context: Context for prompt rendering.

Returns:
Rendered prompt string with workspace instructions prepended if configured.
Rendered prompt string with workspace instructions and optional
expert knowledge prepended if configured.

Raises:
TemplateError: If prompt rendering fails.
"""
rendered = self.renderer.render(agent.prompt, context)
if self.instructions_preamble:
rendered = self.instructions_preamble + rendered
prefix = self._build_prompt_prefix(agent)
if prefix:
rendered = prefix + rendered
return rendered

def _should_inject_expert(self, agent: AgentDef) -> bool:
"""Determine whether to inject Conductor Expert knowledge for an agent.

Resolution order:
- If the agent explicitly sets ``conductor_expert``, use that value.
- Otherwise, fall back to the workflow-level default.
"""
if agent.conductor_expert is not None:
return agent.conductor_expert
return self._conductor_expert_default

def _build_prompt_prefix(self, agent: AgentDef) -> str:
"""Build the prefix to prepend before an agent's rendered prompt.

Combines workspace instructions and optional Conductor Expert
knowledge into a single prefix string. This helper is shared by
:meth:`execute` and :meth:`render_prompt` to keep them in sync.
"""
parts: list[str] = []
if self.instructions_preamble:
parts.append(self.instructions_preamble)
if self._should_inject_expert(agent):
from conductor.expert.loader import load_expert_knowledge

parts.append(load_expert_knowledge())
return "".join(parts)
14 changes: 14 additions & 0 deletions src/conductor/expert/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""Conductor Expert — reusable knowledge base for Conductor-aware agents.

This module provides opt-in access to Conductor's bundled knowledge base,
giving agents deep understanding of the YAML schema, execution model,
authoring patterns, and CLI commands. Agents that need to evaluate, improve,
debug, or generate Conductor workflows can enable it via the
``conductor_expert`` flag at the agent or workflow level.

See :mod:`conductor.expert.loader` for loading and caching details.
"""

from conductor.expert.loader import load_expert_knowledge

__all__ = ["load_expert_knowledge"]
Loading
Loading