Project

tama-rb

0.0
The project is in a healthy, maintained state
An HTTP client with immutable models for the Tama neural, memory, perception, agentic, and broadcast APIs.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

>= 2.0, < 3.0
>= 2.0, < 3.0
>= 2.6
 Project Readme

Tama Ruby

tama-rb is the Ruby client for Tama APIs. It provides namespace-aware Faraday services, strict immutable response models, typed errors, and incremental server-sent event parsing.

Installation

Add the gem to your bundle:

gem "tama-rb", "~> 0.1.0"

Then run bundle install and load the client with:

require "tama"

Ruby 3.2 or newer is required.

Client Setup

Create a client with the base URL for the API namespace being used:

client = Tama::Client.new(
  base_url: "https://api.example.com/provision",
  headers: {"Authorization" => "Bearer token"},
  timeout: 300,
  retries: 2
)

Timeouts are expressed in seconds. Global headers are merged with per-request headers, with per-request values taking precedence. Retries use faraday-retry for retryable requests and statuses. The default transport is Faraday's Net::HTTP adapter.

An existing connection can be injected when custom Faraday middleware or an adapter is needed. The injected connection is used as configured; base_url is still required for request URL construction and namespace validation.

connection = Faraday.new do |faraday|
  faraday.request :json
  faraday.request :retry, max: 3
  faraday.adapter :net_http
end

client = Tama::Client.new(
  base_url: "https://api.example.com/perception",
  connection: connection
)

Namespace URLs

The final base URL path segment is validated for each operation. Prefixes such as /api/v1 are preserved.

Namespace Operations
provision Neural space/class/operation, perception chain lookup
ingest Memory entity creation
perception Perception concept listing
agentic Agentic message creation and streaming

Use separate clients when an application calls multiple namespaces.

Neural

client = Tama::Client.new(base_url: "https://api.example.com/provision")

space = client.neural.get_space("my-space")
klass = client.neural.get_class(space, "article")

operation = client.neural.create_class_operation(
  klass,
  chain_ids: ["chain-1", "chain-2"],
  node_type: "compute"
)

get_class accepts a Tama::Neural::Space or a space ID. create_class_operation accepts a Tama::Neural::Klass or class ID and either a hash or Tama::Neural::OperationParams.

Memory

client = Tama::Client.new(base_url: "https://api.example.com/ingest")

entity = client.memory.create_entity(
  klass,
  identifier: "article-123",
  record: {title: "Tama with Ruby"},
  validate_record: true
)

validate_record defaults to true. A Tama::Memory::EntityParams object can be passed instead of a hash.

Perception

Chain lookup uses a provision client:

client = Tama::Client.new(base_url: "https://api.example.com/provision")
chain = client.perception.get_chain(space, "summarize")

get_chain accepts a Tama::Neural::Space or space ID. Concept listing uses a perception client and supports query parameters:

client = Tama::Client.new(base_url: "https://api.example.com/perception")

concepts = client.perception.list_concepts(
  "entity-123",
  query: {limit: 20, offset: 0, relation: "reply"}
)

Agentic

client = Tama::Client.new(base_url: "https://api.example.com/agentic")

message = client.agentic.create_message(
  recipient: "user-123",
  identifier: "message-123",
  content: "Hello",
  index: 1,
  author: {identifier: "agent-1", source: "system"},
  thread: {identifier: "thread-1"}
)

Message class defaults are user-message, actor, and thread. A Tama::Agentic::MessageParams object can also be supplied.

Streaming

Streaming requires either callback: or a block. Each handler call receives one decoded JSON event. The parser buffers fragmented chunks, supports LF and CRLF separators, multiline data: fields, multiple events per chunk, and [DONE].

response = client.agentic.create_message(message_attributes, stream: true) do |event|
  puts event.inspect
end

The streaming form returns the successful Faraday::Response. Non-streaming creation parses the API's top-level JSON response into a Tama::Agentic::Message.

Request Options

Every operation accepts headers: and timeout: request options where applicable:

space = client.neural.get_space(
  "my-space",
  headers: {"X-Request-ID" => "request-1"},
  timeout: 30
)

Dynamic path segments are percent-encoded. Query parameters should be passed only through query: on list_concepts.

Models

Response and parser models are immutable Ruby Data objects:

  • Tama::Neural::Space, Tama::Neural::Klass, Tama::Neural::Operation, Tama::Neural::OperationParams
  • Tama::Memory::Entity, Tama::Memory::EntityParams
  • Tama::Perception::Chain, Tama::Perception::Concept, Tama::Perception::Generator
  • Tama::Agentic::Message, Tama::Agentic::MessageParams, Tama::Agentic::Author, Tama::Agentic::Thread
  • Tama::Broadcast and Tama::Broadcast::Event, Metadata, Step, Concept, Thought, Chain, Branch, Flow, OriginEntity

Broadcast payloads are parsed without making an HTTP request. Top-level event and step values are required:

broadcast = Tama::Broadcast.parse(
  event: {name: "step.updated", domain: "workflow"},
  step: {id: "step-1", concepts: []}
)

Response models also expose .parse(hash_or_json). Invalid JSON, required fields, types, enums, or nested models raise rather than creating partial empty models.

Errors

Failures raise subclasses of Tama::Error:

  • Tama::Error::ConfigurationError for malformed client configuration
  • Tama::Error::InvalidNamespaceError for a mismatched final base URL segment
  • Tama::Error::ValidationError for local parameters and HTTP 422 responses; inspect errors
  • Tama::Error::NotFoundError for HTTP 404 responses
  • Tama::Error::HTTPError for other non-2xx responses; inspect status and body
  • Tama::Error::TransportError for Faraday transport failures; inspect cause
  • Tama::Error::ParseError for malformed JSON, response envelopes, models, or SSE events

All HTTP statuses from 200 through 299 are successful. Neural, Memory, and Perception model endpoints require the API's exact { "data": ... } response envelope; Agentic message creation uses its top-level response object.

Development

bin/setup
bundle exec rspec
bundle exec standardrb
bundle exec rake build

bin/console starts an IRB session with Tama loaded.

Releasing

Releases use RubyGems Trusted Publishing, so the repository does not store a long-lived RubyGems API key.

Before the first release, create a pending trusted publisher at https://rubygems.org/profile/oidc/pending_trusted_publishers with:

  • Gem name: tama-rb
  • Repository owner: upmaru
  • Repository name: tama-rb
  • Workflow filename: publish.yml
  • GitHub environment: release

Create the release environment in the GitHub repository settings. After updating Tama::VERSION and CHANGELOG.md, publish by pushing a matching version tag:

git tag v0.1.0
git push origin v0.1.0

The first successful workflow run publishes the gem and converts the pending publisher into a trusted publisher. RubyGems organizations are currently in private beta; organization ownership requires beta access followed by transferring the published gem to the organization.

License

The gem is available under the MIT License.