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")
= client.agentic.(
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.(, 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::OperationParamsTama::Memory::Entity,Tama::Memory::EntityParamsTama::Perception::Chain,Tama::Perception::Concept,Tama::Perception::GeneratorTama::Agentic::Message,Tama::Agentic::MessageParams,Tama::Agentic::Author,Tama::Agentic::ThreadTama::BroadcastandTama::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::ConfigurationErrorfor malformed client configurationTama::Error::InvalidNamespaceErrorfor a mismatched final base URL segmentTama::Error::ValidationErrorfor local parameters and HTTP 422 responses; inspecterrorsTama::Error::NotFoundErrorfor HTTP 404 responsesTama::Error::HTTPErrorfor other non-2xx responses; inspectstatusandbodyTama::Error::TransportErrorfor Faraday transport failures; inspectcauseTama::Error::ParseErrorfor 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.