Class: ActionAgent::AgentContext

Inherits:
ApplicationRecord show all
Defined in:
app/models/action_agent/agent_context.rb

Overview

Conversation context persisted by SolidAgent::HasContext — one row per (contextable, agent, action). On this platform the contextable is the dashboard Agent record, so a context is that agent's interaction stream.

Based on the solid_agent install generator's AgentContext, extended with record_generation_with_provenance! (the concern's duck-typed extension point) so each generation carries the telemetry trace_id and provenance.

Instance Method Summary collapse

Methods inherited from ApplicationRecord

for_owner, owner_association

Instance Method Details

#add_assistant_message(content, **attributes) ⇒ Object



72
73
74
# File 'app/models/action_agent/agent_context.rb', line 72

def add_assistant_message(content, **attributes)
  messages.create!(role: "assistant", content: content, **attributes)
end

#add_system_message(content) ⇒ Object



76
77
78
# File 'app/models/action_agent/agent_context.rb', line 76

def add_system_message(content)
  messages.create!(role: "system", content: content)
end

#add_tool_message(tool_call_id:, tool_name:, result:, arguments: nil, duration_ms: nil) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
# File 'app/models/action_agent/agent_context.rb', line 80

def add_tool_message(tool_call_id:, tool_name:, result:, arguments: nil, duration_ms: nil)
  messages.create!(
    role: "tool",
    tool_call_id: tool_call_id,
    tool_name: tool_name,
    tool_result: result,
    tool_arguments: arguments.presence || {},
    metadata: duration_ms ? { "duration_ms" => duration_ms } : {},
    content: result.is_a?(String) ? result : result.to_json
  )
end

#add_user_message(content, **attributes) ⇒ Object



68
69
70
# File 'app/models/action_agent/agent_context.rb', line 68

def add_user_message(content, **attributes)
  messages.create!(role: "user", content: content, **attributes)
end

#input_paramsObject



96
97
98
# File 'app/models/action_agent/agent_context.rb', line 96

def input_params
  options&.dig("input_params") || {}
end

#record_generation!(response, extra_attributes = {}) ⇒ Object

Records a generation response and updates token counts.

Defensive against response objects that don't expose provider/duration (activeagent 1.0.3 responses don't) — solid_agent's stock template would raise (and silently drop the generation) on those.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'app/models/action_agent/agent_context.rb', line 30

def record_generation!(response, extra_attributes = {})
  usage = response.respond_to?(:usage) ? response.usage : nil

  generation = generations.create!({
    content: response.message&.content,
    model: value_if_responds(response, :model),
    provider: value_if_responds(response, :provider),
    finish_reason: value_if_responds(response, :finish_reason),
    input_tokens: usage&.input_tokens || 0,
    output_tokens: usage&.output_tokens || 0,
    cached_tokens: value_if_responds(usage, :cached_tokens) || 0,
    reasoning_tokens: value_if_responds(usage, :reasoning_tokens) || 0,
    tool_calls: extract_tool_calls(response),
    raw_response: value_if_responds(response, :raw_response),
    duration_seconds: extract_duration_seconds(response, usage)
  }.merge(extra_attributes))

  increment!(:total_input_tokens, generation.input_tokens)
  increment!(:total_output_tokens, generation.output_tokens)

  add_assistant_message(response.message&.content, metadata: { "tool_calls" => generation.tool_calls })

  generation
end

#record_generation_with_provenance!(response, provenance) ⇒ Object

Called by SolidAgent::HasContext when defined: persists the generation together with its provenance hash and the telemetry trace_id, so conversation records join to active_agent_telemetry_traces.



58
59
60
61
62
63
64
65
66
# File 'app/models/action_agent/agent_context.rb', line 58

def record_generation_with_provenance!(response, provenance)
  provenance = (provenance || {}).deep_stringify_keys

  record_generation!(
    response,
    trace_id: provenance["trace_id"],
    provenance: provenance
  )
end

#total_tokensObject



92
93
94
# File 'app/models/action_agent/agent_context.rb', line 92

def total_tokens
  total_input_tokens + total_output_tokens
end