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.



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

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.



6
7
8
# File 'lib/smith/workflow/transition.rb', line 6

def agent_name
  @agent_name
end

#agent_optsObject (readonly)

Returns the value of attribute agent_opts.



6
7
8
# File 'lib/smith/workflow/transition.rb', line 6

def agent_opts
  @agent_opts
end

#deterministic_blockObject (readonly)

Returns the value of attribute deterministic_block.



6
7
8
# File 'lib/smith/workflow/transition.rb', line 6

def deterministic_block
  @deterministic_block
end

#deterministic_kindObject (readonly)

Returns the value of attribute deterministic_kind.



6
7
8
# File 'lib/smith/workflow/transition.rb', line 6

def deterministic_kind
  @deterministic_kind
end

#deterministic_routesObject (readonly)

Returns the value of attribute deterministic_routes.



6
7
8
# File 'lib/smith/workflow/transition.rb', line 6

def deterministic_routes
  @deterministic_routes
end

#failure_transitionObject (readonly)

Returns the value of attribute failure_transition.



6
7
8
# File 'lib/smith/workflow/transition.rb', line 6

def failure_transition
  @failure_transition
end

#fanout_configObject (readonly)

Returns the value of attribute fanout_config.



6
7
8
# File 'lib/smith/workflow/transition.rb', line 6

def fanout_config
  @fanout_config
end

#fromObject (readonly)

Returns the value of attribute from.



6
7
8
# File 'lib/smith/workflow/transition.rb', line 6

def from
  @from
end

#nameObject (readonly)

Returns the value of attribute name.



6
7
8
# File 'lib/smith/workflow/transition.rb', line 6

def name
  @name
end

#optimization_configObject (readonly)

Returns the value of attribute optimization_config.



6
7
8
# File 'lib/smith/workflow/transition.rb', line 6

def optimization_config
  @optimization_config
end

#orchestrator_configObject (readonly)

Returns the value of attribute orchestrator_config.



6
7
8
# File 'lib/smith/workflow/transition.rb', line 6

def orchestrator_config
  @orchestrator_config
end

#retry_configObject (readonly)

Returns the value of attribute retry_config.



6
7
8
# File 'lib/smith/workflow/transition.rb', line 6

def retry_config
  @retry_config
end

#router_configObject (readonly)

Returns the value of attribute router_config.



6
7
8
# File 'lib/smith/workflow/transition.rb', line 6

def router_config
  @router_config
end

#success_transitionObject (readonly)

Returns the value of attribute success_transition.



6
7
8
# File 'lib/smith/workflow/transition.rb', line 6

def success_transition
  @success_transition
end

#toObject (readonly)

Returns the value of attribute to.



6
7
8
# File 'lib/smith/workflow/transition.rb', line 6

def to
  @to
end

#workflow_classObject (readonly)

Returns the value of attribute workflow_class.



6
7
8
# File 'lib/smith/workflow/transition.rb', line 6

def workflow_class
  @workflow_class
end

Instance Method Details

#deterministic?Boolean

Returns:

  • (Boolean)


151
152
153
# File 'lib/smith/workflow/transition.rb', line 151

def deterministic?
  !@deterministic_block.nil?
end

#execute(agent_name, **opts) ⇒ Object



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

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



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

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)


159
160
161
# File 'lib/smith/workflow/transition.rb', line 159

def fanout?
  !@fanout_config.nil?
end

#nested?Boolean

Returns:

  • (Boolean)


178
179
180
# File 'lib/smith/workflow/transition.rb', line 178

def nested?
  !@workflow_class.nil?
end

#on_failure(transition_name) ⇒ Object



37
38
39
# File 'lib/smith/workflow/transition.rb', line 37

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

#on_success(transition_name) ⇒ Object



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

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



69
70
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
# File 'lib/smith/workflow/transition.rb', line 69

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)


174
175
176
# File 'lib/smith/workflow/transition.rb', line 174

def optimized?
  !@optimization_config.nil?
end

#orchestrate(**opts) ⇒ Object



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

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)


155
156
157
# File 'lib/smith/workflow/transition.rb', line 155

def orchestrated?
  !@orchestrator_config.nil?
end

#parallel?Boolean

Returns:

  • (Boolean)


186
187
188
# File 'lib/smith/workflow/transition.rb', line 186

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

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



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

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



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

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)


182
183
184
# File 'lib/smith/workflow/transition.rb', line 182

def routed?
  !@router_config.nil?
end

#workflow(klass) ⇒ Object

Raises:



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

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