Class: Smith::Workflow::Transition

Inherits:
Object
  • Object
show all
Defined in:
lib/smith/workflow/transition.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, from:, to:) ⇒ Transition

Returns a new instance of Transition.



13
14
15
16
17
18
# File 'lib/smith/workflow/transition.rb', line 13

def initialize(name, from:, to:, &)
  @name = own_identifier(name)
  @from = own_identifier(from, allow_nil: true)
  @to = own_identifier(to)
  instance_eval(&) if block_given?
end

Instance Attribute Details

#agent_nameObject (readonly)

Returns the value of attribute agent_name.



8
9
10
# File 'lib/smith/workflow/transition.rb', line 8

def agent_name
  @agent_name
end

#agent_optsObject (readonly)

Returns the value of attribute agent_opts.



8
9
10
# File 'lib/smith/workflow/transition.rb', line 8

def agent_opts
  @agent_opts
end

#deterministic_blockObject (readonly)

Returns the value of attribute deterministic_block.



8
9
10
# File 'lib/smith/workflow/transition.rb', line 8

def deterministic_block
  @deterministic_block
end

#deterministic_kindObject (readonly)

Returns the value of attribute deterministic_kind.



8
9
10
# File 'lib/smith/workflow/transition.rb', line 8

def deterministic_kind
  @deterministic_kind
end

#deterministic_routesObject (readonly)

Returns the value of attribute deterministic_routes.



8
9
10
# File 'lib/smith/workflow/transition.rb', line 8

def deterministic_routes
  @deterministic_routes
end

#failure_transitionObject (readonly)

Returns the value of attribute failure_transition.



8
9
10
# File 'lib/smith/workflow/transition.rb', line 8

def failure_transition
  @failure_transition
end

#fanout_configObject (readonly)

Returns the value of attribute fanout_config.



8
9
10
# File 'lib/smith/workflow/transition.rb', line 8

def fanout_config
  @fanout_config
end

#fromObject (readonly)

Returns the value of attribute from.



8
9
10
# File 'lib/smith/workflow/transition.rb', line 8

def from
  @from
end

#nameObject (readonly)

Returns the value of attribute name.



8
9
10
# File 'lib/smith/workflow/transition.rb', line 8

def name
  @name
end

#optimization_configObject (readonly)

Returns the value of attribute optimization_config.



8
9
10
# File 'lib/smith/workflow/transition.rb', line 8

def optimization_config
  @optimization_config
end

#orchestrator_configObject (readonly)

Returns the value of attribute orchestrator_config.



8
9
10
# File 'lib/smith/workflow/transition.rb', line 8

def orchestrator_config
  @orchestrator_config
end

#retry_configObject (readonly)

Returns the value of attribute retry_config.



8
9
10
# File 'lib/smith/workflow/transition.rb', line 8

def retry_config
  @retry_config
end

#router_configObject (readonly)

Returns the value of attribute router_config.



8
9
10
# File 'lib/smith/workflow/transition.rb', line 8

def router_config
  @router_config
end

#success_transitionObject (readonly)

Returns the value of attribute success_transition.



8
9
10
# File 'lib/smith/workflow/transition.rb', line 8

def success_transition
  @success_transition
end

#toObject (readonly)

Returns the value of attribute to.



8
9
10
# File 'lib/smith/workflow/transition.rb', line 8

def to
  @to
end

#workflow_classObject (readonly)

Returns the value of attribute workflow_class.



8
9
10
# File 'lib/smith/workflow/transition.rb', line 8

def workflow_class
  @workflow_class
end

Instance Method Details

#deterministic?Boolean

Returns:

  • (Boolean)


153
154
155
# File 'lib/smith/workflow/transition.rb', line 153

def deterministic?
  !@deterministic_block.nil?
end

#execute(agent_name, **opts) ⇒ Object



20
21
22
23
24
25
26
27
28
29
# File 'lib/smith/workflow/transition.rb', line 20

def execute(agent_name, **opts)
  validate_execution_primitive_conflict!("execute")

  normalized_agent = normalize_agent_reference!(agent_name, "agent")
  validate_parallel_options!(opts)

  @agent_name = normalized_agent
  @agent_opts = opts.freeze
  commit_execution_primitive!("execute")
end

#fan_out(branches:) ⇒ Object Also known as: fanout



113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/smith/workflow/transition.rb', line 113

def fan_out(branches:)
  validate_execution_primitive_conflict!("fan_out")

  normalized = normalize_fanout_branches!(branches)
  @fanout_branch_lookup = normalized.to_h do |key, agent|
    [key.to_s.freeze, [key, agent].freeze]
  end.freeze
  config = { branches: normalized }.freeze

  @fanout_config = config
  commit_execution_primitive!("fan_out")
end

#fanout?Boolean

Returns:

  • (Boolean)


161
162
163
# File 'lib/smith/workflow/transition.rb', line 161

def fanout?
  !@fanout_config.nil?
end

#nested?Boolean

Returns:

  • (Boolean)


180
181
182
# File 'lib/smith/workflow/transition.rb', line 180

def nested?
  !@workflow_class.nil?
end

#on_failure(transition_name) ⇒ Object



39
40
41
# File 'lib/smith/workflow/transition.rb', line 39

def on_failure(transition_name)
  @failure_transition = own_identifier(transition_name)
end

#on_success(transition_name) ⇒ Object



31
32
33
34
35
36
37
# File 'lib/smith/workflow/transition.rb', line 31

def on_success(transition_name)
  if routed?
    raise WorkflowError, "routed transitions cannot declare on_success; router routes select the next transition"
  end

  @success_transition = own_identifier(transition_name)
end

#optimize(generator:, evaluator:, max_rounds:, evaluator_schema:, improvement_threshold: nil, evaluator_context: nil, before_eval: nil, on_exhaustion: :raise, on_converged: :raise, on_threshold: :raise) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/smith/workflow/transition.rb', line 71

def optimize(generator:, evaluator:, max_rounds:, evaluator_schema:,
             improvement_threshold: nil,
             evaluator_context: nil,
             before_eval: nil,
             on_exhaustion: :raise,
             on_converged: :raise,
             on_threshold: :raise)
  validate_execution_primitive_conflict!("optimize")
  validate_optimize_controls!(generator, evaluator, max_rounds, evaluator_schema)
  validate_optimize_exit_modes!(on_exhaustion: on_exhaustion, on_converged: on_converged,
                                on_threshold: on_threshold)
  validate_optimize_evaluator_context!(evaluator_context)
  validate_optimize_before_eval!(before_eval)

  config = {
    generator: normalize_agent_reference!(generator, "optimizer generator"),
    evaluator: normalize_agent_reference!(evaluator, "optimizer evaluator"),
    max_rounds: max_rounds,
    evaluator_schema: evaluator_schema, improvement_threshold: improvement_threshold,
    evaluator_context: evaluator_context,
    before_eval: before_eval,
    on_exhaustion: on_exhaustion,
    on_converged: on_converged,
    on_threshold: on_threshold
  }.freeze

  @optimization_config = config
  commit_execution_primitive!("optimize")
end

#optimized?Boolean

Returns:

  • (Boolean)


176
177
178
# File 'lib/smith/workflow/transition.rb', line 176

def optimized?
  !@optimization_config.nil?
end

#orchestrate(**opts) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
# File 'lib/smith/workflow/transition.rb', line 101

def orchestrate(**opts)
  validate_execution_primitive_conflict!("orchestrate")
  validate_orchestrate_controls!(opts)
  config = opts.merge(
    orchestrator: normalize_agent_reference!(opts.fetch(:orchestrator), "orchestrator"),
    worker: normalize_agent_reference!(opts.fetch(:worker), "orchestrator worker")
  ).freeze

  @orchestrator_config = config
  commit_execution_primitive!("orchestrate")
end

#orchestrated?Boolean

Returns:

  • (Boolean)


157
158
159
# File 'lib/smith/workflow/transition.rb', line 157

def orchestrated?
  !@orchestrator_config.nil?
end

#parallel?Boolean

Returns:

  • (Boolean)


188
189
190
# File 'lib/smith/workflow/transition.rb', line 188

def parallel?
  agent_opts&.dig(:parallel) == true
end

#retry_on(*error_classes, attempts:, backoff: 0, max_delay: nil, jitter: 0) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
# File 'lib/smith/workflow/transition.rb', line 127

def retry_on(*error_classes, attempts:, backoff: 0, max_delay: nil, jitter: 0)
  policy = normalize_retry_policy!(error_classes, attempts:, backoff:, max_delay:, jitter:)

  @retry_config = {
    error_classes: error_classes.freeze,
    attempts: policy.attempts,
    backoff: policy.base_delay,
    max_delay: policy.max_delay,
    jitter: policy.jitter
  }.freeze
end

#route(agent_name, routes:, confidence_threshold:, fallback:) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/smith/workflow/transition.rb', line 43

def route(agent_name, routes:, confidence_threshold:, fallback:)
  validate_execution_primitive_conflict!("route")
  if @success_transition
    raise WorkflowError, "routed transitions cannot declare on_success; router routes select the next transition"
  end

  normalized_agent = normalize_agent_name!(agent_name, "router")
  normalized_config = {
    routes: normalize_router_routes!(routes),
    confidence_threshold: normalize_confidence_threshold!(confidence_threshold),
    fallback: normalize_transition_reference!(fallback, "router fallback")
  }.freeze

  @agent_name = normalized_agent
  @router_config = normalized_config
  commit_execution_primitive!("route")
end

#routed?Boolean

Returns:

  • (Boolean)


184
185
186
# File 'lib/smith/workflow/transition.rb', line 184

def routed?
  !@router_config.nil?
end

#workflow(klass) ⇒ Object

Raises:



61
62
63
64
65
66
67
68
69
# File 'lib/smith/workflow/transition.rb', line 61

def workflow(klass)
  raise WorkflowError, "workflow binding must be a Class" unless klass.is_a?(Class)
  raise WorkflowError, "workflow binding must be a Smith::Workflow subclass" unless klass < Workflow

  validate_execution_primitive_conflict!("workflow")

  @workflow_class = klass
  commit_execution_primitive!("workflow")
end