Contents

Developers

Step config format

๐Ÿ“‹ Overview

The step_config.json file stores step-specific agent configurations (LLM models, tool selections, execution settings) separate from the main plan structure. This separation allows plan.json to focus on workflow structure while step_config.json manages execution details.

Key Benefits:

  • Separation of concerns: Plan structure vs execution configuration
  • Consistent format: Object format with steps array (both frontend and backend)
  • Backward compatibility: Legacy array format supported during migration

๐Ÿ“ Key Files & Locations

Component File Path Key Functions
Frontend Parser usePlanData.ts normalizeStepConfigFile(), saveStepConfig()
Backend Parser source ParseStepConfigContent(), ReadStepConfigs(), WriteStepConfigs()
Type Definitions stepConfigMatching.ts StepConfig, AgentConfigs
Backend Types source AgentConfigs struct definition

๐Ÿ“‚ File Locations

The step_config.json file can exist in two locations (with priority):

  1. Run-specific config (highest priority): {workspacePath}/runs/{runFolder}/planning/step_config.json

    • Used when a specific run folder is selected
    • Allows different configs for different execution runs
  2. Default config (fallback): {workspacePath}/planning/step_config.json

    • Used when no run folder is selected or run-specific config doesn't exist
    • Shared across all runs

Source: view on GitHub

The backend automatically checks run-specific config first, then falls back to default config.


๐Ÿ”„ Format Structure

Object Format (Only Supported Format)

Both frontend and backend read and write only the object format with steps field:

{
  "steps": [
    {
      "id": "step-id-here",
      "title": "Optional step title",
      "agent_configs": {
        "selected_servers": ["server1", "server2"],
        "selected_tools": ["server1:tool1", "server1:tool2", "server2:*"],
        "enabled_custom_tools": ["workspace_browser:agent_browser"],
        "execution_llm": {
          "provider": "openai",
          "model_id": "gpt-4o"
        },
        "use_code_execution_mode": true,
        "disable_validation": false,
        "llm_validation_mode": "skip",
        "learnings_access": "read-write",
        "learning_objective": "Capture target-system selectors, auth flow quirks, and session-expiry signals",
        "enable_context_offloading": true,
        "enable_prerequisite_detection": true,
        "prerequisite_rules": [
          {
            "depends_on_step": "step-0",
            "description": "If login session is missing or expired, go back to step 0"
          }
        ]
      }
    }
  ]
}

Field Structure

Field Required Type Description
steps โœ… array Root array containing step configurations
steps[].id โœ… string Stable step ID from plan.json
steps[].title โŒ string Step title for reference/display only
steps[].agent_configs โŒ object Nested configuration object

๐Ÿ”„ Implementation Details

Frontend Implementation

File: usePlanData.ts

Read:

function normalizeStepConfigFile(rawContent: unknown): StepConfig[] {
  // Handles object format: { "steps": [...] }
  if (rawContent && typeof rawContent === 'object' && !Array.isArray(rawContent)) {
    const obj = rawContent as Record<string, unknown>
    if ('steps' in obj && Array.isArray(obj.steps)) {
      return obj.steps as StepConfig[]
    }
  }
  // Legacy array format support (with warning)
  if (Array.isArray(rawContent)) {
    return rawContent as StepConfig[]
  }
  return []
}

Write:

const content = JSON.stringify({ steps: stepConfigs }, null, 2)
await agentApi.updatePlannerFile(stepConfigPath, content, `Updated step config for step ${stepId}`)

Backend Implementation

Source: view on GitHub

Read:

type StepConfigFile struct {
    Steps []StepConfig `json:"steps"`
}

func ParseStepConfigContent(content string) ([]StepConfig, error) {
    var file StepConfigFile
    if err := json.Unmarshal([]byte(content), &file); err != nil {
        return nil, err
    }
    return file.Steps, nil
}

Write:

file := StepConfigFile{Steps: configs}
content, err := json.MarshalIndent(file, "", "  ")

โš™๏ธ Configuration Fields

Source: view on GitHub โ€” AgentConfigs struct

LLM Configuration

Field Type Default Purpose
execution_llm object Preset default LLM config for execution agent ({ provider: string, model_id: string })
validation_llm object Preset default LLM config for validation agent

Turn Limits

Per-step and workflow-default turn-limit properties are retired. Legacy execution_max_turns values are ignored on load and omitted from typed config saves; execution uses the shared runtime limit.

Tool & Server Configuration

Field Type Default Purpose
selected_servers string[] [] MCP servers to use for this step (subset of preset servers)
selected_tools string[] [] Specific tools (format: "server:tool" or "server:*" for all tools)
enabled_custom_tools string[] [] Optional additions in "category:tool" or "category:*" format. Execution agents automatically receive workspace_advanced plus human_feedback, notify_user, and create_human_input_request. Name any additional human_tools entry explicitly. Legacy human_tools:* is normalized to the same three-tool baseline.
enabled_custom_tool_categories string[] [] Legacy format: Tool categories (e.g., ["workspace_tools", "human_tools"]) - deprecated, use enabled_custom_tools instead

Validation Configuration

Field Type Default Purpose
disable_validation boolean true (nil = disabled) LLM validation control: nil/true = disabled (auto-approve), false = enabled. Pre-validation always runs if schema exists.
llm_validation_mode "skip"|"auto"|"always" "skip" Validation strategy: "skip" (trust pre-validation), "auto" (skip after 3 successes), "always" (standard)

Learning Configuration

Field Type Default Purpose
learnings_access "read"|"read-write"|"none" "read" (auto-migrated from learning_objective if unset) Primary gate for the global learnings store. "read" โ€” step sees learnings/_global/SKILL.md in its prompt; "read-write" โ€” step also contributes (requires non-empty learning_objective); "none" โ€” step neither reads nor contributes. Mirrors knowledgebase_access.
learning_objective string "" Extraction instruction for the post-step learning agent โ€” describes what patterns/selectors/recipes should land in SKILL.md. Required when learnings_access="read-write"; the validator rejects the combination of write access with an empty objective.

Execution Mode Configuration

Field Type Default Purpose
use_code_execution_mode boolean Preset default (nil = use preset) Step-level code execution mode override (nil = use preset default, true/false = override)
enable_context_offloading boolean true (nil = enabled) Enable/disable context offloading virtual tools

Prerequisite Detection Configuration

Field Type Default Purpose
enable_prerequisite_detection boolean false Enable prerequisite failure detection for this step
prerequisite_rules array [] Array of prerequisite rules, each with depends_on_step (string) and description (string)

๐Ÿ› ๏ธ Common Issues & Solutions

Issue Cause Solution
"steps" field not found File uses legacy array format Use normalizeStepConfigFile() to handle both formats (frontend) or ensure backend uses object format
Step ID mismatch Step ID doesn't match plan.json Ensure step IDs are stable and match plan.json exactly
agent_configs is null Step has no configuration This is valid - step will use preset defaults
Parse error Invalid JSON structure Verify file uses object format: { "steps": [...] }
Config not found Run-specific config missing Backend automatically falls back to default config in {workspacePath}/planning/step_config.json
enabled_custom_tool_categories ignored Using legacy format Migrate to unified enabled_custom_tools format: "category:tool" or "category:*"

๐Ÿ” For LLMs: Quick Reference

Constraints:

  • โœ… Allowed: Object format { "steps": [...] }
  • โœ… Allowed: Empty steps array []
  • โœ… Allowed: Missing agent_configs (uses defaults)
  • โŒ Forbidden: Root-level array format (legacy, deprecated)
  • โŒ Forbidden: Missing id field in step config

Example:

{
  "steps": [
    {
      "id": "step-1",
      "agent_configs": {
        "selected_servers": ["aws"],
        "execution_llm": {
          "provider": "openai",
          "model_id": "gpt-4o"
        }
      }
    }
  ]
}

File Operations:

  • Read: Always parse object format, extract steps array
  • Write: Always write object format: JSON.stringify({ steps: stepConfigs }, null, 2)
  • Update: Find step by id, update agent_configs, save entire file
  • Config Priority: Run-specific config (runs/{runFolder}/planning/step_config.json) takes precedence over default config (planning/step_config.json)

Field Notes:

  • All boolean fields use nil (undefined) to mean "use default/preset value"
  • enabled_custom_tools uses unified format: "category:tool" or "category:*". Current categories include workspace_advanced, workspace_tools, workspace_browser, and human_tools; use execute_shell_command / diff_patch_workspace_file for file access instead of legacy basic workspace tool names.
  • learning_detail_level accepts "exact", "general", or "none" (default: "exact")

  • Workflow Docs - Overall workflow architecture
  • Learn Code and Code Execution Modes - Scripted execution configuration and flow
  • Step Config Matching - Type definitions and matching logic