Package 'rho'

Title: Asynchronous R Agent and Bioinformatics Substrate
Description: Defines asynchronous tasks, streams, HTTP and provider protocols, agent and extension runtimes, compute and transport backends, coding tools, graphics artifacts, and declared bioinformatics resources in one package.
Authors: Sounkou Mahamane Toure [aut, cre]
Maintainer: Sounkou Mahamane Toure <[email protected]>
License: MIT + file LICENSE
Version: 0.0.1.9001
Built: 2026-09-26 20:25:15 UTC
Source: https://github.com/RGenomicsETL/Rho

Help Index


Agent state machine, policy, scheduling, and lifecycle events

Description

rho_prompt() and rho_continue() return tasks. The agent consumes typed assistant events, schedules tool tasks, preserves source-order results, and emits typed lifecycle events. Steering and follow-up queues have separate, typed draining policies.

Details

Policy and scheduling decisions are S7 generics. Packages can specialize context transformation, before/after-tool behavior, next-turn preparation, assistant event reduction, queue draining, and tool batch execution without replacing the core loop.


Explicit credentials, login effects, and provider catalog state

Description

Credentials are owned by a CredentialStore; login interaction is owned by a LoginIO. Reads, refreshes, writes, prompts, and notifications are explicit async operations. RhoModels owns provider selection and serialized refresh gates instead of relying on process-global auth state.

Details

rho_memory_credential_store() keeps credentials for one R process. rho_file_credential_store() persists them as a versioned JSON document at an explicitly supplied path. rho_encrypted_file_credential_store() encrypts that document with an explicitly supplied passphrase or 32-byte key using Argon2id and XChaCha20-Poly1305. rho_keychain_credential_store() keeps each provider credential in the operating system's native keychain and rejects keyring's environment and file backends. File updates are serialized, replace the prior document, and use owner-only permissions where the platform supports them. rho_user_credential_path() returns R's platform-specific user configuration path without creating it.


Normalized assistant and provider event protocols

Description

Providers emit the typed AssistantEvent hierarchy. Provider-specific wire events are decoded and reduced through separate S7 generics, keeping wire formats out of the agent loop.


Message content and tool contracts

Description

Messages contain typed content objects rather than discriminator strings. Tool execution is asynchronous, and overlap is represented by an S7 value that the agent can dispatch on.


Semantic operations, handlers, and provider activity

Description

A RhoOperation states what a conversation may do. A handler binds that semantic request to a concrete implementation for the selected model. Bindings record both the handler and the reason it was selected; request translators turn bindings into provider wire values while encoding a request.

Details

Provider-hosted activity is normalized as Content, never as a local ToolCall. The agent can therefore retain and report a web search without placing it in its executable tool registry.


Models, providers, and capability operations

Description

Shared model facts live in typed capability, limits, and pricing objects. Provider-specific behavior is queried with typed operation values and S7 dispatch, avoiding a lowest-common-denominator boolean map.

Details

Provider turns are independent of byte transport. rho_stream() always returns normalized assistant events whether an implementation uses SSE, WebSocket, an embedded model, or a remote evaluator. ProviderTransport values describe executable strategies. AutomaticTransport is a selection policy rather than a model capability. rho_select_provider_transport() records the selected strategy and reason; rho_open_provider_transport() is the provider-open execution point.


Usage observations and nominal pricing

Description

ProviderUsage records token and cache counts supplied by a provider. EstimatedUsage records an explicitly named estimator and method. UsageUnavailable records that a provider did not supply counts; it has no fabricated token counts or cost. Usage components are disjoint: input excludes cache reads and writes, while output includes any reported reasoning tokens. reasoning is an optional breakdown of output; it is never added to total a second time. The optional cache_write_1h value is a subset of cache_write.

Details

rho_price_usage() is the open pricing protocol. Its default Model method selects the highest matching long-context tier, prices every component, and returns a new counted usage value with a NominalUsageCost. It does not claim to report a subscription charge. Model subclasses may provide methods for provider-specific pricing rules.

rho_summarize_usage() preserves every typed observation and reports disjoint token totals, nominal cost, and the latest cache-hit proportion. complete is false when any turn has UsageUnavailable; cost_complete is false when a counted turn has no nominal price. Zeroes therefore never hide missing provider data.


Anthropic Messages dialect

Description

Anthropic request construction is a reduction over typed request sections. Model catalog facts select thinking, temperature, cache, and tool-input capabilities; request methods never infer behavior from model names.

Details

AnthropicMessagesEndpoint separates the Messages dialect from endpoint authentication and transport. Anthropic and GitHub Copilot therefore share message translation and event reduction while retaining their own endpoint headers, URLs, and credentials.

Stream JSON is decoded once into typed wire events. S7 methods translate blocks, deltas, and stop reasons into the provider-neutral AssistantEvent protocol.


Asynchronous task and stream contracts

Description

Rho tasks represent one eventual value, while Rho streams represent an asynchronous sequence of typed stream items. Effectful callers compose tasks with rho_then() or coroutines and block only at rho_await().

Details

rho_new_state() and the concrete adapter task classes are exported for packages implementing new async backends. Polling actions return one of the typed RhoPollDecision subclasses; timing remains inside rho.async. rho_serial_queue() orders asynchronous actions without blocking the event loop. Cancelling a queued task removes only that entry; cancelling active work propagates to the task returned by its action.


Bio-agent extension registration

Description

This downstream package exposes bioinformatics manifests through ordinary Rho extension tools. It does not redefine provider or agent-core semantics.


Bioinformatics resource and operation contracts

Description

Manifests declare virtual resources, resolvers, term sets, and operations. Resolution is asynchronous and returns a ResolutionReceipt containing the selected resolver version, parameter digest, source snapshots, result handle, and provenance.

Details

rho.bio defines the generic SQL contract but does not depend on a database implementation or the agent packages.


Coding tools and their execution contracts

Description

The shell contract preserves Bash semantics across platforms and returns a typed resolution explaining which executable was selected. Shell processes execute through rho.compute and processx.

Details

R evaluation has explicit state semantics: RhoMiraiExpressionEvaluator is isolated and may overlap, while RhoCurrentSessionREvaluator receives a caller-supplied environment and requires exclusive scheduling.


Authored memory revisions and tools

Description

Authored memory is an append-only temporal port. rho_remember() creates a live note, rho_edit_memory() applies a typed edit only when its expected revision is still current, and rho_forget() appends a tombstone. Recall and history retain attribution and revision identity; no operation destroys an earlier observation.

Details

MemoryStore is the structural interface consumed by the coding tools. rho_in_memory_memory_store() is the process-local reference implementation. Other packages can implement the same generics over DuckDB, NNG, or another temporal observation store.

rho_memory_tools() returns remember, recall, edit_memory, forget, and memory_history. Mutating calls require an explicit author. Edit and forget require the revision identifier returned by recall, so a stale model action resolves to RhoMemoryConflict instead of overwriting newer work.


JSON session documents and the coding-host JSONL journal

Description

rho_json_session_codec() contains an explicit registry of stable semantic record types. A RhoJsonSemanticAdapter maps one stable wire tag and field set to the current in-memory S7 class. Package names, S7 class names, and reflected property sets are never written to the journal. An extension adds a value by supplying rho_json_semantic_adapter() with its own stable tag and explicit fields.

Details

rho_encode_session_value() and rho_decode_session_value() retain R atomic storage modes, list names, missing values, and registered semantic values. Unknown S7 objects resolve to RhoSessionCodecErrorValue rather than acquiring an accidental storage schema from the current package namespace.

rho_jsonl_session_journal() implements the SessionJournal interface as a coding-host adapter. File reads, locking, validation, and append run in mirai workers. Each LF-delimited entry record carries a committed position and typed entry document. A file lock and the append request's expected position reject stale writers before mutation. A missing final LF, malformed record, or invalid semantic document resolves to a typed error value.


Session journal, context, and compaction contracts

Description

A SessionJournal is the consumer-defined structural interface for committed session compare-and-append and snapshots. rho_memory_session_journal() is the process-local implementation. rho_agent() receives a journal explicitly; rho_sync_session() asynchronously projects an existing snapshot into an idle agent. Assistant streaming state remains in RhoAssistantTurn and only its terminal message is committed.

Details

The journal is append-only. Compare-and-append rejects a stale committed position before mutation. Message entries retain the complete interaction, reset entries begin a new active context without erasing history, and rho_build_agent_context() projects through the latest compaction entry and any explicit exclusions.

rho_compact() prepares a stable cut point, runs an asynchronous compactor, appends a semantic checkpoint, and invokes before/after policy methods. Automatic threshold compaction and one bounded provider-input recovery use the same protocol. Applications can supply another RhoCompactor class or specialize the public generics without replacing the agent loop.


Typed compute specifications and the mirai backend

Description

RhoComputeExpressionSpec carries captured R code plus an explicit named argument list. RhoComputeCallSpec carries a worker function plus explicit arguments, avoiding dynamically injected globals in calling packages. rho_submit_compute() is the backend extension point. The convenience functions rho_mirai_eval() and rho_mirai_call() construct the respective specifications and return RhoMiraiTask values.

Details

Worker failures resolve as RhoComputeErrorValue; they are values that downstream packages may translate through S7 dispatch.


DuckDB implementation of the Rho SQL contract

Description

Connections are explicit RhoDuckDbConn values. Queries and statements return tasks through the generic SQL API declared in rho.bio. rho_check_readonly_sql() is intentionally conservative and is not a substitute for the parser-backed guard required before accepting untrusted SQL. It returns a typed RhoSqlAccepted or RhoSqlRejected value. Database failures resolve to RhoDuckDbErrorValue rather than aborting the task.


Extension registration and asynchronous dispatch

Description

An extension receives RhoExtensionAPI and registers typed tools, providers, commands, or event handlers. rho_dispatch_event() normalizes an event pipeline to a task so asynchronous handlers remain part of the agent control flow.


Graphic specifications, devices, and artifacts

Description

Graphics are rendered from an explicit specification to an explicit device. rho_render_graphic() returns a task resolving to RhoGraphicArtifact or a typed RhoGraphicErrorValue. The mirai backend closes the graphics device before hashing the resulting file.

Details

Device and backend behavior are S7 generics so extension packages may add formats and renderers without changing this package.


Asynchronous HTTP and server-sent event contracts

Description

RhoHttpRequest is a typed request value. HttpClient requires rho_http_send() and rho_http_open_stream(). The latter resolves to a RhoHttpBodyStream after the response head arrives. RhoSseDecoder preserves protocol state across arbitrary byte chunks. rho_sse_connect() is the default composition over any RhoHttpClient implementation and exposes decoded RhoSseEvent values through the common Rho stream protocol. WebSocketClient is deliberately separate: an HTTP client does not imply that it can open a WebSocket. rho_ws_connect() resolves to a RhoWebSocket, an asynchronous duplex whose inbound values use the common stream protocol.

Details

rho_http_client() constructs the built-in RhoNanonextHttpClient. Its TLS configuration is created in memory by nanonext::tls_config(); this package does not search the host filesystem for certificate bundles. Another client subclasses RhoHttpClient, implements HttpClient, and returns its own RhoHttpBodyStream subclass with stream-next and close methods. Providers and SSE decoding do not depend on its connection handle.

rho_http_open_execution() reports where response-head opening runs. The built-in client returns RhoHttpAioOpen; a worker-owned implementation may return RhoHttpWorkerOpen. The inherited RhoHttpClient method deliberately returns RhoHttpCallerOpen until a subclass declares asynchronous opening. The latter records that constructing the response stream may occupy the calling R process even though later body reads are asynchronous.


Worker-owned httr2 and curl implementation of the Rho HTTP contract

Description

rho_httr2_http_client() constructs an HttpClient owned by a compute worker. Complete requests use httr2. For a streaming request, the worker uses curl's native multi event loop, captures the final response head before relaying its first body chunk, and sends typed head, raw chunk, completion, or error values over a private localhost NNG socket. The calling process receives those values through RhoTask and RhoStream without blocking its R event loop.

Details

Complete requests also execute through the selected compute backend. Closing a body stream or client closes its NNG socket and cancels the owning compute task. The default compute backend is mirai; callers may supply another RhoComputeBackend that preserves the same call specification semantics. rho_http_open_execution() returns RhoHttpWorkerOpen for this client because connection setup and receipt of the response head occur in that selected worker.


Kimi Platform provider

Description

Kimi Platform uses its own Chat Completions dialect. Its typed request methods preserve Kimi thinking controls, use max_completion_tokens, and accept explicit image content. The global and China endpoints remain separate providers because their credentials and model catalogs are scoped independently.


Runtime-compiled model catalog

Description

The catalog stores model facts as package data. rho_model_expression() turns a typed provider profile, protocol, and record into an inspectable R call. rho_compile_catalog_model() evaluates that call to produce the S7 model value used by provider dispatch. Extensions may add provider profiles, protocols, and expression methods without rewriting the catalog reader.

Details

Catalog refresh is an explicit development operation. Package installation and ordinary runtime use never contact a catalog service.


OpenAI-compatible Chat Completions stream protocol

Description

Chat Completions chunks are parsed into typed wire values and reduced by S7 methods to the normalized AssistantEvent protocol.


Typed OpenAI Responses request composition

Description

OpenAI request bodies are reductions over typed sections. Model-specific methods select the sections and their defaults; section methods alone emit wire field names and provider values. Extensions can specialize rho_openai_request_sections() for a model subclass or append a new OpenAIRequestSection with a rho_request_fields() method.

Details

Canonical thinking requests are values. ThinkingOff therefore dispatches separately from enabled levels without comparing provider wire strings.


Typed OpenAI Responses wire protocol

Description

The OpenAI Responses decoder maps JSON/SSE payloads to typed wire event and output-item classes before reducing them to normalized assistant events. Provider extensions may add narrower S7 methods for new item or event types.


Z.ai provider

Description

Z.ai uses the OpenAI-compatible Chat Completions protocol with explicit thinking preservation and tool-call streaming policies.