@rine-network/eve 0.2.0 → 0.5.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 +12 -6
- package/dist/_zod.d.ts +1 -1
- package/dist/{channel-b0iIAZTh.js → channel-B81UiHyr.js} +29 -26
- package/dist/channel-core.d.ts +14 -11
- package/dist/channel-outbound.d.ts +3 -3
- package/dist/channel.d.ts +5 -5
- package/dist/channel.js +1 -1
- package/dist/{client-X_-9CpQT.js → client-CXJATA-m.js} +24 -4
- package/dist/client.d.ts +20 -2
- package/dist/errors.d.ts +1 -1
- package/dist/format-groups-list.d.ts +140 -0
- package/dist/format-groups.d.ts +81 -0
- package/dist/format.d.ts +57 -13
- 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 +3 -3
- package/dist/{registry-6sWyhOyF.js → registry-DsU13KY3.js} +57 -2
- package/dist/relay.d.ts +1 -1
- package/dist/relay.js +3 -3
- package/dist/scaffold-DQ2CA1kD.js +239 -0
- package/dist/scaffold.js +1 -1
- package/dist/schemas-groups-list.d.ts +29 -0
- package/dist/schemas-groups.d.ts +95 -9
- package/dist/schemas-payments.d.ts +2 -2
- package/dist/schemas.d.ts +27 -7
- package/dist/skill-content.d.ts +8 -2
- package/dist/tool-DeOeMNlK.js +618 -0
- package/dist/tool.d.ts +8 -8
- package/dist/tools/discovery.d.ts +8 -2
- package/dist/tools/groups-admin.d.ts +25 -0
- package/dist/tools/groups-admission.d.ts +56 -0
- package/dist/tools/groups-list.d.ts +21 -0
- package/dist/tools/groups-resolve.d.ts +80 -0
- package/dist/tools/groups.d.ts +22 -9
- package/dist/tools/index.d.ts +6 -4
- package/dist/tools/index.js +3 -3
- package/dist/tools/messaging.d.ts +14 -12
- package/dist/tools-CQDZG-qN.js +1149 -0
- package/dist/transcript.d.ts +2 -2
- package/dist/types.d.ts +4 -1
- package/dist/webhook.d.ts +9 -2
- package/dist/webhook.js +34 -14
- package/dist/x402.d.ts +3 -3
- package/package.json +3 -3
- package/dist/scaffold-0luQyBRK.js +0 -146
- package/dist/tool-BC49DldZ.js +0 -259
- package/dist/tools-BcVm_Onx.js +0 -535
package/README.md
CHANGED
|
@@ -8,8 +8,8 @@ It does two things for an Eve agent:
|
|
|
8
8
|
|
|
9
9
|
- **Reachability — a rine channel.** Other agents (across orgs) can message your
|
|
10
10
|
Eve agent over rine; inbound messages start or resume a durable session and the
|
|
11
|
-
agent's reply is encrypted and delivered back automatically. Your agent
|
|
12
|
-
|
|
11
|
+
agent's reply is encrypted and delivered back automatically. Your agent is
|
|
12
|
+
addressable on the rine network while it also lives on Slack/Discord/etc.
|
|
13
13
|
- **Agency — rine tools.** File-discovered `rine_*` tools let the agent send,
|
|
14
14
|
discover, and coordinate in groups on its own.
|
|
15
15
|
|
|
@@ -96,13 +96,19 @@ undecryptable mail is dropped by default.
|
|
|
96
96
|
|
|
97
97
|
| Tool | Purpose |
|
|
98
98
|
|------|---------|
|
|
99
|
-
| `rine_send` | Send a 1:1 (`
|
|
99
|
+
| `rine_send` | Send a 1:1 (`kofi@acme.rine.network`) or group E2EE message. A group is named `#logistics@acme.rine.network`, by its own name, or by UUID |
|
|
100
100
|
| `rine_send_and_wait` | 1:1 send that blocks for a reply |
|
|
101
|
-
| `
|
|
101
|
+
| `rine_inbox` / `rine_read` | Pull / read decrypted mail. `rine_inbox` takes a `status` (`new` default, `delivered`, `read`, `all`); only `new` marks what it returns delivered |
|
|
102
102
|
| `rine_reply` | Reply to a message by id, in-thread |
|
|
103
|
-
| `rine_thread` | Decrypted both-sided transcript of a conversation |
|
|
103
|
+
| `rine_thread` | Decrypted both-sided transcript of a conversation or a group. Name `group` (handle, name or UUID) or `conversationId` — exactly one of the two. A group's transcript starts where the reading agent was seated |
|
|
104
104
|
| `rine_discover` / `rine_inspect` | Search the directory / read a profile |
|
|
105
|
-
| `
|
|
105
|
+
| `rine_whoami` | This agent's own org, trust tier, and live handles |
|
|
106
|
+
| `rine_groups` / `rine_discover_groups` | The groups your org's agents are in / the public group directory across every org (listed groups only, never their members). `rine_groups` is org-scoped, and each row's `your agents` clause names by handle which of your org's agents are seated in that group: look for the acting agent's own handle there before posting, because an empty clause means none of them is and a send into that group would be refused. To read what has been said in the group since this agent joined, name the group to `rine_thread` — its handle or its id; each `rine_groups` row's `conversation_id` works too, and a group nobody has posted in yet has none |
|
|
107
|
+
| `rine_group_create` / `_invite` / `_remove` / `_inspect` / `_roster` / `_join` / `_invites` | MLS-by-default groups. A founding roster on create invites under every enrollment policy; a later `_invite` mints an invitation on a closed group and **nominates** on a majority or unanimity one, where the electorate decides. `_create`'s `voteDurationHours` (1-72, default 72) sets how long such a vote stays open; `description` is server-visible house rules, NOT end-to-end encrypted. `_inspect` says what kind of group it is, `_roster` says who is in it and marks your own org's members `(yours)` without hiding anybody else's, and `_invites` lists invitations and nominations addressed to this agent, told apart by status |
|
|
108
|
+
| `rine_group_requests` / `_vote` | The outstanding admissions of a group, and the vote that decides one — by the members it had when it was filed who are still in it. Denials refuse it on that same electorate, so both bars fall as members leave |
|
|
109
|
+
| `rine_group_leave` | Leave a group, retiring this host's key material for it |
|
|
110
|
+
| `rine_group_sync` | Catch this host's MLS state up with a group it fell behind |
|
|
111
|
+
| `rine_group_reclaim` | Seat the unseated, then retire the ratchet-tree leaves no member and no live invitation accounts for |
|
|
106
112
|
| `rine_pay` | Pay a received `rine.v1.x402_payment_required` quote under the local spend policy |
|
|
107
113
|
| `rine_fulfill` | Payee side: verify + settle a received payment and reply with a receipt |
|
|
108
114
|
|
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 { _ as
|
|
1
|
+
import { _ as renderThreadLine, b as verifiedNote, n as asRecipient, p as renderMessageBody, y as senderLabel } from "./tool-DeOeMNlK.js";
|
|
2
2
|
import { n as verifyRineSignature } from "./hmac-CoaKHmf6.js";
|
|
3
|
-
import {
|
|
3
|
+
import { n as getRineClient, t as actingAgent } from "./client-CXJATA-m.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,27 +256,30 @@ 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
|
-
* TRUST NOTE: `verified === true`
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
* verified
|
|
268
|
-
*
|
|
263
|
+
* TRUST NOTE: `verified === true` means the envelope signature checked out AND the
|
|
264
|
+
* signing key it names belongs to the agent the server authenticated as the sender.
|
|
265
|
+
* The `from_agent_id` this module routes and displays therefore IS the signer: a
|
|
266
|
+
* peer cannot re-seal another agent's signed content and have it render here as
|
|
267
|
+
* verified content of its own. Two limits remain. `sender_handle` is the server's
|
|
268
|
+
* rendering of that agent id, so routing stays on the id. And the signature covers
|
|
269
|
+
* the payload only — not this recipient, and no nonce — so an agent re-sending
|
|
270
|
+
* content it signed earlier produces a copy that verifies as its own; the message
|
|
271
|
+
* `id` is the de-duplication key (what the dedupe step above uses).
|
|
269
272
|
*/
|
|
270
273
|
/** The line of context handed to the model so it knows who/where the message is from. */
|
|
271
274
|
function senderContextLine(msg) {
|
|
272
275
|
const where = msg.group_handle ? ` in group ${msg.group_handle}` : "";
|
|
273
276
|
return `Inbound rine message from ${senderLabel(msg)}${where} (type ${msg.type}, ${verifiedNote(msg)}). Your reply is delivered back to the sender over rine.`;
|
|
274
277
|
}
|
|
275
|
-
/** Cap on turns fetched for the push-injected transcript
|
|
278
|
+
/** Cap on turns fetched for the push-injected transcript. */
|
|
276
279
|
const THREAD_FETCH_LIMIT = 50;
|
|
277
280
|
/**
|
|
278
281
|
* The inbound pipeline. Returns the HTTP {@link Response} the route should send.
|
|
279
|
-
* Status codes are retry-aware
|
|
282
|
+
* Status codes are retry-aware: `5xx` = transient (caller should retry),
|
|
280
283
|
* `4xx` = terminal drop, `2xx` = accepted/benign-ignore.
|
|
281
284
|
*/
|
|
282
285
|
async function processInbound(deps) {
|
|
@@ -331,15 +334,15 @@ async function processInbound(deps) {
|
|
|
331
334
|
* unit-testable with fake clients. `channel.ts` wires these to Eve's
|
|
332
335
|
* `message.completed` / failure events; the INBOUND half lives in `channel-core.ts`.
|
|
333
336
|
*
|
|
334
|
-
* On a terminal assistant message
|
|
335
|
-
* endpoint, preserving the inbound conversation
|
|
337
|
+
* On a terminal assistant message, reply back over rine IN-PLACE via the reply
|
|
338
|
+
* endpoint, preserving the inbound conversation; falls back to
|
|
336
339
|
* `parentConversationId` for legacy tokens. A session started by an x402 frame never
|
|
337
340
|
* prose-replies into the payment thread (the pay / fulfill tools transmit the signed
|
|
338
341
|
* frame in-thread instead) — the `x402` continuation-token flag short-circuits both.
|
|
339
342
|
*/
|
|
340
343
|
/**
|
|
341
344
|
* Outbound for `message.completed`: every TERMINAL assistant message (any
|
|
342
|
-
* `finishReason` except the intermediate `tool-calls
|
|
345
|
+
* `finishReason` except the intermediate `tool-calls`) with text becomes a
|
|
343
346
|
* reply. When the continuation token carries the inbound message id we reply
|
|
344
347
|
* IN-PLACE via the reply endpoint (same conversation, no fork) keeping the
|
|
345
348
|
* connector's `replyMessageType` unchanged — type-preserving, so terminal/wake
|
|
@@ -386,15 +389,15 @@ async function processFailure(continuationToken, client) {
|
|
|
386
389
|
const DEFAULT_INBOUND_PATH = "/rine/v1/inbound";
|
|
387
390
|
const DEFAULT_REPLY_TYPE = "rine.v1.task_response";
|
|
388
391
|
const DEFAULT_MAX_BODY_BYTES = 512 * 1024;
|
|
389
|
-
/** Default token budget for the push-injected transcript (
|
|
392
|
+
/** Default token budget for the push-injected transcript (≈8000 chars). */
|
|
390
393
|
const DEFAULT_THREAD_CONTEXT_TOKEN_BUDGET = 2e3;
|
|
391
394
|
/**
|
|
392
|
-
* Message types never auto-replied to (loop guard
|
|
395
|
+
* Message types never auto-replied to (loop guard): the connector's OWN
|
|
393
396
|
* outbound types (task_response/error/receipt), so two rine-eve agents don't
|
|
394
397
|
* auto-reply to each other forever.
|
|
395
398
|
*
|
|
396
399
|
* The three x402 payment frames are NOT here: v1.1 re-surfaces them as
|
|
397
|
-
* payment-aware agent turns
|
|
400
|
+
* payment-aware agent turns, routed by `handleX402Inbound` with the prose
|
|
398
401
|
* auto-reply suppressed (the `x402` continuation-token flag), never by the generic
|
|
399
402
|
* assistant reply. Adding them here would revert to the v1.0 silent-drop behavior.
|
|
400
403
|
*/
|
|
@@ -418,7 +421,7 @@ function rineChannel(opts = {}) {
|
|
|
418
421
|
const autoPay = opts.payments?.autoPay ?? envFlag(process.env.RINE_X402_AUTO_PAY);
|
|
419
422
|
const seen = /* @__PURE__ */ new Set();
|
|
420
423
|
const client = () => opts.client ?? getRineClient({
|
|
421
|
-
agent: opts
|
|
424
|
+
agent: actingAgent(opts),
|
|
422
425
|
apiUrl: opts.apiUrl,
|
|
423
426
|
configDir: opts.configDir
|
|
424
427
|
});
|
package/dist/channel-core.d.ts
CHANGED
|
@@ -4,16 +4,19 @@
|
|
|
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
|
-
* TRUST NOTE: `verified === true`
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* verified
|
|
16
|
-
*
|
|
11
|
+
* TRUST NOTE: `verified === true` means the envelope signature checked out AND the
|
|
12
|
+
* signing key it names belongs to the agent the server authenticated as the sender.
|
|
13
|
+
* The `from_agent_id` this module routes and displays therefore IS the signer: a
|
|
14
|
+
* peer cannot re-seal another agent's signed content and have it render here as
|
|
15
|
+
* verified content of its own. Two limits remain. `sender_handle` is the server's
|
|
16
|
+
* rendering of that agent id, so routing stays on the id. And the signature covers
|
|
17
|
+
* the payload only — not this recipient, and no nonce — so an agent re-sending
|
|
18
|
+
* content it signed earlier produces a copy that verifies as its own; the message
|
|
19
|
+
* `id` is the de-duplication key (what the dedupe step above uses).
|
|
17
20
|
*/
|
|
18
21
|
import type { AsyncRineClient } from "@rine-network/sdk";
|
|
19
22
|
import type { DecryptedMessage } from "./types.js";
|
|
@@ -41,7 +44,7 @@ export interface InboundDeps {
|
|
|
41
44
|
/** Inbound types to ignore (loop guard). */
|
|
42
45
|
ignoreTypes: readonly string[];
|
|
43
46
|
/**
|
|
44
|
-
*
|
|
47
|
+
* Opt-in auto-pay (default OFF). When true, an inbound `x402_payment_required`
|
|
45
48
|
* at/below the policy's `autoPayThreshold` is paid with NO LLM turn — still
|
|
46
49
|
* bounded by the caps, deny-by-default, journal and reserve-lock. Any decline
|
|
47
50
|
* falls back to surfacing the quote to the model.
|
|
@@ -51,13 +54,13 @@ export interface InboundDeps {
|
|
|
51
54
|
seen?: Set<string>;
|
|
52
55
|
/**
|
|
53
56
|
* Approximate token budget for the role-tagged transcript push-injected into the
|
|
54
|
-
* session context
|
|
57
|
+
* session context. When unset, only the sender line is injected.
|
|
55
58
|
*/
|
|
56
59
|
threadContextTokenBudget?: number;
|
|
57
60
|
}
|
|
58
61
|
/**
|
|
59
62
|
* The inbound pipeline. Returns the HTTP {@link Response} the route should send.
|
|
60
|
-
* Status codes are retry-aware
|
|
63
|
+
* Status codes are retry-aware: `5xx` = transient (caller should retry),
|
|
61
64
|
* `4xx` = terminal drop, `2xx` = accepted/benign-ignore.
|
|
62
65
|
*/
|
|
63
66
|
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,19 +15,19 @@ 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
|
*/
|
|
27
27
|
export declare const DEFAULT_IGNORE_TYPES: string[];
|
|
28
28
|
/** Options for {@link rineChannel}. All optional; identity defaults to env. */
|
|
29
29
|
export interface RineChannelOptions {
|
|
30
|
-
/** Acting agent (handle/name/UUID);
|
|
30
|
+
/** Acting agent (handle/name/UUID); falls back to the `RINE_AGENT` env var. */
|
|
31
31
|
agent?: string;
|
|
32
32
|
apiUrl?: string;
|
|
33
33
|
configDir?: string;
|
|
@@ -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-B81UiHyr.js";
|
|
2
2
|
export { DEFAULT_IGNORE_TYPES, processCompletion, processFailure, processInbound, rineChannel, senderContextLine };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { AsyncRineClient } from "@rine-network/sdk";
|
|
2
|
-
import { resolveApiUrl, resolveConfigDir } from "@rine-network/core";
|
|
2
|
+
import { actorFromEnv, normalizeActor, 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
|
|
@@ -17,6 +17,26 @@ import { resolveApiUrl, resolveConfigDir } from "@rine-network/core";
|
|
|
17
17
|
* `resolveConfigDir()` (env `RINE_CONFIG_DIR` → `~/.config/rine` → cwd/.rine).
|
|
18
18
|
* - the SDK ignores `RINE_API_URL`; we resolve `apiUrl` via `resolveApiUrl()`.
|
|
19
19
|
*/
|
|
20
|
+
/**
|
|
21
|
+
* Rungs 1–3 of the acting-agent ladder, for every rine surface Eve ships: the
|
|
22
|
+
* caller's own value, then `RINE_AGENT`. Returns `undefined` when neither
|
|
23
|
+
* answers, leaving the later rungs (the org's only agent, then a refusal) to
|
|
24
|
+
* whoever needs a resolved id.
|
|
25
|
+
*
|
|
26
|
+
* 🔴 Deliberately NOT folded into {@link getRineClient}. The environment read is
|
|
27
|
+
* a *surface* decision — `rine-ts-sdk` reads no environment at all, because
|
|
28
|
+
* `rine-mastra` builds a bare client for an operator-fixed actor and would
|
|
29
|
+
* inherit anything ambient the SDK picked up. Eve is a surface and opts in here,
|
|
30
|
+
* once, so the four call sites cannot drift apart. Reading it inside
|
|
31
|
+
* `getRineClient` would also make the memoized bare client env-dependent.
|
|
32
|
+
*
|
|
33
|
+
* `normalizeActor` trims and treats empty-after-trim as absent, which is what
|
|
34
|
+
* makes the bare `RINE_AGENT=` line `scaffold.ts` writes into every generated
|
|
35
|
+
* project mean "no actor set" rather than an actor named "".
|
|
36
|
+
*/
|
|
37
|
+
function actingAgent(opts = {}) {
|
|
38
|
+
return normalizeActor(opts.agent) ?? actorFromEnv();
|
|
39
|
+
}
|
|
20
40
|
const clientCache = /* @__PURE__ */ new Map();
|
|
21
41
|
function cacheKey(configDir, apiUrl) {
|
|
22
42
|
return `${configDir} ${apiUrl}`;
|
|
@@ -24,7 +44,7 @@ function cacheKey(configDir, apiUrl) {
|
|
|
24
44
|
/**
|
|
25
45
|
* Get (or lazily build + memoize) the shared `AsyncRineClient` for `opts`,
|
|
26
46
|
* already scoped to `opts.agent` when present. Call ONLY from inside a tool
|
|
27
|
-
* `execute` / a channel handler — never at module top level
|
|
47
|
+
* `execute` / a channel handler — never at module top level.
|
|
28
48
|
*/
|
|
29
49
|
function getRineClient(opts = {}) {
|
|
30
50
|
const configDir = opts.configDir ?? resolveConfigDir();
|
|
@@ -41,4 +61,4 @@ function getRineClient(opts = {}) {
|
|
|
41
61
|
return opts.agent ? base.withAgent(opts.agent) : base;
|
|
42
62
|
}
|
|
43
63
|
//#endregion
|
|
44
|
-
export { getRineClient as t };
|
|
64
|
+
export { getRineClient as n, actingAgent as t };
|
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
|
|
@@ -24,10 +24,28 @@ export interface RineClientOpts {
|
|
|
24
24
|
/** Acting agent (handle/name/UUID) sent as `X-Rine-Agent` on every request. */
|
|
25
25
|
agent?: string;
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Rungs 1–3 of the acting-agent ladder, for every rine surface Eve ships: the
|
|
29
|
+
* caller's own value, then `RINE_AGENT`. Returns `undefined` when neither
|
|
30
|
+
* answers, leaving the later rungs (the org's only agent, then a refusal) to
|
|
31
|
+
* whoever needs a resolved id.
|
|
32
|
+
*
|
|
33
|
+
* 🔴 Deliberately NOT folded into {@link getRineClient}. The environment read is
|
|
34
|
+
* a *surface* decision — `rine-ts-sdk` reads no environment at all, because
|
|
35
|
+
* `rine-mastra` builds a bare client for an operator-fixed actor and would
|
|
36
|
+
* inherit anything ambient the SDK picked up. Eve is a surface and opts in here,
|
|
37
|
+
* once, so the four call sites cannot drift apart. Reading it inside
|
|
38
|
+
* `getRineClient` would also make the memoized bare client env-dependent.
|
|
39
|
+
*
|
|
40
|
+
* `normalizeActor` trims and treats empty-after-trim as absent, which is what
|
|
41
|
+
* makes the bare `RINE_AGENT=` line `scaffold.ts` writes into every generated
|
|
42
|
+
* project mean "no actor set" rather than an actor named "".
|
|
43
|
+
*/
|
|
44
|
+
export declare function actingAgent(opts?: Pick<RineClientOpts, "agent">): string | undefined;
|
|
27
45
|
/**
|
|
28
46
|
* Get (or lazily build + memoize) the shared `AsyncRineClient` for `opts`,
|
|
29
47
|
* already scoped to `opts.agent` when present. Call ONLY from inside a tool
|
|
30
|
-
* `execute` / a channel handler — never at module top level
|
|
48
|
+
* `execute` / a channel handler — never at module top level.
|
|
31
49
|
*/
|
|
32
50
|
export declare function getRineClient(opts?: RineClientOpts): AsyncRineClient;
|
|
33
51
|
/** 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
|
*
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The plural group renderers: the caller's own groups, a directory search, and
|
|
3
|
+
* one group's roster. `format.ts`'s `renderGroup` renders exactly ONE group and
|
|
4
|
+
* is what `rine_group_inspect` returns; these render pages, one numbered row
|
|
5
|
+
* each, in the shape `renderInbox`/`renderDiscover` already use.
|
|
6
|
+
*
|
|
7
|
+
* A sibling of `format.ts` rather than part of it, for the same reason
|
|
8
|
+
* `format-groups.ts` is one — `format.ts` holds its ~200-LOC budget.
|
|
9
|
+
*
|
|
10
|
+
* The types come from `@rine-network/sdk` directly: the SDK exports them
|
|
11
|
+
* alongside their schemas, so there is nothing here to re-derive.
|
|
12
|
+
*/
|
|
13
|
+
import { type AgentHandleMap, type GroupMember, type GroupRead, type GroupSummary } from "@rine-network/sdk";
|
|
14
|
+
/**
|
|
15
|
+
* What a group with no conversation renders instead of an id.
|
|
16
|
+
*
|
|
17
|
+
* A group's thread is created lazily on its first post, so a null
|
|
18
|
+
* `conversation_id` is the fact "nothing has been said in this group yet" — not
|
|
19
|
+
* an error, not a refusal, and not a missing field. The clause is never omitted
|
|
20
|
+
* on null: a model that sees it on some rows and not others reads the absence
|
|
21
|
+
* as a rendering fault rather than as a fact about the group.
|
|
22
|
+
*
|
|
23
|
+
* `format.ts`'s `renderGroup` imports it from here so the two renderers cannot
|
|
24
|
+
* tell a model two different things about the same group. The same sentence is
|
|
25
|
+
* printed by the CLI, crewai, langchain, hermes and mastra; it is restated per
|
|
26
|
+
* package because there is no runtime module all of them import.
|
|
27
|
+
*/
|
|
28
|
+
export declare const NO_CONVERSATION = "(none \u2014 nothing has been said in this group yet)";
|
|
29
|
+
/**
|
|
30
|
+
* What a group renders in place of an agent list when this org holds no seat.
|
|
31
|
+
*
|
|
32
|
+
* The group list is ORG-scoped — it reports every group any agent of this org
|
|
33
|
+
* is in — so a row on it was never proof that the agent this host is acting as
|
|
34
|
+
* may post there. The empty list is that proof's absence stated plainly: no
|
|
35
|
+
* agent of this org is seated, and a send into the group would be refused.
|
|
36
|
+
*
|
|
37
|
+
* Never omitted, for the reason `NO_CONVERSATION` gives above: a clause a model
|
|
38
|
+
* sees on some rows and not others reads as a rendering fault rather than as a
|
|
39
|
+
* fact about the group. Restated per package because there is no runtime module
|
|
40
|
+
* all seven rendering surfaces import — though this package and its twin do
|
|
41
|
+
* share one (`@rine-network/sdk`), so the day either reworded its row would be
|
|
42
|
+
* the day the sentence belongs there instead.
|
|
43
|
+
*
|
|
44
|
+
* Pinned meanwhile: `tests/test_client-server-contract_group0.py` compares the
|
|
45
|
+
* four declared copies against `rine.group_words.NO_OWN_AGENTS`, which the
|
|
46
|
+
* three Python surfaces import, so a reword in one package fails there rather
|
|
47
|
+
* than shipping two answers to one question.
|
|
48
|
+
*/
|
|
49
|
+
export declare const NO_OWN_AGENTS = "(none \u2014 no agent of your org is seated in this group)";
|
|
50
|
+
/**
|
|
51
|
+
* The seated-agents clause, from the one place both renderers read it.
|
|
52
|
+
*
|
|
53
|
+
* `format.ts`'s `renderGroup` calls this too, so the row and the single-group
|
|
54
|
+
* view cannot tell a model two different things about the same group — the same
|
|
55
|
+
* reason `NO_CONVERSATION` is imported there rather than retyped.
|
|
56
|
+
*
|
|
57
|
+
* Each id renders as its HANDLE. The three cases, and why a name is never one
|
|
58
|
+
* of them, are stated once on `AgentHandleMap` in the SDK
|
|
59
|
+
* (`rine-ts-sdk/src/resources/agent-handles.ts`); this renderer is one of the
|
|
60
|
+
* four that follow them. In short: a known id prints its handle, an unknown one
|
|
61
|
+
* prints itself, an empty list prints {@link NO_OWN_AGENTS}. A model handed a
|
|
62
|
+
* UUID cannot tell which of its agents it names — that is the whole reason
|
|
63
|
+
* handle resolution exists here — but a UUID is still addressable, so an
|
|
64
|
+
* unresolved id is degraded, not lost.
|
|
65
|
+
*
|
|
66
|
+
* `handles` is omitted whenever the org's agent list could not be read; that is
|
|
67
|
+
* case 2 for every id, and it is why nothing here throws.
|
|
68
|
+
*
|
|
69
|
+
* `undefined` is accepted on purpose. `GroupReadSchema` defaults the field to
|
|
70
|
+
* `[]`, so a parsed row always has one — but a row that never went through that
|
|
71
|
+
* parse (a hand-built object, a fake) has nothing, and a renderer whose job is
|
|
72
|
+
* to state an absence must not throw on one.
|
|
73
|
+
*/
|
|
74
|
+
export declare function renderOwnAgents(ids: readonly string[] | undefined, handles?: AgentHandleMap): string;
|
|
75
|
+
/**
|
|
76
|
+
* How this package names a group's regime in one field, for a LIST ROW.
|
|
77
|
+
*
|
|
78
|
+
* One definition for the row, and for the row only. It is NOT what the create
|
|
79
|
+
* confirmation head asks: what a freshly created group runs is decided from the
|
|
80
|
+
* create RESULT, by `createdGroupMls` in `@rine-network/core`, because the row
|
|
81
|
+
* alone cannot tell a founded group from an unfounded one. `renderGroup`'s
|
|
82
|
+
* `[OK]` line re-derives its first clause from the predicates directly and has
|
|
83
|
+
* never called this either. So a reword here reaches this row and nothing else,
|
|
84
|
+
* and a reword in either of those two does not reach this row.
|
|
85
|
+
*
|
|
86
|
+
* The init window is reported as MLS because sends into it already are MLS, and
|
|
87
|
+
* a field that said "sender-key" there would state the opposite of what is
|
|
88
|
+
* happening. The window's own distinction is `rine_group_inspect`'s to make.
|
|
89
|
+
*
|
|
90
|
+
* A group created to run MLS whose ratchet tree was never founded really does
|
|
91
|
+
* carry sender-key traffic, so it names sender keys — and says the rest of the
|
|
92
|
+
* answer, because that row is otherwise field-for-field an open group's and
|
|
93
|
+
* nothing else on the page can tell the two apart. The parenthesis carries NO
|
|
94
|
+
* comma: the row below is comma-separated, which is the same reason its last
|
|
95
|
+
* clause opens with `; `. The whole sentence lives in `rine_group_inspect`; a
|
|
96
|
+
* list row is not the place for it.
|
|
97
|
+
*/
|
|
98
|
+
export declare function groupModeLabel(g: GroupRead): string;
|
|
99
|
+
/**
|
|
100
|
+
* A numbered list of the groups this org's agents are seated in, or the
|
|
101
|
+
* empty-state line.
|
|
102
|
+
*
|
|
103
|
+
* The list is org-scoped, and each row's `your agents` clause names which of
|
|
104
|
+
* this org's agents are seated in that group — an empty clause means none of
|
|
105
|
+
* them is, and a send into that group would be refused. The clause names them
|
|
106
|
+
* by handle because that is the spelling `rine_whoami` prints, so the two
|
|
107
|
+
* outputs can be read against each other — a UUID matched nothing this surface
|
|
108
|
+
* had ever shown the model. What neither tool says is which agent this host is
|
|
109
|
+
* acting AS: `WhoAmI` carries no such field and `renderWhoAmI` marks no row, so
|
|
110
|
+
* in a multi-agent org that still has to come from the host's own config (the
|
|
111
|
+
* `agent` this client was built with, which may itself have been given as a
|
|
112
|
+
* UUID).
|
|
113
|
+
*/
|
|
114
|
+
export declare function renderGroups(items: readonly GroupRead[], handles?: AgentHandleMap): string;
|
|
115
|
+
/**
|
|
116
|
+
* A numbered list of publicly listed groups, or the empty-state line.
|
|
117
|
+
*
|
|
118
|
+
* The header says what the list IS. `GET /directory/groups` is an
|
|
119
|
+
* unauthenticated public-visibility scan across every org and carries no
|
|
120
|
+
* identity at all, so nothing on a row can say whether this agent holds a seat
|
|
121
|
+
* in that group — while `renderGroups` above prints near-identical rows that
|
|
122
|
+
* end with exactly that. Two numbered lists told apart by two words in a header
|
|
123
|
+
* is not enough, so this one says the difference outright.
|
|
124
|
+
*
|
|
125
|
+
* It names no verb: the header states what the caller is looking at, and which
|
|
126
|
+
* tool to reach for next is the tool description's sentence, not this one's.
|
|
127
|
+
*/
|
|
128
|
+
export declare function renderGroupSummaries(items: readonly GroupSummary[]): string;
|
|
129
|
+
/**
|
|
130
|
+
* A numbered roster, or the empty-state line.
|
|
131
|
+
*
|
|
132
|
+
* The roster is members only. An invitation and a nomination hold a seat
|
|
133
|
+
* against the group's ceiling without appearing here — `rine_group_requests`
|
|
134
|
+
* is what reports those — so a roster shorter than the ceiling suggests is not
|
|
135
|
+
* a gap in this list.
|
|
136
|
+
*
|
|
137
|
+
* Every member is listed, from every org. Nothing here filters on whose agent
|
|
138
|
+
* a row is; `(yours)` marks this org's rows and takes none away.
|
|
139
|
+
*/
|
|
140
|
+
export declare function renderRoster(items: readonly GroupMember[]): string;
|