Ratel Docs
ReferencePython packages

ratel-ai

Raw API of ratel-ai — every exported class, function, and constant of the Python SDK.

v0.4.2 · Python · PyPI · source

Generated from the doc comments at ratel-ai/ratel@3be0ecb — do not edit by hand. Regenerate with pnpm sync:api in apps/docs.

Classes

ExecutableTool

ExecutableTool(id: str, name: str, description: str, input_schema: dict[str, Any] = dict(), output_schema: dict[str, Any] = dict(), execute: Executor = None)

A Tool plus the handler that runs it. Registered into a ToolCatalog.

Attributes:

  • execute: Executor = field(default=None)

McpServerHandle

McpServerHandle(tool_ids: list[str], server_instructions: str | None, close: Callable[[], Awaitable[None]])

What register_mcp_server returns: the registration's outcome.

Attributes:

  • tool_ids (list[str]) — the namespaced <server>__<tool> ids registered into the catalog, in upstream listing order.
  • server_instructions (str | None) — the instructions value passed to register_mcp_server (the caller reads it from its own initialize result), or None.
  • close (Callable[[], Awaitable[None]]) — async teardown — the on_close passed to register_mcp_server, or a no-op. The session itself stays caller-owned either way.

SearchHit

A single search result: the matched tool id and its relevance score.

Attributes:

  • score: float — Relevance score; higher ranks first. The scale depends on the search method: raw BM25 (unbounded) for "bm25", cosine similarity for "semantic", reciprocal-rank-fusion for "hybrid" — scores from different methods are not comparable.
  • tool_id: str — Id of the matched tool, as passed to register.

Skill

Skill(id: str, name: str, description: str, tags: list[str] = list(), tools: list[str] = list(), metadata: dict[str, list[str]] = dict(), body: str = '')

Skill metadata: what the index ranks and the capability tools surface.

Attributes:

  • body: str = ''
  • description: str
  • id: str
  • metadata: dict[str, list[str]] = field(default_factory=dict)
  • name: str
  • tags: list[str] = field(default_factory=list)
  • tools: list[str] = field(default_factory=list)

SkillCatalog

SkillCatalog(trace: TraceSinkConfig | None = None, method: SearchMethod = 'bm25')

Registry of skills. Register once, then search and load bodies by id.

Create an empty skill catalog.

Parameters:

  • trace (TraceSinkConfig | None) — where trace events go; None keeps the default no-op sink.
  • method (SearchMethod) — default retrieval method for search — see ToolCatalog.__init__; a semantic/hybrid catalog eagerly embeds each skill at registration.

build_embeddings

build_embeddings() -> None

Pre-compute embeddings for not-yet-embedded skills.

See ToolCatalog.build_embeddings for when to call and what it raises.

drain_trace_events

drain_trace_events() -> list[dict[str, Any]]

Drain captured trace envelopes; [] unless the sink is "memory".

get

get(skill_id: str) -> Skill | None

Return the registered Skill for an id, or None if unknown.

has

has(skill_id: str) -> bool

Return whether a skill with this id is registered.

invoke

invoke(skill_id: str) -> str

Return a skill's body for dispatch, recording a skill_invoke event.

Synchronous, unlike ToolCatalog.invoke — the body is already in memory, there is no handler to run.

Parameters:

  • skill_id (str) — id of a registered skill.

Returns: str — The skill's body (Markdown), verbatim as registered.

Raises:

  • ValueError — on an unknown id — callers at the capability-tool boundary translate this into a structured error for the agent.

record_event

record_event(event: dict[str, Any]) -> None

Record a trace event into the catalog's sink.

See ToolCatalog.record_event for the event contract.

register

register(skill: Skill) -> None

Add a skill to the catalog (metadata into the index, body stored).

Registering an id that is already present replaces it in place — the index never holds a duplicate. Name, description and tags are indexed for ranking; tools, metadata and body are stored but not indexed.

Parameters:

  • skill (Skill) — the skill to register.

Raises:

  • RuntimeError — on a semantic/hybrid catalog, if the embedding model fails to load while eagerly embedding the new skill.
search(query: str, top_k: int, origin: SearchOrigin = 'direct', method: SearchMethod | None = None) -> list[SkillHit]

Rank registered skills against a natural-language query.

The skill twin of ToolCatalog.search — same arguments, same method-override and ValueError/RuntimeError semantics, ranked against the skill corpus.

Returns: list[SkillHit] — Up to top_k SkillHits, best first.

size

size() -> int

Return the number of registered skills.

SkillHit

A single skill search result: the matched skill id and its relevance score.

The skill analogue of SearchHit (tool_idskill_id).

Attributes:

  • score: float — Relevance score; higher ranks first. Same method-dependent scale as SearchHit.score, computed against the skill corpus.
  • skill_id: str — Id of the matched skill, as passed to register.

SkillRegistry

SkillRegistry()

Metadata-only BM25 index over the skill corpus (separate from tools).

The on-demand analogue of ToolRegistry: a separate index, so skills are ranked independently of tools (own corpus statistics, own top-K).

build_embeddings

build_embeddings() -> None

See ToolRegistry.build_embeddings.

drain_trace_events

drain_trace_events() -> list[dict[str, Any]]

Drain captured envelopes — see ToolRegistry.drain_trace_events.

record_event

record_event(event: dict[str, Any]) -> None

Record an SDK-layer trace event — see ToolRegistry.record_event.

register

register(id: str, name: str, description: str, tags: list[str], tools: list[str], metadata: dict[str, list[str]], body: str) -> None

Register a skill's metadata into the index.

Replaces in place when id is already registered. tags are indexed for ranking; tools and metadata ride along un-indexed for higher layers; body is the full instruction text, stored for on-demand load.

search

search(query: str, top_k: int) -> list[SkillHit]

Lexical BM25 search over the skill corpus — see ToolRegistry.search.

search_with_method

search_with_method(query: str, top_k: int, origin: str, method: str) -> list[SkillHit]

Search with an explicit method — see ToolRegistry.search_with_method.

search_with_origin

search_with_origin(query: str, top_k: int, origin: str) -> list[SkillHit]

BM25 search tagged with who initiated it — see ToolRegistry.search_with_origin.

set_trace_sink

set_trace_sink(kind: str, session_id: str | None = ..., path: str | None = ...) -> None

Route trace events to a sink — see ToolRegistry.set_trace_sink.

Tool

Tool(id: str, name: str, description: str, input_schema: dict[str, Any] = dict(), output_schema: dict[str, Any] = dict())

Tool metadata: what the index ranks and the capability tools surface.

Attributes:

  • description: str
  • id: str
  • input_schema: dict[str, Any] = field(default_factory=dict)
  • name: str
  • output_schema: dict[str, Any] = field(default_factory=dict)

ToolCatalog

ToolCatalog(trace: TraceSinkConfig | None = None, method: SearchMethod = 'bm25')

Registry + executors. Register tools once, then search and invoke by id.

Create an empty catalog.

Parameters:

  • trace (TraceSinkConfig | None) — where trace events go; None keeps the default no-op sink.
  • method (SearchMethod) — default retrieval method for search — "bm25" (the historical, model-free behavior), "semantic" or "hybrid". A per-call method= overrides it. A semantic/hybrid catalog eagerly embeds each tool at registration so searches never pay the embedding cost; a BM25 catalog never touches the model.

build_embeddings

build_embeddings() -> None

Pre-compute embeddings for any not-yet-embedded tools.

Incremental: only tools registered since the last call are embedded. Call after a bulk register, or rely on the automatic per-register embedding that a semantic/hybrid catalog does. A BM25 catalog never needs it.

Raises:

  • RuntimeError — if the embedding model fails to load.

drain_trace_events

drain_trace_events() -> list[dict[str, Any]]

Drain captured trace envelopes; [] unless the sink is "memory".

get

get(tool_id: str) -> Tool | None

Return the metadata-only Tool for an id, or None if unknown.

get_executable

get_executable(tool_id: str) -> ExecutableTool | None

Return the ExecutableTool (metadata plus handler) for an id, or None.

has

has(tool_id: str) -> bool

Return whether a tool with this id is registered.

invoke

async invoke(tool_id: str, args: dict[str, Any]) -> Any

Run a registered tool's handler and return its result.

This is the canonical place that absorbs the sync/async executor difference: the handler is called first and the result awaited only if it is awaitable, so plain functions and async def executors (e.g. MCP/HTTP tools) are both supported. Callers must route invocations here rather than re-deriving that logic. Emits invoke_start / invoke_end / invoke_error trace events and wraps the call in an execute_tool OTel span (ADR-0007).

Parameters:

  • tool_id (str) — id of a registered tool.
  • args (dict[str, Any]) — the arguments dict passed to the handler.

Returns: Any — Whatever the handler returns (awaited if it returned an awaitable).

Raises:

  • ValueError — if tool_id is not registered.
  • Exception — whatever the handler raises, re-raised after an invoke_error trace event is recorded.

record_event

record_event(event: dict[str, Any]) -> None

Record a trace event into the catalog's sink.

Parameters:

  • event (dict[str, Any]) — a dict matching one of the core-owned TraceEvent shapes (ADR-0007), e.g. {"type": "gateway_search", ...}.

Raises:

  • ValueError — if the dict doesn't match any known event shape.

register

register(tool: ExecutableTool) -> None

Add a tool to the catalog (metadata into the index, handler by id).

Registering an id that is already present replaces it in place — the index never holds a duplicate.

Parameters:

  • tool (ExecutableTool) — the tool to register; execute must be set.

Raises:

  • ValueError — if tool.execute is None, or if input_schema / output_schema contain values that are not JSON-serializable.
  • RuntimeError — on a semantic/hybrid catalog, if the embedding model fails to load while eagerly embedding the new tool.

search

search(query: str, top_k: int, origin: SearchOrigin = 'direct', method: SearchMethod | None = None) -> list[SearchHit]

Rank registered tools against a natural-language query.

Parameters:

  • query (str) — what the caller wants to do.
  • top_k (int) — max hits to return.
  • origin (SearchOrigin) — who initiated the search — labels the trace event only.
  • method (SearchMethod | None) — per-call override of the catalog's default retrieval method ("bm25" | "semantic" | "hybrid").

Returns: list[SearchHit] — Up to top_k SearchHits, best first.

Raises:

  • ValueError — if method is not "bm25", "semantic" or "hybrid".
  • RuntimeError — for "semantic"/"hybrid" when the embedding cache is not built (call build_embeddings) or query embedding fails.

ToolRegistry

ToolRegistry()

Metadata-only BM25 index over ratel-ai-core.

Executors and the capability-tool / MCP layers live in the pure-Python ratel_ai package above this binding.

build_embeddings

build_embeddings() -> None

Pre-compute embeddings for not-yet-embedded tools (incremental).

A later semantic/hybrid search then only embeds the query. Raises RuntimeError if the model fails to load. The catalog calls this after register in semantic mode; BM25-only callers never do.

drain_trace_events

drain_trace_events() -> list[dict[str, Any]]

Drain captured envelopes from the active sink.

Returns [] unless the active sink is "memory".

record_event

record_event(event: dict[str, Any]) -> None

Record an SDK-layer trace event into the active sink.

event must be a dict matching one of the core-owned TraceEvent shapes (ADR-0007, e.g. {"type": "gateway_search", ...}); anything else raises ValueError.

register

register(id: str, name: str, description: str, input_schema: dict[str, Any], output_schema: dict[str, Any]) -> None

Register a tool's metadata into the index.

Replaces in place when id is already registered. The schemas must be JSON-serializable dicts; anything else raises ValueError.

search

search(query: str, top_k: int) -> list[SearchHit]

Lexical BM25 search: the top top_k tools for query, best first.

Model-free and infallible; the trace event records origin "direct".

search_with_method

search_with_method(query: str, top_k: int, origin: str, method: str) -> list[SearchHit]

Search with an explicit method ("bm25" | "semantic" | "hybrid").

"bm25" is infallible; "semantic"/"hybrid" rank against the prebuilt embedding cache and raise RuntimeError (EmbeddingsNotBuilt) if it isn't built — the model loads at build_embeddings, never inside a search. An unknown method string raises ValueError.

search_with_origin

search_with_origin(query: str, top_k: int, origin: str) -> list[SearchHit]

BM25 search tagged with who initiated it.

origin is "agent" (a model calling a capability tool) or anything else → "direct" (host code). The origin only labels the emitted trace event — ranking is identical to search.

set_trace_sink

set_trace_sink(kind: str, session_id: str | None = ..., path: str | None = ...) -> None

Route trace events to a sink.

kind is "noop" (drop everything, the initial state), "memory" (buffer for drain_trace_events; requires session_id) or "jsonl" (append to a file; requires session_id and path). Raises ValueError on an unknown kind, a missing required argument, or a jsonl path that cannot be opened.

TraceSinkConfig

TraceSinkConfig(kind: str, session_id: str | None = None, path: str | None = None)

Where the catalog's trace events go. Mirrors the TS TraceSinkConfig union.

kind: "noop" | "memory" | "jsonl". session_id is required for memory/jsonl; path is required for jsonl.

Attributes:

  • kind: str
  • path: str | None = None
  • session_id: str | None = None

UpstreamServerInfo

UpstreamServerInfo(name: str, description: str | None = None, instructions: str | None = None, tool_count: int | None = None, needs_auth: bool = False)

An upstream MCP server, as advertised in the capability-tool descriptions.

Pass a list of these to search_capabilities_tool (or the deprecated search_tools_tool) to append a "this catalog aggregates…" listing to the tool description shown to the model, and to enrich each search result's server group with the upstream's description and instructions.

Attributes:

  • name (str) — the catalog namespace of the server — the <name> prefix of its <name>__<tool> tool ids.
  • description (str | None) — what the server offers; compacted to one line in listings.
  • instructions (str | None) — the server's usage instructions (from its MCP initialize result), surfaced on matching server groups.
  • tool_count (int | None) — number of tools the server contributed, shown in listings.
  • needs_auth (bool) — True when the upstream rejected its boot connection with a 401 / re-auth needed; listings append "(auth required)".

Functions

configure_telemetry

configure_telemetry(*, api_key: str | None = None, endpoint: str | None = None, headers: dict[str, str] | None = None, service_name: str | None = None, capture_content: ContentCapture | str | None = None, include_span_and_events: bool | None = None) -> Any

Register a Ratel-owned OTLP exporter (convenience wiring for the greenfield case).

Ships the spans this SDK emits to Ratel Cloud (or any OTLP endpoint) by delegating to ratel_ai_telemetry.init, which needs the OpenTelemetry SDK — install it with pip install 'ratel-ai[otlp]'. A host already running its own OpenTelemetry provider should skip this (the SDK's spans flow to that provider) and add ratel_span_processor from ratel_ai_telemetry.

capture_content / include_span_and_events opt into message/tool content capture in code via set_content_capture: capture_content sets an exact mode, include_span_and_events is bool sugar (True -> SPAN_AND_EVENT, False -> NO_CONTENT); capture_content wins when both are given. A provided option beats OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT (the env var is the fallback when neither is given, as in OTel). The returned handle's shutdown() clears the override, restoring env-driven behavior; the clear is generation-scoped, so a stale handle shutting down late never clobbers an override a newer configure_telemetry/set_content_capture call installed.

Parameters:

  • api_key (str | None) — Ratel Cloud API key override; defaults to RATEL_API_KEY.
  • endpoint (str | None) — OTLP endpoint override; defaults to RATEL_URL.
  • headers (dict[str, str] | None) — Extra headers sent with every export request.
  • service_name (str | None) — service.name resource attribute; defaults per init.
  • capture_content (ContentCapture | str | None) — Exact content-capture mode to set (see above).
  • include_span_and_events (bool | None) — Boolean sugar for capture_content (see above).

Returns: Any — A per-call shutdown handle (handle.shutdown() / handle.force_flush()), the same shape on every path. Attribute access delegates to the shared handle init returns; because that handle is shared across callers, shutting it down stops export for all of them.

Raises:

  • ModuleNotFoundError — if the OpenTelemetry exporter is not installed (pip install 'ratel-ai[otlp]').
  • ValueError — if capture_content is not a recognized mode — raised before any exporter is wired, so a bad option has no side effects.

format_upstream_line

format_upstream_line(s: UpstreamServerInfo) -> str

Render one upstream server as a listing bullet for a tool description.

Format: - <name> — <description> (<N> tools) (auth required), where the description is whitespace-collapsed and truncated to ~160 chars, and each trailing part appears only when the corresponding field is set.

Parameters:

  • s (UpstreamServerInfo) — the upstream server to render.

Returns: str — A single - -prefixed line, ready to join into the "this catalog aggregates…" listing.

get_skill_content_tool

get_skill_content_tool(catalog: SkillCatalog) -> ExecutableTool

Build the get_skill_content tool: load a skill's full body by id.

The returned tool resolves skillId and answers {"body": <markdown>} via SkillCatalog.invoke (which records a skill_invoke trace event). It never raises into the host: an unknown or non-string id comes back as a structured {"error": ..., "isError": True} payload the model can recover from, mirroring invoke_tool.

Parameters:

  • catalog (SkillCatalog) — the skill catalog to load bodies from.

Returns: ExecutableTool — An ExecutableTool to put in the agent's direct tool list alongside search_capabilities.

invoke_tool_tool

invoke_tool_tool(catalog: ToolCatalog, *, on_unauthorized: OnUnauthorized | None = None) -> ExecutableTool

Build the invoke_tool tool: run any catalog tool by id.

The returned tool resolves toolId, forwards the nested args object to ToolCatalog.invoke, and never raises into the host: an unknown id, malformed args, or a tool exception all come back as a structured {"error": ..., "isError": True} payload the model can recover from. A flattened call (arguments at the top level instead of nested under args) is tolerated. When the tool raises an UnauthorizedError, the payload is {"error": "needs_auth", ...} with a re-auth hint and, for namespaced <server>__<tool> ids, the upstream server name.

Parameters:

  • catalog (ToolCatalog) — the catalog to resolve and run tool ids against.
  • on_unauthorized (OnUnauthorized | None) — called with the upstream server name when a tool raises UnauthorizedError; may be sync or async. Skipped when the tool id has no <server>__ namespace prefix.

Returns: ExecutableTool — An ExecutableTool to put in the agent's direct tool list.

register_mcp_server

async register_mcp_server(catalog: ToolCatalog, *, name: str, session: Any, transport_label: str = 'unknown', instructions: str | None = None, on_close: Callable[[], Awaitable[None]] | None = None) -> McpServerHandle

Ingest an initialized MCP ClientSession into the catalog.

Parameters:

  • catalog (ToolCatalog) — the catalog to register the upstream tools into.
  • name (str) — namespace prefix for tool ids (<name>__<tool>).
  • session (Any) — an initialized mcp.ClientSession owned by the caller.
  • transport_label (str) — recorded on the upstream_register trace event.
  • instructions (str | None) — the upstream's server instructions (from initialize), if any.
  • on_close (Callable[[], Awaitable[None]] | None) — optional async teardown invoked by the handle's close().

Returns: McpServerHandle — An McpServerHandle with the registered tool ids.

Raises:

  • ImportError — if the optional mcp package is not installed (pip install 'ratel-ai[mcp]').

search_capabilities_tool

search_capabilities_tool(catalog: ToolCatalog, skill_catalog: SkillCatalog | None = None, *, upstream_servers: Sequence[UpstreamServerInfo] | None = None) -> ExecutableTool

Build the search_capabilities tool: unified discovery over tools AND skills.

The returned tool ranks two independent buckets, each with its own top-K budget — so a relevant skill is never starved out of the results by a large number of matching tools (and the two BM25 corpora are never score-compared). Tools land grouped by upstream server; a matched skill's declared tools are pulled into the tools bucket additively (score 0), so the agent gets the playbook and its toolkit in one turn. The skills bucket (and the mention of get_skill_content in the description) is only advertised when a non-empty skill_catalog is wired in.

Parameters:

  • catalog (ToolCatalog) — the tool catalog to search.
  • skill_catalog (SkillCatalog | None) — optional skill catalog, ranked against the same query in its own bucket.
  • upstream_servers (Sequence[UpstreamServerInfo] | None) — upstream MCP servers to advertise in the tool description and to enrich result server groups with.

Returns: ExecutableTool — An ExecutableTool to put in the agent's direct tool list.

search_tools_tool

search_tools_tool(catalog: ToolCatalog, *, upstream_servers: Sequence[UpstreamServerInfo] | None = None) -> ExecutableTool

Build the pre-0.2.0 tools-only discovery tool (id search_tools).

Keeps the original behaviour: a flat {groups} result and no skills bucket. New code should use ratel_ai.search_capabilities_tool instead. Registering both lets a host serve the old and new names during a migration window.

Parameters:

  • catalog (ToolCatalog) — the tool catalog to search.
  • upstream_servers (Sequence[UpstreamServerInfo] | None) — upstream MCP servers to advertise in the tool description and to enrich result server groups with.

Returns: ExecutableTool — An ExecutableTool to put in the agent's direct tool list.

Deprecated — Since 0.2.0: use ratel_ai.search_capabilities_tool. Tracked for removal in RAT-250.

Constants

  • GET_SKILL_CONTENT_ID = 'get_skill_content' — Id (and name) of the skill-loading tool built by get_skill_content_tool.
  • INVOKE_TOOL_ID = 'invoke_tool' — Id (and name) of the invocation tool built by invoke_tool_tool.
  • SEARCH_CAPABILITIES_ID = 'search_capabilities' — Id (and name) of the discovery tool built by search_capabilities_tool.
  • SEARCH_TOOLS_ID = 'search_tools' — Id (and name) of the deprecated pre-0.2.0 discovery tool built by search_tools_tool; superseded by ratel_ai.SEARCH_CAPABILITIES_ID.
  • Executor = Callable[[dict[str, Any]], Union[Awaitable[Any], Any]] — A tool handler: takes the tool's arguments dict, returns the result. May be sync or async (tool inputs are heterogeneous across the catalog); ToolCatalog.invoke absorbs the difference.
  • OnUnauthorized = Callable[[str], Union[Awaitable[None], None]] — Notified when the underlying tool raises UnauthorizedError, with the upstream server name inferred from the toolId. May be sync or async.
  • SearchMethod = str — Retrieval engine: "bm25" (lexical, model-free, the default), "semantic" (dense embeddings) or "hybrid" (both, fused).
  • SearchOrigin = str — Who initiated a search: "direct" (host code, the default) or "agent" (a model calling a capability tool). Labels the emitted trace event only — ranking is unaffected.

On this page