Class: TurnKit::Agent
- Inherits:
-
Object
- Object
- TurnKit::Agent
- Defined in:
- lib/turnkit/agent.rb
Instance Attribute Summary collapse
-
#available_skills ⇒ Object
readonly
Returns the value of attribute available_skills.
-
#client ⇒ Object
readonly
Returns the value of attribute client.
-
#compaction ⇒ Object
readonly
Returns the value of attribute compaction.
-
#description ⇒ Object
readonly
Returns the value of attribute description.
-
#input_schema ⇒ Object
readonly
Returns the value of attribute input_schema.
-
#instructions ⇒ Object
readonly
Returns the value of attribute instructions.
-
#max_depth ⇒ Object
readonly
Returns the value of attribute max_depth.
-
#max_iterations ⇒ Object
readonly
Returns the value of attribute max_iterations.
-
#max_spend ⇒ Object
readonly
Returns the value of attribute max_spend.
-
#max_tool_executions ⇒ Object
readonly
Returns the value of attribute max_tool_executions.
-
#max_tool_executions_by_name ⇒ Object
readonly
Returns the value of attribute max_tool_executions_by_name.
-
#model ⇒ Object
readonly
Returns the value of attribute model.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#on_event ⇒ Object
readonly
Returns the value of attribute on_event.
-
#output_policy ⇒ Object
readonly
Returns the value of attribute output_policy.
-
#output_policy_mode ⇒ Object
readonly
Returns the value of attribute output_policy_mode.
-
#output_policy_model ⇒ Object
readonly
Returns the value of attribute output_policy_model.
-
#output_retries ⇒ Object
readonly
Returns the value of attribute output_retries.
-
#output_schema ⇒ Object
readonly
Returns the value of attribute output_schema.
-
#prompt_mode ⇒ Object
readonly
Returns the value of attribute prompt_mode.
-
#prompt_sections ⇒ Object
readonly
Returns the value of attribute prompt_sections.
-
#skills ⇒ Object
readonly
Returns the value of attribute skills.
-
#store ⇒ Object
readonly
Returns the value of attribute store.
-
#sub_agents ⇒ Object
readonly
Returns the value of attribute sub_agents.
-
#system_prompt ⇒ Object
readonly
Returns the value of attribute system_prompt.
-
#thinking ⇒ Object
readonly
Returns the value of attribute thinking.
-
#timeout ⇒ Object
readonly
Returns the value of attribute timeout.
-
#tools ⇒ Object
readonly
Returns the value of attribute tools.
Class Method Summary collapse
Instance Method Summary collapse
- #build_budget(root_started_at: Clock.now) ⇒ Object
- #conversation(model: nil, subject: nil, metadata: {}) ⇒ Object
- #cost ⇒ Object
- #effective_available_skills ⇒ Object
- #effective_client ⇒ Object
- #effective_model ⇒ Object
- #effective_on_event ⇒ Object
- #effective_output_policy ⇒ Object
- #effective_prompt_mode(turn: nil) ⇒ Object
- #effective_prompt_sections ⇒ Object
- #effective_store ⇒ Object
- #effective_thinking ⇒ Object
- #effective_tools ⇒ Object
-
#initialize(name:, description: "", model: nil, instructions: "", tools: [], skills: [], available_skills: [], sub_agents: [], system_prompt: nil, prompt_sections: nil, prompt_mode: nil, client: nil, store: nil, max_iterations: nil, timeout: nil, max_spend: nil, max_depth: nil, max_tool_executions: nil, max_tool_executions_by_name: nil, thinking: nil, compaction: nil, output_schema: nil, input_schema: nil, output_policy: nil, output_policy_mode: nil, output_policy_model: nil, output_policy_thinking: nil, output_retries: 0, on_event: nil) ⇒ Agent
constructor
A new instance of Agent.
- #instructions_with_skills ⇒ Object
- #run(prompt = nil, task: nil, input: nil, async: false, subject: nil, metadata: {}, parent_run: nil, root_turn_id: nil, prompt_mode: :task, **options) ⇒ Object
- #system_prompt_for(turn:, conversation:) ⇒ Object
- #usage ⇒ Object
Constructor Details
#initialize(name:, description: "", model: nil, instructions: "", tools: [], skills: [], available_skills: [], sub_agents: [], system_prompt: nil, prompt_sections: nil, prompt_mode: nil, client: nil, store: nil, max_iterations: nil, timeout: nil, max_spend: nil, max_depth: nil, max_tool_executions: nil, max_tool_executions_by_name: nil, thinking: nil, compaction: nil, output_schema: nil, input_schema: nil, output_policy: nil, output_policy_mode: nil, output_policy_model: nil, output_policy_thinking: nil, output_retries: 0, on_event: nil) ⇒ Agent
Returns a new instance of Agent.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/turnkit/agent.rb', line 10 def initialize(name:, description: "", model: nil, instructions: "", tools: [], skills: [], available_skills: [], sub_agents: [], system_prompt: nil, prompt_sections: nil, prompt_mode: nil, client: nil, store: nil, max_iterations: nil, timeout: nil, max_spend: nil, max_depth: nil, max_tool_executions: nil, max_tool_executions_by_name: nil, thinking: nil, compaction: nil, output_schema: nil, input_schema: nil, output_policy: nil, output_policy_mode: nil, output_policy_model: nil, output_policy_thinking: nil, output_retries: 0, on_event: nil) @name = name.to_s @description = description.to_s @model = model @instructions = instructions.to_s @tools = Array(tools) @skills = Array(skills) @available_skills = Array(available_skills) @sub_agents = Array(sub_agents) @system_prompt = system_prompt @prompt_sections = prompt_sections @prompt_mode = prompt_mode&.to_sym @client = client @store = store @max_iterations = max_iterations @timeout = timeout @max_spend = max_spend @max_depth = max_depth @max_tool_executions = max_tool_executions @max_tool_executions_by_name = max_tool_executions_by_name @thinking = self.class.normalize_thinking(thinking) @compaction = compaction @output_schema = output_schema @input_schema = input_schema @output_policy_model = output_policy_model @output_policy = normalize_output_policy(output_policy, model: output_policy_model, thinking: output_policy_thinking) @output_policy_mode = normalize_output_policy_mode(output_policy_mode) @output_retries = Integer(output_retries || 0) @on_event = on_event raise ArgumentError, "name is required" if @name.empty? validate_tools! end |
Instance Attribute Details
#available_skills ⇒ Object (readonly)
Returns the value of attribute available_skills.
5 6 7 |
# File 'lib/turnkit/agent.rb', line 5 def available_skills @available_skills end |
#client ⇒ Object (readonly)
Returns the value of attribute client.
6 7 8 |
# File 'lib/turnkit/agent.rb', line 6 def client @client end |
#compaction ⇒ Object (readonly)
Returns the value of attribute compaction.
7 8 9 |
# File 'lib/turnkit/agent.rb', line 7 def compaction @compaction end |
#description ⇒ Object (readonly)
Returns the value of attribute description.
5 6 7 |
# File 'lib/turnkit/agent.rb', line 5 def description @description end |
#input_schema ⇒ Object (readonly)
Returns the value of attribute input_schema.
7 8 9 |
# File 'lib/turnkit/agent.rb', line 7 def input_schema @input_schema end |
#instructions ⇒ Object (readonly)
Returns the value of attribute instructions.
5 6 7 |
# File 'lib/turnkit/agent.rb', line 5 def instructions @instructions end |
#max_depth ⇒ Object (readonly)
Returns the value of attribute max_depth.
6 7 8 |
# File 'lib/turnkit/agent.rb', line 6 def max_depth @max_depth end |
#max_iterations ⇒ Object (readonly)
Returns the value of attribute max_iterations.
6 7 8 |
# File 'lib/turnkit/agent.rb', line 6 def max_iterations @max_iterations end |
#max_spend ⇒ Object (readonly)
Returns the value of attribute max_spend.
6 7 8 |
# File 'lib/turnkit/agent.rb', line 6 def max_spend @max_spend end |
#max_tool_executions ⇒ Object (readonly)
Returns the value of attribute max_tool_executions.
6 7 8 |
# File 'lib/turnkit/agent.rb', line 6 def max_tool_executions @max_tool_executions end |
#max_tool_executions_by_name ⇒ Object (readonly)
Returns the value of attribute max_tool_executions_by_name.
6 7 8 |
# File 'lib/turnkit/agent.rb', line 6 def max_tool_executions_by_name @max_tool_executions_by_name end |
#model ⇒ Object (readonly)
Returns the value of attribute model.
5 6 7 |
# File 'lib/turnkit/agent.rb', line 5 def model @model end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
5 6 7 |
# File 'lib/turnkit/agent.rb', line 5 def name @name end |
#on_event ⇒ Object (readonly)
Returns the value of attribute on_event.
7 8 9 |
# File 'lib/turnkit/agent.rb', line 7 def on_event @on_event end |
#output_policy ⇒ Object (readonly)
Returns the value of attribute output_policy.
8 9 10 |
# File 'lib/turnkit/agent.rb', line 8 def output_policy @output_policy end |
#output_policy_mode ⇒ Object (readonly)
Returns the value of attribute output_policy_mode.
8 9 10 |
# File 'lib/turnkit/agent.rb', line 8 def output_policy_mode @output_policy_mode end |
#output_policy_model ⇒ Object (readonly)
Returns the value of attribute output_policy_model.
8 9 10 |
# File 'lib/turnkit/agent.rb', line 8 def output_policy_model @output_policy_model end |
#output_retries ⇒ Object (readonly)
Returns the value of attribute output_retries.
8 9 10 |
# File 'lib/turnkit/agent.rb', line 8 def output_retries @output_retries end |
#output_schema ⇒ Object (readonly)
Returns the value of attribute output_schema.
7 8 9 |
# File 'lib/turnkit/agent.rb', line 7 def output_schema @output_schema end |
#prompt_mode ⇒ Object (readonly)
Returns the value of attribute prompt_mode.
7 8 9 |
# File 'lib/turnkit/agent.rb', line 7 def prompt_mode @prompt_mode end |
#prompt_sections ⇒ Object (readonly)
Returns the value of attribute prompt_sections.
7 8 9 |
# File 'lib/turnkit/agent.rb', line 7 def prompt_sections @prompt_sections end |
#skills ⇒ Object (readonly)
Returns the value of attribute skills.
5 6 7 |
# File 'lib/turnkit/agent.rb', line 5 def skills @skills end |
#store ⇒ Object (readonly)
Returns the value of attribute store.
6 7 8 |
# File 'lib/turnkit/agent.rb', line 6 def store @store end |
#sub_agents ⇒ Object (readonly)
Returns the value of attribute sub_agents.
5 6 7 |
# File 'lib/turnkit/agent.rb', line 5 def sub_agents @sub_agents end |
#system_prompt ⇒ Object (readonly)
Returns the value of attribute system_prompt.
7 8 9 |
# File 'lib/turnkit/agent.rb', line 7 def system_prompt @system_prompt end |
#thinking ⇒ Object (readonly)
Returns the value of attribute thinking.
7 8 9 |
# File 'lib/turnkit/agent.rb', line 7 def thinking @thinking end |
#timeout ⇒ Object (readonly)
Returns the value of attribute timeout.
6 7 8 |
# File 'lib/turnkit/agent.rb', line 6 def timeout @timeout end |
#tools ⇒ Object (readonly)
Returns the value of attribute tools.
5 6 7 |
# File 'lib/turnkit/agent.rb', line 5 def tools @tools end |
Class Method Details
.normalize_thinking(value) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/turnkit/agent.rb', line 46 def self.normalize_thinking(value) return nil if value.nil? attrs = value.respond_to?(:to_h) ? value.to_h : value raise ArgumentError, "thinking must be a hash" unless attrs.is_a?(Hash) attrs = attrs.transform_keys(&:to_sym) unknown = attrs.keys - %i[effort budget] raise ArgumentError, "unknown thinking attributes: #{unknown.join(", ")}" if unknown.any? raise ArgumentError, "thinking requires :effort or :budget" if attrs[:effort].nil? && attrs[:budget].nil? raise ArgumentError, "thinking budget must be an Integer" if attrs[:budget] && !attrs[:budget].is_a?(Integer) attrs.slice(:effort, :budget).compact end |
Instance Method Details
#build_budget(root_started_at: Clock.now) ⇒ Object
154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/turnkit/agent.rb', line 154 def build_budget(root_started_at: Clock.now) Budget.new( max_iterations: max_iterations || TurnKit.max_iterations, timeout: timeout || TurnKit.timeout, max_depth: max_depth || TurnKit.max_depth, max_tool_executions: max_tool_executions || TurnKit.max_tool_executions, max_tool_executions_by_name: max_tool_executions_by_name || TurnKit.max_tool_executions_by_name, max_spend: max_spend || TurnKit.max_spend, root_started_at: root_started_at ) end |
#conversation(model: nil, subject: nil, metadata: {}) ⇒ Object
61 62 63 64 65 66 67 68 69 70 |
# File 'lib/turnkit/agent.rb', line 61 def conversation(model: nil, subject: nil, metadata: {}) store = effective_store record = store.create_conversation( "agent_name" => name, "model" => model || effective_model, "subject" => subject, "metadata" => ) Conversation.new(agent: self, record: record, store: store, model: model || effective_model, subject: subject, metadata: ) end |
#cost ⇒ Object
89 90 91 |
# File 'lib/turnkit/agent.rb', line 89 def cost Cost.from_records(effective_store.list_turns(agent_name: name)) end |
#effective_available_skills ⇒ Object
127 128 129 |
# File 'lib/turnkit/agent.rb', line 127 def effective_available_skills (Array(TurnKit.available_skills) + available_skills).uniq { |skill| skill.key } end |
#effective_client ⇒ Object
109 110 111 |
# File 'lib/turnkit/agent.rb', line 109 def effective_client client || TurnKit.client end |
#effective_model ⇒ Object
97 98 99 |
# File 'lib/turnkit/agent.rb', line 97 def effective_model model || TurnKit.default_model end |
#effective_on_event ⇒ Object
123 124 125 |
# File 'lib/turnkit/agent.rb', line 123 def effective_on_event on_event || TurnKit.on_event end |
#effective_output_policy ⇒ Object
105 106 107 |
# File 'lib/turnkit/agent.rb', line 105 def effective_output_policy Array(output_policy).compact end |
#effective_prompt_mode(turn: nil) ⇒ Object
135 136 137 138 139 |
# File 'lib/turnkit/agent.rb', line 135 def effective_prompt_mode(turn: nil) return prompt_mode if prompt_mode turn&.depth.to_i.positive? ? :minimal : :full end |
#effective_prompt_sections ⇒ Object
131 132 133 |
# File 'lib/turnkit/agent.rb', line 131 def effective_prompt_sections prompt_sections || TurnKit.prompt_sections end |
#effective_store ⇒ Object
113 114 115 |
# File 'lib/turnkit/agent.rb', line 113 def effective_store store || TurnKit.store end |
#effective_thinking ⇒ Object
101 102 103 |
# File 'lib/turnkit/agent.rb', line 101 def effective_thinking thinking end |
#effective_tools ⇒ Object
117 118 119 120 121 |
# File 'lib/turnkit/agent.rb', line 117 def effective_tools configured = tools + sub_agents.map { |agent| SubAgentTool.for(agent) } skills = effective_available_skills skills.empty? ? configured : configured + [ LoadSkillTool.for(skills) ] end |
#instructions_with_skills ⇒ Object
166 167 168 169 170 |
# File 'lib/turnkit/agent.rb', line 166 def instructions_with_skills parts = [ instructions ] parts << SystemPrompt.loaded_skills_text(skills) parts.reject(&:empty?).join("\n\n") end |
#run(prompt = nil, task: nil, input: nil, async: false, subject: nil, metadata: {}, parent_run: nil, root_turn_id: nil, prompt_mode: :task, **options) ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/turnkit/agent.rb', line 72 def run(prompt = nil, task: nil, input: nil, async: false, subject: nil, metadata: {}, parent_run: nil, root_turn_id: nil, prompt_mode: :task, **) task = task || prompt raise ArgumentError, "task is required" if task.to_s.empty? SchemaCheck.validate!(input, input_schema, error_class: InputError, label: "input") if input_schema conversation = self.conversation(subject: subject, metadata: ) = conversation.say((task, input), metadata: { "source" => "application", "task" => true }) turn = conversation.build_turn( trigger_message_id: .id, root_turn_id: root_turn_id || parent_run_root_turn_id(parent_run), prompt_mode: prompt_mode, ** ) run = Run.new(turn) async ? run : run.run! end |
#system_prompt_for(turn:, conversation:) ⇒ Object
141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/turnkit/agent.rb', line 141 def system_prompt_for(turn:, conversation:) prompt = SystemPrompt.new(agent: self, turn: turn, conversation: conversation, mode: effective_prompt_mode(turn: turn)) case system_prompt when nil prompt.to_s when String system_prompt else system_prompt.call(prompt).to_s end end |
#usage ⇒ Object
93 94 95 |
# File 'lib/turnkit/agent.rb', line 93 def usage Usage.from_records(effective_store.list_turns(agent_name: name)) end |