Resource I/O
connectorRead and connectorWrite let agents (and muscles) read and write resources by kind and URI without coupling to a specific connector. The platform resolves which connector handles the kind and routes the operation.
Why connector-agnostic I/O?
Agents declare kinds (e.g. core.email.message), not "read from Gmail" or "write to Salesforce." Resource policies and the connector registry decide where data lives. So agent code calls connectorRead / connectorWrite with kind + URI (and for write, payload); the SDK and platform resolve the right connector and delegate the operation.
How it helps agent authors and operators: Agents don't care which connector backs a kind — one code path works for vault, SaaS, or self-hosted. Operators change policies or swap connectors without touching agent code.
connectorRead / connectorWrite
Both take a ResourceIOContext (your execution context) and an options object. Read returns ConnectorReadResult (data, connectorId, uri, kind). Write returns ConnectorWriteResult (ok, connectorId, uri, kind, meta).
import { connectorRead, connectorWrite } from '@human/connector-sdk';
// Inside an agent or a muscle (with ctx that satisfies ResourceIOContext):const result = await connectorRead(ctx, { kind: 'core.email.message', uri: 'resource://core/email/msg_abc123',});
// result: { data: { ... }, connectorId: 'vault', uri, kind }
await connectorWrite(ctx, { kind: 'core.meeting.notes', uri: 'resource://core/meeting/notes_xyz', data: { meeting_id: 'm1', notes: [...] },});// Resolves connector from policy + registry, writes through itResourceIOContext
The context must provide orgId, agentId, delegation, and log. The full Agent SDK ExecutionContext satisfies this.
import type { ResourceIOContext } from '@human/connector-sdk';
// Minimal context needed for resource I/O (ExecutionContext has this and more):interface ResourceIOContext { orgId: unknown; agentId: string; delegation: { id: string }; log: { warn(msg: string, meta?: object): void; error(msg: string, meta?: object): void };}Errors
ConnectorIOError is thrown when no connector is found for the kind, or when read/write fails. It includes code, kind, and uri.
import { ConnectorIOError } from '@human/connector-sdk';
try { const result = await connectorRead(ctx, { kind: 'core.health.ct_scan', uri });} catch (err) { if (err instanceof ConnectorIOError) { // err.code: 'NO_CONNECTOR' | 'READ_FAILED' | 'WRITE_FAILED' // err.kind, err.uri }}See also
- Kind support & resolution — how connectors declare kind_pattern and how resolution works.
- Agent resources — ctx.resources.load / save and kinds.