Skip to content

judus/argon-workflows

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PHP Build codecov Psalm Level Code Style Latest Version License: MIT

Argon Workflows

A minimal workflow runner. Define state handlers and wire them together into workflows. Transitions can be static or triggered by signals emitted from handlers.

Basic Concept

Define a ContextInterface that represents the state of your system and passes through your workflow.

Each state has a StateHandlerInterface, which processes the context and returns a HandlerResult, possibly with transition signals.

The WorkflowRunner coordinates:

  • Calling handlers in a loop
  • Transitioning based on signal or static mapping

Example

$context = new MyContext(state: 'start');

$registry = new StateHandlerRegistry();
$registry->register('start', new StartHandler());
$registry->register('next', new NextHandler());

$workflow = new WorkflowDefinition(
    staticTransitions: ['start' => 'next'],
    signalTransitions: ['done' => 'final']
);

$workflows = new WorkflowRegistry();
$workflows->add('default', $workflow);

$runner = new WorkflowRunner($registry, new TransitionResolver(), $workflows);
$finalContext = $runner->run($context);

Execution Events

The runner can emit execution events (run/step/transition) via an observer. Provide your own runId when you want to correlate runs with external systems (queues, UIs, logs).

$observer = new MyExecutionObserver();
$runner = new WorkflowRunner(
    $registry,
    new TransitionResolver(),
    $workflows,
    null,
    $observer
);

$finalContext = $runner->run($context, 'default', runId: 'job-123');

Transition Behavior

If a handler "emits" a signal (via HandlerResult::$signals), that takes precedence over the static transition.

return new HandlerResult(
    context: $context,
    signals: ['done' => true] // will override static transition
);

If no signals match, the runner falls back to the static transition based on current state.

Graph Export

You can export a workflow definition as a graph (nodes + edges) to visualize it in a UI.

$graph = $workflow->toGraph();

Signal transitions are global in the current model, so they use from = '*' in the graph.

Integration Example

In a real project:

final class Agent
{
    public function __construct(
        private WorkflowRunner $workflowRunner,
    ) {}

    public function run(string $agentId, string $input): LLMResponse
    {
        $context = new AgentContext(agentId: $agentId, input: $input);
        $result = $this->workflowRunner->run($context, 'default', runId: $context->agentId);

        return $result->getFinalResponse()
            ?? throw new RuntimeException('Agent completed but returned no response.');
    }
}

Interface Definitions

Implement:

  • ContextInterface: your mutable data object, immutable in use.
  • StateHandlerInterface: logic per step/state.

TODO

  • Make StateHandlerRegistry container aware (allow passing a PSR-11 compliant DI container)
  • Decide whether observer errors should fail workflow execution or be swallowed
  • Consider how to expose a start node in graph exports when no static transition includes it
  • Clarify UI handling for global signal edges (from = '*')
  • Decide whether to validate runId inputs (empty/uniqueness) in core or leave to telemetry

License

MIT License

About

PHP workflow runner with dynamic transitions.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages