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 withpnpm sync:apiinapps/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) — theinstructionsvalue passed toregister_mcp_server(the caller reads it from its owninitializeresult), orNone.close(Callable[[], Awaitable[None]]) — async teardown — theon_closepassed toregister_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 toregister.
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: strid: strmetadata: dict[str, list[str]] = field(default_factory=dict)name: strtags: 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;Nonekeeps the default no-op sink.method(SearchMethod) — default retrieval method forsearch— seeToolCatalog.__init__; a semantic/hybrid catalog eagerly embeds each skill at registration.
build_embeddings
build_embeddings() -> NonePre-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 | NoneReturn the registered Skill for an id, or None if unknown.
has
has(skill_id: str) -> boolReturn whether a skill with this id is registered.
invoke
invoke(skill_id: str) -> strReturn 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]) -> NoneRecord a trace event into the catalog's sink.
See ToolCatalog.record_event for the event contract.
register
register(skill: Skill) -> NoneAdd 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
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() -> intReturn 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_id → skill_id).
Attributes:
score: float— Relevance score; higher ranks first. Same method-dependent scale asSearchHit.score, computed against the skill corpus.skill_id: str— Id of the matched skill, as passed toregister.
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() -> NoneSee 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]) -> NoneRecord 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) -> NoneRegister 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 = ...) -> NoneRoute 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: strid: strinput_schema: dict[str, Any] = field(default_factory=dict)name: stroutput_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;Nonekeeps the default no-op sink.method(SearchMethod) — default retrieval method forsearch— "bm25" (the historical, model-free behavior), "semantic" or "hybrid". A per-callmethod=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() -> NonePre-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 | NoneReturn the metadata-only Tool for an id, or None if unknown.
get_executable
get_executable(tool_id: str) -> ExecutableTool | NoneReturn the ExecutableTool (metadata plus handler) for an id, or None.
has
has(tool_id: str) -> boolReturn whether a tool with this id is registered.
invoke
async invoke(tool_id: str, args: dict[str, Any]) -> AnyRun 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— iftool_idis not registered.Exception— whatever the handler raises, re-raised after aninvoke_errortrace event is recorded.
record_event
record_event(event: dict[str, Any]) -> NoneRecord a trace event into the catalog's sink.
Parameters:
event(dict[str, Any]) — a dict matching one of the core-ownedTraceEventshapes (ADR-0007), e.g.{"type": "gateway_search", ...}.
Raises:
ValueError— if the dict doesn't match any known event shape.
register
register(tool: ExecutableTool) -> NoneAdd 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;executemust be set.
Raises:
ValueError— iftool.executeisNone, or ifinput_schema/output_schemacontain 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— ifmethodis not "bm25", "semantic" or "hybrid".RuntimeError— for "semantic"/"hybrid" when the embedding cache is not built (callbuild_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() -> NonePre-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]) -> NoneRecord 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]) -> NoneRegister 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 = ...) -> NoneRoute 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: strpath: str | None = Nonesession_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 MCPinitializeresult), 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) -> AnyRegister 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 toRATEL_API_KEY.endpoint(str | None) — OTLP endpoint override; defaults toRATEL_URL.headers(dict[str, str] | None) — Extra headers sent with every export request.service_name(str | None) —service.nameresource attribute; defaults perinit.capture_content(ContentCapture | str | None) — Exact content-capture mode to set (see above).include_span_and_events(bool | None) — Boolean sugar forcapture_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— ifcapture_contentis 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) -> strRender 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) -> ExecutableToolBuild 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) -> ExecutableToolBuild 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 raisesUnauthorizedError; 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) -> McpServerHandleIngest 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 initializedmcp.ClientSessionowned by the caller.transport_label(str) — recorded on theupstream_registertrace event.instructions(str | None) — the upstream's server instructions (frominitialize), if any.on_close(Callable[[], Awaitable[None]] | None) — optional async teardown invoked by the handle'sclose().
Returns: McpServerHandle — An McpServerHandle with the registered tool ids.
Raises:
ImportError— if the optionalmcppackage 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) -> ExecutableToolBuild 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) -> ExecutableToolBuild 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 byget_skill_content_tool.INVOKE_TOOL_ID = 'invoke_tool'— Id (and name) of the invocation tool built byinvoke_tool_tool.SEARCH_CAPABILITIES_ID = 'search_capabilities'— Id (and name) of the discovery tool built bysearch_capabilities_tool.SEARCH_TOOLS_ID = 'search_tools'— Id (and name) of the deprecated pre-0.2.0 discovery tool built bysearch_tools_tool; superseded byratel_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.invokeabsorbs the difference.OnUnauthorized = Callable[[str], Union[Awaitable[None], None]]— Notified when the underlying tool raisesUnauthorizedError, 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.