Class: Llm::Agent::Rails::Orchestrator
- Inherits:
-
Object
- Object
- Llm::Agent::Rails::Orchestrator
- Defined in:
- lib/llm/agent/rails/orchestrator.rb
Constant Summary collapse
- POLICY =
<<~SYS You are a task-oriented assistant that turns chat into structured tool calls. Rules: - First, extract as many required fields as possible from the user's latest message and prior context. - Only ask for fields that are truly missing or ambiguous (one concise question at a time). - Derive a short, descriptive title if not supplied (e.g., "Apple Pay checkout failure on mobile"). - Prefer sensible defaults when the schema allows (e.g., priority=medium). - When you have all required fields, call exactly one function. Reply briefly and clearly. SYS
Instance Method Summary collapse
-
#initialize(adapter:, registry:, store:) ⇒ Orchestrator
constructor
A new instance of Orchestrator.
- #step(thread_id:, tenant_id:, actor_id:, messages:) ⇒ Object
Constructor Details
#initialize(adapter:, registry:, store:) ⇒ Orchestrator
Returns a new instance of Orchestrator.
21 22 23 |
# File 'lib/llm/agent/rails/orchestrator.rb', line 21 def initialize(adapter:, registry:, store:) @adapter, @registry, @store = adapter, registry, store end |
Instance Method Details
#step(thread_id:, tenant_id:, actor_id:, messages:) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/llm/agent/rails/orchestrator.rb', line 25 def step(thread_id:, tenant_id:, actor_id:, messages:) prior_tool_msgs = @store.(thread_id) res = @adapter.step( system_prompt: POLICY, messages: , tools: @registry.tools_for_llm, tool_results: prior_tool_msgs ) if (calls = res[:tool_calls]).is_a?(Array) && calls.any? call = calls.first fn = call.respond_to?(:function) ? call.function : nil name = fn&.respond_to?(:name) ? fn.name : nil args_json = fn&.respond_to?(:arguments) ? fn.arguments.to_s : "{}" args = args_json.empty? ? {} : JSON.parse(args_json) tool_name, version = (name or "").split(/_v/i) version ||= "v1" tool = @registry.tool(tool_name, version: "v1") Validators.validate!(tool.schema, args) ctx = { tenant_id: tenant_id, actor_id: actor_id, thread_id: thread_id } result = tool.handler.call(args, ctx) tool_msg = @adapter.( tool_call_id: call.respond_to?(:id) ? call.id : nil, name: "#{tool_name}_v1", content: result ) @store.(thread_id, tool_msg) return { type: :tool_ran, tool_name: tool_name, result: result } end if (fc = res[:function_call]) name_with_version = fc["name"] args_json = fc["arguments"].to_s args = args_json.empty? ? {} : JSON.parse(args_json) tool_name, version = name_with_version.split(/_v/i) version ||= "v1" tool = @registry.tool(tool_name, version: "v1") Validators.validate!(tool.schema, args) ctx = { tenant_id: tenant_id, actor_id: actor_id, thread_id: thread_id } result = tool.handler.call(args, ctx) return { type: :tool_ran, tool_name: tool_name, result: result } end { type: :assistant, text: res[:content].to_s } end |