Project

ask-agent

0.0
The project is in a healthy, maintained state
Agent loop, session management, tool execution, context compaction, hooks, and extensions.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

~> 5.25
~> 3.1
~> 13.0

Runtime

 Project Readme

ask-agent

Agent runtime for the ask-rb ecosystem. Runs the core agent loop: think, call tools, execute, feed results back, and repeat until the task is done. Built on ask-core, ask-state-providers, ask-llm-providers, ask-tools, ask-skills, and ask-instrumentation, and it powers the askr CLI.

Installation

gem "ask-agent"

Quick Start

require "ask-agent"

session = Ask::Agent::Session.new(model: "gpt-4o", max_turns: 25)
response = session.run("What files are in the current directory?")
puts response

Stream execution in real time with events:

session.on_event do |event|
  case event
  when Ask::Agent::Events::TextDelta
    print event.content
  when Ask::Agent::Events::ToolExecutionStart
    puts "\nRunning #{event.name}..."
  end
end

Declarative Agents

Agents follow a file convention. Each agent lives in a directory under agents/ (or app/agents/ in Rails); the directory name is the agent name, the file agent.rb defines the agent as a <Name>::Agent < Ask::Agent::Definition subclass, and a sibling instructions.md is auto-loaded as the system prompt.

agents/
└── health_check/          # agent name: "health_check"
    ├── agent.rb           # module HealthCheck; class Agent < Ask::Agent::Definition
    ├── instructions.md    # auto-loaded system prompt
    └── tools/             # per-agent tools (referenced with `tools :name`)
# agents/health_check/agent.rb
module HealthCheck
  class Agent < Ask::Agent::Definition
    model "gpt-4o"
    tools :bash, :read, :grep
  end
end

Run it by name:

agent = Ask::Agent.new("health_check")
response = agent.run("Check server health")

Shared tools for all agents go in agents/shared/tools/. Per-agent skills go in agents/<name>/skills/, shared skills in agents/shared/skills/.

Essential API

Entry point Purpose
Ask::Agent::Session.new(model:, tools: [], max_turns: 25, ...) Full agent loop: message, tool calls, results, follow-up
session.run(message) Run the loop for one message
session.on_event { |e| } Stream Ask::Agent::Events (text deltas, tool execution, evaluation)
Ask::Agent.new("name") Build a session from a declarative agent definition
Ask.chat(message) One-shot chat without instantiating a Session
Ask::Agent.configure { |c| ... } Global defaults: model, provider, turns, compactor, middleware
askr CLI: askr run <agent> [prompt], askr list, askr schedule, askr new, askr skills

Configuration

Ask::Agent.configure do |c|
  c.default_model = "claude-sonnet-4"
  c.default_provider = :anthropic
  c.default_max_turns = 50
  c.compactor_enabled = true
  c.compactor_threshold = 0.8
  c.parallel_tool_execution = true
  c.max_tool_retries = 3
end

default_provider pins which provider serves the default model when the model name doesn't uniquely identify one (for example, the same model id registered under multiple OpenAI-compatible providers). A provider: passed to Session.new or declared in an agent Definition always wins over the global default.

Full documentation

The full ask-rb documentation lives at https://ask-rb.github.io/ask-docs. https://ask-rb.github.io/ask-docs/core/agent covers ask-agent in depth, including the evaluator, middleware, extensions, cost tracking, and persistence. API reference: https://ask-rb.github.io/ask-docs/reference/api.

Development

bundle install bundle exec rake test

License

MIT