@tangle-network/agent-app 0.46.54 → 0.46.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,187 @@
1
+ // src/web-react/session-gateway.ts
2
+ var GATEWAY_TERMINAL_EVENT_TYPES = /* @__PURE__ */ new Set([
3
+ "done",
4
+ "error",
5
+ "result",
6
+ "session.run.completed",
7
+ "session.run.failed"
8
+ ]);
9
+ var GATEWAY_TRANSPORT_NOTICE_TYPES = /* @__PURE__ */ new Set([
10
+ "connection.established",
11
+ "heartbeat",
12
+ "ping",
13
+ "pong"
14
+ ]);
15
+ function isTerminalGatewayEvent(type) {
16
+ return GATEWAY_TERMINAL_EVENT_TYPES.has(type);
17
+ }
18
+ function isGatewayTransportNotice(type) {
19
+ return GATEWAY_TRANSPORT_NOTICE_TYPES.has(type);
20
+ }
21
+ function isRecord(value) {
22
+ return !!value && typeof value === "object" && !Array.isArray(value);
23
+ }
24
+ function gatewayFrameToTurnEvent(raw) {
25
+ if (!isRecord(raw)) return null;
26
+ const type = typeof raw.type === "string" ? raw.type.trim() : "";
27
+ if (type) {
28
+ const { type: _ignored, properties, ...rest } = raw;
29
+ return { type, data: isRecord(properties) ? properties : rest };
30
+ }
31
+ if (isRecord(raw.outcome) || typeof raw.outcome === "string") {
32
+ return { type: "done", data: raw };
33
+ }
34
+ return null;
35
+ }
36
+ function parseSessionStreamGrant(body) {
37
+ if (!isRecord(body) || body.available !== true) return null;
38
+ const { url, token, sessionId, expiresAt } = body;
39
+ if (typeof url !== "string" || !url.trim() || !isWebSocketUrl(url) || typeof token !== "string" || !token.trim() || typeof sessionId !== "string" || !sessionId.trim() || typeof expiresAt !== "number" || !Number.isFinite(expiresAt) || expiresAt < 0) {
40
+ return null;
41
+ }
42
+ return { url, token, sessionId, expiresAt };
43
+ }
44
+ function isWebSocketUrl(value) {
45
+ try {
46
+ const protocol = new URL(value).protocol;
47
+ return protocol === "ws:" || protocol === "wss:";
48
+ } catch {
49
+ return false;
50
+ }
51
+ }
52
+ function createSessionStreamGrantFetcher(options) {
53
+ const fetchImpl = options.fetchImpl ?? fetch;
54
+ return async (signal) => {
55
+ try {
56
+ const url = typeof options.url === "function" ? options.url(options.scopeId) : options.url;
57
+ const response = await fetchImpl(url, {
58
+ ...options.requestInit,
59
+ signal
60
+ });
61
+ if (!response.ok) return null;
62
+ return parseSessionStreamGrant(await response.json());
63
+ } catch {
64
+ return null;
65
+ }
66
+ };
67
+ }
68
+ var APPLIED_SEQ_CAP = 1e5;
69
+ async function defaultCreateClient(config) {
70
+ const module = await import("@tangle-network/sandbox/session-gateway");
71
+ return new module.SessionGatewayClient(config);
72
+ }
73
+ function defaultReplayStorage() {
74
+ try {
75
+ return typeof window !== "undefined" && window.localStorage ? window.localStorage : void 0;
76
+ } catch {
77
+ return void 0;
78
+ }
79
+ }
80
+ function createSessionGatewayLane(options) {
81
+ const cap = options.appliedSeqCap ?? APPLIED_SEQ_CAP;
82
+ const createClient = options.createClient ?? defaultCreateClient;
83
+ return async (handlers) => {
84
+ let grant;
85
+ try {
86
+ grant = await options.fetchGrant(handlers.signal);
87
+ } catch {
88
+ return null;
89
+ }
90
+ if (!grant || handlers.signal.aborted) return null;
91
+ const appliedSeqs = /* @__PURE__ */ new Set();
92
+ let firstTurnEventSent = false;
93
+ let closed = false;
94
+ let client;
95
+ const replayStorage = options.replayStorage === null ? void 0 : options.replayStorage ?? defaultReplayStorage();
96
+ const config = {
97
+ url: grant.url,
98
+ token: grant.token,
99
+ sessionId: grant.sessionId,
100
+ autoReconnect: true,
101
+ ...replayStorage ? { enableReplayPersistence: true, replayStorage } : {},
102
+ onTokenRefresh: async () => {
103
+ const refreshed = await options.fetchGrant(handlers.signal);
104
+ if (!refreshed) throw new Error("stream token refresh unavailable");
105
+ return { token: refreshed.token, expiresAt: refreshed.expiresAt };
106
+ },
107
+ handlers: {
108
+ onAgentEvent: (_channel, data, sequenceId) => {
109
+ if (closed) return;
110
+ if (typeof sequenceId === "number" && Number.isSafeInteger(sequenceId) && sequenceId >= 0) {
111
+ if (appliedSeqs.has(sequenceId)) return;
112
+ if (appliedSeqs.size < cap) appliedSeqs.add(sequenceId);
113
+ }
114
+ const event = gatewayFrameToTurnEvent(data);
115
+ if (!event || isGatewayTransportNotice(event.type)) return;
116
+ if (!firstTurnEventSent) {
117
+ firstTurnEventSent = true;
118
+ handlers.onFirstTurnEvent?.();
119
+ }
120
+ handlers.onEvent(event);
121
+ if (isTerminalGatewayEvent(event.type)) handlers.onTerminal?.();
122
+ },
123
+ onBackpressureWarning: (_dropped, since) => {
124
+ if (closed) return;
125
+ try {
126
+ const replay = client.replay(since);
127
+ if (replay && typeof replay.then === "function") {
128
+ void replay.catch((error) => {
129
+ if (!closed) {
130
+ handlers.onUnusable?.(
131
+ `replay failed: ${error instanceof Error ? error.message : String(error)}`
132
+ );
133
+ }
134
+ });
135
+ }
136
+ } catch (error) {
137
+ handlers.onUnusable?.(
138
+ `replay failed: ${error instanceof Error ? error.message : String(error)}`
139
+ );
140
+ }
141
+ },
142
+ onTokenExpired: () => {
143
+ if (!closed) handlers.onUnusable?.("token expired");
144
+ },
145
+ onError: (message, code) => {
146
+ if (!closed) handlers.onUnusable?.(code ? `${code}: ${message}` : message);
147
+ }
148
+ }
149
+ };
150
+ try {
151
+ client = await createClient(config);
152
+ } catch {
153
+ return null;
154
+ }
155
+ if (handlers.signal.aborted) {
156
+ client.disconnect();
157
+ return null;
158
+ }
159
+ try {
160
+ client.connect();
161
+ } catch {
162
+ client.disconnect();
163
+ return null;
164
+ }
165
+ return {
166
+ close: () => {
167
+ if (closed) return;
168
+ closed = true;
169
+ appliedSeqs.clear();
170
+ client.clearReplayState();
171
+ client.disconnect();
172
+ }
173
+ };
174
+ };
175
+ }
176
+ export {
177
+ APPLIED_SEQ_CAP,
178
+ GATEWAY_TERMINAL_EVENT_TYPES,
179
+ GATEWAY_TRANSPORT_NOTICE_TYPES,
180
+ createSessionGatewayLane,
181
+ createSessionStreamGrantFetcher,
182
+ gatewayFrameToTurnEvent,
183
+ isGatewayTransportNotice,
184
+ isTerminalGatewayEvent,
185
+ parseSessionStreamGrant
186
+ };
187
+ //# sourceMappingURL=session-gateway.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/web-react/session-gateway.ts"],"sourcesContent":["/**\n * Browser adapter for the Sandbox session gateway.\n *\n * The Sandbox SDK owns the WebSocket, reconnect, replay, cursor persistence,\n * and raw event delivery. This module only composes that client with a\n * product-owned grant endpoint and decodes the gateway's event envelope.\n *\n * Keep this entry separate from `web-react`: `@tangle-network/sandbox` is an\n * optional peer, and the dynamic import keeps it out of apps without a\n * sandbox-backed session.\n */\n\n/** A short-lived, read-only grant for one session's gateway stream. */\nexport interface SessionStreamGrant {\n /** `wss://…/session`, resolved by the product server. */\n url: string\n /** Read-only JWT. A browser must never receive a Sandbox API key. */\n token: string\n /** Browser-facing session channel selected by the product. */\n sessionId: string\n /** Unix seconds, as expected by the SDK token refresher. */\n expiresAt: number\n}\n\n/** Common soft-miss reasons a product grant route may report. */\nexport type SessionGrantUnavailableReason =\n | 'sandbox-absent'\n | 'sandbox-not-running'\n | 'session-absent'\n | 'gateway-unreachable'\n | 'mint-failed'\n\n/** The grant endpoint response accepted by {@link parseSessionStreamGrant}. */\nexport type SessionStreamGrantResponse =\n | ({ available: true } & SessionStreamGrant)\n | { available: false; reason?: SessionGrantUnavailableReason }\n\n/** A decoded event from the raw Sandbox gateway payload. */\nexport interface GatewayTurnEvent {\n type: string\n data?: Record<string, unknown>\n}\n\n/** Event types that terminate a Sandbox execution. */\nexport const GATEWAY_TERMINAL_EVENT_TYPES: ReadonlySet<string> = new Set([\n 'done',\n 'error',\n 'result',\n 'session.run.completed',\n 'session.run.failed',\n])\n\n/** Gateway bookkeeping events that are not turn feedback. */\nexport const GATEWAY_TRANSPORT_NOTICE_TYPES: ReadonlySet<string> = new Set([\n 'connection.established',\n 'heartbeat',\n 'ping',\n 'pong',\n])\n\n/** Report whether a decoded event ends the execution. */\nexport function isTerminalGatewayEvent(type: string): boolean {\n return GATEWAY_TERMINAL_EVENT_TYPES.has(type)\n}\n\n/** Report whether a decoded event is gateway bookkeeping. */\nexport function isGatewayTransportNotice(type: string): boolean {\n return GATEWAY_TRANSPORT_NOTICE_TYPES.has(type)\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value)\n}\n\n/**\n * Decode one raw `onAgentEvent` payload into the event shape a turn reducer\n * consumes. The gateway carries both message-lane and run/stream envelopes.\n */\nexport function gatewayFrameToTurnEvent(raw: unknown): GatewayTurnEvent | null {\n if (!isRecord(raw)) return null\n\n const type = typeof raw.type === 'string' ? raw.type.trim() : ''\n if (type) {\n const { type: _ignored, properties, ...rest } = raw\n return { type, data: isRecord(properties) ? properties : rest }\n }\n\n // The gateway's terminal broadcast can lose its event type. The outcome is\n // the stable completion marker in that frame shape.\n if (isRecord(raw.outcome) || typeof raw.outcome === 'string') {\n return { type: 'done', data: raw }\n }\n\n return null\n}\n\n/** Parse a grant response. Invalid or unavailable responses are soft misses. */\nexport function parseSessionStreamGrant(body: unknown): SessionStreamGrant | null {\n if (!isRecord(body) || body.available !== true) return null\n\n const { url, token, sessionId, expiresAt } = body\n if (\n typeof url !== 'string' ||\n !url.trim() ||\n !isWebSocketUrl(url) ||\n typeof token !== 'string' ||\n !token.trim() ||\n typeof sessionId !== 'string' ||\n !sessionId.trim() ||\n typeof expiresAt !== 'number' ||\n !Number.isFinite(expiresAt) ||\n expiresAt < 0\n ) {\n return null\n }\n\n return { url, token, sessionId, expiresAt }\n}\n\nfunction isWebSocketUrl(value: string): boolean {\n try {\n const protocol = new URL(value).protocol\n return protocol === 'ws:' || protocol === 'wss:'\n } catch {\n return false\n }\n}\n\n/** Options for a product-owned grant fetcher. */\nexport interface SessionStreamGrantFetcherOptions {\n /** Endpoint URL, or a function that receives the product scope id. */\n url: string | ((scopeId: string) => string)\n scopeId: string\n /** Injectable for tests or a product-specific fetch wrapper. */\n fetchImpl?: typeof fetch\n /** For example, `{ credentials: 'include' }` on a cross-origin endpoint. */\n requestInit?: RequestInit\n}\n\n/**\n * Build a grant fetcher that never throws. A grant route is an optional live\n * lane, so auth misses, network failures, and malformed bodies fall back to\n * the product's durable lane.\n */\nexport function createSessionStreamGrantFetcher(\n options: SessionStreamGrantFetcherOptions,\n): (signal: AbortSignal) => Promise<SessionStreamGrant | null> {\n const fetchImpl = options.fetchImpl ?? fetch\n\n return async (signal) => {\n try {\n const url =\n typeof options.url === 'function'\n ? options.url(options.scopeId)\n : options.url\n const response = await fetchImpl(url, {\n ...options.requestInit,\n signal,\n })\n if (!response.ok) return null\n return parseSessionStreamGrant(await response.json())\n } catch {\n return null\n }\n }\n}\n\n/** Minimal structural surface of the SDK session gateway client. */\nexport interface SessionGatewayClientLike {\n connect(): void\n disconnect(): void\n replay(since: number): void | Promise<void>\n clearReplayState(): void\n}\n\n/** Structural replay storage accepted by the SDK client. */\nexport interface ReplayCursorStorage {\n getItem(key: string): string | null\n setItem(key: string, value: string): void\n removeItem(key: string): void\n}\n\n/** Subset of the SDK client configuration used by this adapter. */\nexport interface SessionGatewayClientConfigLike {\n url: string\n token: string\n sessionId: string\n autoReconnect?: boolean\n enableReplayPersistence?: boolean\n replayStorage?: ReplayCursorStorage\n onTokenRefresh?: () => Promise<{ token: string; expiresAt: number }>\n handlers?: {\n onAgentEvent?: (channel: string, data: unknown, sequenceId?: number) => void\n onBackpressureWarning?: (dropped: number, since: number, totalDropped?: number) => void\n onTokenExpired?: () => void\n onError?: (message: string, code?: string) => void\n }\n}\n\n/** Injectable SDK-client constructor, used for tests and alternate transports. */\nexport type SessionGatewayClientFactory = (\n config: SessionGatewayClientConfigLike,\n) => SessionGatewayClientLike | Promise<SessionGatewayClientLike>\n\n/** Callbacks driven by one live gateway attachment. */\nexport interface SessionGatewayLiveViewHandlers {\n signal: AbortSignal\n /** Every non-duplicate, non-transport event. */\n onEvent: (event: GatewayTurnEvent) => void\n /** Called after the first real turn event, not a gateway notice. */\n onFirstTurnEvent?: () => void\n /** Called for each terminal turn event. */\n onTerminal?: () => void\n /** Called when an attached lane becomes unusable. */\n onUnusable?: (reason: string) => void\n}\n\n/** A handle that stops one gateway attachment. */\nexport interface SessionGatewayLiveViewAttachment {\n close(): void\n}\n\n/** Structural connector returned by {@link createSessionGatewayLane}. */\nexport type SessionGatewayLiveViewConnector = (\n handlers: SessionGatewayLiveViewHandlers,\n) => Promise<SessionGatewayLiveViewAttachment | null>\n\n/** Options for {@link createSessionGatewayLane}. */\nexport interface SessionGatewayLaneOptions {\n /** Mint a grant. `null` is a soft miss with no attachable live stream. */\n fetchGrant(signal: AbortSignal): Promise<SessionStreamGrant | null>\n /** Replay cursor storage. Defaults to `window.localStorage`; `null` disables it. */\n replayStorage?: ReplayCursorStorage | null\n /** Override the SDK client constructor for tests or another compatible client. */\n createClient?: SessionGatewayClientFactory\n /** Maximum sequence ids retained for duplicate suppression. */\n appliedSeqCap?: number\n}\n\n/** Default bound on applied sequence ids retained by one attachment. */\nexport const APPLIED_SEQ_CAP = 100_000\n\nasync function defaultCreateClient(\n config: SessionGatewayClientConfigLike,\n): Promise<SessionGatewayClientLike> {\n // Keep the optional Sandbox peer out of consumers that do not use this\n // subpath, and out of SSR evaluation.\n const module = (await import('@tangle-network/sandbox/session-gateway')) as unknown as {\n SessionGatewayClient: new (config: SessionGatewayClientConfigLike) => SessionGatewayClientLike\n }\n return new module.SessionGatewayClient(config)\n}\n\nfunction defaultReplayStorage(): ReplayCursorStorage | undefined {\n try {\n return typeof window !== 'undefined' && window.localStorage\n ? window.localStorage\n : undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * Build a browser-direct Sandbox live-view connector.\n *\n * The caller supplies a product-authenticated grant fetcher and owns the\n * transcript reducer. A missing grant returns `null`, allowing a durable\n * replay lane to take over without changing the turn.\n */\nexport function createSessionGatewayLane(\n options: SessionGatewayLaneOptions,\n): SessionGatewayLiveViewConnector {\n const cap = options.appliedSeqCap ?? APPLIED_SEQ_CAP\n const createClient = options.createClient ?? defaultCreateClient\n\n return async (handlers) => {\n let grant: SessionStreamGrant | null\n try {\n grant = await options.fetchGrant(handlers.signal)\n } catch {\n return null\n }\n if (!grant || handlers.signal.aborted) return null\n\n const appliedSeqs = new Set<number>()\n let firstTurnEventSent = false\n let closed = false\n let client: SessionGatewayClientLike\n\n const replayStorage =\n options.replayStorage === null\n ? undefined\n : (options.replayStorage ?? defaultReplayStorage())\n\n const config: SessionGatewayClientConfigLike = {\n url: grant.url,\n token: grant.token,\n sessionId: grant.sessionId,\n autoReconnect: true,\n ...(replayStorage\n ? { enableReplayPersistence: true, replayStorage }\n : {}),\n onTokenRefresh: async () => {\n const refreshed = await options.fetchGrant(handlers.signal)\n if (!refreshed) throw new Error('stream token refresh unavailable')\n return { token: refreshed.token, expiresAt: refreshed.expiresAt }\n },\n handlers: {\n onAgentEvent: (_channel, data, sequenceId) => {\n if (closed) return\n if (typeof sequenceId === 'number' && Number.isSafeInteger(sequenceId) && sequenceId >= 0) {\n if (appliedSeqs.has(sequenceId)) return\n if (appliedSeqs.size < cap) appliedSeqs.add(sequenceId)\n }\n\n const event = gatewayFrameToTurnEvent(data)\n if (!event || isGatewayTransportNotice(event.type)) return\n\n if (!firstTurnEventSent) {\n firstTurnEventSent = true\n handlers.onFirstTurnEvent?.()\n }\n handlers.onEvent(event)\n if (isTerminalGatewayEvent(event.type)) handlers.onTerminal?.()\n },\n onBackpressureWarning: (_dropped, since) => {\n if (closed) return\n try {\n const replay = client.replay(since)\n if (replay && typeof replay.then === 'function') {\n void replay.catch((error: unknown) => {\n if (!closed) {\n handlers.onUnusable?.(\n `replay failed: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n })\n }\n } catch (error) {\n handlers.onUnusable?.(\n `replay failed: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n },\n onTokenExpired: () => {\n if (!closed) handlers.onUnusable?.('token expired')\n },\n onError: (message, code) => {\n if (!closed) handlers.onUnusable?.(code ? `${code}: ${message}` : message)\n },\n },\n }\n\n try {\n client = await createClient(config)\n } catch {\n return null\n }\n if (handlers.signal.aborted) {\n client.disconnect()\n return null\n }\n\n try {\n client.connect()\n } catch {\n client.disconnect()\n return null\n }\n\n return {\n close: () => {\n if (closed) return\n closed = true\n appliedSeqs.clear()\n // The next attachment starts with a fresh dedupe set. The SDK cursor\n // is therefore cleared with the socket rather than reused against a\n // different reducer state.\n client.clearReplayState()\n client.disconnect()\n },\n }\n }\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-app",
3
- "version": "0.46.54",
3
+ "version": "0.46.56",
4
4
  "packageManager": "pnpm@11.24.0",
5
5
  "description": "Build agent applications with typed chat, tools, sandboxes, integrations, billing, and evaluation.",
6
6
  "keywords": [
@@ -252,6 +252,11 @@
252
252
  "import": "./dist/web-react/terminal.js",
253
253
  "default": "./dist/web-react/terminal.js"
254
254
  },
255
+ "./web-react/session-gateway": {
256
+ "types": "./dist/web-react/session-gateway.d.ts",
257
+ "import": "./dist/web-react/session-gateway.js",
258
+ "default": "./dist/web-react/session-gateway.js"
259
+ },
255
260
  "./work-product": {
256
261
  "types": "./dist/work-product/index.d.ts",
257
262
  "import": "./dist/work-product/index.js",
@@ -531,9 +536,9 @@
531
536
  "@tangle-network/agent-interface": "2.3.0",
532
537
  "@tangle-network/agent-knowledge": "13.0.1",
533
538
  "@tangle-network/agent-profile-materialize": "0.19.0",
534
- "@tangle-network/agent-runtime": "0.191.0",
539
+ "@tangle-network/agent-runtime": "0.192.2",
535
540
  "@tangle-network/brand": "1.5.0",
536
- "@tangle-network/sandbox": "0.36.4",
541
+ "@tangle-network/sandbox": "0.37.0",
537
542
  "@tangle-network/sandbox-ui": "0.113.3",
538
543
  "@tangle-network/ui": "^11.8.0",
539
544
  "@testing-library/dom": "^10.4.1",
@@ -591,9 +596,9 @@
591
596
  "@tangle-network/agent-interface": "^2.3.0",
592
597
  "@tangle-network/agent-knowledge": "^13.0.1",
593
598
  "@tangle-network/agent-profile-materialize": ">=0.19.0 <0.20.0",
594
- "@tangle-network/agent-runtime": ">=0.191.0 <0.192.0",
599
+ "@tangle-network/agent-runtime": ">=0.191.0 <0.193.0",
595
600
  "@tangle-network/brand": ">=1.5.0",
596
- "@tangle-network/sandbox": ">=0.36.4 <0.37.0",
601
+ "@tangle-network/sandbox": ">=0.36.4 <0.38.0",
597
602
  "@tangle-network/sandbox-ui": ">=0.113.3 <0.114.0",
598
603
  "@tangle-network/ui": ">=11.6.0 <12.0.0",
599
604
  "@tiptap/core": ">=3.28.0 <4.0.0",