Get started

Research adapters

Research semantics belong to the bundled feature and provider plugins, not the Gateway or Plugin SDK. The feature's local typed contract binds explicitly to google.research.v1 over the existing trusted plugin RPC transport. Google validates its request and native response at ingress; the feature consumes the loaded provider's reply by reference. There is no new SDK adapter registry.

The feature owns logical jobs, polling, cancellation intent, recovery, budgets, and stable result publication. A provider owns its endpoint, authentication, remote handle and attribution parsing. describe distinguishes a full managed research service from ordinary native search tools. Search grounding alone is not a managed-research capability.

Requests use { version: 1, action: "describe" | "start" | "poll" | "cancel" }. Start carries question, optional output and asOf; poll/cancel carry the provider's opaque handle. RPC parameters wrap this as request, alongside sessionKey and agentId for the existing session-access policy. Responses have version: 1 and either ok: true, value or ok: false, state, reason. Unknown versions, shapes, services, and unsupported constraints fail explicitly.

Google is activated through plugins.entries.google.config.research, with enabled: true and an existing profileId. Registration loads no credentials and makes no network calls. The provider requires the same pinned API-key profile for start, poll and cancel. It rejects OAuth and profile substitution. The provider persists an interaction binding to the original agent, session, incarnation, profile, and credential account in its admitted plugin state. A caller-supplied handle is only an identifier, not authority. Poll and cancel reject foreign or stale owners before native HTTP; restarting with the same genuinely current owner can reuse the recorded interaction without another submission.

Every external effect checks current session and provider authority after preparation. Registered plugin RPC handlers receive assertHandlerCurrent() in their options: combine this live provider-owner fence with session authority and recheck after awaits and immediately before effects or report delivery. It retires when the provider owner retires, before in-flight cleanup drains. Cleanup hooks and possession of a remote handle do not authorize late publication.

A returned start receipt may be persisted as local bookkeeping under the live provider/service owners even when the source borrow has closed. Persist only its original binding and handle, never report content or permission to execute; later polling still needs fresh authority. A newer or terminal job must not be overwritten. If the provider owner retires or storage fails before its binding is committed, a returned handle cannot bypass the ownership check on a later poll or cancel. This receipt-before-binding window remains indeterminate and requires inspection at the original provider account; automatic recovery does not reconstruct custody from the handle alone or perform cancellation without current authority. The same local custody boundary can retain a definitive not-sent outcome before source delivery closes. A blocked start may include retryAfterMs only when the refusal is temporary; an indeterminate transport outcome never authorizes another submission. The feature bounds retries and reacquires authority each time, including when the initial describe probe receives a retryable refusal. The in-process dispatcher preserves canonical authority refusals from its own source preparation as structured RPC errors before method work begins. It does not reclassify errors from already-entered method work as proof of non-submission. isSessionAccessRefreshingError from openclaw/plugin-sdk/gateway-runtime recognizes only the canonical temporary session-preparation error. It is a bounded retry hint, not a grant. Permanent session revocation remains blocked.

Provider citations attribute generated report text; they are not fetched source passages. Their optional startByte/endByte offsets are UTF-8 bytes into the report. Adapters must omit thought/tool traces, bound their outputs, preserve partial states, and never infer successful cancellation from a successful HTTP response alone. A create without a recorded remote receipt or definitive not-sent outcome is indeterminate: there is no automatic submission retry without documented provider idempotency.

No consumer OAuth, Codex managed-research RPC, or cross-auth-mode proof is implied by this contract.

Was this useful?