@nority/bridge-sdk 0.2.0 → 0.2.2
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 +124 -10
- package/dist/agent.d.ts +58 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/auth/jwt.d.ts +9 -0
- package/dist/auth/jwt.d.ts.map +1 -1
- package/dist/auth/jwt.js +2 -0
- package/dist/auth/jwt.js.map +1 -1
- package/dist/auth/pairing.d.ts +9 -0
- package/dist/auth/pairing.d.ts.map +1 -1
- package/dist/auth/pairing.js +6 -0
- package/dist/auth/pairing.js.map +1 -1
- package/dist/auth/reconnect.d.ts +9 -0
- package/dist/auth/reconnect.d.ts.map +1 -1
- package/dist/auth/reconnect.js +2 -0
- package/dist/auth/reconnect.js.map +1 -1
- package/dist/connection-types.d.ts +20 -0
- package/dist/connection-types.d.ts.map +1 -1
- package/dist/conversation/replay.d.ts +22 -0
- package/dist/conversation/replay.d.ts.map +1 -1
- package/dist/conversation/replay.js +9 -0
- package/dist/conversation/replay.js.map +1 -1
- package/dist/conversation/runtime.d.ts +1 -0
- package/dist/conversation/runtime.d.ts.map +1 -1
- package/dist/conversation/runtime.js.map +1 -1
- package/dist/conversation/state.d.ts +7 -0
- package/dist/conversation/state.d.ts.map +1 -1
- package/dist/conversation/state.js +6 -0
- package/dist/conversation/state.js.map +1 -1
- package/dist/crypto/conversation.d.ts +2 -0
- package/dist/crypto/conversation.d.ts.map +1 -1
- package/dist/crypto/conversation.js +2 -0
- package/dist/crypto/conversation.js.map +1 -1
- package/dist/crypto/identity.d.ts +3 -0
- package/dist/crypto/identity.d.ts.map +1 -1
- package/dist/crypto/identity.js.map +1 -1
- package/dist/crypto/x25519.d.ts +6 -0
- package/dist/crypto/x25519.d.ts.map +1 -1
- package/dist/crypto/x25519.js +3 -0
- package/dist/crypto/x25519.js.map +1 -1
- package/dist/pairing/client.d.ts.map +1 -1
- package/dist/pairing/client.js +3 -5
- package/dist/pairing/client.js.map +1 -1
- package/dist/pairing/types.d.ts +25 -0
- package/dist/pairing/types.d.ts.map +1 -1
- package/dist/protocol/frames.d.ts +3 -0
- package/dist/protocol/frames.d.ts.map +1 -1
- package/dist/protocol/frames.js.map +1 -1
- package/dist/protocol/validation.d.ts +4 -0
- package/dist/protocol/validation.d.ts.map +1 -1
- package/dist/protocol/validation.js +1 -0
- package/dist/protocol/validation.js.map +1 -1
- package/dist/runtime/proactive.d.ts +4 -0
- package/dist/runtime/proactive.d.ts.map +1 -1
- package/dist/runtime/proactive.js.map +1 -1
- package/dist/transport/websocket.d.ts +44 -0
- package/dist/transport/websocket.d.ts.map +1 -1
- package/dist/transport/websocket.js +9 -1
- package/dist/transport/websocket.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -68,18 +68,92 @@ const bridge = new NorityBridge({
|
|
|
68
68
|
backendUrl: "wss://api.nority.ai/v1/bridge",
|
|
69
69
|
dataDir: "./bridge-data",
|
|
70
70
|
agent: new MyAdapter(),
|
|
71
|
-
|
|
71
|
+
onPairingInfo: (info) => {
|
|
72
72
|
console.log(`Pair: ${info.deeplinkUrl} (expires ${info.expiresAt})`);
|
|
73
73
|
},
|
|
74
74
|
});
|
|
75
75
|
|
|
76
76
|
await bridge.start();
|
|
77
|
+
// Bridge is now connected and handling conversations
|
|
77
78
|
```
|
|
78
79
|
|
|
79
|
-
On first run, the SDK generates an Ed25519 identity, enters the pairing flow, and calls `
|
|
80
|
+
On first run, the SDK generates an Ed25519 identity, enters the pairing flow, and calls `onPairingInfo` with a QR/deeplink URL. `start()` blocks until the user approves in the Nority app and the bridge connects.
|
|
80
81
|
|
|
81
82
|
On subsequent runs, the SDK loads the stored credential, mints a fresh JWT via challenge-response, reconnects, replays missed events, and resumes normal operation.
|
|
82
83
|
|
|
84
|
+
## Layered API
|
|
85
|
+
|
|
86
|
+
The SDK exposes three levels of abstraction. Most developers only need `NorityBridge`.
|
|
87
|
+
|
|
88
|
+
### `NorityBridge` — managed (recommended)
|
|
89
|
+
|
|
90
|
+
Handles everything: pairing, credential persistence, auth, transport, conversations. `start()` blocks until fully connected regardless of whether pairing was needed.
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
import { NorityBridge } from "@nority/bridge-sdk";
|
|
94
|
+
|
|
95
|
+
const bridge = new NorityBridge({
|
|
96
|
+
backendUrl: "wss://api.nority.ai/v1/bridge",
|
|
97
|
+
dataDir: "./bridge-data",
|
|
98
|
+
agent: myAdapter,
|
|
99
|
+
onPairingInfo: (info) => console.log(`Scan: ${info.deeplinkUrl}`),
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
await bridge.start(); // blocks until connected
|
|
103
|
+
await bridge.stop(); // graceful shutdown
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### `PairingClient` — standalone pairing
|
|
107
|
+
|
|
108
|
+
Use this when you want to control the pairing ceremony yourself — embed the QR in your own UI, store the credential in your own database, or skip pairing entirely with pre-provisioned credentials.
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
import { PairingClient } from "@nority/bridge-sdk";
|
|
112
|
+
|
|
113
|
+
const pairing = new PairingClient({
|
|
114
|
+
backendUrl: "wss://api.nority.ai/v1/bridge",
|
|
115
|
+
dataDir: "./bridge-data",
|
|
116
|
+
onPairingInfo: (info) => renderQRCode(info.deeplinkUrl),
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const result = await pairing.pair(); // blocks until user approves
|
|
120
|
+
// result.credential — durable bridge credential
|
|
121
|
+
// result.identity — Ed25519 keypair
|
|
122
|
+
// result.initialToken — first JWT (pass as seedJwt to BridgeConnection)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Methods:**
|
|
126
|
+
- `pair()` — performs the pairing ceremony. Resolves when the user approves. Single-flight (throws if called while already pairing).
|
|
127
|
+
- `cancel()` — cancels in-progress pairing. Rejects the pending `pair()` promise. Idempotent.
|
|
128
|
+
- `regenerateToken()` — closes the WebSocket, opens a new one, sends a fresh `pair_request`. Returns updated `PairingInfo`.
|
|
129
|
+
- `getPairingInfo()` — returns current pairing info or `null`.
|
|
130
|
+
|
|
131
|
+
### `BridgeConnection` — standalone connection
|
|
132
|
+
|
|
133
|
+
Use this when you already have a credential (pre-provisioned from a dashboard, stored in your own secret manager, or obtained via `PairingClient`).
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
import { BridgeConnection } from "@nority/bridge-sdk";
|
|
137
|
+
|
|
138
|
+
const connection = new BridgeConnection({
|
|
139
|
+
backendUrl: "wss://api.nority.ai/v1/bridge",
|
|
140
|
+
dataDir: "./bridge-data",
|
|
141
|
+
credential: process.env.BRIDGE_CREDENTIAL,
|
|
142
|
+
privateKeyPem: fs.readFileSync("./bridge-key.pem", "utf-8"),
|
|
143
|
+
agent: myAdapter,
|
|
144
|
+
seedJwt: cachedToken, // optional — skip first challenge-response
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
await connection.connect(); // blocks until connected
|
|
148
|
+
await connection.disconnect(); // graceful shutdown
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**Methods:**
|
|
152
|
+
- `connect()` — authenticates via challenge-response, opens authenticated WebSocket, sends replay request. Resolves when connected.
|
|
153
|
+
- `disconnect()` — closes connection, stops reconnection, aborts active agent invocations. Idempotent.
|
|
154
|
+
- `getState()` — returns current state (`idle | connecting | connected | reconnecting | blocked | failed | stopped`).
|
|
155
|
+
- `createProactiveTurnFrame(conversationId, request)` — creates an `assistant_turn_start` frame for bridge-initiated turns.
|
|
156
|
+
|
|
83
157
|
## Key concepts
|
|
84
158
|
|
|
85
159
|
| Concept | Description |
|
|
@@ -141,16 +215,56 @@ idle → pairing → connecting → connected
|
|
|
141
215
|
|
|
142
216
|
## Configuration
|
|
143
217
|
|
|
218
|
+
### `BridgeConfig` (for `NorityBridge`)
|
|
219
|
+
|
|
144
220
|
```ts
|
|
145
221
|
interface BridgeConfig {
|
|
146
|
-
backendUrl: string;
|
|
147
|
-
dataDir: string;
|
|
148
|
-
agent: AgentAdapter;
|
|
149
|
-
|
|
150
|
-
logger?: BridgeLogger;
|
|
151
|
-
webSocketFactory?: WebSocketFactory;
|
|
152
|
-
|
|
153
|
-
|
|
222
|
+
backendUrl: string; // Nority backend WebSocket URL
|
|
223
|
+
dataDir: string; // Directory for durable state (identity, keys)
|
|
224
|
+
agent: AgentAdapter; // Your adapter implementation
|
|
225
|
+
onPairingInfo?: (pairing: PairingInfo) => void; // Called when pairing token is ready
|
|
226
|
+
logger?: BridgeLogger; // Structured logging
|
|
227
|
+
webSocketFactory?: WebSocketFactory; // Override the built-in ws-based WebSocket
|
|
228
|
+
fetchImplementation?: typeof fetch; // Custom fetch (for auth challenge-response)
|
|
229
|
+
clock?: () => Date; // Custom clock (for testing)
|
|
230
|
+
pairingTokenFactory?: () => string; // Custom pairing token generator
|
|
231
|
+
backoffRandom?: () => number; // Custom RNG for reconnect backoff jitter
|
|
232
|
+
heartbeatIntervalMs?: number; // Default: 15000
|
|
233
|
+
idleTimeoutMs?: number; // Default: 45000
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### `PairingClientConfig`
|
|
238
|
+
|
|
239
|
+
```ts
|
|
240
|
+
interface PairingClientConfig {
|
|
241
|
+
backendUrl: string;
|
|
242
|
+
dataDir: string;
|
|
243
|
+
onPairingInfo?: (info: PairingInfo) => void;
|
|
244
|
+
logger?: BridgeLogger;
|
|
245
|
+
webSocketFactory?: WebSocketFactory; // Override the built-in ws-based WebSocket
|
|
246
|
+
clock?: () => Date;
|
|
247
|
+
pairingTokenFactory?: () => string;
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### `BridgeConnectionConfig`
|
|
252
|
+
|
|
253
|
+
```ts
|
|
254
|
+
interface BridgeConnectionConfig {
|
|
255
|
+
backendUrl: string;
|
|
256
|
+
dataDir: string;
|
|
257
|
+
credential: string;
|
|
258
|
+
privateKeyPem: string;
|
|
259
|
+
agent: AgentAdapter;
|
|
260
|
+
logger?: BridgeLogger;
|
|
261
|
+
seedJwt?: AccessTokenRecord;
|
|
262
|
+
fetchImplementation?: typeof fetch;
|
|
263
|
+
webSocketFactory?: WebSocketFactory; // Override the built-in ws-based WebSocket
|
|
264
|
+
clock?: () => Date;
|
|
265
|
+
backoffRandom?: () => number;
|
|
266
|
+
heartbeatIntervalMs?: number;
|
|
267
|
+
idleTimeoutMs?: number;
|
|
154
268
|
}
|
|
155
269
|
```
|
|
156
270
|
|
package/dist/agent.d.ts
CHANGED
|
@@ -3,12 +3,21 @@
|
|
|
3
3
|
* Provider-agnostic — no assumptions about the agent runtime transport.
|
|
4
4
|
*/
|
|
5
5
|
import type { WebSocketFactory } from "./transport/websocket.js";
|
|
6
|
+
/** Reference to a media asset (image, file, etc.) within a conversation. */
|
|
6
7
|
export interface MediaReference {
|
|
8
|
+
/** Unique identifier for the media asset. */
|
|
7
9
|
mediaId: string;
|
|
10
|
+
/** MIME type of the media (e.g. "image/png"). */
|
|
8
11
|
mediaType: string;
|
|
12
|
+
/** Size of the media in bytes. */
|
|
9
13
|
size: number;
|
|
14
|
+
/** Optional base64-encoded thumbnail for preview. */
|
|
10
15
|
thumbnailB64?: string;
|
|
11
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* A single piece of content within a conversation turn.
|
|
19
|
+
* Multimodal-safe: supports text and media from day one.
|
|
20
|
+
*/
|
|
12
21
|
export type ContentPart = {
|
|
13
22
|
kind: "text";
|
|
14
23
|
text: string;
|
|
@@ -16,15 +25,28 @@ export type ContentPart = {
|
|
|
16
25
|
kind: "media";
|
|
17
26
|
media: MediaReference;
|
|
18
27
|
};
|
|
28
|
+
/** A single turn in a conversation, representing either a user or assistant message. */
|
|
19
29
|
export interface ChatTurn {
|
|
30
|
+
/** Who produced this turn. */
|
|
20
31
|
role: "user" | "assistant";
|
|
32
|
+
/** Ordered content parts that make up the turn. */
|
|
21
33
|
parts: ContentPart[];
|
|
22
34
|
}
|
|
35
|
+
/** The request payload passed to {@link AgentAdapter.invokeAgent}. */
|
|
23
36
|
export interface InvokeRequest {
|
|
37
|
+
/** Unique conversation identifier. */
|
|
24
38
|
conversationId: string;
|
|
39
|
+
/** Content parts from the current user turn. */
|
|
25
40
|
inputs: ContentPart[];
|
|
41
|
+
/** Previous conversation turns for context. */
|
|
26
42
|
history: ChatTurn[];
|
|
27
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* A streaming event yielded by the agent adapter during an invocation.
|
|
46
|
+
*
|
|
47
|
+
* The SDK encrypts each event and forwards it to the backend in real time.
|
|
48
|
+
* The final event yielded **must** be `{ type: "done" }`.
|
|
49
|
+
*/
|
|
28
50
|
export type AgentEvent = {
|
|
29
51
|
type: "text_delta";
|
|
30
52
|
content: string;
|
|
@@ -70,32 +92,68 @@ export type AgentEvent = {
|
|
|
70
92
|
} | {
|
|
71
93
|
type: "done";
|
|
72
94
|
};
|
|
95
|
+
/**
|
|
96
|
+
* Provider-agnostic agent adapter interface.
|
|
97
|
+
*
|
|
98
|
+
* Implement this to connect your agent runtime to the Nority bridge.
|
|
99
|
+
* The SDK calls {@link invokeAgent} for each incoming user message and
|
|
100
|
+
* streams the yielded {@link AgentEvent}s back to the user.
|
|
101
|
+
*/
|
|
73
102
|
export interface AgentAdapter {
|
|
103
|
+
/**
|
|
104
|
+
* Invokes the agent with the given request and yields streaming events.
|
|
105
|
+
*
|
|
106
|
+
* @param signal - Aborted when the conversation is deleted or the bridge disconnects.
|
|
107
|
+
* @param req - The invocation request containing user input and conversation history.
|
|
108
|
+
*/
|
|
74
109
|
invokeAgent(signal: AbortSignal, req: InvokeRequest): AsyncIterable<AgentEvent>;
|
|
75
110
|
}
|
|
111
|
+
/** Information about an active pairing token, used to display a QR code or deeplink. */
|
|
76
112
|
export interface PairingInfo {
|
|
113
|
+
/** The pairing token string. */
|
|
77
114
|
token: string;
|
|
115
|
+
/** The `nority://` deeplink URL containing the token. */
|
|
78
116
|
deeplinkUrl: string;
|
|
117
|
+
/** ISO 8601 timestamp when this token expires (auto-regenerates after expiry). */
|
|
79
118
|
expiresAt: string;
|
|
80
119
|
}
|
|
120
|
+
/** Structured logger interface accepted by all SDK components. */
|
|
81
121
|
export interface BridgeLogger {
|
|
82
122
|
debug: (msg: string, ...args: unknown[]) => void;
|
|
83
123
|
info: (msg: string, ...args: unknown[]) => void;
|
|
84
124
|
warn: (msg: string, ...args: unknown[]) => void;
|
|
85
125
|
error: (msg: string, ...args: unknown[]) => void;
|
|
86
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* Configuration for {@link NorityBridge}, the managed entry point.
|
|
129
|
+
*
|
|
130
|
+
* Only `backendUrl`, `dataDir`, and `agent` are required.
|
|
131
|
+
* All other fields have sensible defaults.
|
|
132
|
+
*/
|
|
87
133
|
export interface BridgeConfig {
|
|
134
|
+
/** Nority backend WebSocket URL. */
|
|
88
135
|
backendUrl: string;
|
|
136
|
+
/** Directory for durable state (Ed25519 identity, conversation keys). */
|
|
89
137
|
dataDir: string;
|
|
138
|
+
/** Your agent adapter implementation. */
|
|
90
139
|
agent: AgentAdapter;
|
|
140
|
+
/** Called when a pairing token is ready — use this to display a QR code. */
|
|
91
141
|
onPairingInfo?: (pairing: PairingInfo) => void;
|
|
142
|
+
/** Structured logger. Defaults to no-op. */
|
|
92
143
|
logger?: BridgeLogger;
|
|
144
|
+
/** Override the default `fetch` used for challenge-response auth. */
|
|
93
145
|
fetchImplementation?: typeof fetch;
|
|
146
|
+
/** Override the built-in `ws`-based WebSocket. */
|
|
94
147
|
webSocketFactory?: WebSocketFactory;
|
|
148
|
+
/** Override the system clock (useful for testing). */
|
|
95
149
|
clock?: () => Date;
|
|
150
|
+
/** Override the random pairing token generator. */
|
|
96
151
|
pairingTokenFactory?: () => string;
|
|
152
|
+
/** Override `Math.random` for reconnect backoff jitter (useful for testing). */
|
|
97
153
|
backoffRandom?: () => number;
|
|
154
|
+
/** Heartbeat interval in milliseconds. Default: 15000. */
|
|
98
155
|
heartbeatIntervalMs?: number;
|
|
156
|
+
/** Idle timeout in milliseconds. Must be greater than `heartbeatIntervalMs`. Default: 45000. */
|
|
99
157
|
idleTimeoutMs?: number;
|
|
100
158
|
}
|
|
101
159
|
//# sourceMappingURL=agent.d.ts.map
|
package/dist/agent.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/jwt.d.ts
CHANGED
|
@@ -6,15 +6,24 @@
|
|
|
6
6
|
* - Bridge-scoped (audience: "nority-bridge")
|
|
7
7
|
* - Least-privilege (scope: "bridge:connect bridge:replay bridge:events")
|
|
8
8
|
*/
|
|
9
|
+
/** JWT audience claim for bridge access tokens. */
|
|
9
10
|
export declare const BRIDGE_JWT_AUDIENCE = "nority-bridge";
|
|
11
|
+
/** JWT scopes granted to bridge access tokens. */
|
|
10
12
|
export declare const BRIDGE_JWT_SCOPES: readonly ["bridge:connect", "bridge:replay", "bridge:events"];
|
|
13
|
+
/** A short-lived bridge access JWT with its expiry metadata. */
|
|
11
14
|
export interface AccessTokenRecord {
|
|
15
|
+
/** The raw JWT string. */
|
|
12
16
|
accessJwt: string;
|
|
17
|
+
/** ISO 8601 expiry timestamp. */
|
|
13
18
|
expiresAt: string;
|
|
19
|
+
/** Agent ID the token was issued for (when available). */
|
|
14
20
|
agentId?: string;
|
|
15
21
|
}
|
|
22
|
+
/** Options for {@link JwtCache}. */
|
|
16
23
|
export interface JwtCacheOptions {
|
|
24
|
+
/** Override the system clock (useful for testing). */
|
|
17
25
|
clock?: () => Date;
|
|
26
|
+
/** How many milliseconds before expiry to consider a token stale. Default: 5000. */
|
|
18
27
|
expirySkewMs?: number;
|
|
19
28
|
}
|
|
20
29
|
/**
|
package/dist/auth/jwt.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/auth/jwt.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/auth/jwt.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,mDAAmD;AACnD,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AAEnD,kDAAkD;AAClD,eAAO,MAAM,iBAAiB,+DAIpB,CAAC;AAEX,gEAAgE;AAChE,MAAM,WAAW,iBAAiB;IAChC,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,oCAAoC;AACpC,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB,oFAAoF;IACpF,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,MAAM,EACX,eAAe,SAAoB,GAClC,OAAO,CAqBT;AAED;;GAEG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,OAAO,CAAkC;gBAErC,OAAO,GAAE,eAAoB;IAKzC,IAAI,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAKrC,KAAK,IAAI,IAAI;IAIb,QAAQ,IAAI,iBAAiB,GAAG,IAAI;IAqBpC,OAAO,CAAC,YAAY;CAarB"}
|
package/dist/auth/jwt.js
CHANGED
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
* - Bridge-scoped (audience: "nority-bridge")
|
|
7
7
|
* - Least-privilege (scope: "bridge:connect bridge:replay bridge:events")
|
|
8
8
|
*/
|
|
9
|
+
/** JWT audience claim for bridge access tokens. */
|
|
9
10
|
export const BRIDGE_JWT_AUDIENCE = "nority-bridge";
|
|
11
|
+
/** JWT scopes granted to bridge access tokens. */
|
|
10
12
|
export const BRIDGE_JWT_SCOPES = [
|
|
11
13
|
"bridge:connect",
|
|
12
14
|
"bridge:replay",
|
package/dist/auth/jwt.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../src/auth/jwt.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../src/auth/jwt.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/pairing.d.ts
CHANGED
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Pairing flow helpers.
|
|
3
3
|
*/
|
|
4
|
+
/** How long a pairing token remains valid before auto-regeneration (seconds). */
|
|
4
5
|
export declare const PAIRING_TOKEN_TTL_SECONDS = 120;
|
|
6
|
+
/** URL scheme prefix for Nority pairing deeplinks. */
|
|
5
7
|
export declare const DEEPLINK_PREFIX = "nority://pair-bridge?token=";
|
|
8
|
+
/** Clock and TTL overrides for pairing expiry calculations. */
|
|
6
9
|
export interface PairingClockOptions {
|
|
10
|
+
/** Override the system clock (useful for testing). */
|
|
7
11
|
clock?: () => Date;
|
|
12
|
+
/** Override the token TTL. Default: {@link PAIRING_TOKEN_TTL_SECONDS}. */
|
|
8
13
|
tokenTtlSeconds?: number;
|
|
9
14
|
}
|
|
15
|
+
/** Creates a `nority://` deeplink URL from a pairing token. */
|
|
10
16
|
export declare function createDeeplinkUrl(token: string): string;
|
|
17
|
+
/** Generates a cryptographically random pairing token prefixed with `pair_`. */
|
|
11
18
|
export declare function createPairingToken(): string;
|
|
19
|
+
/** Returns an ISO 8601 timestamp representing when the pairing token expires. */
|
|
12
20
|
export declare function createPairingExpiry(options?: PairingClockOptions): string;
|
|
21
|
+
/** Returns `true` if the pairing token's `expiresAt` timestamp is in the past. */
|
|
13
22
|
export declare function isPairingExpired(expiresAt: string, clock?: () => Date): boolean;
|
|
14
23
|
//# sourceMappingURL=pairing.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pairing.d.ts","sourceRoot":"","sources":["../../src/auth/pairing.ts"],"names":[],"mappings":"AAEA;;GAEG;AAEH,eAAO,MAAM,yBAAyB,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"pairing.d.ts","sourceRoot":"","sources":["../../src/auth/pairing.ts"],"names":[],"mappings":"AAEA;;GAEG;AAEH,iFAAiF;AACjF,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C,sDAAsD;AACtD,eAAO,MAAM,eAAe,gCAAgC,CAAC;AAE7D,+DAA+D;AAC/D,MAAM,WAAW,mBAAmB;IAClC,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB,0EAA0E;IAC1E,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,+DAA+D;AAC/D,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED,gFAAgF;AAChF,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,iFAAiF;AACjF,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,mBAAwB,GAChC,MAAM,CAUR;AAED,kFAAkF;AAClF,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,MAAM,IAAuB,GACnC,OAAO,CAaT"}
|
package/dist/auth/pairing.js
CHANGED
|
@@ -2,17 +2,22 @@ import { randomBytes } from "node:crypto";
|
|
|
2
2
|
/**
|
|
3
3
|
* Pairing flow helpers.
|
|
4
4
|
*/
|
|
5
|
+
/** How long a pairing token remains valid before auto-regeneration (seconds). */
|
|
5
6
|
export const PAIRING_TOKEN_TTL_SECONDS = 120;
|
|
7
|
+
/** URL scheme prefix for Nority pairing deeplinks. */
|
|
6
8
|
export const DEEPLINK_PREFIX = "nority://pair-bridge?token=";
|
|
9
|
+
/** Creates a `nority://` deeplink URL from a pairing token. */
|
|
7
10
|
export function createDeeplinkUrl(token) {
|
|
8
11
|
if (!token) {
|
|
9
12
|
throw new Error("createDeeplinkUrl: token is required");
|
|
10
13
|
}
|
|
11
14
|
return `${DEEPLINK_PREFIX}${token}`;
|
|
12
15
|
}
|
|
16
|
+
/** Generates a cryptographically random pairing token prefixed with `pair_`. */
|
|
13
17
|
export function createPairingToken() {
|
|
14
18
|
return `pair_${randomBytes(15).toString("base64url")}`;
|
|
15
19
|
}
|
|
20
|
+
/** Returns an ISO 8601 timestamp representing when the pairing token expires. */
|
|
16
21
|
export function createPairingExpiry(options = {}) {
|
|
17
22
|
const clock = options.clock ?? (() => new Date());
|
|
18
23
|
const tokenTtlSeconds = options.tokenTtlSeconds ?? PAIRING_TOKEN_TTL_SECONDS;
|
|
@@ -21,6 +26,7 @@ export function createPairingExpiry(options = {}) {
|
|
|
21
26
|
}
|
|
22
27
|
return new Date(clock().getTime() + tokenTtlSeconds * 1000).toISOString();
|
|
23
28
|
}
|
|
29
|
+
/** Returns `true` if the pairing token's `expiresAt` timestamp is in the past. */
|
|
24
30
|
export function isPairingExpired(expiresAt, clock = () => new Date()) {
|
|
25
31
|
if (!expiresAt) {
|
|
26
32
|
throw new Error("isPairingExpired: expiresAt is required");
|
package/dist/auth/pairing.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pairing.js","sourceRoot":"","sources":["../../src/auth/pairing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C;;GAEG;AAEH,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"pairing.js","sourceRoot":"","sources":["../../src/auth/pairing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C;;GAEG;AAEH,iFAAiF;AACjF,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAC;AAE7C,sDAAsD;AACtD,MAAM,CAAC,MAAM,eAAe,GAAG,6BAA6B,CAAC;AAU7D,+DAA+D;AAC/D,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,GAAG,eAAe,GAAG,KAAK,EAAE,CAAC;AACtC,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,kBAAkB;IAChC,OAAO,QAAQ,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;AACzD,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,mBAAmB,CACjC,UAA+B,EAAE;IAEjC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAClD,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,yBAAyB,CAAC;IAC7E,IAAI,eAAe,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACb,8DAA8D,eAAe,EAAE,CAChF,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,GAAG,eAAe,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;AAC5E,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,gBAAgB,CAC9B,SAAiB,EACjB,QAAoB,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE;IAEpC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACvC,IAAI,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,oDAAoD,SAAS,EAAE,CAChE,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,EAAE,CAAC,OAAO,EAAE,IAAI,QAAQ,CAAC;AACvC,CAAC"}
|
package/dist/auth/reconnect.d.ts
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
import { AccessTokenRecord, type JwtCacheOptions } from "./jwt.js";
|
|
2
|
+
/** HTTP path for requesting an Ed25519 challenge from the backend. */
|
|
2
3
|
export declare const CHALLENGE_ENDPOINT = "/v1/bridge/auth/challenge";
|
|
4
|
+
/** HTTP path for submitting a signed challenge and receiving a JWT. */
|
|
3
5
|
export declare const VERIFY_ENDPOINT = "/v1/bridge/auth/verify";
|
|
6
|
+
/** Options for {@link BridgeAccessTokenManager}. */
|
|
4
7
|
export interface BridgeAccessTokenManagerOptions extends JwtCacheOptions {
|
|
8
|
+
/** Nority backend WebSocket URL (protocol is swapped to HTTP for auth). */
|
|
5
9
|
backendUrl: string;
|
|
10
|
+
/** Override the default `fetch` used for challenge-response requests. */
|
|
6
11
|
fetchImplementation?: typeof fetch;
|
|
7
12
|
}
|
|
13
|
+
/** Options for {@link BridgeAccessTokenManager.getAccessToken}. */
|
|
8
14
|
export interface GetAccessTokenOptions {
|
|
15
|
+
/** The durable bridge credential. */
|
|
9
16
|
credential: string;
|
|
17
|
+
/** Ed25519 private key in PEM format for signing the challenge. */
|
|
10
18
|
privateKeyPem: string;
|
|
19
|
+
/** When `true`, bypasses the cache and performs a fresh challenge-response. */
|
|
11
20
|
forceRefresh?: boolean;
|
|
12
21
|
}
|
|
13
22
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconnect.d.ts","sourceRoot":"","sources":["../../src/auth/reconnect.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EAEjB,KAAK,eAAe,EACrB,MAAM,UAAU,CAAC;AAGlB,eAAO,MAAM,kBAAkB,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"reconnect.d.ts","sourceRoot":"","sources":["../../src/auth/reconnect.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EAEjB,KAAK,eAAe,EACrB,MAAM,UAAU,CAAC;AAGlB,sEAAsE;AACtE,eAAO,MAAM,kBAAkB,8BAA8B,CAAC;AAE9D,uEAAuE;AACvE,eAAO,MAAM,eAAe,2BAA2B,CAAC;AAaxD,oDAAoD;AACpD,MAAM,WAAW,+BAAgC,SAAQ,eAAe;IACtE,2EAA2E;IAC3E,UAAU,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,mBAAmB,CAAC,EAAE,OAAO,KAAK,CAAC;CACpC;AAED,mEAAmE;AACnE,MAAM,WAAW,qBAAqB;IACpC,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,aAAa,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,qBAAa,wBAAwB;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAe;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;gBAExB,OAAO,EAAE,+BAA+B;IAapD,IAAI,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAIrC,KAAK,IAAI,IAAI;IAIP,cAAc,CAClB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,iBAAiB,CAAC;YA0Cf,cAAc;YA+Bd,WAAW;CAmC1B;AAWD,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/auth/reconnect.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { JwtCache, } from "./jwt.js";
|
|
2
2
|
import { signEd25519 } from "../crypto/identity.js";
|
|
3
|
+
/** HTTP path for requesting an Ed25519 challenge from the backend. */
|
|
3
4
|
export const CHALLENGE_ENDPOINT = "/v1/bridge/auth/challenge";
|
|
5
|
+
/** HTTP path for submitting a signed challenge and receiving a JWT. */
|
|
4
6
|
export const VERIFY_ENDPOINT = "/v1/bridge/auth/verify";
|
|
5
7
|
/**
|
|
6
8
|
* Mints and caches short-lived bridge access JWTs.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconnect.js","sourceRoot":"","sources":["../../src/auth/reconnect.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,GAET,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,CAAC,MAAM,kBAAkB,GAAG,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"reconnect.js","sourceRoot":"","sources":["../../src/auth/reconnect.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +1,40 @@
|
|
|
1
1
|
import type { AgentAdapter, BridgeLogger } from "./agent.js";
|
|
2
2
|
import type { AccessTokenRecord } from "./auth/jwt.js";
|
|
3
3
|
import type { WebSocketFactory } from "./transport/websocket.js";
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for {@link BridgeConnection}, the standalone connection layer.
|
|
6
|
+
*
|
|
7
|
+
* Use this when you already have a bridge credential (from {@link PairingClient}
|
|
8
|
+
* or pre-provisioned) and want full control over the connection lifecycle.
|
|
9
|
+
*/
|
|
4
10
|
export interface BridgeConnectionConfig {
|
|
11
|
+
/** Nority backend WebSocket URL. */
|
|
5
12
|
backendUrl: string;
|
|
13
|
+
/** Directory for durable state (conversation keys). */
|
|
6
14
|
dataDir: string;
|
|
15
|
+
/** Long-lived bridge credential obtained during pairing. */
|
|
7
16
|
credential: string;
|
|
17
|
+
/** Ed25519 private key in PEM format for challenge-response auth. */
|
|
8
18
|
privateKeyPem: string;
|
|
19
|
+
/** Your agent adapter implementation. */
|
|
9
20
|
agent: AgentAdapter;
|
|
21
|
+
/** Structured logger. Defaults to no-op. */
|
|
10
22
|
logger?: BridgeLogger;
|
|
23
|
+
/** Pre-existing JWT to skip the first challenge-response round-trip. */
|
|
11
24
|
seedJwt?: AccessTokenRecord;
|
|
25
|
+
/** Override the default `fetch` used for challenge-response auth. */
|
|
12
26
|
fetchImplementation?: typeof fetch;
|
|
27
|
+
/** Override the built-in `ws`-based WebSocket. */
|
|
13
28
|
webSocketFactory?: WebSocketFactory;
|
|
29
|
+
/** Override the system clock (useful for testing). */
|
|
14
30
|
clock?: () => Date;
|
|
31
|
+
/** Override `Math.random` for reconnect backoff jitter (useful for testing). */
|
|
15
32
|
backoffRandom?: () => number;
|
|
33
|
+
/** Heartbeat interval in milliseconds. Default: 15000. */
|
|
16
34
|
heartbeatIntervalMs?: number;
|
|
35
|
+
/** Idle timeout in milliseconds. Must be greater than `heartbeatIntervalMs`. Default: 45000. */
|
|
17
36
|
idleTimeoutMs?: number;
|
|
18
37
|
}
|
|
38
|
+
/** Lifecycle states for {@link BridgeConnection}. */
|
|
19
39
|
export type BridgeConnectionState = "idle" | "connecting" | "connected" | "reconnecting" | "blocked" | "failed" | "stopped";
|
|
20
40
|
//# sourceMappingURL=connection-types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-types.d.ts","sourceRoot":"","sources":["../src/connection-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,mBAAmB,CAAC,EAAE,OAAO,KAAK,CAAC;IACnC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,MAAM,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,qBAAqB,GAC7B,MAAM,GACN,YAAY,GACZ,WAAW,GACX,cAAc,GACd,SAAS,GACT,QAAQ,GACR,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"connection-types.d.ts","sourceRoot":"","sources":["../src/connection-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,aAAa,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,KAAK,EAAE,YAAY,CAAC;IACpB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,wEAAwE;IACxE,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,qEAAqE;IACrE,mBAAmB,CAAC,EAAE,OAAO,KAAK,CAAC;IACnC,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB,gFAAgF;IAChF,aAAa,CAAC,EAAE,MAAM,MAAM,CAAC;IAC7B,0DAA0D;IAC1D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,gGAAgG;IAChG,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qDAAqD;AACrD,MAAM,MAAM,qBAAqB,GAC7B,MAAM,GACN,YAAY,GACZ,WAAW,GACX,cAAc,GACd,SAAS,GACT,QAAQ,GACR,SAAS,CAAC"}
|
|
@@ -10,21 +10,43 @@
|
|
|
10
10
|
* Event format matches what the bridge SDK encrypts and stores:
|
|
11
11
|
* { type: "text_delta", content: "...", message_id: "..." }
|
|
12
12
|
*/
|
|
13
|
+
/** A reconstructed conversation turn produced by the replay engine. */
|
|
13
14
|
export interface Turn {
|
|
15
|
+
/** Who produced this turn. */
|
|
14
16
|
role: "user" | "assistant";
|
|
17
|
+
/** The concatenated text content of the turn. */
|
|
15
18
|
text: string;
|
|
19
|
+
/** Whether the turn is still being streamed or is finalized. */
|
|
16
20
|
status: "complete" | "streaming";
|
|
17
21
|
}
|
|
22
|
+
/** Snapshot of a conversation's replay state, used as both input and output of {@link rebuildHistory}. */
|
|
18
23
|
export interface ConversationState {
|
|
24
|
+
/** Sequence number of the last event that was applied. */
|
|
19
25
|
last_applied_seq: number;
|
|
26
|
+
/** Ordered list of reconstructed turns. */
|
|
20
27
|
turns: Turn[];
|
|
21
28
|
}
|
|
29
|
+
/** A single event in a replay batch, decrypted and ready for application. */
|
|
22
30
|
export interface ReplayEvent {
|
|
31
|
+
/** Monotonically increasing sequence number. */
|
|
23
32
|
seq: number;
|
|
33
|
+
/** Event type (e.g. "user_message", "text_delta", "done"). */
|
|
24
34
|
type: string;
|
|
35
|
+
/** Text content (used by some event types). */
|
|
25
36
|
text?: string;
|
|
37
|
+
/** Content payload (used by text_delta and user_message). */
|
|
26
38
|
content?: string;
|
|
39
|
+
/** Groups streaming deltas into a single assistant turn. */
|
|
27
40
|
message_id?: string;
|
|
28
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Deterministically rebuilds conversation history from a replay batch.
|
|
44
|
+
*
|
|
45
|
+
* Follows the bridge protocol replay rules:
|
|
46
|
+
* 1. Skip events at or below `last_applied_seq`
|
|
47
|
+
* 2. Deduplicate by seq (first occurrence wins)
|
|
48
|
+
* 3. Sort by ascending seq
|
|
49
|
+
* 4. Apply events in order
|
|
50
|
+
*/
|
|
29
51
|
export declare function rebuildHistory(initialState: ConversationState, replayEvents: ReplayEvent[]): ConversationState;
|
|
30
52
|
//# sourceMappingURL=replay.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../src/conversation/replay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,GAAG,WAAW,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,cAAc,CAC5B,YAAY,EAAE,iBAAiB,EAC/B,YAAY,EAAE,WAAW,EAAE,GAC1B,iBAAiB,CAgFnB"}
|
|
1
|
+
{"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../src/conversation/replay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,uEAAuE;AACvE,MAAM,WAAW,IAAI;IACnB,8BAA8B;IAC9B,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,MAAM,EAAE,UAAU,GAAG,WAAW,CAAC;CAClC;AAED,0GAA0G;AAC1G,MAAM,WAAW,iBAAiB;IAChC,0DAA0D;IAC1D,gBAAgB,EAAE,MAAM,CAAC;IACzB,2CAA2C;IAC3C,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAED,6EAA6E;AAC7E,MAAM,WAAW,WAAW;IAC1B,gDAAgD;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,YAAY,EAAE,iBAAiB,EAC/B,YAAY,EAAE,WAAW,EAAE,GAC1B,iBAAiB,CAgFnB"}
|
|
@@ -10,6 +10,15 @@
|
|
|
10
10
|
* Event format matches what the bridge SDK encrypts and stores:
|
|
11
11
|
* { type: "text_delta", content: "...", message_id: "..." }
|
|
12
12
|
*/
|
|
13
|
+
/**
|
|
14
|
+
* Deterministically rebuilds conversation history from a replay batch.
|
|
15
|
+
*
|
|
16
|
+
* Follows the bridge protocol replay rules:
|
|
17
|
+
* 1. Skip events at or below `last_applied_seq`
|
|
18
|
+
* 2. Deduplicate by seq (first occurrence wins)
|
|
19
|
+
* 3. Sort by ascending seq
|
|
20
|
+
* 4. Apply events in order
|
|
21
|
+
*/
|
|
13
22
|
export function rebuildHistory(initialState, replayEvents) {
|
|
14
23
|
if (!initialState) {
|
|
15
24
|
throw new Error("rebuildHistory: initialState is required");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replay.js","sourceRoot":"","sources":["../../src/conversation/replay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"replay.js","sourceRoot":"","sources":["../../src/conversation/replay.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AgentAdapter, AgentEvent, BridgeLogger } from "../agent.js";
|
|
2
2
|
import { type BridgeFrame } from "../protocol/frames.js";
|
|
3
3
|
import { type ProactiveTurnRequest } from "../runtime/proactive.js";
|
|
4
|
+
/** Options for {@link ConversationRuntime}. */
|
|
4
5
|
export interface ConversationRuntimeOptions {
|
|
5
6
|
dataDir: string;
|
|
6
7
|
agent: AgentAdapter;
|