@rine-network/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Standalone org registration — REQ-01, REQ-02, REQ-03.
3
+ *
4
+ * Module-level function (not a client method) because credentials don't
5
+ * exist yet at registration time. Delegates to rine-core's
6
+ * `performRegistration` for the PoW + credential persistence flow.
7
+ */
8
+ import { validateSlug } from "@rine-network/core";
9
+ export { validateSlug };
10
+ export interface RegisterOptions {
11
+ /** API base URL (e.g. "https://rine.network"). */
12
+ apiUrl: string;
13
+ /** Path to the rine config directory for credential persistence. */
14
+ configDir: string;
15
+ /** Registration email address. */
16
+ email: string;
17
+ /** Organisation slug (validated client-side via `validateSlug`). */
18
+ slug: string;
19
+ /** Organisation display name. */
20
+ name: string;
21
+ /** Optional PoW progress callback — called with 0-100. */
22
+ onProgress?: (pct: number) => void;
23
+ }
24
+ /** Returned on successful registration. */
25
+ export interface RegistrationResult {
26
+ orgId: string;
27
+ clientId: string;
28
+ }
29
+ /**
30
+ * Register a new org on the Rine network.
31
+ *
32
+ * Solves the RSA time-lock proof-of-work, saves credentials to
33
+ * `{configDir}/credentials.json`, and caches the initial OAuth token.
34
+ *
35
+ * @throws {ValidationError} If the slug fails client-side validation.
36
+ * @throws {ConflictError} If the email or slug is already registered.
37
+ * @throws {RateLimitError} On 429 from the server.
38
+ * @throws {RineError} On PoW challenge expiry or other failures.
39
+ */
40
+ export declare function register(opts: RegisterOptions): Promise<RegistrationResult>;
@@ -0,0 +1,111 @@
1
+ /**
2
+ * `ConversationScope` — SPEC §11.2.
3
+ *
4
+ * A lightweight builder returned by `client.conversation(convId)` that
5
+ * auto-scopes `send`, `reply`, `messages`, and `history` to a single
6
+ * `conversation_id`. This is explicitly NOT the deferred "conversation
7
+ * management API" (SPEC §10.13) — no `metadata()` / `status()` /
8
+ * `participants()` methods in v0.1.
9
+ *
10
+ * Design notes:
11
+ *
12
+ * - `send()` routes through `client.reply(anchorMessageId, …)` when the
13
+ * scope was built from a message (the common case). The server's reply
14
+ * endpoint threads the new message into the original conversation.
15
+ * Scopes built from bare conversation id strings throw on `send()` —
16
+ * the old `parentConversationId` path only created sub-conversations.
17
+ *
18
+ * - `reply()` delegates straight through; the server infers the
19
+ * conversation from the parent message id. The scoped method exists
20
+ * for ergonomic symmetry (so agents inside the scope don't have to
21
+ * reach for `ctx.client.reply`).
22
+ *
23
+ * - `messages()` post-filters the agent-wide SSE stream by
24
+ * `conversation_id` — the server's stream endpoint is per-agent in
25
+ * v0.1, not per-conversation. When a server-side
26
+ * `GET /conversations/{id}/stream` ships, this method can switch
27
+ * transports without changing its public signature.
28
+ *
29
+ * - `history()` walks `client.inbox({ cursor, limit })` pages and drops
30
+ * items whose `conversation_id` does not match. Also a v0.1 trade
31
+ * (SPEC §11.2.2) — same migration story as `messages()`.
32
+ *
33
+ * Typed generics (`send<T>`, `messages<T>({ schema })`, etc.) landed in
34
+ * Step 19. The four methods thread a `<T = unknown>` generic and a
35
+ * `schema?: StandardSchemaV1<unknown, T>` slot so one schema written once
36
+ * narrows an entire conversation's payload type end-to-end.
37
+ */
38
+ import type { StandardSchemaV1 } from "@standard-schema/spec";
39
+ import type { AsyncRineClient, MessagesOptions, ReplyOptions } from "../client.js";
40
+ import { type AgentHandle, type AgentUuid, type DecryptedMessage, type GroupHandle, type GroupUuid, type MessageRead, type MessageUuid } from "../types.js";
41
+ type Recipient = AgentHandle | AgentUuid | GroupHandle | GroupUuid;
42
+ /** Options accepted by `ConversationScope.send` — maps to `ReplyOptions<T>`
43
+ * when the scope is message-anchored (the common case). */
44
+ export type ConversationSendOptions<T = unknown> = ReplyOptions<T>;
45
+ /** Options accepted by `ConversationScope.reply` — identical to `ReplyOptions<T>`. */
46
+ export type ConversationReplyOptions<T = unknown> = ReplyOptions<T>;
47
+ /** Options accepted by `ConversationScope.messages` — `MessagesOptions<T>`
48
+ * minus the `includeReserved` debug escape hatch, which is meaningless
49
+ * inside a scope that already drops everything except the pinned
50
+ * conversation. Using `Omit` keeps this type aligned with
51
+ * `MessagesOptions` for free as new fields land there. */
52
+ export type ConversationMessagesOptions<T = unknown> = Omit<MessagesOptions<T>, "includeReserved">;
53
+ export interface ConversationHistoryOptions<T = unknown> {
54
+ /** Page size forwarded to `client.inbox()`. Default: 50. */
55
+ limit?: number;
56
+ /** Starting cursor. Defaults to the first page. */
57
+ cursor?: string;
58
+ /** Hard cap on items yielded across all pages. Unbounded by default. */
59
+ maxItems?: number;
60
+ /** Agent override forwarded to `client.inbox()`. */
61
+ agent?: string;
62
+ signal?: AbortSignal;
63
+ /**
64
+ * Standard Schema v1 — narrows `plaintext` on every yielded message.
65
+ * A decrypt-failed envelope (with `decrypt_error`) is yielded untouched
66
+ * so callers can still observe the failure; a successful decrypt that
67
+ * fails schema validation throws `ValidationError` out of the generator.
68
+ */
69
+ schema?: StandardSchemaV1<unknown, T>;
70
+ }
71
+ export declare class ConversationScope {
72
+ private readonly client;
73
+ readonly id: string;
74
+ /**
75
+ * Peer auto-wired when the scope was built via `client.conversation(msg)`.
76
+ * When set, the two-arg `scope.send(payload)` form routes to this peer
77
+ * without requiring an explicit recipient. Null when the scope was
78
+ * built from a bare conversation id.
79
+ */
80
+ readonly peer: Recipient | null;
81
+ /**
82
+ * Anchor message id — set when the scope was built via
83
+ * `client.conversation(msg)`. When present, `scope.send()` routes
84
+ * through `client.reply(anchorMessageId, …)` so the server threads
85
+ * the new message into the existing conversation. Null when the
86
+ * scope was built from a bare conversation id string.
87
+ */
88
+ readonly anchorMessageId: MessageUuid | null;
89
+ constructor(client: AsyncRineClient, id: string, peer?: Recipient | null, anchorMessageId?: MessageUuid | null);
90
+ /**
91
+ * Send a message in this conversation.
92
+ *
93
+ * scope.send(to, payload) // explicit recipient
94
+ * scope.send(payload) // uses the peer derived from the
95
+ * // originating message
96
+ *
97
+ * When the scope was built via `client.conversation(msg)` (i.e. it has
98
+ * an `anchorMessageId`), sends route through `client.reply()` so the
99
+ * server threads the new message into the existing conversation. A scope
100
+ * built from a bare conversation id string throws — `parentConversationId`
101
+ * on `POST /messages` only creates sub-conversations, not threads.
102
+ */
103
+ send<T = unknown>(to: Recipient, payload: T, opts?: ConversationSendOptions<T>): Promise<MessageRead>;
104
+ send<T = unknown>(payload: T, opts?: ConversationSendOptions<T>): Promise<MessageRead>;
105
+ reply<T = unknown>(messageId: MessageUuid, payload: T, opts?: ConversationReplyOptions<T>): Promise<MessageRead>;
106
+ messages<T = unknown>(opts?: ConversationMessagesOptions<T>): AsyncIterable<DecryptedMessage<T>>;
107
+ history<T = unknown>(opts?: ConversationHistoryOptions<T>): AsyncIterable<DecryptedMessage<T>>;
108
+ private messagesGenerator;
109
+ private historyGenerator;
110
+ }
111
+ export {};
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Shared decryption helper used by `messages.inbox()`, `messages.read()`,
3
+ * `messages.sendAndWait()` (Phase 2), and `client.messages()` (§11.1).
4
+ *
5
+ * Dispatch is driven by `encryption_version`:
6
+ * - `hpke-v1` → `decryptMessage` (1:1, recipient's X25519 private key).
7
+ * - `sender-key-v1` → `decryptGroupMessage`. On a sender-key dispatch failure,
8
+ * optionally retries once after calling
9
+ * `fetchAndIngestPendingSKDistributions` (matches Python
10
+ * SDK `read()` discipline).
11
+ * - anything else → returned as-is with `decrypt_error` populated.
12
+ *
13
+ * Crypto failures (including the post-retry failure on the sender-key path)
14
+ * populate `decrypt_error` and do NOT throw — callers branch on
15
+ * `msg.decrypt_error !== null`. User cancellation (`AbortError`) is always
16
+ * re-thrown so a cancelled `inbox()` rejects cleanly instead of resolving
17
+ * with a page of "failed" items.
18
+ */
19
+ import { type HttpClient as CoreHttpClient } from "@rine-network/core";
20
+ import type { DecryptedMessage } from "../types.js";
21
+ /**
22
+ * Looser input shape accepted by `decryptEnvelope` and its helpers.
23
+ *
24
+ * The `parse(DecryptedMessageSchema, raw)` adapter erases Zod's precise
25
+ * output type through its `z.ZodType<T>` parameter, so the value we pass
26
+ * here is statically typed with a few fields still optional even though
27
+ * the Zod `.default()` chains guarantee them at runtime. Accepting the
28
+ * loose type avoids sprinkling `as` casts at every call site; the two
29
+ * `applyDecrypt*` helpers normalize the output back to the full
30
+ * `DecryptedMessage` shape before returning.
31
+ */
32
+ export type ParsedDecryptedMessage = Omit<DecryptedMessage, "metadata" | "verified" | "verification_status"> & {
33
+ metadata?: Record<string, unknown>;
34
+ verified?: boolean;
35
+ verification_status?: DecryptedMessage["verification_status"];
36
+ };
37
+ export interface DecryptEnvelopeOptions {
38
+ readonly core: CoreHttpClient;
39
+ readonly configDir: string;
40
+ readonly agentId: string;
41
+ readonly msg: ParsedDecryptedMessage;
42
+ readonly retrySenderKey?: boolean;
43
+ }
44
+ export declare function decryptEnvelope(opts: DecryptEnvelopeOptions): Promise<DecryptedMessage>;
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Discovery resource — discover, inspect, discoverGroups.
3
+ */
4
+ import type { SDKHttpClient } from "../api/http.js";
5
+ export interface DiscoverGroupsOptions {
6
+ q?: string;
7
+ limit?: number;
8
+ cursor?: string;
9
+ }
10
+ export interface DiscoveryFilters {
11
+ q?: string;
12
+ category?: string;
13
+ language?: string;
14
+ verified?: boolean;
15
+ limit?: number;
16
+ cursor?: string;
17
+ }
18
+ export declare class DiscoveryResource {
19
+ private readonly http;
20
+ constructor(http: SDKHttpClient);
21
+ discover(filters?: DiscoveryFilters): Promise<import("../index.js").CursorPage<{
22
+ id: string;
23
+ name: string;
24
+ handle: string;
25
+ verified: boolean;
26
+ description?: string | null | undefined;
27
+ category?: string | null | undefined;
28
+ }>>;
29
+ /**
30
+ * Fetch a directory agent profile and unwrap the A2A card envelope
31
+ *
32
+ *
33
+ * Accepts either a UUID (pass-through) or an agent handle
34
+ * (`name@org.rine.network`, resolved via WebFinger by
35
+ * `resolveToUuid`). The directory route only accepts UUIDs, so the
36
+ * handle lookup has to happen client-side.
37
+ *
38
+ * Server response shape:
39
+ * ```
40
+ * {
41
+ * card: { name, description, rine: { agent_id, handle, category, verified, human_oversight } },
42
+ * directory_metadata: { registered_at, ... }
43
+ * }
44
+ * ```
45
+ *
46
+ * Legacy flat shape is still accepted (the fallback `parse()` branch).
47
+ */
48
+ inspect(handleOrId: string): Promise<{
49
+ id: string;
50
+ name: string;
51
+ handle: string;
52
+ human_oversight: boolean;
53
+ verified: boolean;
54
+ created_at?: string | null | undefined;
55
+ description?: string | null | undefined;
56
+ category?: string | null | undefined;
57
+ }>;
58
+ discoverGroups(opts?: DiscoverGroupsOptions): Promise<import("../index.js").CursorPage<{
59
+ id: string;
60
+ name: string;
61
+ handle: string;
62
+ visibility: string;
63
+ member_count: number;
64
+ description?: string | null | undefined;
65
+ }>>;
66
+ }
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Groups resource — create, get, list, join, members, invite,
3
+ * update, delete, removeMember, listRequests, vote.
4
+ *
5
+ * Step 10 — Track B: routes + bodies aligned with server endpoints per
6
+ * SPEC §10.6. Handle-resolution (`_resolveGroupAsync`) is not added here
7
+ * (Step 11+), so UUID-only parameters remain the current limit.
8
+ */
9
+ import type { SDKHttpClient } from "../api/http.js";
10
+ import type { AgentUuid, GroupUuid, JoinRequestRead, JoinResult } from "../types.js";
11
+ export interface GroupCreateOptions {
12
+ description?: string;
13
+ enrollment?: "open" | "closed" | "majority" | "unanimity";
14
+ visibility?: "public" | "private";
15
+ signal?: AbortSignal;
16
+ }
17
+ export interface InviteOptions {
18
+ message?: string;
19
+ signal?: AbortSignal;
20
+ }
21
+ export interface GroupUpdateOptions {
22
+ description?: string;
23
+ enrollment?: "open" | "closed" | "majority" | "unanimity";
24
+ visibility?: "public" | "private";
25
+ voteDurationHours?: number;
26
+ signal?: AbortSignal;
27
+ }
28
+ export declare class GroupsResource {
29
+ private readonly http;
30
+ constructor(http: SDKHttpClient);
31
+ list(): Promise<import("../index.js").CursorPage<{
32
+ id: string;
33
+ name: string;
34
+ created_at: string;
35
+ handle: string;
36
+ enrollment_policy: string;
37
+ visibility: string;
38
+ isolated: boolean;
39
+ vote_duration_hours: number;
40
+ member_count: number;
41
+ description?: string | null | undefined;
42
+ }>>;
43
+ /**
44
+ * Create a new group. Two call styles:
45
+ *
46
+ * client.groups.create('my-group', { visibility: 'public' })
47
+ * client.groups.create({ name: 'my-group', visibility: 'public' })
48
+ *
49
+ * The options-bag form matches the rest of the SDK surface (`inbox`,
50
+ * `discover`, `sendAndWait`) and is the recommended ergonomic for
51
+ * first-time users; the positional form is kept for existing callers.
52
+ */
53
+ create(nameOrOpts: string | ({
54
+ name: string;
55
+ } & GroupCreateOptions), maybeOpts?: GroupCreateOptions): Promise<{
56
+ id: string;
57
+ name: string;
58
+ created_at: string;
59
+ handle: string;
60
+ enrollment_policy: string;
61
+ visibility: string;
62
+ isolated: boolean;
63
+ vote_duration_hours: number;
64
+ member_count: number;
65
+ description?: string | null | undefined;
66
+ }>;
67
+ get(groupId: GroupUuid): Promise<{
68
+ id: string;
69
+ name: string;
70
+ created_at: string;
71
+ handle: string;
72
+ enrollment_policy: string;
73
+ visibility: string;
74
+ isolated: boolean;
75
+ vote_duration_hours: number;
76
+ member_count: number;
77
+ description?: string | null | undefined;
78
+ }>;
79
+ /**
80
+ * Update group metadata.
81
+ *
82
+ * Route: `PATCH /groups/{id}` with body of camelCase → snake_case
83
+ * mapped fields. Previously missing from the TS SDK.
84
+ */
85
+ update(groupId: GroupUuid, opts: GroupUpdateOptions): Promise<{
86
+ id: string;
87
+ name: string;
88
+ created_at: string;
89
+ handle: string;
90
+ enrollment_policy: string;
91
+ visibility: string;
92
+ isolated: boolean;
93
+ vote_duration_hours: number;
94
+ member_count: number;
95
+ description?: string | null | undefined;
96
+ }>;
97
+ /**
98
+ * Delete a group (owner only). Previously missing from the TS SDK.
99
+ */
100
+ delete(groupId: GroupUuid, opts?: {
101
+ signal?: AbortSignal;
102
+ }): Promise<void>;
103
+ join(groupId: GroupUuid, opts?: {
104
+ message?: string;
105
+ signal?: AbortSignal;
106
+ }): Promise<JoinResult>;
107
+ invite(groupId: GroupUuid, agentId: AgentUuid, opts?: InviteOptions): Promise<{
108
+ status: string;
109
+ request_id?: string | null | undefined;
110
+ }>;
111
+ /**
112
+ * Remove a member from a group. Previously missing from the TS SDK.
113
+ *
114
+ * Route: `DELETE /groups/{groupId}/members/{agentId}`.
115
+ */
116
+ removeMember(groupId: GroupUuid, agentId: AgentUuid, opts?: {
117
+ signal?: AbortSignal;
118
+ }): Promise<void>;
119
+ members(groupId: GroupUuid): Promise<import("../index.js").CursorPage<{
120
+ group_id: string;
121
+ agent_id: string;
122
+ role: string;
123
+ joined_at: string;
124
+ id?: string | null | undefined;
125
+ agent_handle?: string | null | undefined;
126
+ }>>;
127
+ /**
128
+ * List pending join requests for a group.
129
+ *
130
+ * Route: `GET /groups/{groupId}/requests` (fixes parity gap — TS
131
+ * previously used `/join-requests`). Returns a plain array to match
132
+ * Python SDK `groups.list_requests`.
133
+ */
134
+ listRequests(groupId: GroupUuid): Promise<readonly JoinRequestRead[]>;
135
+ /**
136
+ * Vote on a pending join request (fixes audit C-adjacent — missing
137
+ * group segment).
138
+ *
139
+ * Route: `POST /groups/{groupId}/requests/{requestId}/vote`.
140
+ */
141
+ vote(groupId: GroupUuid, requestId: string, choice: "approve" | "deny"): Promise<{
142
+ status: string;
143
+ your_vote: string;
144
+ request_id: string;
145
+ }>;
146
+ }
@@ -0,0 +1,272 @@
1
+ /**
2
+ * Identity resource — whoami, createAgent, listAgents, getAgent, updateAgent,
3
+ * revokeAgent, rotateKeys, agent cards, poll tokens, quotas.
4
+ */
5
+ import type { SDKHttpClient } from "../api/http.js";
6
+ import type { AgentUuid, ErasureResult, OrgRead } from "../types.js";
7
+ export interface CreateAgentOptions {
8
+ human_oversight?: boolean;
9
+ unlisted?: boolean;
10
+ signal?: AbortSignal;
11
+ }
12
+ export interface RotateKeysOptions {
13
+ signal?: AbortSignal;
14
+ }
15
+ export type UpdateAgentPatch = {
16
+ name?: string;
17
+ human_oversight?: boolean;
18
+ incoming_policy?: "accept_all" | "groups_only";
19
+ outgoing_policy?: "send_all" | "groups_only";
20
+ unlisted?: boolean;
21
+ };
22
+ export interface UpdateOrgPatch {
23
+ name?: string;
24
+ contact_email?: string;
25
+ country_code?: string;
26
+ slug?: string;
27
+ }
28
+ export interface EraseOrgOptions {
29
+ confirm: boolean;
30
+ signal?: AbortSignal;
31
+ }
32
+ export interface AgentCardInput {
33
+ name: string;
34
+ description: string;
35
+ version?: string;
36
+ is_public?: boolean;
37
+ skills?: Array<{
38
+ id: string;
39
+ name: string;
40
+ description: string;
41
+ tags?: string[];
42
+ }>;
43
+ categories?: string[];
44
+ languages?: string[];
45
+ pricing_model?: "free" | "per_request" | "subscription" | "negotiated";
46
+ }
47
+ export declare class IdentityResource {
48
+ private readonly http;
49
+ constructor(http: SDKHttpClient);
50
+ /**
51
+ * Fetch the current org identity, agent list, and trust tier.
52
+ *
53
+ * Routes: `GET /agents` + `GET /org` — the server does not expose a
54
+ * single `/agents/whoami` endpoint; the Python SDK makes both calls and
55
+ * composes the `WhoAmI` client-side (`_client.py:605-621`). This TS
56
+ * implementation mirrors that exactly.
57
+ */
58
+ whoami(opts?: {
59
+ signal?: AbortSignal;
60
+ }): Promise<{
61
+ trust_tier: number;
62
+ org: {
63
+ id: string;
64
+ name: string;
65
+ trust_tier: number;
66
+ agent_count: number;
67
+ created_at: string;
68
+ slug?: string | null | undefined;
69
+ contact_email?: string | null | undefined;
70
+ country_code?: string | null | undefined;
71
+ };
72
+ agents: {
73
+ id: string;
74
+ name: string;
75
+ created_at: string;
76
+ handle: string;
77
+ human_oversight: boolean;
78
+ incoming_policy: string;
79
+ outgoing_policy: string;
80
+ revoked_at?: string | null | undefined;
81
+ unlisted?: boolean | undefined;
82
+ verification_words?: string | null | undefined;
83
+ warnings?: string[] | null | undefined;
84
+ poll_url?: string | null | undefined;
85
+ }[];
86
+ }>;
87
+ /**
88
+ * Create a new agent with locally generated E2EE keypairs.
89
+ *
90
+ * Matches Python `rine._onboard.create_agent` flow:
91
+ * 1. Generate Ed25519 + X25519 keypairs via rine-core `generateAgentKeys()`.
92
+ * 2. POST `/agents` with `{name, human_oversight, unlisted, signing_public_key,
93
+ * encryption_public_key}` (public keys as JWKs). The server's `AgentCreate`
94
+ * schema is `extra="forbid"`, so no other fields may be sent on creation.
95
+ * 3. Persist private keys under `{configDir}/keys/{agentId}/` via
96
+ * rine-core `saveAgentKeys()` so the new agent can immediately participate
97
+ * in E2EE send/receive without any manual key setup.
98
+ *
99
+ * Partial failure: if the POST succeeds but `saveAgentKeys` throws, the
100
+ * server-side agent exists but the caller has no private keys — surfaced
101
+ * as the raw I/O error. Callers must treat this as a partial failure.
102
+ */
103
+ createAgent(name: string, opts?: CreateAgentOptions): Promise<{
104
+ id: string;
105
+ name: string;
106
+ created_at: string;
107
+ handle: string;
108
+ human_oversight: boolean;
109
+ incoming_policy: string;
110
+ outgoing_policy: string;
111
+ revoked_at?: string | null | undefined;
112
+ unlisted?: boolean | undefined;
113
+ verification_words?: string | null | undefined;
114
+ warnings?: string[] | null | undefined;
115
+ poll_url?: string | null | undefined;
116
+ }>;
117
+ listAgents(opts?: {
118
+ includeRevoked?: boolean;
119
+ }): Promise<{
120
+ id: string;
121
+ name: string;
122
+ created_at: string;
123
+ handle: string;
124
+ human_oversight: boolean;
125
+ incoming_policy: string;
126
+ outgoing_policy: string;
127
+ revoked_at?: string | null | undefined;
128
+ unlisted?: boolean | undefined;
129
+ verification_words?: string | null | undefined;
130
+ warnings?: string[] | null | undefined;
131
+ poll_url?: string | null | undefined;
132
+ }[]>;
133
+ getAgent(agentId: AgentUuid): Promise<{
134
+ id: string;
135
+ name: string;
136
+ created_at: string;
137
+ handle: string;
138
+ human_oversight: boolean;
139
+ incoming_policy: string;
140
+ outgoing_policy: string;
141
+ revoked_at?: string | null | undefined;
142
+ unlisted?: boolean | undefined;
143
+ verification_words?: string | null | undefined;
144
+ warnings?: string[] | null | undefined;
145
+ poll_url?: string | null | undefined;
146
+ }>;
147
+ updateAgent(agentId: AgentUuid, patch: UpdateAgentPatch): Promise<{
148
+ id: string;
149
+ name: string;
150
+ created_at: string;
151
+ handle: string;
152
+ human_oversight: boolean;
153
+ incoming_policy: string;
154
+ outgoing_policy: string;
155
+ revoked_at?: string | null | undefined;
156
+ unlisted?: boolean | undefined;
157
+ verification_words?: string | null | undefined;
158
+ warnings?: string[] | null | undefined;
159
+ poll_url?: string | null | undefined;
160
+ }>;
161
+ revokeAgent(agentId: AgentUuid): Promise<{
162
+ id: string;
163
+ name: string;
164
+ created_at: string;
165
+ handle: string;
166
+ human_oversight: boolean;
167
+ incoming_policy: string;
168
+ outgoing_policy: string;
169
+ revoked_at?: string | null | undefined;
170
+ unlisted?: boolean | undefined;
171
+ verification_words?: string | null | undefined;
172
+ warnings?: string[] | null | undefined;
173
+ poll_url?: string | null | undefined;
174
+ }>;
175
+ /**
176
+ * Rotate this agent's signing + encryption keypairs.
177
+ *
178
+ * Route: `POST /agents/{id}/keys`.
179
+ *
180
+ * Generates fresh Ed25519 + X25519 keypairs locally, uploads the public
181
+ * halves to the server (JWK-encoded), then overwrites the on-disk private
182
+ * keys via `saveAgentKeys()`. Matches Python `AsyncRineClient.rotate_keys`
183
+ * flow.
184
+ *
185
+ * Key rotation is visible to future peers immediately; messages encrypted
186
+ * to the previous encryption key can still be decrypted as long as the
187
+ * caller retains a copy of the old private key out-of-band (the SDK does
188
+ * not keep a history of rotated-out keys).
189
+ *
190
+ * Partial failure: if the POST succeeds but `saveAgentKeys` throws mid-write,
191
+ * the server has the new public keys while the on-disk state may be
192
+ * inconsistent (`saveAgentKeys` writes signing.key then encryption.key as
193
+ * two separate file ops, not atomically). Senders will encrypt to the new
194
+ * keys the server advertises but the client may still hold the old private
195
+ * half — silent decryption failure. Track as rine-core follow-up.
196
+ */
197
+ rotateKeys(agentId: AgentUuid, opts?: RotateKeysOptions): Promise<{
198
+ id: string;
199
+ name: string;
200
+ created_at: string;
201
+ handle: string;
202
+ human_oversight: boolean;
203
+ incoming_policy: string;
204
+ outgoing_policy: string;
205
+ revoked_at?: string | null | undefined;
206
+ unlisted?: boolean | undefined;
207
+ verification_words?: string | null | undefined;
208
+ warnings?: string[] | null | undefined;
209
+ poll_url?: string | null | undefined;
210
+ }>;
211
+ getAgentCard(agentId: AgentUuid): Promise<{
212
+ id: string;
213
+ name: string;
214
+ created_at: string;
215
+ agent_id: string;
216
+ is_public: boolean;
217
+ skills: Record<string, unknown>[];
218
+ rine: Record<string, unknown>;
219
+ description?: string | null | undefined;
220
+ version?: string | null | undefined;
221
+ updated_at?: string | null | undefined;
222
+ }>;
223
+ /**
224
+ * Upsert an agent card.
225
+ *
226
+ * Body shape: `{name, description, version?, is_public?, skills?, rine?}`
227
+ * where `categories`, `languages` and `pricing_model` are nested inside
228
+ * the `rine` sub-object — matches Python exactly. The previous TS
229
+ * flattened everything, which the server silently dropped.
230
+ */
231
+ setAgentCard(agentId: AgentUuid, card: AgentCardInput): Promise<{
232
+ id: string;
233
+ name: string;
234
+ created_at: string;
235
+ agent_id: string;
236
+ is_public: boolean;
237
+ skills: Record<string, unknown>[];
238
+ rine: Record<string, unknown>;
239
+ description?: string | null | undefined;
240
+ version?: string | null | undefined;
241
+ updated_at?: string | null | undefined;
242
+ }>;
243
+ deleteAgentCard(agentId: AgentUuid): Promise<void>;
244
+ /**
245
+ * Regenerate the agent's poll token.
246
+ *
247
+ * Route: `POST /agents/{id}/poll-token` — the old `/poll-token/regenerate`
248
+ * path never existed on the server.
249
+ */
250
+ regeneratePollToken(agentId: AgentUuid): Promise<{
251
+ poll_url: string;
252
+ }>;
253
+ revokePollToken(agentId: AgentUuid): Promise<void>;
254
+ getQuotas(): Promise<{
255
+ tier: number;
256
+ quotas: Record<string, {
257
+ limit: number | null;
258
+ used?: number | null | undefined;
259
+ }>;
260
+ }>;
261
+ /** Lazy-cached org ID for erase/export URL paths. */
262
+ private cachedOrgId;
263
+ /** Fetch the caller's org UUID, caching on the instance. */
264
+ private getOrgId;
265
+ updateOrg(patch: UpdateOrgPatch, opts?: {
266
+ signal?: AbortSignal;
267
+ }): Promise<OrgRead>;
268
+ eraseOrg(opts: EraseOrgOptions): Promise<ErasureResult>;
269
+ exportOrg(opts?: {
270
+ signal?: AbortSignal;
271
+ }): Promise<unknown[]>;
272
+ }