Class: Fosm::Agent

Inherits:
Object
  • Object
show all
Defined in:
lib/fosm/agent.rb

Overview

Base class for FOSM AI agents powered by Gemlings.

Each generated FOSM app gets an agent class that inherits from this. ::Gemlings::Tool instances are auto-generated from the lifecycle definition, giving the AI agent a bounded, machine-enforced set of actions.

The AI agent can ONLY fire lifecycle events. It cannot directly update state. This is the “bounded autonomy” guarantee — the state machine is the guardrail. If a transition isn’t valid, the tool returns { success: false } — the agent cannot bypass the machine.

Gemlings is a required dependency of fosm-rails (declared in gemspec). See: github.com/khasinski/gemlings

Usage:

class Fosm::InvoiceAgent < Fosm::Agent
  model_class Fosm::Invoice
  default_model "anthropic/claude-sonnet-4-20250514"

  # Optional: add custom tools using Gemlings inline API
  # fosm_tool :find_overdue,
  #           description: "Find sent invoices past their due date",
  #           inputs: {} do
  #   Fosm::Invoice.where(state: "sent").where("due_date < ?", Date.today)
  #                .map { |inv| { id: inv.id, due_date: inv.due_date } }
  # end
end

# Build and run a Gemlings agent
agent = Fosm::InvoiceAgent.build_agent
agent.run("Mark all sent invoices older than 30 days as overdue")

Class Method Summary collapse

Class Method Details

.build_agent(model: nil, agent_type: :tool_calling, instructions: nil, **kwargs) ⇒ Object

Builds and returns a configured ::Gemlings::CodeAgent (default) or ::Gemlings::ToolCallingAgent ready to run tasks within FOSM constraints.

Parameters:

  • model (String) (defaults to: nil)

    override the default model, e.g. “openai/gpt-4o”

  • agent_type (Symbol) (defaults to: :tool_calling)

    :code (default) or :tool_calling

  • instructions (String) (defaults to: nil)

    extra instructions appended to system prompt

  • kwargs (Hash)

    additional ::Gemlings::CodeAgent options (max_steps:, planning_interval:, callbacks:, output_type:, etc.)



89
90
91
92
93
94
95
96
97
98
# File 'lib/fosm/agent.rb', line 89

def build_agent(model: nil, agent_type: :tool_calling, instructions: nil, **kwargs)
  agent_class = agent_type == :tool_calling ? ::Gemlings::ToolCallingAgent : ::Gemlings::CodeAgent

  agent_class.new(
    model: model || default_model,
    tools: tools,
    instructions: build_system_instructions(instructions),
    **kwargs
  )
end

.default_model(model = nil) ⇒ Object

Sets/gets the default Gemlings model string. Format: “provider/model_name” — see Gemlings docs for supported providers.



49
50
51
52
# File 'lib/fosm/agent.rb', line 49

def default_model(model = nil)
  @default_model = model if model
  @default_model || "anthropic/claude-sonnet-4-20250514"
end

.fosm_tool(name, description:, inputs: {}, &block) ⇒ Object

Declare a custom Gemlings tool using the inline ::Gemlings.tool API.

Example:

fosm_tool :find_overdue_invoices,
          description: "Find all invoices that are past their due date",
          inputs: {} do
  Fosm::Invoice.where(state: "sent")
               .where("due_date < ?", Date.today)
               .map { |inv| { id: inv.id, due_date: inv.due_date.to_s } }
end

Parameters:

  • name (Symbol)

    snake_case tool name

  • description (String)

    what this tool does (shown to the LLM)

  • inputs (Hash) (defaults to: {})

    { param_name: “description” } for each parameter

  • block (Proc)

    the tool implementation



69
70
71
72
73
# File 'lib/fosm/agent.rb', line 69

def fosm_tool(name, description:, inputs: {}, &block)
  @custom_tool_definitions ||= []
  @custom_tool_definitions << { name: name, description: description, inputs: inputs, block: block }
  @tools = nil # Reset cached tools
end

.model_class(klass = nil) ⇒ Object

Declares the model class this agent operates on. Resets the cached tool list so tools are regenerated on next call to .tools



39
40
41
42
43
44
45
# File 'lib/fosm/agent.rb', line 39

def model_class(klass = nil)
  if klass
    @model_class = klass
    @tools = nil
  end
  @model_class
end

.toolsObject

Returns all Gemlings tool instances for this agent. Lazily built and cached — standard tools from lifecycle + custom tools.



77
78
79
# File 'lib/fosm/agent.rb', line 77

def tools
  @tools ||= build_all_tools
end