@rine-network/eve 0.2.0 → 0.3.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.
- package/README.md +1 -1
- package/dist/_zod.d.ts +1 -1
- package/dist/{channel-b0iIAZTh.js → channel-WlN3x1wP.js} +19 -19
- package/dist/channel-core.d.ts +5 -5
- package/dist/channel-outbound.d.ts +3 -3
- package/dist/channel.d.ts +4 -4
- package/dist/channel.js +1 -1
- package/dist/{client-X_-9CpQT.js → client-DsG2xtKs.js} +2 -2
- package/dist/client.d.ts +2 -2
- package/dist/errors.d.ts +1 -1
- package/dist/format.d.ts +8 -4
- package/dist/inbound.d.ts +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +7 -7
- package/dist/onboard.d.ts +1 -1
- package/dist/onboard.js +1 -1
- package/dist/{registry-6sWyhOyF.js → registry-Bn4EqPcp.js} +10 -0
- package/dist/relay.d.ts +1 -1
- package/dist/relay.js +2 -2
- package/dist/{scaffold-0luQyBRK.js → scaffold-3cEUy3jD.js} +3 -2
- package/dist/scaffold.js +1 -1
- package/dist/schemas-groups.d.ts +14 -2
- package/dist/schemas-payments.d.ts +2 -2
- package/dist/schemas.d.ts +2 -2
- package/dist/skill-content.d.ts +2 -2
- package/dist/{tool-BC49DldZ.js → tool-xlLdY8kn.js} +29 -12
- package/dist/tool.d.ts +7 -7
- package/dist/tools/groups.d.ts +11 -2
- package/dist/tools/index.d.ts +2 -2
- package/dist/tools/index.js +3 -3
- package/dist/tools/messaging.d.ts +1 -1
- package/dist/{tools-BcVm_Onx.js → tools-BhkhV3Mv.js} +71 -11
- package/dist/transcript.d.ts +2 -2
- package/dist/types.d.ts +3 -1
- package/dist/webhook.d.ts +1 -1
- package/dist/webhook.js +2 -2
- package/dist/x402.d.ts +3 -3
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -102,7 +102,7 @@ undecryptable mail is dropped by default.
|
|
|
102
102
|
| `rine_reply` | Reply to a message by id, in-thread |
|
|
103
103
|
| `rine_thread` | Decrypted both-sided transcript of a conversation |
|
|
104
104
|
| `rine_discover` / `rine_inspect` | Search the directory / read a profile |
|
|
105
|
-
| `rine_group_create` / `_invite` / `_remove` / `_inspect` | MLS-by-default groups |
|
|
105
|
+
| `rine_group_create` / `_invite` / `_remove` / `_inspect` / `_join` / `_invites` | MLS-by-default groups |
|
|
106
106
|
| `rine_pay` | Pay a received `rine.v1.x402_payment_required` quote under the local spend policy |
|
|
107
107
|
| `rine_fulfill` | Payee side: verify + settle a received payment and reply with a receipt |
|
|
108
108
|
|
package/dist/_zod.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* accuracy) and parse the raw model input with the zod schema inside `execute`
|
|
10
10
|
* (applying defaults + coercion). One source of truth (zod), version-independent.
|
|
11
11
|
*
|
|
12
|
-
* Every tool's `outputSchema` is `string`
|
|
12
|
+
* Every tool's `outputSchema` is `string` — a tool returns clean text, so
|
|
13
13
|
* ciphertext can never ride a struct field.
|
|
14
14
|
*/
|
|
15
15
|
import { z, type ZodTypeAny } from "zod";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { b as verifiedNote, m as renderMessageBody, n as asRecipient, v as renderThreadLine, y as senderLabel } from "./tool-xlLdY8kn.js";
|
|
2
2
|
import { n as verifyRineSignature } from "./hmac-CoaKHmf6.js";
|
|
3
|
-
import { t as getRineClient } from "./client-
|
|
3
|
+
import { t as getRineClient } from "./client-DsG2xtKs.js";
|
|
4
4
|
import { POST, defineChannel } from "eve/channels";
|
|
5
5
|
import { X402Error, X402_MESSAGE_TYPE, asMessageUuid } from "@rine-network/sdk";
|
|
6
6
|
//#region src/transcript.ts
|
|
7
|
-
/** char ≈ 4 × tokens — the coarse proxy the spec specifies
|
|
7
|
+
/** char ≈ 4 × tokens — the coarse proxy the spec specifies. */
|
|
8
8
|
const CHARS_PER_TOKEN = 4;
|
|
9
9
|
/** Marker prepended when older turns were dropped to fit the budget. */
|
|
10
10
|
const OMITTED_MARKER = "[…earlier turns omitted]";
|
|
@@ -40,14 +40,14 @@ function renderTranscriptContext(entries, tokenBudget) {
|
|
|
40
40
|
* Inbound webhook helpers for the rine channel: extracting the message id from a
|
|
41
41
|
* rine standard-webhook body, and the continuation-token codec.
|
|
42
42
|
*
|
|
43
|
-
* The continuation token is how the channel makes outbound replies STATELESS
|
|
43
|
+
* The continuation token is how the channel makes outbound replies STATELESS:
|
|
44
44
|
* it encodes the rine `conversation_id`, the reply target (the group handle for
|
|
45
45
|
* group mail, else the sender handle), and — for 1:1 inbound only — the inbound
|
|
46
46
|
* `message id` so the `message.completed` handler can reply IN-PLACE (via the reply
|
|
47
47
|
* endpoint, preserving the inbound conversation) without any durable per-session map.
|
|
48
48
|
* Because the token bakes in the per-message `m`, it differs on every 1:1 inbound
|
|
49
49
|
* turn, so Eve does NOT resume a prior session from it — cross-turn continuity comes
|
|
50
|
-
* from the general thread primitive (push-injected transcript
|
|
50
|
+
* from the general thread primitive (push-injected transcript), not session
|
|
51
51
|
* resume. The message id is optional: group inbound and tokens minted by an older
|
|
52
52
|
* build carry only `{c,r}` and decode with `messageId === undefined`, so the outbound
|
|
53
53
|
* handler falls back to the `send()+parentConversationId` broadcast path.
|
|
@@ -133,7 +133,7 @@ function messageIdFromWebhook(body) {
|
|
|
133
133
|
//#endregion
|
|
134
134
|
//#region src/x402.ts
|
|
135
135
|
/**
|
|
136
|
-
* x402 payment-aware inbound re-surfacing for the rine channel
|
|
136
|
+
* x402 payment-aware inbound re-surfacing for the rine channel.
|
|
137
137
|
*
|
|
138
138
|
* The three x402 payment frames are first-class message types carrying a verbatim
|
|
139
139
|
* x402 V2 object, NOT a chat turn. v1.0 dropped them wholesale (a stateless gateway
|
|
@@ -146,7 +146,7 @@ function messageIdFromWebhook(body) {
|
|
|
146
146
|
* - `x402_payment` → the signed authorization + guidance to `rine_fulfill`.
|
|
147
147
|
* - `x402_receipt` → the settlement outcome, informational (no reply).
|
|
148
148
|
*
|
|
149
|
-
*
|
|
149
|
+
* Auto-pay (opt-in, DEFAULT OFF): when enabled, a `payment_required` at/below the
|
|
150
150
|
* policy's `autoPayThreshold` is paid with NO LLM turn — still bounded by the policy
|
|
151
151
|
* caps, deny-by-default, journal and reserve-lock (all in rine-core). Any decline
|
|
152
152
|
* falls back to surfacing the quote to the model.
|
|
@@ -200,7 +200,7 @@ function x402GuidanceLine(msg) {
|
|
|
200
200
|
return `x402 receipt from ${who} (${note}). This is informational — no reply is expected.`;
|
|
201
201
|
}
|
|
202
202
|
/**
|
|
203
|
-
*
|
|
203
|
+
* Auto-pay attempt. Returns `null` when the quote was paid (no session needed),
|
|
204
204
|
* or a one-line decline note when auto-pay was refused or errored (the caller then
|
|
205
205
|
* surfaces the quote to the model). A policy refusal / above-threshold quote is a
|
|
206
206
|
* typed {@link X402Error}; anything else (network, wallet) is reported verbatim.
|
|
@@ -232,7 +232,7 @@ async function surfaceX402(deps, msg, messageId, note) {
|
|
|
232
232
|
return new Response("ok", { status: 200 });
|
|
233
233
|
}
|
|
234
234
|
/**
|
|
235
|
-
* Handle a verified inbound x402 frame
|
|
235
|
+
* Handle a verified inbound x402 frame. `payment_required` may auto-pay
|
|
236
236
|
* when enabled and at/below threshold; otherwise, and for `payment` / `receipt`,
|
|
237
237
|
* the frame is surfaced to the model as a payment-aware turn.
|
|
238
238
|
*/
|
|
@@ -256,9 +256,9 @@ async function handleX402Inbound(deps, msg, messageId) {
|
|
|
256
256
|
* `defineChannel` route; the OUTBOUND half (`processCompletion`/`processFailure`)
|
|
257
257
|
* lives in `channel-outbound.ts`.
|
|
258
258
|
*
|
|
259
|
-
* - INBOUND (`processInbound`): HMAC-verify (transport auth
|
|
259
|
+
* - INBOUND (`processInbound`): HMAC-verify (transport auth) → parse → dedupe
|
|
260
260
|
* → `client.read(id)` to HPKE-decrypt + verify the sender's Ed25519 signature
|
|
261
|
-
* (content auth
|
|
261
|
+
* (content auth) → loop-guard → mark delivered → start/resume the session.
|
|
262
262
|
*
|
|
263
263
|
* TRUST NOTE: `verified === true` cryptographically binds the message's *signer*
|
|
264
264
|
* (the envelope `kid`), but the SDK exposes only the server-asserted
|
|
@@ -272,11 +272,11 @@ function senderContextLine(msg) {
|
|
|
272
272
|
const where = msg.group_handle ? ` in group ${msg.group_handle}` : "";
|
|
273
273
|
return `Inbound rine message from ${senderLabel(msg)}${where} (type ${msg.type}, ${verifiedNote(msg)}). Your reply is delivered back to the sender over rine.`;
|
|
274
274
|
}
|
|
275
|
-
/** Cap on turns fetched for the push-injected transcript
|
|
275
|
+
/** Cap on turns fetched for the push-injected transcript. */
|
|
276
276
|
const THREAD_FETCH_LIMIT = 50;
|
|
277
277
|
/**
|
|
278
278
|
* The inbound pipeline. Returns the HTTP {@link Response} the route should send.
|
|
279
|
-
* Status codes are retry-aware
|
|
279
|
+
* Status codes are retry-aware: `5xx` = transient (caller should retry),
|
|
280
280
|
* `4xx` = terminal drop, `2xx` = accepted/benign-ignore.
|
|
281
281
|
*/
|
|
282
282
|
async function processInbound(deps) {
|
|
@@ -331,15 +331,15 @@ async function processInbound(deps) {
|
|
|
331
331
|
* unit-testable with fake clients. `channel.ts` wires these to Eve's
|
|
332
332
|
* `message.completed` / failure events; the INBOUND half lives in `channel-core.ts`.
|
|
333
333
|
*
|
|
334
|
-
* On a terminal assistant message
|
|
335
|
-
* endpoint, preserving the inbound conversation
|
|
334
|
+
* On a terminal assistant message, reply back over rine IN-PLACE via the reply
|
|
335
|
+
* endpoint, preserving the inbound conversation; falls back to
|
|
336
336
|
* `parentConversationId` for legacy tokens. A session started by an x402 frame never
|
|
337
337
|
* prose-replies into the payment thread (the pay / fulfill tools transmit the signed
|
|
338
338
|
* frame in-thread instead) — the `x402` continuation-token flag short-circuits both.
|
|
339
339
|
*/
|
|
340
340
|
/**
|
|
341
341
|
* Outbound for `message.completed`: every TERMINAL assistant message (any
|
|
342
|
-
* `finishReason` except the intermediate `tool-calls
|
|
342
|
+
* `finishReason` except the intermediate `tool-calls`) with text becomes a
|
|
343
343
|
* reply. When the continuation token carries the inbound message id we reply
|
|
344
344
|
* IN-PLACE via the reply endpoint (same conversation, no fork) keeping the
|
|
345
345
|
* connector's `replyMessageType` unchanged — type-preserving, so terminal/wake
|
|
@@ -386,15 +386,15 @@ async function processFailure(continuationToken, client) {
|
|
|
386
386
|
const DEFAULT_INBOUND_PATH = "/rine/v1/inbound";
|
|
387
387
|
const DEFAULT_REPLY_TYPE = "rine.v1.task_response";
|
|
388
388
|
const DEFAULT_MAX_BODY_BYTES = 512 * 1024;
|
|
389
|
-
/** Default token budget for the push-injected transcript (
|
|
389
|
+
/** Default token budget for the push-injected transcript (≈8000 chars). */
|
|
390
390
|
const DEFAULT_THREAD_CONTEXT_TOKEN_BUDGET = 2e3;
|
|
391
391
|
/**
|
|
392
|
-
* Message types never auto-replied to (loop guard
|
|
392
|
+
* Message types never auto-replied to (loop guard): the connector's OWN
|
|
393
393
|
* outbound types (task_response/error/receipt), so two rine-eve agents don't
|
|
394
394
|
* auto-reply to each other forever.
|
|
395
395
|
*
|
|
396
396
|
* The three x402 payment frames are NOT here: v1.1 re-surfaces them as
|
|
397
|
-
* payment-aware agent turns
|
|
397
|
+
* payment-aware agent turns, routed by `handleX402Inbound` with the prose
|
|
398
398
|
* auto-reply suppressed (the `x402` continuation-token flag), never by the generic
|
|
399
399
|
* assistant reply. Adding them here would revert to the v1.0 silent-drop behavior.
|
|
400
400
|
*/
|
package/dist/channel-core.d.ts
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* `defineChannel` route; the OUTBOUND half (`processCompletion`/`processFailure`)
|
|
5
5
|
* lives in `channel-outbound.ts`.
|
|
6
6
|
*
|
|
7
|
-
* - INBOUND (`processInbound`): HMAC-verify (transport auth
|
|
7
|
+
* - INBOUND (`processInbound`): HMAC-verify (transport auth) → parse → dedupe
|
|
8
8
|
* → `client.read(id)` to HPKE-decrypt + verify the sender's Ed25519 signature
|
|
9
|
-
* (content auth
|
|
9
|
+
* (content auth) → loop-guard → mark delivered → start/resume the session.
|
|
10
10
|
*
|
|
11
11
|
* TRUST NOTE: `verified === true` cryptographically binds the message's *signer*
|
|
12
12
|
* (the envelope `kid`), but the SDK exposes only the server-asserted
|
|
@@ -41,7 +41,7 @@ export interface InboundDeps {
|
|
|
41
41
|
/** Inbound types to ignore (loop guard). */
|
|
42
42
|
ignoreTypes: readonly string[];
|
|
43
43
|
/**
|
|
44
|
-
*
|
|
44
|
+
* Opt-in auto-pay (default OFF). When true, an inbound `x402_payment_required`
|
|
45
45
|
* at/below the policy's `autoPayThreshold` is paid with NO LLM turn — still
|
|
46
46
|
* bounded by the caps, deny-by-default, journal and reserve-lock. Any decline
|
|
47
47
|
* falls back to surfacing the quote to the model.
|
|
@@ -51,13 +51,13 @@ export interface InboundDeps {
|
|
|
51
51
|
seen?: Set<string>;
|
|
52
52
|
/**
|
|
53
53
|
* Approximate token budget for the role-tagged transcript push-injected into the
|
|
54
|
-
* session context
|
|
54
|
+
* session context. When unset, only the sender line is injected.
|
|
55
55
|
*/
|
|
56
56
|
threadContextTokenBudget?: number;
|
|
57
57
|
}
|
|
58
58
|
/**
|
|
59
59
|
* The inbound pipeline. Returns the HTTP {@link Response} the route should send.
|
|
60
|
-
* Status codes are retry-aware
|
|
60
|
+
* Status codes are retry-aware: `5xx` = transient (caller should retry),
|
|
61
61
|
* `4xx` = terminal drop, `2xx` = accepted/benign-ignore.
|
|
62
62
|
*/
|
|
63
63
|
export declare function processInbound(deps: InboundDeps): Promise<Response>;
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* unit-testable with fake clients. `channel.ts` wires these to Eve's
|
|
4
4
|
* `message.completed` / failure events; the INBOUND half lives in `channel-core.ts`.
|
|
5
5
|
*
|
|
6
|
-
* On a terminal assistant message
|
|
7
|
-
* endpoint, preserving the inbound conversation
|
|
6
|
+
* On a terminal assistant message, reply back over rine IN-PLACE via the reply
|
|
7
|
+
* endpoint, preserving the inbound conversation; falls back to
|
|
8
8
|
* `parentConversationId` for legacy tokens. A session started by an x402 frame never
|
|
9
9
|
* prose-replies into the payment thread (the pay / fulfill tools transmit the signed
|
|
10
10
|
* frame in-thread instead) — the `x402` continuation-token flag short-circuits both.
|
|
@@ -19,7 +19,7 @@ export interface CompletionDeps {
|
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* Outbound for `message.completed`: every TERMINAL assistant message (any
|
|
22
|
-
* `finishReason` except the intermediate `tool-calls
|
|
22
|
+
* `finishReason` except the intermediate `tool-calls`) with text becomes a
|
|
23
23
|
* reply. When the continuation token carries the inbound message id we reply
|
|
24
24
|
* IN-PLACE via the reply endpoint (same conversation, no fork) keeping the
|
|
25
25
|
* connector's `replyMessageType` unchanged — type-preserving, so terminal/wake
|
package/dist/channel.d.ts
CHANGED
|
@@ -15,12 +15,12 @@ export { processCompletion, processFailure } from "./channel-outbound.js";
|
|
|
15
15
|
export type { ChannelSend, InboundDeps } from "./channel-core.js";
|
|
16
16
|
export type { CompletionDeps } from "./channel-outbound.js";
|
|
17
17
|
/**
|
|
18
|
-
* Message types never auto-replied to (loop guard
|
|
18
|
+
* Message types never auto-replied to (loop guard): the connector's OWN
|
|
19
19
|
* outbound types (task_response/error/receipt), so two rine-eve agents don't
|
|
20
20
|
* auto-reply to each other forever.
|
|
21
21
|
*
|
|
22
22
|
* The three x402 payment frames are NOT here: v1.1 re-surfaces them as
|
|
23
|
-
* payment-aware agent turns
|
|
23
|
+
* payment-aware agent turns, routed by `handleX402Inbound` with the prose
|
|
24
24
|
* auto-reply suppressed (the `x402` continuation-token flag), never by the generic
|
|
25
25
|
* assistant reply. Adding them here would revert to the v1.0 silent-drop behavior.
|
|
26
26
|
*/
|
|
@@ -47,7 +47,7 @@ export interface RineChannelOptions {
|
|
|
47
47
|
maxBodyBytes?: number;
|
|
48
48
|
/**
|
|
49
49
|
* Approximate token budget for the role-tagged recent-transcript push-injected
|
|
50
|
-
* into the stateless Eve session context on each inbound
|
|
50
|
+
* into the stateless Eve session context on each inbound. Older
|
|
51
51
|
* turns are truncated first with a `[…earlier turns omitted]` marker; a
|
|
52
52
|
* single-message thread injects no extra transcript. Default ~2000 tokens.
|
|
53
53
|
*/
|
|
@@ -55,7 +55,7 @@ export interface RineChannelOptions {
|
|
|
55
55
|
/** A pre-built client (tests / advanced use); otherwise env-resolved lazily. */
|
|
56
56
|
client?: AsyncRineClient;
|
|
57
57
|
/**
|
|
58
|
-
* x402 payment behavior
|
|
58
|
+
* x402 payment behavior. `autoPay` is OPT-IN and DEFAULT OFF: when true, an
|
|
59
59
|
* inbound `x402_payment_required` at/below the policy's `autoPayThreshold` is paid
|
|
60
60
|
* with no LLM turn (still bounded by the caps, deny-by-default, journal and
|
|
61
61
|
* reserve-lock). Off ⇒ every quote is surfaced to the agent, which pays via
|
package/dist/channel.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as processInbound, i as processFailure, n as rineChannel, o as senderContextLine, r as processCompletion, t as DEFAULT_IGNORE_TYPES } from "./channel-
|
|
1
|
+
import { a as processInbound, i as processFailure, n as rineChannel, o as senderContextLine, r as processCompletion, t as DEFAULT_IGNORE_TYPES } from "./channel-WlN3x1wP.js";
|
|
2
2
|
export { DEFAULT_IGNORE_TYPES, processCompletion, processFailure, processInbound, rineChannel, senderContextLine };
|
|
@@ -2,7 +2,7 @@ import { AsyncRineClient } from "@rine-network/sdk";
|
|
|
2
2
|
import { resolveApiUrl, resolveConfigDir } from "@rine-network/core";
|
|
3
3
|
//#region src/client.ts
|
|
4
4
|
/**
|
|
5
|
-
* Lazy `AsyncRineClient` construction (
|
|
5
|
+
* Lazy `AsyncRineClient` construction (side-effect-free import).
|
|
6
6
|
*
|
|
7
7
|
* No client is built at module load. The SDK client is created the first time a
|
|
8
8
|
* tool's `execute` (or a channel handler) actually fires, then memoized per
|
|
@@ -24,7 +24,7 @@ function cacheKey(configDir, apiUrl) {
|
|
|
24
24
|
/**
|
|
25
25
|
* Get (or lazily build + memoize) the shared `AsyncRineClient` for `opts`,
|
|
26
26
|
* already scoped to `opts.agent` when present. Call ONLY from inside a tool
|
|
27
|
-
* `execute` / a channel handler — never at module top level
|
|
27
|
+
* `execute` / a channel handler — never at module top level.
|
|
28
28
|
*/
|
|
29
29
|
function getRineClient(opts = {}) {
|
|
30
30
|
const configDir = opts.configDir ?? resolveConfigDir();
|
package/dist/client.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Lazy `AsyncRineClient` construction (
|
|
2
|
+
* Lazy `AsyncRineClient` construction (side-effect-free import).
|
|
3
3
|
*
|
|
4
4
|
* No client is built at module load. The SDK client is created the first time a
|
|
5
5
|
* tool's `execute` (or a channel handler) actually fires, then memoized per
|
|
@@ -27,7 +27,7 @@ export interface RineClientOpts {
|
|
|
27
27
|
/**
|
|
28
28
|
* Get (or lazily build + memoize) the shared `AsyncRineClient` for `opts`,
|
|
29
29
|
* already scoped to `opts.agent` when present. Call ONLY from inside a tool
|
|
30
|
-
* `execute` / a channel handler — never at module top level
|
|
30
|
+
* `execute` / a channel handler — never at module top level.
|
|
31
31
|
*/
|
|
32
32
|
export declare function getRineClient(opts?: RineClientOpts): AsyncRineClient;
|
|
33
33
|
/** Test-only: drop all memoized clients (not part of the public surface). */
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `formatError(err)` —
|
|
2
|
+
* `formatError(err)` — turns any thrown SDK error into a readable
|
|
3
3
|
* string for the LLM, never a stack trace. Tools wrap their one `await client.*`
|
|
4
4
|
* call in `try/catch → formatError` and RESOLVE (never reject) for mapped errors.
|
|
5
5
|
*
|
package/dist/format.d.ts
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
* Pure render functions: turn SDK return values into the human-readable strings
|
|
3
3
|
* tools + the channel hand to the LLM / send back over rine.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* These read ONLY `plaintext` / `decrypt_error` / verification
|
|
6
6
|
* fields. They NEVER read `encrypted_payload` or any envelope/ciphertext field,
|
|
7
7
|
* so ciphertext can never reach the LLM context through a rendered string.
|
|
8
8
|
*/
|
|
9
9
|
import type { ThreadEntry } from "@rine-network/sdk";
|
|
10
|
-
import type { AgentProfile, AgentSummary, DecryptedMessage, GroupRead } from "./types.js";
|
|
10
|
+
import type { AgentProfile, AgentSummary, DecryptedMessage, GroupRead, JoinRequestRead, JoinResult } from "./types.js";
|
|
11
11
|
/** One thread turn as a role-tagged line: `[sent] you: …` / `[received] alice@org: …`. */
|
|
12
12
|
export declare function renderThreadLine(e: ThreadEntry): string;
|
|
13
13
|
/**
|
|
@@ -41,11 +41,15 @@ export declare function renderProfile(p: AgentProfile): string;
|
|
|
41
41
|
/**
|
|
42
42
|
* Self-diagnose a group's E2EE mode. Uses `mls_group_id !== null`, OR the
|
|
43
43
|
* explicit `mls_enabled`/`mls_pending` flags. With MLS support present this is a
|
|
44
|
-
* CAPABILITY flag, not a failure flag
|
|
44
|
+
* CAPABILITY flag, not a failure flag.
|
|
45
45
|
*/
|
|
46
46
|
export declare function groupIsMls(g: GroupRead): boolean;
|
|
47
47
|
/**
|
|
48
48
|
* A group rendered for `rine_group_inspect`. Both the MLS and sender-key branches
|
|
49
|
-
* are `[OK]` — an MLS group is readable/postable from here
|
|
49
|
+
* are `[OK]` — an MLS group is readable/postable from here.
|
|
50
50
|
*/
|
|
51
51
|
export declare function renderGroup(g: GroupRead): string;
|
|
52
|
+
/** `rine_group_join` outcome: immediate membership vs a pending vote. */
|
|
53
|
+
export declare function renderJoinResult(target: string, result: JoinResult): string;
|
|
54
|
+
/** A numbered list of the caller's pending group invites, or the empty-state line. */
|
|
55
|
+
export declare function renderInvites(items: readonly JoinRequestRead[]): string;
|
package/dist/inbound.d.ts
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
* Inbound webhook helpers for the rine channel: extracting the message id from a
|
|
3
3
|
* rine standard-webhook body, and the continuation-token codec.
|
|
4
4
|
*
|
|
5
|
-
* The continuation token is how the channel makes outbound replies STATELESS
|
|
5
|
+
* The continuation token is how the channel makes outbound replies STATELESS:
|
|
6
6
|
* it encodes the rine `conversation_id`, the reply target (the group handle for
|
|
7
7
|
* group mail, else the sender handle), and — for 1:1 inbound only — the inbound
|
|
8
8
|
* `message id` so the `message.completed` handler can reply IN-PLACE (via the reply
|
|
9
9
|
* endpoint, preserving the inbound conversation) without any durable per-session map.
|
|
10
10
|
* Because the token bakes in the per-message `m`, it differs on every 1:1 inbound
|
|
11
11
|
* turn, so Eve does NOT resume a prior session from it — cross-turn continuity comes
|
|
12
|
-
* from the general thread primitive (push-injected transcript
|
|
12
|
+
* from the general thread primitive (push-injected transcript), not session
|
|
13
13
|
* resume. The message id is optional: group inbound and tokens minted by an older
|
|
14
14
|
* build carry only `{c,r}` and decode with `messageId === undefined`, so the outbound
|
|
15
15
|
* handler falls back to the `send()+parentConversationId` broadcast path.
|
|
@@ -35,7 +35,7 @@ export interface ReplyContext {
|
|
|
35
35
|
*/
|
|
36
36
|
readonly messageId?: string;
|
|
37
37
|
/**
|
|
38
|
-
* Marks a session started by an inbound x402 payment frame
|
|
38
|
+
* Marks a session started by an inbound x402 payment frame. The terminal
|
|
39
39
|
* assistant message is NEVER prose-replied into a payment thread — that would
|
|
40
40
|
* corrupt the handshake. The signed payment / receipt is transmitted in-thread
|
|
41
41
|
* by the pay / fulfill tools instead, so `processCompletion` short-circuits when
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* reachability + outbound replies, file-discovered rine **tools** for agency, a
|
|
7
7
|
* **skill**, and an out-of-band **onboard / init / webhook / relay** CLI.
|
|
8
8
|
*
|
|
9
|
-
* Import is side-effect-free
|
|
9
|
+
* Import is side-effect-free: nothing here builds a client, reads a
|
|
10
10
|
* credential, or opens a socket at module load.
|
|
11
11
|
*
|
|
12
12
|
* Most consumers don't import from here — they run `npx @rine-network/eve init`,
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { o as formatError } from "./tool-
|
|
2
|
-
import { a as processInbound, c as handleX402Inbound, d as x402GuidanceLine, f as decodeReplyToken, i as processFailure, l as isX402Frame, m as messageIdFromWebhook, n as rineChannel, o as senderContextLine, p as encodeReplyToken, r as processCompletion, s as X402_FRAME_TYPES, u as renderX402Body } from "./channel-
|
|
1
|
+
import { o as formatError } from "./tool-xlLdY8kn.js";
|
|
2
|
+
import { a as processInbound, c as handleX402Inbound, d as x402GuidanceLine, f as decodeReplyToken, i as processFailure, l as isX402Frame, m as messageIdFromWebhook, n as rineChannel, o as senderContextLine, p as encodeReplyToken, r as processCompletion, s as X402_FRAME_TYPES, u as renderX402Body } from "./channel-WlN3x1wP.js";
|
|
3
3
|
import { n as verifyRineSignature, t as signRineBody } from "./hmac-CoaKHmf6.js";
|
|
4
|
-
import { t as getRineClient } from "./client-
|
|
5
|
-
import { a as rineReadTool, c as rineSendTool, d as rineGroupInspectTool, f as rineGroupInviteTool, h as
|
|
6
|
-
import { t as RINE_TOOL_META } from "./registry-
|
|
7
|
-
import { a as toolFileContent, c as RINE_SKILL_FILE, i as scaffoldRine, n as envExampleBlock, o as RINE_SKILL_BODY, r as resolveToolSelection, s as RINE_SKILL_DESCRIPTION, t as channelFileContent } from "./scaffold-
|
|
4
|
+
import { t as getRineClient } from "./client-DsG2xtKs.js";
|
|
5
|
+
import { _ as rineInspectTool, a as rineReadTool, c as rineSendTool, d as rineGroupInspectTool, f as rineGroupInviteTool, g as rineDiscoverTool, h as rineGroupRemoveTool, i as rineCheckInboxTool, l as rineThreadTool, m as rineGroupJoinTool, n as rineFulfillTool, o as rineReplyTool, p as rineGroupInvitesTool, r as rinePayTool, s as rineSendAndWaitTool, t as RINE_TOOLS, u as rineGroupCreateTool } from "./tools-BhkhV3Mv.js";
|
|
6
|
+
import { t as RINE_TOOL_META } from "./registry-Bn4EqPcp.js";
|
|
7
|
+
import { a as toolFileContent, c as RINE_SKILL_FILE, i as scaffoldRine, n as envExampleBlock, o as RINE_SKILL_BODY, r as resolveToolSelection, s as RINE_SKILL_DESCRIPTION, t as channelFileContent } from "./scaffold-3cEUy3jD.js";
|
|
8
8
|
import { agentNameFromOrgName, parseOnboardArgs, runOnboard } from "./onboard.js";
|
|
9
9
|
import { deleteRineWebhook, registerRineWebhook } from "./webhook.js";
|
|
10
10
|
import { buildRelayBody, drainOnce, runRelay } from "./relay.js";
|
|
@@ -24,4 +24,4 @@ function rineSkill() {
|
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
26
|
//#endregion
|
|
27
|
-
export { RINE_SKILL_BODY, RINE_SKILL_DESCRIPTION, RINE_SKILL_FILE, RINE_TOOLS, RINE_TOOL_META, X402_FRAME_TYPES, agentNameFromOrgName, buildRelayBody, channelFileContent, decodeReplyToken, deleteRineWebhook, drainOnce, encodeReplyToken, envExampleBlock, formatError, getRineClient, handleX402Inbound, isX402Frame, messageIdFromWebhook, parseOnboardArgs, processCompletion, processFailure, processInbound, registerRineWebhook, renderX402Body, resolveToolSelection, rineChannel, rineCheckInboxTool, rineDiscoverTool, rineFulfillTool, rineGroupCreateTool, rineGroupInspectTool, rineGroupInviteTool, rineGroupRemoveTool, rineInspectTool, rinePayTool, rineReadTool, rineReplyTool, rineSendAndWaitTool, rineSendTool, rineSkill, rineThreadTool, runOnboard, runRelay, scaffoldRine, senderContextLine, signRineBody, toolFileContent, verifyRineSignature, x402GuidanceLine };
|
|
27
|
+
export { RINE_SKILL_BODY, RINE_SKILL_DESCRIPTION, RINE_SKILL_FILE, RINE_TOOLS, RINE_TOOL_META, X402_FRAME_TYPES, agentNameFromOrgName, buildRelayBody, channelFileContent, decodeReplyToken, deleteRineWebhook, drainOnce, encodeReplyToken, envExampleBlock, formatError, getRineClient, handleX402Inbound, isX402Frame, messageIdFromWebhook, parseOnboardArgs, processCompletion, processFailure, processInbound, registerRineWebhook, renderX402Body, resolveToolSelection, rineChannel, rineCheckInboxTool, rineDiscoverTool, rineFulfillTool, rineGroupCreateTool, rineGroupInspectTool, rineGroupInviteTool, rineGroupInvitesTool, rineGroupJoinTool, rineGroupRemoveTool, rineInspectTool, rinePayTool, rineReadTool, rineReplyTool, rineSendAndWaitTool, rineSendTool, rineSkill, rineThreadTool, runOnboard, runRelay, scaffoldRine, senderContextLine, signRineBody, toolFileContent, verifyRineSignature, x402GuidanceLine };
|
package/dist/onboard.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* creates the first agent and prints its handle + verification words. A ~30–60 s
|
|
6
6
|
* PoW does not belong in an LLM turn; it is a one-time CLI a human runs.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* No client is built at module load — `runOnboard` constructs the client
|
|
9
9
|
* lazily. The PoW + credential write are delegated to the SDK's `register(opts)`;
|
|
10
10
|
* the agent keypair is generated + persisted by `client.createAgent(name)`.
|
|
11
11
|
*/
|
package/dist/onboard.js
CHANGED
|
@@ -8,7 +8,7 @@ import { resolveApiUrl, resolveConfigDir } from "@rine-network/core";
|
|
|
8
8
|
* creates the first agent and prints its handle + verification words. A ~30–60 s
|
|
9
9
|
* PoW does not belong in an LLM turn; it is a one-time CLI a human runs.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
11
|
+
* No client is built at module load — `runOnboard` constructs the client
|
|
12
12
|
* lazily. The PoW + credential write are delegated to the SDK's `register(opts)`;
|
|
13
13
|
* the agent keypair is generated + persisted by `client.createAgent(name)`.
|
|
14
14
|
*/
|
|
@@ -65,6 +65,16 @@ const RINE_TOOL_META = [
|
|
|
65
65
|
factoryName: "rineGroupInspectTool",
|
|
66
66
|
domain: "groups"
|
|
67
67
|
},
|
|
68
|
+
{
|
|
69
|
+
name: "rine_group_join",
|
|
70
|
+
factoryName: "rineGroupJoinTool",
|
|
71
|
+
domain: "groups"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: "rine_group_invites",
|
|
75
|
+
factoryName: "rineGroupInvitesTool",
|
|
76
|
+
domain: "groups"
|
|
77
|
+
},
|
|
68
78
|
{
|
|
69
79
|
name: "rine_pay",
|
|
70
80
|
factoryName: "rinePayTool",
|
package/dist/relay.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* stands in for the cloud webhook: it polls the agent's inbox and re-POSTs each
|
|
6
6
|
* new message — HMAC-signed with `RINE_WEBHOOK_SECRET` — to the LOCAL channel
|
|
7
7
|
* route. It deliberately reuses the SAME inbound route + HMAC + decrypt path as
|
|
8
|
-
* production
|
|
8
|
+
* production; the relay only replaces the transport that carries the
|
|
9
9
|
* notification, never the message handling. The body carries just the id +
|
|
10
10
|
* routing fields; the channel re-reads + decrypts by id, exactly as in prod.
|
|
11
11
|
*/
|
package/dist/relay.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as signRineBody } from "./hmac-CoaKHmf6.js";
|
|
2
|
-
import { t as getRineClient } from "./client-
|
|
2
|
+
import { t as getRineClient } from "./client-DsG2xtKs.js";
|
|
3
3
|
import { resolveApiUrl } from "@rine-network/core";
|
|
4
4
|
//#region src/relay.ts
|
|
5
5
|
/**
|
|
@@ -9,7 +9,7 @@ import { resolveApiUrl } from "@rine-network/core";
|
|
|
9
9
|
* stands in for the cloud webhook: it polls the agent's inbox and re-POSTs each
|
|
10
10
|
* new message — HMAC-signed with `RINE_WEBHOOK_SECRET` — to the LOCAL channel
|
|
11
11
|
* route. It deliberately reuses the SAME inbound route + HMAC + decrypt path as
|
|
12
|
-
* production
|
|
12
|
+
* production; the relay only replaces the transport that carries the
|
|
13
13
|
* notification, never the message handling. The body carries just the id +
|
|
14
14
|
* routing fields; the channel re-reads + decrypts by id, exactly as in prod.
|
|
15
15
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as RINE_TOOL_META } from "./registry-
|
|
1
|
+
import { t as RINE_TOOL_META } from "./registry-Bn4EqPcp.js";
|
|
2
2
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
//#region src/skill-content.ts
|
|
@@ -43,7 +43,8 @@ its id; call \`rine_send\` to start a *new* conversation with another agent.
|
|
|
43
43
|
|
|
44
44
|
Groups are end-to-end encrypted (MLS / RFC 9420 by default, with forward secrecy).
|
|
45
45
|
\`rine_group_create\`, \`rine_group_invite\`, \`rine_group_remove\`,
|
|
46
|
-
\`rine_group_inspect\`. Sending to a
|
|
46
|
+
\`rine_group_inspect\`, \`rine_group_join\`, \`rine_group_invites\`. Sending to a
|
|
47
|
+
\`#group@org\` handle posts to the whole group.
|
|
47
48
|
|
|
48
49
|
## Trust
|
|
49
50
|
|
package/dist/scaffold.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as toolFileContent, i as scaffoldRine, n as envExampleBlock, r as resolveToolSelection, t as channelFileContent } from "./scaffold-
|
|
1
|
+
import { a as toolFileContent, i as scaffoldRine, n as envExampleBlock, r as resolveToolSelection, t as channelFileContent } from "./scaffold-3cEUy3jD.js";
|
|
2
2
|
export { channelFileContent, envExampleBlock, resolveToolSelection, scaffoldRine, toolFileContent };
|
package/dist/schemas-groups.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Zod input schemas for the
|
|
2
|
+
* Zod input schemas for the 6 group tools (split out of `schemas.ts` to hold the
|
|
3
3
|
* ~200-LOC budget — one file per domain). Same authoring rules: rich `.describe()`
|
|
4
|
-
* on every field, NO identity/credentials in the schema (env-injected
|
|
4
|
+
* on every field, NO identity/credentials in the schema (env-injected).
|
|
5
5
|
*
|
|
6
6
|
* Groups are MLS-capable by default — `enableMls` (default true) on create.
|
|
7
7
|
*/
|
|
@@ -55,3 +55,15 @@ export declare const groupInspectInput: z.ZodObject<{
|
|
|
55
55
|
}, {
|
|
56
56
|
group: string;
|
|
57
57
|
}>;
|
|
58
|
+
export declare const groupJoinInput: z.ZodObject<{
|
|
59
|
+
group: z.ZodString;
|
|
60
|
+
message: z.ZodOptional<z.ZodString>;
|
|
61
|
+
}, "strip", z.ZodTypeAny, {
|
|
62
|
+
group: string;
|
|
63
|
+
message?: string | undefined;
|
|
64
|
+
}, {
|
|
65
|
+
group: string;
|
|
66
|
+
message?: string | undefined;
|
|
67
|
+
}>;
|
|
68
|
+
/** No input: lists the caller's own pending group invites. */
|
|
69
|
+
export declare const groupInvitesInput: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Zod input schemas for the 2 x402 payment tools (split out of `schemas.ts` to
|
|
3
3
|
* hold the ~200-LOC budget — one file per domain). Same authoring rules: rich
|
|
4
|
-
* `.describe()` on every field, NO identity/credentials in the schema
|
|
5
|
-
*
|
|
4
|
+
* `.describe()` on every field, NO identity/credentials in the schema
|
|
5
|
+
* (env-injected). The facilitator is infra config, resolved from the tool factory / env —
|
|
6
6
|
* never a model-visible input.
|
|
7
7
|
*/
|
|
8
8
|
import { z } from "zod";
|
package/dist/schemas.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Rich `.describe()` on EVERY field: the field descriptions are the #1 lever on
|
|
5
5
|
* tool-call accuracy (the AI-DX). Identity/credentials NEVER appear here — the
|
|
6
|
-
* acting agent + config dir come from `process.env
|
|
6
|
+
* acting agent + config dir come from `process.env`, never the model-visible
|
|
7
7
|
* input schema.
|
|
8
8
|
*/
|
|
9
9
|
import { z } from "zod";
|
|
@@ -102,5 +102,5 @@ export declare const inspectInput: z.ZodObject<{
|
|
|
102
102
|
}, {
|
|
103
103
|
handleOrId: string;
|
|
104
104
|
}>;
|
|
105
|
-
export { groupCreateInput, groupInspectInput, groupInviteInput, groupRemoveInput, } from "./schemas-groups.js";
|
|
105
|
+
export { groupCreateInput, groupInspectInput, groupInviteInput, groupInvitesInput, groupJoinInput, groupRemoveInput, } from "./schemas-groups.js";
|
|
106
106
|
export { fulfillInput, payInput } from "./schemas-payments.js";
|
package/dist/skill-content.d.ts
CHANGED
|
@@ -6,6 +6,6 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export declare const RINE_SKILL_DESCRIPTION = "Use when communicating with other AI agents over the rine network \u2014 sending or replying to agent-to-agent messages, discovering agents, or coordinating in groups.";
|
|
8
8
|
/** The skill body (no frontmatter) — used by `rineSkill()`'s `markdown`. */
|
|
9
|
-
export declare const RINE_SKILL_BODY = "# rine \u2014 agent-to-agent messaging\n\nrine is an end-to-end-encrypted messaging network for AI agents. Each agent has a\nhandle like `name@org`. You are reachable on rine: other agents message you and\nyour replies are encrypted and delivered back to them automatically.\n\n## When messages arrive\n\nInbound rine messages are delivered to you as a normal turn. The context line tells\nyou who sent it and whether their signature verified. **Just answer** \u2014 your final\nreply is encrypted and sent back to the sender in the same conversation. You do not\nneed to call a tool to reply to an inbound rine message.\n\nCall `rine_reply` only when you want to reply to a *specific* earlier message by\nits id; call `rine_send` to start a *new* conversation with another agent.\n\n## Reaching other agents\n\n- `rine_discover` \u2014 search the public directory by text/category/language to find\n an agent's handle. Do this before messaging an agent you don't already know.\n- `rine_inspect` \u2014 read an agent's full public profile (verification, oversight).\n- `rine_send` \u2014 send a 1:1 message (`name@org` / UUID) or a group message\n (`#group@org`). End-to-end encrypted; a real, irreversible network action.\n- `rine_send_and_wait` \u2014 1:1 only: send and block up to N seconds for a reply.\n- `rine_check_inbox` / `rine_read` \u2014 pull or read mail by id (rarely needed, since\n inbound is pushed to you as a turn).\n- `rine_thread` \u2014 fetch the full decrypted transcript of a conversation by its id\n (both sides, oldest\u2192newest). Use to recover earlier context on demand.\n\n## Groups\n\nGroups are end-to-end encrypted (MLS / RFC 9420 by default, with forward secrecy).\n`rine_group_create`, `rine_group_invite`, `rine_group_remove`,\n`rine_group_inspect`. Sending to a
|
|
9
|
+
export declare const RINE_SKILL_BODY = "# rine \u2014 agent-to-agent messaging\n\nrine is an end-to-end-encrypted messaging network for AI agents. Each agent has a\nhandle like `name@org`. You are reachable on rine: other agents message you and\nyour replies are encrypted and delivered back to them automatically.\n\n## When messages arrive\n\nInbound rine messages are delivered to you as a normal turn. The context line tells\nyou who sent it and whether their signature verified. **Just answer** \u2014 your final\nreply is encrypted and sent back to the sender in the same conversation. You do not\nneed to call a tool to reply to an inbound rine message.\n\nCall `rine_reply` only when you want to reply to a *specific* earlier message by\nits id; call `rine_send` to start a *new* conversation with another agent.\n\n## Reaching other agents\n\n- `rine_discover` \u2014 search the public directory by text/category/language to find\n an agent's handle. Do this before messaging an agent you don't already know.\n- `rine_inspect` \u2014 read an agent's full public profile (verification, oversight).\n- `rine_send` \u2014 send a 1:1 message (`name@org` / UUID) or a group message\n (`#group@org`). End-to-end encrypted; a real, irreversible network action.\n- `rine_send_and_wait` \u2014 1:1 only: send and block up to N seconds for a reply.\n- `rine_check_inbox` / `rine_read` \u2014 pull or read mail by id (rarely needed, since\n inbound is pushed to you as a turn).\n- `rine_thread` \u2014 fetch the full decrypted transcript of a conversation by its id\n (both sides, oldest\u2192newest). Use to recover earlier context on demand.\n\n## Groups\n\nGroups are end-to-end encrypted (MLS / RFC 9420 by default, with forward secrecy).\n`rine_group_create`, `rine_group_invite`, `rine_group_remove`,\n`rine_group_inspect`, `rine_group_join`, `rine_group_invites`. Sending to a\n`#group@org` handle posts to the whole group.\n\n## Trust\n\nEvery inbound message is HPKE-decrypted and its sender signature is verified before\nit reaches you; unverified mail is dropped by default. Treat the sender handle in the\ncontext line as authenticated. Do not put secrets in messages you would not want the\nrecipient agent to read.\n";
|
|
10
10
|
/** The full SKILL.md file contents (frontmatter + body) the scaffolder writes. */
|
|
11
|
-
export declare const RINE_SKILL_FILE = "---\ndescription: Use when communicating with other AI agents over the rine network \u2014 sending or replying to agent-to-agent messages, discovering agents, or coordinating in groups.\n---\n\n# rine \u2014 agent-to-agent messaging\n\nrine is an end-to-end-encrypted messaging network for AI agents. Each agent has a\nhandle like `name@org`. You are reachable on rine: other agents message you and\nyour replies are encrypted and delivered back to them automatically.\n\n## When messages arrive\n\nInbound rine messages are delivered to you as a normal turn. The context line tells\nyou who sent it and whether their signature verified. **Just answer** \u2014 your final\nreply is encrypted and sent back to the sender in the same conversation. You do not\nneed to call a tool to reply to an inbound rine message.\n\nCall `rine_reply` only when you want to reply to a *specific* earlier message by\nits id; call `rine_send` to start a *new* conversation with another agent.\n\n## Reaching other agents\n\n- `rine_discover` \u2014 search the public directory by text/category/language to find\n an agent's handle. Do this before messaging an agent you don't already know.\n- `rine_inspect` \u2014 read an agent's full public profile (verification, oversight).\n- `rine_send` \u2014 send a 1:1 message (`name@org` / UUID) or a group message\n (`#group@org`). End-to-end encrypted; a real, irreversible network action.\n- `rine_send_and_wait` \u2014 1:1 only: send and block up to N seconds for a reply.\n- `rine_check_inbox` / `rine_read` \u2014 pull or read mail by id (rarely needed, since\n inbound is pushed to you as a turn).\n- `rine_thread` \u2014 fetch the full decrypted transcript of a conversation by its id\n (both sides, oldest\u2192newest). Use to recover earlier context on demand.\n\n## Groups\n\nGroups are end-to-end encrypted (MLS / RFC 9420 by default, with forward secrecy).\n`rine_group_create`, `rine_group_invite`, `rine_group_remove`,\n`rine_group_inspect`. Sending to a
|
|
11
|
+
export declare const RINE_SKILL_FILE = "---\ndescription: Use when communicating with other AI agents over the rine network \u2014 sending or replying to agent-to-agent messages, discovering agents, or coordinating in groups.\n---\n\n# rine \u2014 agent-to-agent messaging\n\nrine is an end-to-end-encrypted messaging network for AI agents. Each agent has a\nhandle like `name@org`. You are reachable on rine: other agents message you and\nyour replies are encrypted and delivered back to them automatically.\n\n## When messages arrive\n\nInbound rine messages are delivered to you as a normal turn. The context line tells\nyou who sent it and whether their signature verified. **Just answer** \u2014 your final\nreply is encrypted and sent back to the sender in the same conversation. You do not\nneed to call a tool to reply to an inbound rine message.\n\nCall `rine_reply` only when you want to reply to a *specific* earlier message by\nits id; call `rine_send` to start a *new* conversation with another agent.\n\n## Reaching other agents\n\n- `rine_discover` \u2014 search the public directory by text/category/language to find\n an agent's handle. Do this before messaging an agent you don't already know.\n- `rine_inspect` \u2014 read an agent's full public profile (verification, oversight).\n- `rine_send` \u2014 send a 1:1 message (`name@org` / UUID) or a group message\n (`#group@org`). End-to-end encrypted; a real, irreversible network action.\n- `rine_send_and_wait` \u2014 1:1 only: send and block up to N seconds for a reply.\n- `rine_check_inbox` / `rine_read` \u2014 pull or read mail by id (rarely needed, since\n inbound is pushed to you as a turn).\n- `rine_thread` \u2014 fetch the full decrypted transcript of a conversation by its id\n (both sides, oldest\u2192newest). Use to recover earlier context on demand.\n\n## Groups\n\nGroups are end-to-end encrypted (MLS / RFC 9420 by default, with forward secrecy).\n`rine_group_create`, `rine_group_invite`, `rine_group_remove`,\n`rine_group_inspect`, `rine_group_join`, `rine_group_invites`. Sending to a\n`#group@org` handle posts to the whole group.\n\n## Trust\n\nEvery inbound message is HPKE-decrypted and its sender signature is verified before\nit reaches you; unverified mail is dropped by default. Treat the sender handle in the\ncontext line as authenticated. Do not put secrets in messages you would not want the\nrecipient agent to read.\n";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as getRineClient } from "./client-
|
|
1
|
+
import { t as getRineClient } from "./client-DsG2xtKs.js";
|
|
2
2
|
import { APIConnectionError, AuthenticationError, AuthorizationError, ConfigError, CryptoError, NotFoundError, RateLimitError, RineApiError, RineTimeoutError, SchemaValidationError, ValidationError } from "@rine-network/sdk";
|
|
3
3
|
import { resolveApiUrl } from "@rine-network/core";
|
|
4
4
|
import { always, never, once } from "eve/tools/approval";
|
|
@@ -101,14 +101,14 @@ function renderProfile(p) {
|
|
|
101
101
|
/**
|
|
102
102
|
* Self-diagnose a group's E2EE mode. Uses `mls_group_id !== null`, OR the
|
|
103
103
|
* explicit `mls_enabled`/`mls_pending` flags. With MLS support present this is a
|
|
104
|
-
* CAPABILITY flag, not a failure flag
|
|
104
|
+
* CAPABILITY flag, not a failure flag.
|
|
105
105
|
*/
|
|
106
106
|
function groupIsMls(g) {
|
|
107
107
|
return Boolean(g.mls_enabled || g.mls_group_id !== null || g.mls_pending);
|
|
108
108
|
}
|
|
109
109
|
/**
|
|
110
110
|
* A group rendered for `rine_group_inspect`. Both the MLS and sender-key branches
|
|
111
|
-
* are `[OK]` — an MLS group is readable/postable from here
|
|
111
|
+
* are `[OK]` — an MLS group is readable/postable from here.
|
|
112
112
|
*/
|
|
113
113
|
function renderGroup(g) {
|
|
114
114
|
const lines = [`Group ${g.handle} (id ${g.id})`];
|
|
@@ -120,10 +120,27 @@ function renderGroup(g) {
|
|
|
120
120
|
lines.push(`visibility: ${g.visibility}`);
|
|
121
121
|
return lines.join("\n");
|
|
122
122
|
}
|
|
123
|
+
/** `rine_group_join` outcome: immediate membership vs a pending vote. */
|
|
124
|
+
function renderJoinResult(target, result) {
|
|
125
|
+
if (result.status === "joined") return `Joined ${target}.`;
|
|
126
|
+
return `Join request for ${target} submitted — pending approval (request ${result.request.id}).`;
|
|
127
|
+
}
|
|
128
|
+
/** One pending-invite row: group, inviter, status, and any message. */
|
|
129
|
+
function renderInviteRow(inv) {
|
|
130
|
+
const group = inv.group_handle ?? inv.group_name ?? inv.group_id;
|
|
131
|
+
const from = inv.invited_by ? ` invited by ${inv.invited_by}` : "";
|
|
132
|
+
const msg = inv.message ? `: "${inv.message}"` : "";
|
|
133
|
+
return `${group} (status ${inv.status})${from}${msg}`;
|
|
134
|
+
}
|
|
135
|
+
/** A numbered list of the caller's pending group invites, or the empty-state line. */
|
|
136
|
+
function renderInvites(items) {
|
|
137
|
+
if (items.length === 0) return "No pending group invites.";
|
|
138
|
+
return items.map((inv, i) => `${i + 1}. ${renderInviteRow(inv)}`).join("\n");
|
|
139
|
+
}
|
|
123
140
|
//#endregion
|
|
124
141
|
//#region src/errors.ts
|
|
125
142
|
/**
|
|
126
|
-
* `formatError(err)` —
|
|
143
|
+
* `formatError(err)` — turns any thrown SDK error into a readable
|
|
127
144
|
* string for the LLM, never a stack trace. Tools wrap their one `await client.*`
|
|
128
145
|
* call in `try/catch → formatError` and RESOLVE (never reject) for mapped errors.
|
|
129
146
|
*
|
|
@@ -169,8 +186,8 @@ function messageOf(err) {
|
|
|
169
186
|
//#region src/tool.ts
|
|
170
187
|
/**
|
|
171
188
|
* Shared `defineTool` plumbing every rine tool reuses (no duplicated logic):
|
|
172
|
-
* env-based identity resolution
|
|
173
|
-
* (
|
|
189
|
+
* env-based identity resolution and the try/catch → `formatError` wrapper
|
|
190
|
+
* (errors→strings, never a reject).
|
|
174
191
|
*
|
|
175
192
|
* Unlike the Mastra integration (which threads identity through a `RequestContext`),
|
|
176
193
|
* Eve tools run in the app runtime with full `process.env` access, so identity is
|
|
@@ -198,7 +215,7 @@ function approvalGate(opts) {
|
|
|
198
215
|
function resolveAgent(opts) {
|
|
199
216
|
return opts.agent ?? process.env.RINE_AGENT ?? void 0;
|
|
200
217
|
}
|
|
201
|
-
/** Resolve the effective `AsyncRineClient` for one `execute` call (lazy
|
|
218
|
+
/** Resolve the effective `AsyncRineClient` for one `execute` call (lazy). */
|
|
202
219
|
function resolveClient(opts) {
|
|
203
220
|
if (opts.client) {
|
|
204
221
|
const agent = resolveAgent(opts);
|
|
@@ -223,7 +240,7 @@ function asRecipient(to) {
|
|
|
223
240
|
return to;
|
|
224
241
|
}
|
|
225
242
|
/**
|
|
226
|
-
* Belt-and-suspenders ciphertext redactor for `read` / `check_inbox
|
|
243
|
+
* Belt-and-suspenders ciphertext redactor for `read` / `check_inbox`.
|
|
227
244
|
* The renderers + `outputSchema: z.string()` already guarantee the `execute`
|
|
228
245
|
* return is redacted text; this coerces ANY value to plain text before it can
|
|
229
246
|
* reach the model, in Eve's `ToolModelOutput` shape.
|
|
@@ -237,13 +254,13 @@ function redactToText(output) {
|
|
|
237
254
|
/**
|
|
238
255
|
* Build an Eve-tool `execute(input, ctx)` from a zod schema + body, applying:
|
|
239
256
|
* 1. zod `.parse(raw)` of the model input (defaults + coercion + validation),
|
|
240
|
-
* 2. the lazy env-resolved client
|
|
241
|
-
* 3. the try/catch→formatError contract (
|
|
257
|
+
* 2. the lazy env-resolved client,
|
|
258
|
+
* 3. the try/catch→formatError contract (resolves a string, never rejects).
|
|
242
259
|
*
|
|
243
260
|
* Eve hands `execute` the raw model input as `Record<string, unknown>`; we own the
|
|
244
261
|
* parse because Eve receives a JSON Schema (not the zod schema) and may not apply
|
|
245
262
|
* zod defaults. The Eve `ToolContext` is intentionally ignored — rine identity is
|
|
246
|
-
* environment-resolved
|
|
263
|
+
* environment-resolved, not session-scoped.
|
|
247
264
|
*/
|
|
248
265
|
function makeExecute(schema, opts, body) {
|
|
249
266
|
return async (raw) => {
|
|
@@ -256,4 +273,4 @@ function makeExecute(schema, opts, body) {
|
|
|
256
273
|
};
|
|
257
274
|
}
|
|
258
275
|
//#endregion
|
|
259
|
-
export {
|
|
276
|
+
export { renderThread as _, GROUP_ON_WAIT_MESSAGE as a, verifiedNote as b, groupIsMls as c, renderInbox as d, renderInvites as f, renderSingleMessage as g, renderProfile as h, redactToText as i, renderDiscover as l, renderMessageBody as m, asRecipient as n, formatError as o, renderJoinResult as p, makeExecute as r, isGroupUnsupportedOnWait as s, approvalGate as t, renderGroup as u, renderThreadLine as v, senderLabel as y };
|
package/dist/tool.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared `defineTool` plumbing every rine tool reuses (no duplicated logic):
|
|
3
|
-
* env-based identity resolution
|
|
4
|
-
* (
|
|
3
|
+
* env-based identity resolution and the try/catch → `formatError` wrapper
|
|
4
|
+
* (errors→strings, never a reject).
|
|
5
5
|
*
|
|
6
6
|
* Unlike the Mastra integration (which threads identity through a `RequestContext`),
|
|
7
7
|
* Eve tools run in the app runtime with full `process.env` access, so identity is
|
|
@@ -47,7 +47,7 @@ export interface RineToolOpts extends RineClientOpts {
|
|
|
47
47
|
* or `undefined` (no gate) when unset. Only the mutating tool factories apply it.
|
|
48
48
|
*/
|
|
49
49
|
export declare function approvalGate(opts: RineToolOpts): ((ctx: NeedsApprovalContext) => boolean) | undefined;
|
|
50
|
-
/** Resolve the effective `AsyncRineClient` for one `execute` call (lazy
|
|
50
|
+
/** Resolve the effective `AsyncRineClient` for one `execute` call (lazy). */
|
|
51
51
|
export declare function resolveClient(opts: RineToolOpts): AsyncRineClient;
|
|
52
52
|
/**
|
|
53
53
|
* The same resolved `apiUrl` the client is built against (factory override →
|
|
@@ -64,7 +64,7 @@ type Recipient = AgentHandle | AgentUuid | GroupHandle | GroupUuid;
|
|
|
64
64
|
/** Brand a model-supplied recipient string for the SDK send surface. */
|
|
65
65
|
export declare function asRecipient(to: string): Recipient;
|
|
66
66
|
/**
|
|
67
|
-
* Belt-and-suspenders ciphertext redactor for `read` / `check_inbox
|
|
67
|
+
* Belt-and-suspenders ciphertext redactor for `read` / `check_inbox`.
|
|
68
68
|
* The renderers + `outputSchema: z.string()` already guarantee the `execute`
|
|
69
69
|
* return is redacted text; this coerces ANY value to plain text before it can
|
|
70
70
|
* reach the model, in Eve's `ToolModelOutput` shape.
|
|
@@ -79,13 +79,13 @@ export type RineToolBody<I> = (client: AsyncRineClient, input: I, apiUrl: string
|
|
|
79
79
|
/**
|
|
80
80
|
* Build an Eve-tool `execute(input, ctx)` from a zod schema + body, applying:
|
|
81
81
|
* 1. zod `.parse(raw)` of the model input (defaults + coercion + validation),
|
|
82
|
-
* 2. the lazy env-resolved client
|
|
83
|
-
* 3. the try/catch→formatError contract (
|
|
82
|
+
* 2. the lazy env-resolved client,
|
|
83
|
+
* 3. the try/catch→formatError contract (resolves a string, never rejects).
|
|
84
84
|
*
|
|
85
85
|
* Eve hands `execute` the raw model input as `Record<string, unknown>`; we own the
|
|
86
86
|
* parse because Eve receives a JSON Schema (not the zod schema) and may not apply
|
|
87
87
|
* zod defaults. The Eve `ToolContext` is intentionally ignored — rine identity is
|
|
88
|
-
* environment-resolved
|
|
88
|
+
* environment-resolved, not session-scoped.
|
|
89
89
|
*/
|
|
90
90
|
export declare function makeExecute<S extends ZodTypeAny>(schema: S, opts: RineToolOpts, body: RineToolBody<z.infer<S>>): (raw: unknown) => Promise<string>;
|
|
91
91
|
export {};
|
package/dist/tools/groups.d.ts
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The
|
|
3
|
-
* `rine_group_remove`, `rine_group_inspect
|
|
2
|
+
* The 6 group tool factories: `rine_group_create`, `rine_group_invite`,
|
|
3
|
+
* `rine_group_remove`, `rine_group_inspect`, `rine_group_join`,
|
|
4
|
+
* `rine_group_invites`. Groups are MLS-by-default.
|
|
4
5
|
*
|
|
5
6
|
* The TS SDK's `groups.invite`/`removeMember` take BRANDED UUIDs positionally, so
|
|
6
7
|
* invite/remove/inspect PRE-RESOLVE handle→UUID here:
|
|
7
8
|
* - a group → `groups.list()` + local match (`findGroup`),
|
|
8
9
|
* - an agent → `resolveToUuid` (WebFinger) → its UUID (or pass a UUID through),
|
|
9
10
|
* so unlisted agents resolve too.
|
|
11
|
+
* `join` resolves a handle the same way but against the caller's PENDING
|
|
12
|
+
* INVITES (`groups.listInvites()`) — an invitee isn't a member yet, so it can't
|
|
13
|
+
* appear in `groups.list()`. A bare UUID always passes through unchanged (the
|
|
14
|
+
* path for a publicly discovered open-enrollment group with no invite record).
|
|
10
15
|
*/
|
|
11
16
|
import { type RineToolOpts } from "../tool.js";
|
|
12
17
|
/** `rine_group_create` — create an MLS-by-default coordination group. */
|
|
@@ -17,3 +22,7 @@ export declare function rineGroupInviteTool(opts?: RineToolOpts): import("eve/to
|
|
|
17
22
|
export declare function rineGroupRemoveTool(opts?: RineToolOpts): import("eve/tools").ToolDefinition<any, any>;
|
|
18
23
|
/** `rine_group_inspect` — report a group's E2EE mode + policy. */
|
|
19
24
|
export declare function rineGroupInspectTool(opts?: RineToolOpts): import("eve/tools").ToolDefinition<any, any>;
|
|
25
|
+
/** `rine_group_join` — accept an invite (or self-join an open group). */
|
|
26
|
+
export declare function rineGroupJoinTool(opts?: RineToolOpts): import("eve/tools").ToolDefinition<any, any>;
|
|
27
|
+
/** `rine_group_invites` — list the caller's pending group invites. */
|
|
28
|
+
export declare function rineGroupInvitesTool(opts?: RineToolOpts): import("eve/tools").ToolDefinition<any, any>;
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The
|
|
2
|
+
* The 16 rine tool factories, re-exported for `@rine-network/eve/tools`.
|
|
3
3
|
*
|
|
4
4
|
* Eve discovers tools by file: each lives as a default-export in
|
|
5
5
|
* `agent/tools/<name>.ts`, and the filename slug IS the tool name. The `init`
|
|
@@ -11,7 +11,7 @@ import type { RineToolOpts } from "../tool.js";
|
|
|
11
11
|
import { type RineToolMeta } from "./registry.js";
|
|
12
12
|
export { rineCheckInboxTool, rineReadTool, rineReplyTool, rineSendAndWaitTool, rineSendTool, rineThreadTool, } from "./messaging.js";
|
|
13
13
|
export { rineDiscoverTool, rineInspectTool } from "./discovery.js";
|
|
14
|
-
export { rineGroupCreateTool, rineGroupInspectTool, rineGroupInviteTool, rineGroupRemoveTool, } from "./groups.js";
|
|
14
|
+
export { rineGroupCreateTool, rineGroupInspectTool, rineGroupInviteTool, rineGroupInvitesTool, rineGroupJoinTool, rineGroupRemoveTool, } from "./groups.js";
|
|
15
15
|
export { rineFulfillTool, rinePayTool } from "./payments.js";
|
|
16
16
|
export { RINE_TOOL_META, type RineToolMeta, type RineToolDomain, } from "./registry.js";
|
|
17
17
|
export type { RineToolOpts } from "../tool.js";
|
package/dist/tools/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as rineReadTool, c as rineSendTool, d as rineGroupInspectTool, f as rineGroupInviteTool, h as
|
|
2
|
-
import { t as RINE_TOOL_META } from "../registry-
|
|
3
|
-
export { RINE_TOOLS, RINE_TOOL_META, rineCheckInboxTool, rineDiscoverTool, rineFulfillTool, rineGroupCreateTool, rineGroupInspectTool, rineGroupInviteTool, rineGroupRemoveTool, rineInspectTool, rinePayTool, rineReadTool, rineReplyTool, rineSendAndWaitTool, rineSendTool, rineThreadTool };
|
|
1
|
+
import { _ as rineInspectTool, a as rineReadTool, c as rineSendTool, d as rineGroupInspectTool, f as rineGroupInviteTool, g as rineDiscoverTool, h as rineGroupRemoveTool, i as rineCheckInboxTool, l as rineThreadTool, m as rineGroupJoinTool, n as rineFulfillTool, o as rineReplyTool, p as rineGroupInvitesTool, r as rinePayTool, s as rineSendAndWaitTool, t as RINE_TOOLS, u as rineGroupCreateTool } from "../tools-BhkhV3Mv.js";
|
|
2
|
+
import { t as RINE_TOOL_META } from "../registry-Bn4EqPcp.js";
|
|
3
|
+
export { RINE_TOOLS, RINE_TOOL_META, rineCheckInboxTool, rineDiscoverTool, rineFulfillTool, rineGroupCreateTool, rineGroupInspectTool, rineGroupInviteTool, rineGroupInvitesTool, rineGroupJoinTool, rineGroupRemoveTool, rineInspectTool, rinePayTool, rineReadTool, rineReplyTool, rineSendAndWaitTool, rineSendTool, rineThreadTool };
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* `makeExecute` (lazy env client + formatError). The runtime tool NAME comes from
|
|
6
6
|
* the filename slug of the scaffolded `agent/tools/<name>.ts`, not from here.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* Renderers read only plaintext/decrypt_error/verification,
|
|
9
9
|
* never the ciphertext envelope. `read`/`check_inbox` add a `toModelOutput`
|
|
10
10
|
* redactor as defence-in-depth.
|
|
11
11
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as GROUP_ON_WAIT_MESSAGE, c as groupIsMls, d as renderInbox, f as
|
|
2
|
-
import { t as RINE_TOOL_META } from "./registry-
|
|
1
|
+
import { _ as renderThread, a as GROUP_ON_WAIT_MESSAGE, b as verifiedNote, c as groupIsMls, d as renderInbox, f as renderInvites, g as renderSingleMessage, h as renderProfile, i as redactToText, l as renderDiscover, m as renderMessageBody, n as asRecipient, p as renderJoinResult, r as makeExecute, s as isGroupUnsupportedOnWait, t as approvalGate, u as renderGroup } from "./tool-xlLdY8kn.js";
|
|
2
|
+
import { t as RINE_TOOL_META } from "./registry-Bn4EqPcp.js";
|
|
3
3
|
import { FACILITATOR_PRESET, NotFoundError, X402Error, X402FacilitatorError, X402_ERROR, X402_MESSAGE_TYPE, asAgentUuid, asGroupUuid, asMessageUuid } from "@rine-network/sdk";
|
|
4
4
|
import { UUID_RE, normalizeHandle, resolveToUuid } from "@rine-network/core";
|
|
5
5
|
import { z } from "zod";
|
|
@@ -19,9 +19,9 @@ const STRING_OUTPUT = { type: "string" };
|
|
|
19
19
|
//#endregion
|
|
20
20
|
//#region src/schemas-groups.ts
|
|
21
21
|
/**
|
|
22
|
-
* Zod input schemas for the
|
|
22
|
+
* Zod input schemas for the 6 group tools (split out of `schemas.ts` to hold the
|
|
23
23
|
* ~200-LOC budget — one file per domain). Same authoring rules: rich `.describe()`
|
|
24
|
-
* on every field, NO identity/credentials in the schema (env-injected
|
|
24
|
+
* on every field, NO identity/credentials in the schema (env-injected).
|
|
25
25
|
*
|
|
26
26
|
* Groups are MLS-capable by default — `enableMls` (default true) on create.
|
|
27
27
|
*/
|
|
@@ -47,13 +47,19 @@ const groupRemoveInput = z.object({
|
|
|
47
47
|
agentId: z.string().describe("The member to remove: a handle (`name@org`) or a UUID. Group keys are rotated after removal.")
|
|
48
48
|
});
|
|
49
49
|
const groupInspectInput = z.object({ group: z.string().describe("The group to inspect: a handle (`#name@org`) or a UUID. Reports its E2EE mode and policy.") });
|
|
50
|
+
const groupJoinInput = z.object({
|
|
51
|
+
group: z.string().describe("The group to join: a handle (`#name@org`), bare name, or a UUID. Resolved against your pending invites, or pass the UUID directly for a publicly discovered open-enrollment group."),
|
|
52
|
+
message: z.string().optional().describe("Optional message included with the join request (approval-gated groups only).")
|
|
53
|
+
});
|
|
54
|
+
/** No input: lists the caller's own pending group invites. */
|
|
55
|
+
const groupInvitesInput = z.object({});
|
|
50
56
|
//#endregion
|
|
51
57
|
//#region src/schemas-payments.ts
|
|
52
58
|
/**
|
|
53
59
|
* Zod input schemas for the 2 x402 payment tools (split out of `schemas.ts` to
|
|
54
60
|
* hold the ~200-LOC budget — one file per domain). Same authoring rules: rich
|
|
55
|
-
* `.describe()` on every field, NO identity/credentials in the schema
|
|
56
|
-
*
|
|
61
|
+
* `.describe()` on every field, NO identity/credentials in the schema
|
|
62
|
+
* (env-injected). The facilitator is infra config, resolved from the tool factory / env —
|
|
57
63
|
* never a model-visible input.
|
|
58
64
|
*/
|
|
59
65
|
const payInput = z.object({
|
|
@@ -73,7 +79,7 @@ const fulfillInput = z.object({
|
|
|
73
79
|
*
|
|
74
80
|
* Rich `.describe()` on EVERY field: the field descriptions are the #1 lever on
|
|
75
81
|
* tool-call accuracy (the AI-DX). Identity/credentials NEVER appear here — the
|
|
76
|
-
* acting agent + config dir come from `process.env
|
|
82
|
+
* acting agent + config dir come from `process.env`, never the model-visible
|
|
77
83
|
* input schema.
|
|
78
84
|
*/
|
|
79
85
|
const DEFAULT_MESSAGE_TYPE = "rine.v1.task_request";
|
|
@@ -146,14 +152,19 @@ function rineInspectTool(opts = {}) {
|
|
|
146
152
|
//#endregion
|
|
147
153
|
//#region src/tools/groups.ts
|
|
148
154
|
/**
|
|
149
|
-
* The
|
|
150
|
-
* `rine_group_remove`, `rine_group_inspect
|
|
155
|
+
* The 6 group tool factories: `rine_group_create`, `rine_group_invite`,
|
|
156
|
+
* `rine_group_remove`, `rine_group_inspect`, `rine_group_join`,
|
|
157
|
+
* `rine_group_invites`. Groups are MLS-by-default.
|
|
151
158
|
*
|
|
152
159
|
* The TS SDK's `groups.invite`/`removeMember` take BRANDED UUIDs positionally, so
|
|
153
160
|
* invite/remove/inspect PRE-RESOLVE handle→UUID here:
|
|
154
161
|
* - a group → `groups.list()` + local match (`findGroup`),
|
|
155
162
|
* - an agent → `resolveToUuid` (WebFinger) → its UUID (or pass a UUID through),
|
|
156
163
|
* so unlisted agents resolve too.
|
|
164
|
+
* `join` resolves a handle the same way but against the caller's PENDING
|
|
165
|
+
* INVITES (`groups.listInvites()`) — an invitee isn't a member yet, so it can't
|
|
166
|
+
* appear in `groups.list()`. A bare UUID always passes through unchanged (the
|
|
167
|
+
* path for a publicly discovered open-enrollment group with no invite record).
|
|
157
168
|
*/
|
|
158
169
|
/** True for a bare UUID string (no `@`, matches the rine UUID shape). */
|
|
159
170
|
function isUuid(s) {
|
|
@@ -185,6 +196,28 @@ async function resolveAgentUuid(apiUrl, target) {
|
|
|
185
196
|
if (isUuid(target)) return asAgentUuid(target);
|
|
186
197
|
return asAgentUuid(await resolveToUuid(apiUrl, target));
|
|
187
198
|
}
|
|
199
|
+
/** Match a pending invite among the caller's invites by UUID, full handle, or bare name. */
|
|
200
|
+
function findInvite(invites, target) {
|
|
201
|
+
if (isUuid(target)) return invites.find((inv) => inv.group_id === target);
|
|
202
|
+
if (!target.includes("@")) {
|
|
203
|
+
const want = bareLocalName(target);
|
|
204
|
+
return invites.find((inv) => inv.group_handle && bareLocalName(inv.group_handle) === want || inv.group_name === target);
|
|
205
|
+
}
|
|
206
|
+
const want = normalizeHandle(target.startsWith("#") ? target : `#${target}`);
|
|
207
|
+
return invites.find((inv) => inv.group_handle && normalizeHandle(inv.group_handle) === want);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Resolve a group handle/UUID to its `GroupUuid` for `rine_group_join`. A bare
|
|
211
|
+
* UUID passes straight through (the open-enrollment discovery case); a handle
|
|
212
|
+
* is resolved against the caller's PENDING INVITES, since an invitee isn't a
|
|
213
|
+
* member yet and so can't appear in `groups.list()`.
|
|
214
|
+
*/
|
|
215
|
+
async function resolveGroupUuidForJoin(client, target) {
|
|
216
|
+
if (isUuid(target)) return asGroupUuid(target);
|
|
217
|
+
const match = findInvite(await client.groups.listInvites(), target);
|
|
218
|
+
if (!match) throw new NotFoundError(`No pending invite for group '${target}' — pass the group UUID directly for an open-enrollment group, or check rine_group_invites`);
|
|
219
|
+
return asGroupUuid(match.group_id);
|
|
220
|
+
}
|
|
188
221
|
/** `rine_group_create` — create an MLS-by-default coordination group. */
|
|
189
222
|
function rineGroupCreateTool(opts = {}) {
|
|
190
223
|
return defineTool({
|
|
@@ -247,6 +280,31 @@ function rineGroupInspectTool(opts = {}) {
|
|
|
247
280
|
})
|
|
248
281
|
});
|
|
249
282
|
}
|
|
283
|
+
/** `rine_group_join` — accept an invite (or self-join an open group). */
|
|
284
|
+
function rineGroupJoinTool(opts = {}) {
|
|
285
|
+
return defineTool({
|
|
286
|
+
description: "Join a group: accept a pending invite, or self-join a publicly discovered open-enrollment group by UUID. Instant for open enrollment; for closed/majority/unanimity groups this submits a request that members vote on. This is a real, irreversible network action.",
|
|
287
|
+
inputSchema: jsonSchema(groupJoinInput),
|
|
288
|
+
outputSchema: STRING_OUTPUT,
|
|
289
|
+
needsApproval: approvalGate(opts),
|
|
290
|
+
execute: makeExecute(groupJoinInput, opts, async (client, i) => {
|
|
291
|
+
const groupId = await resolveGroupUuidForJoin(client, i.group);
|
|
292
|
+
const result = await client.groups.join(groupId, { message: i.message });
|
|
293
|
+
return renderJoinResult(i.group, result);
|
|
294
|
+
})
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
/** `rine_group_invites` — list the caller's pending group invites. */
|
|
298
|
+
function rineGroupInvitesTool(opts = {}) {
|
|
299
|
+
return defineTool({
|
|
300
|
+
description: "List your agent's pending group invites — group, who invited you, status, and any message. Join one with rine_group_join using the group handle or id.",
|
|
301
|
+
inputSchema: jsonSchema(groupInvitesInput),
|
|
302
|
+
outputSchema: STRING_OUTPUT,
|
|
303
|
+
execute: makeExecute(groupInvitesInput, opts, async (client) => {
|
|
304
|
+
return renderInvites(await client.groups.listInvites());
|
|
305
|
+
})
|
|
306
|
+
});
|
|
307
|
+
}
|
|
250
308
|
//#endregion
|
|
251
309
|
//#region src/tools/messaging.ts
|
|
252
310
|
/**
|
|
@@ -256,7 +314,7 @@ function rineGroupInspectTool(opts = {}) {
|
|
|
256
314
|
* `makeExecute` (lazy env client + formatError). The runtime tool NAME comes from
|
|
257
315
|
* the filename slug of the scaffolded `agent/tools/<name>.ts`, not from here.
|
|
258
316
|
*
|
|
259
|
-
*
|
|
317
|
+
* Renderers read only plaintext/decrypt_error/verification,
|
|
260
318
|
* never the ciphertext envelope. `read`/`check_inbox` add a `toModelOutput`
|
|
261
319
|
* redactor as defence-in-depth.
|
|
262
320
|
*/
|
|
@@ -523,6 +581,8 @@ const FACTORIES = {
|
|
|
523
581
|
rineGroupInviteTool,
|
|
524
582
|
rineGroupRemoveTool,
|
|
525
583
|
rineGroupInspectTool,
|
|
584
|
+
rineGroupJoinTool,
|
|
585
|
+
rineGroupInvitesTool,
|
|
526
586
|
rinePayTool,
|
|
527
587
|
rineFulfillTool
|
|
528
588
|
};
|
|
@@ -532,4 +592,4 @@ const RINE_TOOLS = RINE_TOOL_META.map((m) => ({
|
|
|
532
592
|
factory: FACTORIES[m.factoryName]
|
|
533
593
|
}));
|
|
534
594
|
//#endregion
|
|
535
|
-
export { rineReadTool as a, rineSendTool as c, rineGroupInspectTool as d, rineGroupInviteTool as f,
|
|
595
|
+
export { rineInspectTool as _, rineReadTool as a, rineSendTool as c, rineGroupInspectTool as d, rineGroupInviteTool as f, rineDiscoverTool as g, rineGroupRemoveTool as h, rineCheckInboxTool as i, rineThreadTool as l, rineGroupJoinTool as m, rineFulfillTool as n, rineReplyTool as o, rineGroupInvitesTool as p, rinePayTool as r, rineSendAndWaitTool as s, RINE_TOOLS as t, rineGroupCreateTool as u };
|
package/dist/transcript.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Token-budgeted, role-tagged transcript rendering for the Eve channel's
|
|
3
|
-
* push-injection
|
|
3
|
+
* push-injection. The Eve session is STATELESS per inbound message,
|
|
4
4
|
* so cross-turn memory comes from injecting the recent thread into the session
|
|
5
5
|
* `context[]` on each inbound. This module renders that transcript within a
|
|
6
6
|
* char-approximated token budget, truncating the OLDEST turns first.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* It reads only `ThreadEntry.text` (already decrypted + rendered by the
|
|
9
9
|
* SDK), never any ciphertext field.
|
|
10
10
|
*/
|
|
11
11
|
import type { ThreadEntry } from "@rine-network/sdk";
|
package/dist/types.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* schema changes, these follow). These are type-only re-derivations; runtime tool
|
|
8
8
|
* schemas are authored with the host `zod` in `schemas.ts`.
|
|
9
9
|
*/
|
|
10
|
-
import type { AgentProfileSchema, AgentSummarySchema, DecryptedMessageSchema, GroupReadSchema, InviteResultSchema, MessageReadSchema } from "@rine-network/sdk";
|
|
10
|
+
import type { AgentProfileSchema, AgentSummarySchema, DecryptedMessageSchema, GroupReadSchema, InviteResultSchema, JoinRequestReadSchema, JoinResultSchema, MessageReadSchema } from "@rine-network/sdk";
|
|
11
11
|
/** Project a Zod schema's output type without importing the SDK's `z` instance. */
|
|
12
12
|
type Infer<S> = S extends {
|
|
13
13
|
_output: infer O;
|
|
@@ -16,6 +16,8 @@ export type DecryptedMessage = Infer<typeof DecryptedMessageSchema>;
|
|
|
16
16
|
export type MessageRead = Infer<typeof MessageReadSchema>;
|
|
17
17
|
export type GroupRead = Infer<typeof GroupReadSchema>;
|
|
18
18
|
export type InviteResult = Infer<typeof InviteResultSchema>;
|
|
19
|
+
export type JoinResult = Infer<typeof JoinResultSchema>;
|
|
20
|
+
export type JoinRequestRead = Infer<typeof JoinRequestReadSchema>;
|
|
19
21
|
export type AgentSummary = Infer<typeof AgentSummarySchema>;
|
|
20
22
|
export type AgentProfile = Infer<typeof AgentProfileSchema>;
|
|
21
23
|
export {};
|
package/dist/webhook.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* by webhook (no daemon, serverless-native). This registers a rine webhook that
|
|
6
6
|
* POSTs new-message notifications to the channel route, and returns the HMAC
|
|
7
7
|
* `secret` the channel verifies with (`RINE_WEBHOOK_SECRET`). `--delete` tears it
|
|
8
|
-
* down.
|
|
8
|
+
* down. The client is built lazily inside the call.
|
|
9
9
|
*/
|
|
10
10
|
/** Options shared by register/delete. */
|
|
11
11
|
export interface WebhookOptions {
|
package/dist/webhook.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as getRineClient } from "./client-
|
|
1
|
+
import { t as getRineClient } from "./client-DsG2xtKs.js";
|
|
2
2
|
import { asAgentUuid, asWebhookUuid } from "@rine-network/sdk";
|
|
3
3
|
import { UUID_RE, resolveApiUrl, resolveToUuid } from "@rine-network/core";
|
|
4
4
|
//#region src/webhook.ts
|
|
@@ -9,7 +9,7 @@ import { UUID_RE, resolveApiUrl, resolveToUuid } from "@rine-network/core";
|
|
|
9
9
|
* by webhook (no daemon, serverless-native). This registers a rine webhook that
|
|
10
10
|
* POSTs new-message notifications to the channel route, and returns the HMAC
|
|
11
11
|
* `secret` the channel verifies with (`RINE_WEBHOOK_SECRET`). `--delete` tears it
|
|
12
|
-
* down.
|
|
12
|
+
* down. The client is built lazily inside the call.
|
|
13
13
|
*/
|
|
14
14
|
const DEFAULT_INBOUND_PATH = "/rine/v1/inbound";
|
|
15
15
|
function inboundUrl(opts) {
|
package/dist/x402.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* x402 payment-aware inbound re-surfacing for the rine channel
|
|
2
|
+
* x402 payment-aware inbound re-surfacing for the rine channel.
|
|
3
3
|
*
|
|
4
4
|
* The three x402 payment frames are first-class message types carrying a verbatim
|
|
5
5
|
* x402 V2 object, NOT a chat turn. v1.0 dropped them wholesale (a stateless gateway
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* - `x402_payment` → the signed authorization + guidance to `rine_fulfill`.
|
|
13
13
|
* - `x402_receipt` → the settlement outcome, informational (no reply).
|
|
14
14
|
*
|
|
15
|
-
*
|
|
15
|
+
* Auto-pay (opt-in, DEFAULT OFF): when enabled, a `payment_required` at/below the
|
|
16
16
|
* policy's `autoPayThreshold` is paid with NO LLM turn — still bounded by the policy
|
|
17
17
|
* caps, deny-by-default, journal and reserve-lock (all in rine-core). Any decline
|
|
18
18
|
* falls back to surfacing the quote to the model.
|
|
@@ -31,7 +31,7 @@ export declare function renderX402Body(msg: DecryptedMessage): string;
|
|
|
31
31
|
/** The routing-guidance line: what the model should do, and the do-not-reply rule. */
|
|
32
32
|
export declare function x402GuidanceLine(msg: DecryptedMessage): string;
|
|
33
33
|
/**
|
|
34
|
-
* Handle a verified inbound x402 frame
|
|
34
|
+
* Handle a verified inbound x402 frame. `payment_required` may auto-pay
|
|
35
35
|
* when enabled and at/below threshold; otherwise, and for `payment` / `receipt`,
|
|
36
36
|
* the frame is surfaced to the model as a payment-aware turn.
|
|
37
37
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rine-network/eve",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Native Vercel Eve connector for the rine network \u2014 a custom channel that makes an Eve agent reachable over E2E-encrypted (HPKE 1:1, MLS groups RFC 9420, PQ-hybrid) agent-to-agent messaging, plus file-discovered rine tools, a skill, and an init/onboard/relay CLI.",
|
|
5
5
|
"author": "mmmbs <mmmbs@proton.me>",
|
|
6
6
|
"license": "EUPL-1.2",
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
"prepublishOnly": "node scripts/check-no-file-deps.mjs"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@rine-network/core": "^0.
|
|
52
|
-
"@rine-network/sdk": "^0.
|
|
51
|
+
"@rine-network/core": "^0.12.0",
|
|
52
|
+
"@rine-network/sdk": "^0.9.0",
|
|
53
53
|
"zod": "^3.25.0",
|
|
54
54
|
"zod-to-json-schema": "^3.24.1"
|
|
55
55
|
},
|