Class: Clacky::GoalState

Inherits:
Object
  • Object
show all
Defined in:
lib/clacky/agent/goal_state.rb

Overview

Serializable per-session goal state for the /goal Ralph-style loop.

A "goal" is a standing objective the agent works toward across multiple turns without the user re-prompting each time. After every turn a judge decides done/continue; while continuing (and under the turn budget) the loop feeds itself a continuation prompt and runs another turn.

Constant Summary collapse

DEFAULT_MAX_TURNS =
20
STATUSES =

active — loop is running, judge fires after each turn paused — stopped but recoverable via /goal resume (budget exhausted, user pause, or repeated judge failures) done — judge decided the goal is satisfied

%w[active paused done].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(goal:, max_turns: DEFAULT_MAX_TURNS, status: "active", turns_used: 0, last_verdict: nil, last_reason: nil, paused_reason: nil, created_at: nil, last_turn_at: nil) ⇒ GoalState

Returns a new instance of GoalState.



23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/clacky/agent/goal_state.rb', line 23

def initialize(goal:, max_turns: DEFAULT_MAX_TURNS, status: "active",
               turns_used: 0, last_verdict: nil, last_reason: nil,
               paused_reason: nil, created_at: nil, last_turn_at: nil)
  @goal = goal.to_s
  @status = STATUSES.include?(status.to_s) ? status.to_s : "active"
  @turns_used = turns_used.to_i
  @max_turns = max_turns.to_i.positive? ? max_turns.to_i : DEFAULT_MAX_TURNS
  @last_verdict = last_verdict
  @last_reason = last_reason
  @paused_reason = paused_reason
  @created_at = created_at || Time.now.to_f
  @last_turn_at = last_turn_at
end

Instance Attribute Details

#created_atObject

Returns the value of attribute created_at.



19
20
21
# File 'lib/clacky/agent/goal_state.rb', line 19

def created_at
  @created_at
end

#goalObject

Returns the value of attribute goal.



19
20
21
# File 'lib/clacky/agent/goal_state.rb', line 19

def goal
  @goal
end

#last_reasonObject

Returns the value of attribute last_reason.



19
20
21
# File 'lib/clacky/agent/goal_state.rb', line 19

def last_reason
  @last_reason
end

#last_turn_atObject

Returns the value of attribute last_turn_at.



19
20
21
# File 'lib/clacky/agent/goal_state.rb', line 19

def last_turn_at
  @last_turn_at
end

#last_verdictObject

Returns the value of attribute last_verdict.



19
20
21
# File 'lib/clacky/agent/goal_state.rb', line 19

def last_verdict
  @last_verdict
end

#max_turnsObject

Returns the value of attribute max_turns.



19
20
21
# File 'lib/clacky/agent/goal_state.rb', line 19

def max_turns
  @max_turns
end

#paused_reasonObject

Returns the value of attribute paused_reason.



19
20
21
# File 'lib/clacky/agent/goal_state.rb', line 19

def paused_reason
  @paused_reason
end

#statusObject

Returns the value of attribute status.



19
20
21
# File 'lib/clacky/agent/goal_state.rb', line 19

def status
  @status
end

#turns_usedObject

Returns the value of attribute turns_used.



19
20
21
# File 'lib/clacky/agent/goal_state.rb', line 19

def turns_used
  @turns_used
end

Class Method Details

.from_h(data) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/clacky/agent/goal_state.rb', line 67

def self.from_h(data)
  return nil unless data.is_a?(Hash)

  # Tolerate both symbol and string keys (session.json round-trips as strings).
  get = ->(key) { data[key] || data[key.to_s] }
  goal = get.call(:goal).to_s
  return nil if goal.strip.empty?

  new(
    goal: goal,
    status: get.call(:status) || "active",
    turns_used: get.call(:turns_used),
    max_turns: get.call(:max_turns),
    last_verdict: get.call(:last_verdict),
    last_reason: get.call(:last_reason),
    paused_reason: get.call(:paused_reason),
    created_at: get.call(:created_at),
    last_turn_at: get.call(:last_turn_at)
  )
end

Instance Method Details

#active?Boolean

Returns:

  • (Boolean)


37
38
39
# File 'lib/clacky/agent/goal_state.rb', line 37

def active?
  @status == "active"
end

#budget_exhausted?Boolean

Returns:

  • (Boolean)


49
50
51
# File 'lib/clacky/agent/goal_state.rb', line 49

def budget_exhausted?
  @turns_used >= @max_turns
end

#done?Boolean

Returns:

  • (Boolean)


45
46
47
# File 'lib/clacky/agent/goal_state.rb', line 45

def done?
  @status == "done"
end

#paused?Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/clacky/agent/goal_state.rb', line 41

def paused?
  @status == "paused"
end

#to_hObject



53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/clacky/agent/goal_state.rb', line 53

def to_h
  {
    goal: @goal,
    status: @status,
    turns_used: @turns_used,
    max_turns: @max_turns,
    last_verdict: @last_verdict,
    last_reason: @last_reason,
    paused_reason: @paused_reason,
    created_at: @created_at,
    last_turn_at: @last_turn_at
  }
end