Module: SolidAgent::HasContext
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/solid_agent/has_context.rb
Instance Method Summary collapse
- #add_assistant_message(content, **attributes) ⇒ Object
- #add_message(role:, content:, **attributes) ⇒ Object
- #add_user_message(content, **attributes) ⇒ Object
-
#agent_checksum ⇒ String
Generate checksum for the agent class configuration.
-
#context ⇒ Object
Backward compatibility methods === These delegate to the primary context (first or :context).
- #context=(value) ⇒ Object
-
#context_checksum ⇒ String?
Generate checksum for current context state.
- #context_class ⇒ Object
- #context_messages ⇒ Object
-
#context_result ⇒ Object
Returns the last assistant message content from the primary context Useful for extracting the final result to pass back to a caller.
-
#context_summary ⇒ Object
Returns a summary hash of the primary context Useful for passing structured results back to a parent context.
- #create_context(contextable: nil, **options) ⇒ Object
-
#current_provenance ⇒ Hash
Generate provenance record for current agent state.
- #generation_class ⇒ Object
-
#last_generation ⇒ Object
Returns the last generation record from the primary context.
- #load_context(contextable: nil, context_id: nil, **options) ⇒ Object
-
#manifest_fingerprint ⇒ String?
Get manifest fingerprint if agent was built from manifest.
- #message_class ⇒ Object
-
#prompt_checksum ⇒ String
Generate checksum for current prompt configuration.
-
#prompt_tool_roster ⇒ Array<Hash>
The tool schemas this generation actually offered the provider, as a compact roster.
- #with_context_messages ⇒ Object
Instance Method Details
#add_assistant_message(content, **attributes) ⇒ Object
411 412 413 |
# File 'lib/solid_agent/has_context.rb', line 411 def (content, **attributes) (role: "assistant", content: content, **attributes) end |
#add_message(role:, content:, **attributes) ⇒ Object
402 403 404 405 |
# File 'lib/solid_agent/has_context.rb', line 402 def (role:, content:, **attributes) primary_context_name = self.class._context_configs.keys.first || :context send("add_#{primary_context_name}_message", role: role, content: content, **attributes) end |
#add_user_message(content, **attributes) ⇒ Object
407 408 409 |
# File 'lib/solid_agent/has_context.rb', line 407 def (content, **attributes) (role: "user", content: content, **attributes) end |
#agent_checksum ⇒ String
Generate checksum for the agent class configuration
Class-level options are read defensively so provenance never raises inside the (rescued) persistence path and silently drops generations.
519 520 521 522 523 524 525 526 |
# File 'lib/solid_agent/has_context.rb', line 519 def agent_checksum data = { class: self.class.name, prompt_options: (:prompt_options), embed_options: (:embed_options) }.compact Digest::MD5.hexdigest(data.to_json) end |
#context ⇒ Object
Backward compatibility methods ===
These delegate to the primary context (first or :context)
357 358 359 360 |
# File 'lib/solid_agent/has_context.rb', line 357 def context primary_context_name = self.class._context_configs.keys.first || :context send(primary_context_name) end |
#context=(value) ⇒ Object
362 363 364 365 |
# File 'lib/solid_agent/has_context.rb', line 362 def context=(value) primary_context_name = self.class._context_configs.keys.first || :context send("#{primary_context_name}=", value) end |
#context_checksum ⇒ String?
Generate checksum for current context state
486 487 488 489 490 491 492 493 |
# File 'lib/solid_agent/has_context.rb', line 486 def context_checksum return nil unless context Digest::MD5.hexdigest({ context_id: context.id, message_count: context..size, last_message_id: context..last&.id }.to_json) end |
#context_class ⇒ Object
367 368 369 370 |
# File 'lib/solid_agent/has_context.rb', line 367 def context_class primary_context_name = self.class._context_configs.keys.first || :context send("#{primary_context_name}_class") end |
#context_messages ⇒ Object
392 393 394 395 |
# File 'lib/solid_agent/has_context.rb', line 392 def primary_context_name = self.class._context_configs.keys.first || :context send("#{primary_context_name}_messages") end |
#context_result ⇒ Object
Returns the last assistant message content from the primary context Useful for extracting the final result to pass back to a caller
417 418 419 420 |
# File 'lib/solid_agent/has_context.rb', line 417 def context_result primary_context_name = self.class._context_configs.keys.first || :context send("#{primary_context_name}_result") end |
#context_summary ⇒ Object
Returns a summary hash of the primary context Useful for passing structured results back to a parent context
430 431 432 433 |
# File 'lib/solid_agent/has_context.rb', line 430 def context_summary primary_context_name = self.class._context_configs.keys.first || :context send("#{primary_context_name}_summary") end |
#create_context(contextable: nil, **options) ⇒ Object
387 388 389 390 |
# File 'lib/solid_agent/has_context.rb', line 387 def create_context(contextable: nil, **) primary_context_name = self.class._context_configs.keys.first || :context send("create_#{primary_context_name}", contextable: contextable, **) end |
#current_provenance ⇒ Hash
Generate provenance record for current agent state
498 499 500 501 502 503 504 505 506 507 508 509 510 511 |
# File 'lib/solid_agent/has_context.rb', line 498 def current_provenance { agent_class: self.class.name, agent_checksum: agent_checksum, prompt_checksum: prompt_checksum, context_checksum: context_checksum, context_id: context&.id, action_name: action_name, trace_id: [:trace_id], timestamp: Time.now.iso8601, manifest_fingerprint: manifest_fingerprint, tools: prompt_tool_roster.presence }.compact end |
#generation_class ⇒ Object
377 378 379 380 |
# File 'lib/solid_agent/has_context.rb', line 377 def generation_class primary_context_name = self.class._context_configs.keys.first || :context send("#{primary_context_name}_generation_class") end |
#last_generation ⇒ Object
Returns the last generation record from the primary context
423 424 425 426 |
# File 'lib/solid_agent/has_context.rb', line 423 def last_generation primary_context_name = self.class._context_configs.keys.first || :context send("#{primary_context_name}_last_generation") end |
#load_context(contextable: nil, context_id: nil, **options) ⇒ Object
382 383 384 385 |
# File 'lib/solid_agent/has_context.rb', line 382 def load_context(contextable: nil, context_id: nil, **) primary_context_name = self.class._context_configs.keys.first || :context send("load_#{primary_context_name}", contextable: contextable, context_id: context_id, **) end |
#manifest_fingerprint ⇒ String?
Get manifest fingerprint if agent was built from manifest
531 532 533 534 |
# File 'lib/solid_agent/has_context.rb', line 531 def manifest_fingerprint return nil unless self.class.respond_to?(:_manifest) && self.class._manifest self.class._manifest.fingerprint end |
#message_class ⇒ Object
372 373 374 375 |
# File 'lib/solid_agent/has_context.rb', line 372 def primary_context_name = self.class._context_configs.keys.first || :context send("#{primary_context_name}_message_class") end |
#prompt_checksum ⇒ String
Generate checksum for current prompt configuration
442 443 444 445 446 447 448 449 450 |
# File 'lib/solid_agent/has_context.rb', line 442 def prompt_checksum data = { instructions: [:instructions], model: [:model], temperature: [:temperature], tools: prompt_tool_roster.map { |tool| tool[:name] }.presence }.compact Digest::MD5.hexdigest(data.to_json) end |
#prompt_tool_roster ⇒ Array<Hash>
The tool schemas this generation actually offered the provider, as a compact roster.
The full schemas are too heavy to persist on every generation, and the checksum above only proves the roster changed — it can't say what the agent could do. Recording names, descriptions and parameter keys makes the tool surface auditable straight from the generation records, without requiring telemetry to be switched on.
Shape matches ActiveAgent's prompt.input.tools span attribute so a
dashboard parses one format from both sources.
465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 |
# File 'lib/solid_agent/has_context.rb', line 465 def prompt_tool_roster Array([:tools]).filter_map do |tool| next unless tool.respond_to?(:[]) name = tool[:name] || tool["name"] next if name.blank? parameters = tool[:parameters] || tool["parameters"] || tool[:input_schema] || tool["input_schema"] properties = parameters.is_a?(Hash) ? (parameters[:properties] || parameters["properties"]) : nil { name: name.to_s, description: (tool[:description] || tool["description"]).to_s.presence, parameters: properties.is_a?(Hash) ? properties.keys.map(&:to_s) : [] }.compact end end |
#with_context_messages ⇒ Object
397 398 399 400 |
# File 'lib/solid_agent/has_context.rb', line 397 def primary_context_name = self.class._context_configs.keys.first || :context send("with_#{primary_context_name}_messages") end |