Module: Omakase::Strategies::CodeAct
- Defined in:
- lib/omakase/strategies/code_act.rb
Overview
The model acts by writing Ruby against the agent object and answers with
finish(value) — the answer is computed, not retyped.
Class Method Summary collapse
- .call(request) ⇒ Object
- .capabilities(request) ⇒ Object
-
.instructions(request) ⇒ Object
Nothing here changes between calls of one generation, so providers can cache it.
- .nudge(request) ⇒ Object
- .run(chat, tool) ⇒ Object
Class Method Details
.call(request) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/omakase/strategies/code_act.rb', line 10 def call(request) tool = Tools::Ruby.new(request.agent, request.schema) chat = Predict.instruct(request.chat, instructions(request), request.context) .with_tools(tool) .ask_later(request.task(preview: true), with: request.) response = run(chat, tool) # A text reply is usually a model that forgot how to answer, not one that is done. response = run(chat.ask_later(nudge(request)), tool) unless tool.done? return tool.answer.value if tool.answer notes = response&.content # It never called finish. A JSON answer can still be given in a tool-free turn. return Predict.call(request, task: "#{request.task}\n\nWork done:\n#{notes}") unless request.schema.code_only? # An object cannot come back as JSON, so there is nowhere to fall back to. raise ContractError, "#{request.generation.name}: the model never called finish(#{request.schema.describe})" end |
.capabilities(request) ⇒ Object
63 64 65 |
# File 'lib/omakase/strategies/code_act.rb', line 63 def capabilities(request) Capabilities.of(request.agent.class, except: request.generation.name).map { |entry| "- #{entry}" } end |
.instructions(request) ⇒ Object
Nothing here changes between calls of one generation, so providers can cache it.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/omakase/strategies/code_act.rb', line 41 def instructions(request) <<~TEXT #{request.instructions} You act by writing Ruby: call the `ruby` tool with code that is evaluated on the agent object, so its methods and state are available on self. The inputs are local variables in that code — use them, do not retype them. #{capabilities(request).join("\n")} `doc(object)` prints what an object of an unfamiliar type offers; a class works too. `how_to_act` is the rest, with examples — call it once before you write code. Run the task; do not define a method for it. Return the answer from inside the code, never as a message — the last thing you run is: finish(#{request.schema.describe}) Work in as few tool calls as you can. TEXT end |
.nudge(request) ⇒ Object
35 36 37 38 |
# File 'lib/omakase/strategies/code_act.rb', line 35 def nudge(request) "Your reply was text with no tool call, so the task is not done. " \ "Call the `ruby` tool and end with finish(#{request.schema.describe})." end |
.run(chat, tool) ⇒ Object
29 30 31 32 33 |
# File 'lib/omakase/strategies/code_act.rb', line 29 def run(chat, tool) response = nil response = chat.step until chat.complete? || tool.done? response end |