Skip to content

Epic: Scripts as third element category in slots (Pre/Post-Hooks) #19

Description

@maddes8cht

Description

Alongside agents and workflows, there should be a third category of executable elements: Scripts. These can be inserted between agents and sub-workflows in any slot (Preparation, Loop, Finalization) and serve as programmable hooks at runtime.

Unlike the existing init_script (which runs only before the opencode subprocess), these scripts run inside the workflow orchestrator and have direct access to WorkflowState.

Use Cases

Scenario Script
Prepare state A Python script sets payload["files"] = get_changed_files() before the agent runs
Manipulate prompt A script appends additional instructions to the prompt based on payload["language"]
Parse output After an agent run, the output is validated and transformed into structured state fields
Conditional logic If payload["coverage"] < 50, set payload["strict_mode"] = True
File operations Copy test results, delete temp files, write logs

Possible Variants

Two types are conceivable, depending on position in the slot:

  1. Pre-Hook (before the agent/sub-workflow) – transforms state or prompt before execution
  2. Post-Hook (after the agent/sub-workflow) – processes results, validates, enriches state

Whether the distinction is made by slot position (script before agent = Pre, after = Post) or by the script definition itself is still open.

Sub-Issues (ToDo)

  • Configuration System (core/config.py) #1 Script Loader – New class core/script_loader.py analogous to AgentLoader: scans a directory (e.g. scripts/) for supported script types (.py, .ps1, .sh), validates and loads them.
  • Core State Management (core/state.py, core/parser.py) #2 Script Runner in Engine_execute_script(name) in core/engine.py that runs a script with read/write access to WorkflowState. Recursion guard, timeout, error handling.
  • Agent Definition Loader (core/agent.py) #3 Integration into Slot Resolution_resolve_slot_entry() recognizes script:name and calls the script runner. A script can be positioned anywhere in a slot (before/after agents or sub-workflows).
  • Subprocess Runner (core/runner.py) #4 GUI: Script Pool – Third pool listbox for scripts in ui/app.py, script preview (display source code), transfer buttons.
  • Execution Engine (core/engine.py) #5 Define Script API – Define the interface: How does a script receive state? How does it return changes? Examples:
    # scripts/prepare_files.py
    def run(state):
        state["payload"]["files"] = ["src/main.py", "src/utils.py"]
        return state
  • Main Entry Point (openloop.py) #6 Integration Tests – Tests with pre/post scripts, state manipulation, error cases in tests/integration.py.

Open Questions

Question Discussion
Script types Only Python (simple, safe) or also Shell (flexible but risky)?
Script interface run(state) -> state (Python function) or arbitrary executable with JSON via stdin/stdout?
Separate Pre/Post slots? Or is a single script type that acts based on its slot position sufficient?
Security Shell scripts could be dangerous – is sandboxing needed?
Directory scripts/ analogous to agents/ and workflows/, or under core/scripts/?

Distinction from Existing Features

Feature Difference
init_script Runs in subprocess before opencode, no state access, Shell only
preparation_agents Runs opencode with system prompt – expensive, LLM-based
Sub-Workflows Recursive workflow execution – full flow, no direct state mapping
Scripts (this feature) Lightweight, programmable, full state access, in-engine

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions