Class: Tools::Think

Inherits:
Base
  • Object
show all
Defined in:
lib/tools/think.rb

Overview

A deliberate reasoning space for the agent’s inner voice. Creates a pause between tool calls where the agent can organize thoughts, plan next steps, or make decisions without interrupting the user.

Think events bridge the gap between the analytical brain (subconscious background processing) and speech (user-facing messages). Without this tool, reasoning leaks into tool arguments as comments.

Two visibility modes control how thoughts appear in the TUI:

  • inner (default) — silent reasoning, visible only in verbose/debug

  • aloud — narration shown in all view modes with a thought bubble

The maxLength on thoughts is controlled by thinking_budget in settings. Sub-agents receive half the main agent’s budget — their tasks are scoped and less complex, so runaway reasoning is a stronger signal of confusion.

Examples:

Silent planning between tool calls

think(thoughts: "Three auth failures — likely a config issue, not individual tests.")

Narrating approach for the user

think(thoughts: "Checking the OAuth config first.", visibility: "aloud")

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

schema, truncation_threshold

Constructor Details

#initialize(session: nil) ⇒ Think

Returns a new instance of Think.

Parameters:

  • session (Session, nil) (defaults to: nil)

    current session for budget calculation



48
49
50
# File 'lib/tools/think.rb', line 48

def initialize(session: nil, **)
  @session = session
end

Class Method Details

.descriptionObject



28
# File 'lib/tools/think.rb', line 28

def self.description = "Think out loud or silently."

.input_schemaObject

Schema is static — maxLength is injected at runtime by the registry via #dynamic_schema when session context is available.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/tools/think.rb', line 32

def self.input_schema
  {
    type: "object",
    properties: {
      thoughts: {type: "string"},
      visibility: {
        type: "string",
        enum: ["inner", "aloud"],
        description: "inner (default) is silent. aloud is shown to the user."
      }
    },
    required: ["thoughts"]
  }
end

.tool_nameObject



26
# File 'lib/tools/think.rb', line 26

def self.tool_name = "think"

Instance Method Details

#dynamic_schemaHash

Returns the tool schema with a thinking budget applied as maxLength on the thoughts property. Sub-agents get half the budget.

Returns:

  • (Hash)

    Anthropic tool schema with maxLength constraint



56
57
58
59
60
61
62
# File 'lib/tools/think.rb', line 56

def dynamic_schema
  schema = self.class.schema.deep_dup
  budget = Anima::Settings.thinking_budget
  budget /= 2 if @session&.sub_agent?
  schema[:input_schema][:properties][:thoughts][:maxLength] = budget
  schema
end

#execute(input) ⇒ String

Returns acknowledgement — the value is in the call, not the result.

Parameters:

  • input (Hash)

    with “thoughts” and optional “visibility”

Returns:

  • (String)

    acknowledgement — the value is in the call, not the result



66
67
68
69
70
71
# File 'lib/tools/think.rb', line 66

def execute(input)
  thoughts = input["thoughts"].to_s
  return {error: "Thoughts cannot be blank"} if thoughts.strip.empty?

  "OK"
end