Class: TurnKit::Conversation

Inherits:
Object
  • Object
show all
Defined in:
lib/turnkit/conversation.rb

Constant Summary collapse

THINKING_UNSET =
Object.new.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(agent:, record:, store:, model:, subject: nil, metadata: {}) ⇒ Conversation

Returns a new instance of Conversation.



9
10
11
12
13
14
15
16
17
# File 'lib/turnkit/conversation.rb', line 9

def initialize(agent:, record:, store:, model:, subject: nil, metadata: {})
  @agent = agent
  @record = record.transform_keys(&:to_s)
  @id = @record.fetch("id")
  @store = store
  @model = model
  @subject = subject
  @metadata =  || {}
end

Instance Attribute Details

#agentObject (readonly)

Returns the value of attribute agent.



7
8
9
# File 'lib/turnkit/conversation.rb', line 7

def agent
  @agent
end

#idObject (readonly)

Returns the value of attribute id.



7
8
9
# File 'lib/turnkit/conversation.rb', line 7

def id
  @id
end

#metadataObject (readonly)

Returns the value of attribute metadata.



7
8
9
# File 'lib/turnkit/conversation.rb', line 7

def 
  @metadata
end

#modelObject (readonly)

Returns the value of attribute model.



7
8
9
# File 'lib/turnkit/conversation.rb', line 7

def model
  @model
end

#storeObject (readonly)

Returns the value of attribute store.



7
8
9
# File 'lib/turnkit/conversation.rb', line 7

def store
  @store
end

#subjectObject (readonly)

Returns the value of attribute subject.



7
8
9
# File 'lib/turnkit/conversation.rb', line 7

def subject
  @subject
end

Instance Method Details

#append_message(role:, kind:, text: nil, content: nil, turn_id: nil, tool_execution_id: nil, metadata: {}) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/turnkit/conversation.rb', line 68

def append_message(role:, kind:, text: nil, content: nil, turn_id: nil, tool_execution_id: nil, metadata: {})
  attrs = store.append_message(
    "conversation_id" => id,
    "turn_id" => turn_id,
    "role" => role,
    "kind" => kind,
    "text" => text,
    "content" => content,
    "tool_execution_id" => tool_execution_id,
    "metadata" => 
  )
  Message.new(attrs)
end

#ask(text, async: false, **options) ⇒ Object



23
24
25
26
27
# File 'lib/turnkit/conversation.rb', line 23

def ask(text, async: false, **options)
  trigger = say(text)
  turn = build_turn(trigger_message_id: trigger.id, **options)
  async ? turn : turn.run!
end

#build_turn(trigger_message_id: nil, model: nil, budget: nil, parent_turn: nil, parent_tool_execution: nil, depth: 0, agent: self.agent, thinking: THINKING_UNSET) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/turnkit/conversation.rb', line 33

def build_turn(trigger_message_id: nil, model: nil, budget: nil, parent_turn: nil, parent_tool_execution: nil, depth: 0, agent: self.agent, thinking: THINKING_UNSET)
  snapshot = latest_message_sequence
  effective_thinking = thinking.equal?(THINKING_UNSET) ? agent.effective_thinking : Agent.normalize_thinking(thinking)
  options = { "trigger_message_id" => trigger_message_id }.compact
  options["thinking"] = effective_thinking
  record = store.create_turn(
    "conversation_id" => id,
    "agent_name" => agent.name,
    "parent_turn_id" => parent_turn&.id,
    "parent_tool_execution_id" => parent_tool_execution&.id,
    "root_turn_id" => parent_turn&.root_turn_id,
    "context_message_sequence" => snapshot,
    "status" => "pending",
    "model" => model || self.model || agent.effective_model,
    "options" => options
  )
  Turn.new(agent: agent, conversation: self, record: record, store: store, budget: budget, depth: depth)
end

#costObject



60
61
62
# File 'lib/turnkit/conversation.rb', line 60

def cost
  Cost.from_records(store.list_turns(conversation_id: id))
end

#latest_message_sequenceObject



82
83
84
85
86
87
88
# File 'lib/turnkit/conversation.rb', line 82

def latest_message_sequence
  if store.respond_to?(:latest_message_sequence)
    store.latest_message_sequence(id)
  else
    messages.map(&:sequence).max.to_i
  end
end

#messagesObject



52
53
54
# File 'lib/turnkit/conversation.rb', line 52

def messages
  store.list_messages(id).map { |attrs| Message.new(attrs) }
end

#messages_for_turn(turn) ⇒ Object



64
65
66
# File 'lib/turnkit/conversation.rb', line 64

def messages_for_turn(turn)
  store.list_messages(id, through_sequence: turn.context_message_sequence, turn_id: turn.id).map { |attrs| Message.new(attrs) }
end

#run!(trigger_message_id: nil, model: nil, budget: nil, parent_turn: nil, parent_tool_execution: nil, depth: 0, agent: self.agent, thinking: THINKING_UNSET) ⇒ Object



29
30
31
# File 'lib/turnkit/conversation.rb', line 29

def run!(trigger_message_id: nil, model: nil, budget: nil, parent_turn: nil, parent_tool_execution: nil, depth: 0, agent: self.agent, thinking: THINKING_UNSET)
  build_turn(trigger_message_id: trigger_message_id, model: model, budget: budget, parent_turn: parent_turn, parent_tool_execution: parent_tool_execution, depth: depth, agent: agent, thinking: thinking).run!
end

#say(text, metadata: {}) ⇒ Object



19
20
21
# File 'lib/turnkit/conversation.rb', line 19

def say(text, metadata: {})
  append_message(role: "user", kind: "text", text: text, metadata: )
end

#usageObject



56
57
58
# File 'lib/turnkit/conversation.rb', line 56

def usage
  Usage.from_records(store.list_turns(conversation_id: id))
end