Class: Xeno::AgentDefinition
- Inherits:
-
Object
- Object
- Xeno::AgentDefinition
- Defined in:
- lib/xeno/agent_definition.rb
Overview
The resolved agent: everything discovered under the app's agent/
directory, plus diagnostics for anything misplaced or broken.
Discovery never raises — a broken agent directory yields a definition
whose diagnostics say exactly what is wrong (surfaced by rake xeno:info).
Defined Under Namespace
Classes: Diagnostic, InstructionContext, Schedule
Constant Summary collapse
- SLOT_DIRS =
%w[tools skills channels schedules hooks lib].freeze
- TOOL_SLUG =
/\A[a-z][a-z0-9_]*\z/
Instance Attribute Summary collapse
-
#channels ⇒ Object
readonly
Returns the value of attribute channels.
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#diagnostics ⇒ Object
readonly
Returns the value of attribute diagnostics.
-
#dynamic_instructions ⇒ Object
readonly
Returns the value of attribute dynamic_instructions.
-
#hooks ⇒ Object
readonly
Returns the value of attribute hooks.
-
#instructions ⇒ Object
readonly
Returns the value of attribute instructions.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#root ⇒ Object
readonly
Returns the value of attribute root.
-
#schedules ⇒ Object
readonly
Returns the value of attribute schedules.
-
#tools ⇒ Object
readonly
Returns the value of attribute tools.
Class Method Summary collapse
-
.load(root, name:, resolver: nil) ⇒ Object
Builds the definition for the app's agent root.
Instance Method Summary collapse
- #discover ⇒ Object
- #dynamic_instructions? ⇒ Boolean
- #errors? ⇒ Boolean
-
#initialize(root:, name:, resolver: nil) ⇒ AgentDefinition
constructor
A new instance of AgentDefinition.
-
#instructions_for(session: nil) ⇒ Object
The system prompt for one turn: static markdown first, the dynamic block's return appended (resolved fresh at every turn stage with the session context — the current_user use case).
- #tool_classes ⇒ Object
Constructor Details
#initialize(root:, name:, resolver: nil) ⇒ AgentDefinition
Returns a new instance of AgentDefinition.
29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/xeno/agent_definition.rb', line 29 def initialize(root:, name:, resolver: nil) @root = Pathname(root) @name = name @resolver = resolver || method(:resolve_tool_constant) @config = AgentConfig.new @instructions = nil @dynamic_instructions = nil @tools = {} @schedules = {} @channels = {} @hooks = {} @diagnostics = [] end |
Instance Attribute Details
#channels ⇒ Object (readonly)
Returns the value of attribute channels.
19 20 21 |
# File 'lib/xeno/agent_definition.rb', line 19 def channels @channels end |
#config ⇒ Object (readonly)
Returns the value of attribute config.
19 20 21 |
# File 'lib/xeno/agent_definition.rb', line 19 def config @config end |
#diagnostics ⇒ Object (readonly)
Returns the value of attribute diagnostics.
19 20 21 |
# File 'lib/xeno/agent_definition.rb', line 19 def diagnostics @diagnostics end |
#dynamic_instructions ⇒ Object (readonly)
Returns the value of attribute dynamic_instructions.
19 20 21 |
# File 'lib/xeno/agent_definition.rb', line 19 def dynamic_instructions @dynamic_instructions end |
#hooks ⇒ Object (readonly)
Returns the value of attribute hooks.
19 20 21 |
# File 'lib/xeno/agent_definition.rb', line 19 def hooks @hooks end |
#instructions ⇒ Object (readonly)
Returns the value of attribute instructions.
19 20 21 |
# File 'lib/xeno/agent_definition.rb', line 19 def instructions @instructions end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
19 20 21 |
# File 'lib/xeno/agent_definition.rb', line 19 def name @name end |
#root ⇒ Object (readonly)
Returns the value of attribute root.
19 20 21 |
# File 'lib/xeno/agent_definition.rb', line 19 def root @root end |
#schedules ⇒ Object (readonly)
Returns the value of attribute schedules.
19 20 21 |
# File 'lib/xeno/agent_definition.rb', line 19 def schedules @schedules end |
#tools ⇒ Object (readonly)
Returns the value of attribute tools.
19 20 21 |
# File 'lib/xeno/agent_definition.rb', line 19 def tools @tools end |
Class Method Details
.load(root, name:, resolver: nil) ⇒ Object
Builds the definition for the app's agent root. resolver maps a tool
file's camelized basename to its constant; the default asks Zeitwerk
(via const_get on Xeno::Tools) and is only overridden in tests.
25 26 27 |
# File 'lib/xeno/agent_definition.rb', line 25 def self.load(root, name:, resolver: nil) new(root: root, name: name, resolver: resolver).tap(&:discover) end |
Instance Method Details
#discover ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/xeno/agent_definition.rb', line 43 def discover unless root.directory? error "no agent/ directory at #{root} — run `rails g xeno:install`" return self end load_agent_config load_instructions discover_tools discover_schedules discover_channels discover_hooks report_misplaced_files self end |
#dynamic_instructions? ⇒ Boolean
63 |
# File 'lib/xeno/agent_definition.rb', line 63 def dynamic_instructions? = !@dynamic_instructions.nil? |
#errors? ⇒ Boolean
86 |
# File 'lib/xeno/agent_definition.rb', line 86 def errors? = diagnostics.any?(&:error?) |
#instructions_for(session: nil) ⇒ Object
The system prompt for one turn: static markdown first, the dynamic block's return appended (resolved fresh at every turn stage with the session context — the current_user use case). A raising block never bricks the session: the turn proceeds on the static instructions and the failure is logged.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/xeno/agent_definition.rb', line 70 def instructions_for(session: nil) parts = [ instructions ] if @dynamic_instructions context = InstructionContext.new(session: session, principal: session&.principal) begin parts << @dynamic_instructions.call(context).to_s rescue StandardError => e Rails.logger.warn( "xeno: agent/instructions.rb raised #{e.class}: #{e.} — using static instructions only" ) end end combined = parts.compact.map(&:strip).reject(&:empty?).join("\n\n") combined.empty? ? nil : combined end |
#tool_classes ⇒ Object
59 60 61 |
# File 'lib/xeno/agent_definition.rb', line 59 def tool_classes tools.values end |