@opengeni/sdk 3.3.2-canary.1 → 3.4.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 +1007 -72
- package/dist/adapters/express.d.ts +31 -0
- package/dist/adapters/express.js +87 -0
- package/dist/adapters/express.js.map +1 -0
- package/dist/adapters/hono.d.ts +16 -0
- package/dist/adapters/hono.js +8 -0
- package/dist/adapters/hono.js.map +1 -0
- package/dist/adapters/next.d.ts +29 -0
- package/dist/adapters/next.js +22 -0
- package/dist/adapters/next.js.map +1 -0
- package/dist/allowance-refusal.d.ts +2 -0
- package/dist/allowance-refusal.js +50 -0
- package/dist/allowance-refusal.js.map +1 -0
- package/dist/app-links.d.ts +42 -0
- package/dist/app-links.js +66 -0
- package/dist/app-links.js.map +1 -0
- package/dist/artifact-catalog.d.ts +40 -0
- package/dist/artifact-client.d.ts +20 -8
- package/dist/artifacts.d.ts +1 -1
- package/dist/artifacts.js +8 -6
- package/dist/automations.js +8 -2
- package/dist/automations.js.map +1 -1
- package/dist/azure-live-transport.d.ts +32 -0
- package/dist/browser.d.ts +6 -2
- package/dist/browser.js +25 -5
- package/dist/chat/fold.d.ts +75 -0
- package/dist/chat/handler.d.ts +41 -0
- package/dist/chat/http.d.ts +67 -0
- package/dist/chat/ids.d.ts +34 -0
- package/dist/chat/index.d.ts +9 -0
- package/dist/chat/index.js +1369 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat/openai.d.ts +30 -0
- package/dist/chat/opengeni.d.ts +129 -0
- package/dist/chat/types.d.ts +207 -0
- package/dist/chat/vercel.d.ts +49 -0
- package/dist/chats.d.ts +8 -0
- package/dist/chunk-4AHR4KGA.js +301 -0
- package/dist/chunk-4AHR4KGA.js.map +1 -0
- package/dist/chunk-6GYGMLX4.js +332 -0
- package/dist/chunk-6GYGMLX4.js.map +1 -0
- package/dist/chunk-7EWT3PV6.js +368 -0
- package/dist/chunk-7EWT3PV6.js.map +1 -0
- package/dist/chunk-FTWVVPR6.js +1665 -0
- package/dist/chunk-FTWVVPR6.js.map +1 -0
- package/dist/{chunk-VYCTL62C.js → chunk-GZQSWAKD.js} +1 -1
- package/dist/chunk-GZQSWAKD.js.map +1 -0
- package/dist/chunk-KGEABAID.js +71 -0
- package/dist/chunk-KGEABAID.js.map +1 -0
- package/dist/{chunk-YKZME56C.js → chunk-KWADQ227.js} +3 -3
- package/dist/{chunk-YKZME56C.js.map → chunk-KWADQ227.js.map} +1 -1
- package/dist/{chunk-E5BNEG2D.js → chunk-NCU5OAN7.js} +27 -2
- package/dist/chunk-NCU5OAN7.js.map +1 -0
- package/dist/{chunk-BESZFWMU.js → chunk-OI5YLASH.js} +73 -2
- package/dist/chunk-OI5YLASH.js.map +1 -0
- package/dist/chunk-OV3POE62.js +359 -0
- package/dist/chunk-OV3POE62.js.map +1 -0
- package/dist/chunk-P7UWKORG.js +561 -0
- package/dist/chunk-P7UWKORG.js.map +1 -0
- package/dist/chunk-QGEIL4TR.js +195 -0
- package/dist/chunk-QGEIL4TR.js.map +1 -0
- package/dist/{chunk-GY6RQPCG.js → chunk-S2NLS3ES.js} +3598 -1278
- package/dist/chunk-S2NLS3ES.js.map +1 -0
- package/dist/chunk-UM4ZXXJR.js +9 -0
- package/dist/chunk-UM4ZXXJR.js.map +1 -0
- package/dist/{chunk-TFCLHRZK.js → chunk-UME3X7CP.js} +28 -32
- package/dist/chunk-UME3X7CP.js.map +1 -0
- package/dist/chunk-VT4YM4XQ.js +210 -0
- package/dist/chunk-VT4YM4XQ.js.map +1 -0
- package/dist/chunk-WSYYXONG.js +1602 -0
- package/dist/chunk-WSYYXONG.js.map +1 -0
- package/dist/{chunk-6NEPJ7NC.js → chunk-WVCJRSGJ.js} +119 -14
- package/dist/chunk-WVCJRSGJ.js.map +1 -0
- package/dist/chunk-X5ITQVXE.js +15 -0
- package/dist/chunk-X5ITQVXE.js.map +1 -0
- package/dist/chunk-XA7HVIHI.js +126 -0
- package/dist/chunk-XA7HVIHI.js.map +1 -0
- package/dist/{chunk-QTBAMHEF.js → chunk-YJCHB7R3.js} +60 -12
- package/dist/chunk-YJCHB7R3.js.map +1 -0
- package/dist/chunk-YKIHNLWD.js +153 -0
- package/dist/chunk-YKIHNLWD.js.map +1 -0
- package/dist/chunk-ZDUBPV33.js +277 -0
- package/dist/chunk-ZDUBPV33.js.map +1 -0
- package/dist/client.d.ts +1056 -118
- package/dist/codex-realtime-controller.d.ts +13 -0
- package/dist/codex-realtime-controller.js +4 -2
- package/dist/codex-realtime-v3-wire.d.ts +3 -2
- package/dist/codex-realtime.d.ts +5 -1
- package/dist/company-brain.d.ts +1 -11
- package/dist/core.d.ts +6 -2
- package/dist/core.js +23 -6
- package/dist/deprecation.d.ts +47 -0
- package/dist/document-authority-client.d.ts +24 -2
- package/dist/document-authority.js +7 -5
- package/dist/editable-artifacts/index.d.ts +1 -1
- package/dist/editable-artifacts/types.d.ts +12 -2
- package/dist/editable-artifacts.js +19 -3
- package/dist/editable-artifacts.js.map +1 -1
- package/dist/embedding-client.d.ts +129 -0
- package/dist/errors.d.ts +64 -1
- package/dist/external-vault-receiver.d.ts +203 -0
- package/dist/external-vault-receiver.js +564 -0
- package/dist/external-vault-receiver.js.map +1 -0
- package/dist/feedback.d.ts +23 -0
- package/dist/gateway-realtime-transport.js +1 -1
- package/dist/github-repositories.d.ts +10 -0
- package/dist/github-repositories.js +36 -0
- package/dist/github-repositories.js.map +1 -0
- package/dist/index.d.ts +61 -11
- package/dist/index.js +555 -338
- package/dist/index.js.map +1 -1
- package/dist/insights-usage.d.ts +33 -0
- package/dist/insights-usage.js +7 -0
- package/dist/insights-usage.js.map +1 -0
- package/dist/interaction.d.ts +165 -71
- package/dist/interaction.js +2 -2
- package/dist/knowledge.d.ts +7 -0
- package/dist/knowledge.js +20 -0
- package/dist/knowledge.js.map +1 -0
- package/dist/known-tools.d.ts +4 -0
- package/dist/message-links.d.ts +68 -0
- package/dist/model-context.d.ts +68 -0
- package/dist/model-display.d.ts +2 -0
- package/dist/model-display.js +17 -0
- package/dist/model-display.js.map +1 -0
- package/dist/organization-integration-policy.d.ts +26 -0
- package/dist/organization-integration-policy.js +26 -0
- package/dist/organization-integration-policy.js.map +1 -0
- package/dist/pr-review-client.d.ts +1 -1
- package/dist/pr-review.d.ts +1 -1
- package/dist/pr-review.js.map +1 -1
- package/dist/preference-registry.d.ts +1 -1
- package/dist/prepared-mcp-setup.d.ts +5 -0
- package/dist/proxy.d.ts +13 -11
- package/dist/realtime.d.ts +1 -1
- package/dist/realtime.js +253 -7
- package/dist/realtime.js.map +1 -1
- package/dist/session-history-import.d.ts +22 -0
- package/dist/session-history-import.js +36 -0
- package/dist/session-history-import.js.map +1 -0
- package/dist/session-list-entries.d.ts +1 -0
- package/dist/session-list-entries.js +7 -0
- package/dist/session-list-entries.js.map +1 -0
- package/dist/session-message-search.d.ts +53 -0
- package/dist/session-proxy-client.d.ts +28 -0
- package/dist/session-proxy.d.ts +334 -0
- package/dist/session-proxy.js +24 -0
- package/dist/session-proxy.js.map +1 -0
- package/dist/session-titles.d.ts +2 -28
- package/dist/session-usage-limits.d.ts +10 -0
- package/dist/session-usage-limits.js +43 -0
- package/dist/session-usage-limits.js.map +1 -0
- package/dist/shared-catalog-loader.d.ts +34 -0
- package/dist/site-ai.d.ts +35 -0
- package/dist/site-bridge-host.d.ts +112 -0
- package/dist/site-bridge-host.js +286 -0
- package/dist/site-bridge-host.js.map +1 -0
- package/dist/site-browser-entry.d.ts +1 -0
- package/dist/site-browser-runtime.gen.d.ts +1 -0
- package/dist/site-data.d.ts +178 -0
- package/dist/site-document.d.ts +5 -0
- package/dist/site-document.js +20 -0
- package/dist/site-document.js.map +1 -0
- package/dist/site-document.test.d.ts +1 -0
- package/dist/site-http.d.ts +17 -0
- package/dist/site-sql.d.ts +31 -0
- package/dist/site-tool-bridge.d.ts +57 -0
- package/dist/site.d.ts +186 -0
- package/dist/site.js +63 -0
- package/dist/site.js.map +1 -0
- package/dist/skills.d.ts +75 -0
- package/dist/sse.d.ts +1 -1
- package/dist/stream.d.ts +2 -0
- package/dist/tenant-workspaces.d.ts +47 -0
- package/dist/tenant-workspaces.js +8 -0
- package/dist/tenant-workspaces.js.map +1 -0
- package/dist/tool-auth.d.ts +87 -0
- package/dist/tool-auth.js +23 -0
- package/dist/tool-auth.js.map +1 -0
- package/dist/tool-display-metadata.d.ts +3 -0
- package/dist/tools-37DCTCNZ.js +12 -0
- package/dist/tools-37DCTCNZ.js.map +1 -0
- package/dist/tools.d.ts +81 -0
- package/dist/transcription.d.ts +1 -1
- package/dist/types.d.ts +2785 -592
- package/dist/usage-allowances.d.ts +36 -0
- package/dist/usage-allowances.js +80 -0
- package/dist/usage-allowances.js.map +1 -0
- package/dist/vault-types.d.ts +324 -0
- package/dist/vaults-api.d.ts +65 -0
- package/dist/workspace-artifacts.d.ts +47 -5
- package/dist/workspace-instruction-policies.d.ts +2 -2
- package/dist/workspace-integrations.d.ts +74 -0
- package/dist/workspace-integrations.js +67 -0
- package/dist/workspace-integrations.js.map +1 -0
- package/dist/workspace-state.d.ts +8 -71
- package/package.json +99 -5
- package/src/adapters/express.ts +136 -0
- package/src/adapters/hono.ts +18 -0
- package/src/adapters/next.ts +42 -0
- package/src/allowance-refusal.ts +5 -0
- package/src/app-links.ts +117 -0
- package/src/artifact-catalog.ts +51 -0
- package/src/artifact-client.ts +40 -49
- package/src/artifacts.ts +1 -0
- package/src/automations-client.ts +8 -2
- package/src/azure-live-transport.ts +286 -0
- package/src/browser.ts +35 -0
- package/src/chat/fold.ts +431 -0
- package/src/chat/handler.ts +240 -0
- package/src/chat/http.ts +257 -0
- package/src/chat/ids.ts +85 -0
- package/src/chat/index.ts +88 -0
- package/src/chat/openai.ts +439 -0
- package/src/chat/opengeni.ts +737 -0
- package/src/chat/types.ts +219 -0
- package/src/chat/vercel.ts +204 -0
- package/src/chats.ts +16 -0
- package/src/client.ts +5595 -1847
- package/src/codex-realtime-controller.ts +163 -8
- package/src/codex-realtime-v3-wire.ts +4 -3
- package/src/codex-realtime-v3.ts +12 -3
- package/src/codex-realtime.ts +11 -3
- package/src/company-brain.ts +0 -40
- package/src/core.ts +18 -0
- package/src/deprecation.ts +149 -0
- package/src/document-authority-client.ts +104 -1
- package/src/editable-artifacts/controller.ts +36 -2
- package/src/editable-artifacts/index.ts +1 -0
- package/src/editable-artifacts/types.ts +29 -16
- package/src/embedding-client.ts +519 -0
- package/src/errors.ts +281 -5
- package/src/external-vault-receiver.ts +914 -0
- package/src/feedback.ts +20 -0
- package/src/gateway-realtime-transport.ts +3 -3
- package/src/github-repositories.ts +60 -0
- package/src/index.ts +592 -65
- package/src/insights-usage.ts +64 -0
- package/src/interaction.ts +315 -93
- package/src/knowledge.ts +72 -0
- package/src/known-tools.ts +279 -0
- package/src/message-links.ts +178 -0
- package/src/model-context.ts +113 -0
- package/src/model-display.ts +11 -0
- package/src/organization-integration-policy.ts +54 -0
- package/src/pr-review-client.ts +1 -1
- package/src/pr-review.ts +1 -1
- package/src/preference-registry.ts +2 -0
- package/src/prepared-mcp-setup.ts +123 -0
- package/src/proxy.ts +23 -12
- package/src/realtime.ts +15 -6
- package/src/session-history-import.ts +84 -0
- package/src/session-list-entries.ts +1 -0
- package/src/session-message-search.ts +47 -0
- package/src/session-proxy-client.ts +68 -0
- package/src/session-proxy.ts +2098 -0
- package/src/session-titles.ts +8 -82
- package/src/session-usage-limits.ts +71 -0
- package/src/shared-catalog-loader.ts +169 -0
- package/src/site-ai.ts +284 -0
- package/src/site-bridge-host.ts +422 -0
- package/src/site-browser-entry.ts +6 -0
- package/src/site-browser-runtime.gen.ts +2 -0
- package/src/site-data.ts +372 -0
- package/src/site-document.test.ts +64 -0
- package/src/site-document.ts +18 -0
- package/src/site-http.ts +171 -0
- package/src/site-sql.ts +153 -0
- package/src/site-tool-bridge.ts +401 -0
- package/src/site.ts +878 -0
- package/src/skills.ts +69 -0
- package/src/sse.ts +9 -3
- package/src/stream.ts +33 -10
- package/src/tenant-workspaces.ts +148 -0
- package/src/tool-auth.ts +301 -0
- package/src/tool-display-metadata.ts +27 -0
- package/src/tools.ts +452 -0
- package/src/transcription.ts +3 -0
- package/src/types.ts +3142 -594
- package/src/usage-allowances.ts +189 -0
- package/src/vault-types.ts +379 -0
- package/src/vaults-api.ts +339 -0
- package/src/workspace-artifacts.ts +55 -6
- package/src/workspace-instruction-policies.ts +2 -1
- package/src/workspace-integrations.ts +402 -0
- package/src/workspace-state.ts +8 -82
- package/dist/chunk-6NEPJ7NC.js.map +0 -1
- package/dist/chunk-BESZFWMU.js.map +0 -1
- package/dist/chunk-E5BNEG2D.js.map +0 -1
- package/dist/chunk-GY6RQPCG.js.map +0 -1
- package/dist/chunk-OO5LPTO7.js +0 -132
- package/dist/chunk-OO5LPTO7.js.map +0 -1
- package/dist/chunk-QTBAMHEF.js.map +0 -1
- package/dist/chunk-TFCLHRZK.js.map +0 -1
- package/dist/chunk-VYCTL62C.js.map +0 -1
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-free host side of the Site MessagePort bridge. The console's
|
|
3
|
+
* `PublishedHtmlArtifactFrame` and the published-Site gateway shell both run
|
|
4
|
+
* this code; each injects its own tool transport, Site HTTP handler, viewer
|
|
5
|
+
* provider and sign-in action.
|
|
6
|
+
*
|
|
7
|
+
* Protocol (v2): the host posts a ready message with a bootstrap port to the
|
|
8
|
+
* frame window once per document load; each SDK client connects through that
|
|
9
|
+
* port with its own MessagePort. Requests are tracked per port so a cancel or
|
|
10
|
+
* a document teardown aborts exactly the requests it owns. A second load of
|
|
11
|
+
* the same frame (a navigation inside the Site) revokes the bridge instead of
|
|
12
|
+
* handing a fresh port to an unknown document.
|
|
13
|
+
*/
|
|
14
|
+
import type { SiteViewer } from "@opengeni/contracts";
|
|
15
|
+
import { type OpenGeniSiteBridgeReadyMessage, type OpenGeniSiteBridgeRequestMessage, type OpenGeniSiteSignInResult, type OpenGeniSiteToolCatalog } from "./site.js";
|
|
16
|
+
import { type SiteHttpRequest } from "./site-http.js";
|
|
17
|
+
import type { ToolGatewayCallRequest, ToolGatewayCallResponse, ToolGatewayDeclarationsResponse, ToolGatewayInvokeRequest, ToolGatewayInvokeResponse, ToolGatewayResolveRequest, ToolGatewayResolvedTool } from "./types.js";
|
|
18
|
+
export type { SiteHttpRequest } from "./site-http.js";
|
|
19
|
+
/** Tool and Site HTTP handlers a host supplies. Credentials stay inside these functions. */
|
|
20
|
+
export type SiteBridgeToolHandlers = {
|
|
21
|
+
resolve?: (request: ToolGatewayResolveRequest, options: {
|
|
22
|
+
signal: AbortSignal;
|
|
23
|
+
}) => Promise<ToolGatewayResolvedTool>;
|
|
24
|
+
invoke?: (request: ToolGatewayInvokeRequest, options: {
|
|
25
|
+
signal: AbortSignal;
|
|
26
|
+
}) => Promise<ToolGatewayInvokeResponse>;
|
|
27
|
+
/** Serves the ordinary SDK's HTTP requests (sessions, Site Data) over the Site HTTP channel. */
|
|
28
|
+
fetch?: (request: SiteHttpRequest, signal: AbortSignal) => Promise<Response>;
|
|
29
|
+
/**
|
|
30
|
+
* Advertise Site Data and Site SQL: `fetch` serves `published-artifacts/current`
|
|
31
|
+
* routes (data, files and `sql/queries/<name>`) for the pinned Site.
|
|
32
|
+
*/
|
|
33
|
+
siteData?: boolean;
|
|
34
|
+
catalog: (options: {
|
|
35
|
+
signal: AbortSignal;
|
|
36
|
+
}) => Promise<OpenGeniSiteToolCatalog>;
|
|
37
|
+
call: (request: ToolGatewayCallRequest, options: {
|
|
38
|
+
signal: AbortSignal;
|
|
39
|
+
}) => Promise<ToolGatewayCallResponse>;
|
|
40
|
+
declarations?: (options: {
|
|
41
|
+
signal: AbortSignal;
|
|
42
|
+
}) => Promise<ToolGatewayDeclarationsResponse>;
|
|
43
|
+
};
|
|
44
|
+
/** Viewer identity and sign-in, answered by the host itself (advertised as `viewer: 1`). */
|
|
45
|
+
export type SiteBridgeViewerHandlers = {
|
|
46
|
+
viewer: (options: {
|
|
47
|
+
signal: AbortSignal;
|
|
48
|
+
}) => Promise<SiteViewer> | SiteViewer;
|
|
49
|
+
/** Defaults to `{ started: false }`: the viewer is already signed in or the host has no sign-in. */
|
|
50
|
+
signIn?: (options: {
|
|
51
|
+
signal: AbortSignal;
|
|
52
|
+
}) => Promise<OpenGeniSiteSignInResult> | OpenGeniSiteSignInResult;
|
|
53
|
+
};
|
|
54
|
+
export type SiteBridgeRequestValue = OpenGeniSiteToolCatalog | ToolGatewayCallResponse | ToolGatewayDeclarationsResponse | ToolGatewayResolvedTool | ToolGatewayInvokeResponse | SiteViewer | OpenGeniSiteSignInResult;
|
|
55
|
+
/** Capabilities the host advertises when a Site connects; Sites never ask for more. */
|
|
56
|
+
export declare function siteBridgeReadyMessage(bridge: SiteBridgeToolHandlers | undefined, viewer?: SiteBridgeViewerHandlers): OpenGeniSiteBridgeReadyMessage;
|
|
57
|
+
/**
|
|
58
|
+
* The inline script a host puts at the top of Site HTML. It accepts exactly
|
|
59
|
+
* one ready message with one port from the parent window and keeps that port
|
|
60
|
+
* on a window global so SDK clients created later can still connect.
|
|
61
|
+
*/
|
|
62
|
+
export declare const SITE_BRIDGE_BOOTSTRAP_SCRIPT: string;
|
|
63
|
+
/** Insert the bootstrap script right after a leading doctype (or at the start). */
|
|
64
|
+
export declare function injectSiteBridgeBootstrap(html: string): string;
|
|
65
|
+
export type SiteBridgeHostSource = {
|
|
66
|
+
/** Read on every request, so a host can swap handlers without reconnecting the Site. */
|
|
67
|
+
tools: () => SiteBridgeToolHandlers | undefined;
|
|
68
|
+
viewer?: () => SiteBridgeViewerHandlers | undefined;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* One frame's bridge host. Call `load(frame.contentWindow)` from the frame's
|
|
72
|
+
* load event and `close()` when the frame goes away.
|
|
73
|
+
*/
|
|
74
|
+
export declare class SiteBridgeHost {
|
|
75
|
+
private readonly source;
|
|
76
|
+
private readonly requests;
|
|
77
|
+
private readonly lease;
|
|
78
|
+
constructor(source: SiteBridgeHostSource, options?: {
|
|
79
|
+
createMessageChannel?: () => MessageChannel;
|
|
80
|
+
});
|
|
81
|
+
/** Offer the bootstrap port to a freshly loaded document. Returns false (and revokes) on reload. */
|
|
82
|
+
load(frameWindow: Pick<Window, "postMessage">): boolean;
|
|
83
|
+
close(): void;
|
|
84
|
+
private attachToolPort;
|
|
85
|
+
}
|
|
86
|
+
export declare class SiteBridgeRequestRegistry {
|
|
87
|
+
private readonly controllersByPort;
|
|
88
|
+
addPort(port: MessagePort): void;
|
|
89
|
+
start(port: MessagePort, requestId: string): AbortController | null;
|
|
90
|
+
cancel(port: MessagePort, requestId: string): void;
|
|
91
|
+
complete(port: MessagePort, requestId: string, controller: AbortController): void;
|
|
92
|
+
closePort(port: MessagePort): void;
|
|
93
|
+
closeAll(): void;
|
|
94
|
+
}
|
|
95
|
+
export declare class SiteBridgeDocumentLease {
|
|
96
|
+
private readonly attachToolPort;
|
|
97
|
+
private readonly closeActivePorts;
|
|
98
|
+
private readonly createMessageChannel;
|
|
99
|
+
private loaded;
|
|
100
|
+
private bootstrapPort;
|
|
101
|
+
constructor(attachToolPort: (data: unknown, ports: readonly MessagePort[]) => void, closeActivePorts: () => void, createMessageChannel?: () => MessageChannel);
|
|
102
|
+
load(frameWindow: Pick<Window, "postMessage">): boolean;
|
|
103
|
+
close(): void;
|
|
104
|
+
}
|
|
105
|
+
export declare function openGeniSiteBridgePortFromBootstrap(data: unknown, ports: readonly MessagePort[]): MessagePort | null;
|
|
106
|
+
export declare function handleSiteBridgeRequest(bridge: SiteBridgeToolHandlers | undefined, message: OpenGeniSiteBridgeRequestMessage, signal: AbortSignal, viewer?: SiteBridgeViewerHandlers): Promise<SiteBridgeRequestValue>;
|
|
107
|
+
export declare function siteBridgeError(error: unknown, legacyCall?: boolean): {
|
|
108
|
+
code: string;
|
|
109
|
+
message: string;
|
|
110
|
+
retryable: boolean;
|
|
111
|
+
outcomeUnknown: boolean;
|
|
112
|
+
};
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OPENGENI_SITE_BRIDGE_BOOTSTRAP_GLOBAL,
|
|
3
|
+
OPENGENI_SITE_BRIDGE_READY,
|
|
4
|
+
OPENGENI_SITE_BRIDGE_RESPONSE,
|
|
5
|
+
OPENGENI_SITE_BRIDGE_SIGN_IN_METHOD,
|
|
6
|
+
OPENGENI_SITE_BRIDGE_VERSION,
|
|
7
|
+
OPENGENI_SITE_BRIDGE_VIEWER_METHOD,
|
|
8
|
+
isOpenGeniSiteBridgeCancelMessage,
|
|
9
|
+
isOpenGeniSiteBridgeConnectMessage,
|
|
10
|
+
isOpenGeniSiteBridgeRequestMessage,
|
|
11
|
+
isSiteHttpRequest,
|
|
12
|
+
sanitizeOpenGeniSiteToolCallRequest,
|
|
13
|
+
sanitizeOpenGeniSiteToolInvokeRequest,
|
|
14
|
+
serveSiteHttp
|
|
15
|
+
} from "./chunk-WSYYXONG.js";
|
|
16
|
+
import "./chunk-OV3POE62.js";
|
|
17
|
+
import "./chunk-P7UWKORG.js";
|
|
18
|
+
import "./chunk-S2NLS3ES.js";
|
|
19
|
+
import "./chunk-X5ITQVXE.js";
|
|
20
|
+
import "./chunk-4AHR4KGA.js";
|
|
21
|
+
import "./chunk-NCU5OAN7.js";
|
|
22
|
+
import "./chunk-YJCHB7R3.js";
|
|
23
|
+
import "./chunk-7EWT3PV6.js";
|
|
24
|
+
|
|
25
|
+
// src/site-bridge-host.ts
|
|
26
|
+
function siteBridgeReadyMessage(bridge, viewer) {
|
|
27
|
+
return {
|
|
28
|
+
type: OPENGENI_SITE_BRIDGE_READY,
|
|
29
|
+
version: OPENGENI_SITE_BRIDGE_VERSION,
|
|
30
|
+
...bridge?.resolve && bridge?.invoke ? { targetTools: 1 } : {},
|
|
31
|
+
...bridge?.fetch && bridge.siteData ? { siteData: 1 } : {},
|
|
32
|
+
...viewer ? { viewer: 1 } : {}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
var SITE_BRIDGE_BOOTSTRAP_SCRIPT = `<script>(()=>{const key=${JSON.stringify(
|
|
36
|
+
OPENGENI_SITE_BRIDGE_BOOTSTRAP_GLOBAL
|
|
37
|
+
)};const parentWindow=window.parent;if(parentWindow===window)return;window.addEventListener("message",event=>{const data=event.data;if(event.source!==parentWindow||!data||data.type!==${JSON.stringify(
|
|
38
|
+
OPENGENI_SITE_BRIDGE_READY
|
|
39
|
+
)}||data.version!==${OPENGENI_SITE_BRIDGE_VERSION}||event.ports.length!==1)return;const port=event.ports[0];const previous=window[key]?.port;if(previous&&previous!==port)previous.close();Object.defineProperty(window,key,{configurable:true,value:{port}});port.start();});})();</script>`;
|
|
40
|
+
function injectSiteBridgeBootstrap(html) {
|
|
41
|
+
const doctypeEnd = leadingDoctypeEnd(html);
|
|
42
|
+
if (doctypeEnd >= 0) {
|
|
43
|
+
return `${html.slice(0, doctypeEnd + 1)}${SITE_BRIDGE_BOOTSTRAP_SCRIPT}${html.slice(doctypeEnd + 1)}`;
|
|
44
|
+
}
|
|
45
|
+
return `${SITE_BRIDGE_BOOTSTRAP_SCRIPT}${html}`;
|
|
46
|
+
}
|
|
47
|
+
function leadingDoctypeEnd(html) {
|
|
48
|
+
const lower = html.toLowerCase();
|
|
49
|
+
let cursor = html.charCodeAt(0) === 65279 ? 1 : 0;
|
|
50
|
+
while (cursor < html.length) {
|
|
51
|
+
while (/\s/.test(html[cursor] ?? "")) cursor += 1;
|
|
52
|
+
if (!html.startsWith("<!--", cursor)) break;
|
|
53
|
+
const commentEnd = html.indexOf("-->", cursor + 4);
|
|
54
|
+
if (commentEnd < 0) return -1;
|
|
55
|
+
cursor = commentEnd + 3;
|
|
56
|
+
}
|
|
57
|
+
if (!lower.startsWith("<!doctype", cursor)) return -1;
|
|
58
|
+
return html.indexOf(">", cursor + 9);
|
|
59
|
+
}
|
|
60
|
+
var SiteBridgeHost = class {
|
|
61
|
+
constructor(source, options = {}) {
|
|
62
|
+
this.source = source;
|
|
63
|
+
this.lease = new SiteBridgeDocumentLease(
|
|
64
|
+
(data, ports) => this.attachToolPort(data, ports),
|
|
65
|
+
() => this.requests.closeAll(),
|
|
66
|
+
options.createMessageChannel
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
requests = new SiteBridgeRequestRegistry();
|
|
70
|
+
lease;
|
|
71
|
+
/** Offer the bootstrap port to a freshly loaded document. Returns false (and revokes) on reload. */
|
|
72
|
+
load(frameWindow) {
|
|
73
|
+
return this.lease.load(frameWindow);
|
|
74
|
+
}
|
|
75
|
+
close() {
|
|
76
|
+
this.lease.close();
|
|
77
|
+
}
|
|
78
|
+
attachToolPort(data, ports) {
|
|
79
|
+
const port = openGeniSiteBridgePortFromBootstrap(data, ports);
|
|
80
|
+
if (!port) return;
|
|
81
|
+
const requests = this.requests;
|
|
82
|
+
requests.addPort(port);
|
|
83
|
+
port.addEventListener("message", (portEvent) => {
|
|
84
|
+
const message = portEvent.data;
|
|
85
|
+
if (isOpenGeniSiteBridgeCancelMessage(message)) {
|
|
86
|
+
requests.cancel(port, message.requestId);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (isSiteHttpRequest(message) && portEvent.ports.length === 1) {
|
|
90
|
+
const controller2 = requests.start(port, message.requestId);
|
|
91
|
+
if (!controller2) {
|
|
92
|
+
portEvent.ports[0].close();
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
void serveSiteHttp(
|
|
96
|
+
message,
|
|
97
|
+
portEvent.ports[0],
|
|
98
|
+
async (request, signal) => {
|
|
99
|
+
const fetch = this.source.tools()?.fetch;
|
|
100
|
+
if (!fetch) throw new Error("This Site host does not support the session SDK");
|
|
101
|
+
return fetch(request, signal);
|
|
102
|
+
},
|
|
103
|
+
controller2.signal
|
|
104
|
+
).finally(() => requests.complete(port, message.requestId, controller2));
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (!isOpenGeniSiteBridgeRequestMessage(message)) return;
|
|
108
|
+
const controller = requests.start(port, message.requestId);
|
|
109
|
+
if (!controller) {
|
|
110
|
+
port.postMessage({
|
|
111
|
+
type: OPENGENI_SITE_BRIDGE_RESPONSE,
|
|
112
|
+
version: OPENGENI_SITE_BRIDGE_VERSION,
|
|
113
|
+
requestId: message.requestId,
|
|
114
|
+
ok: false,
|
|
115
|
+
error: {
|
|
116
|
+
code: "duplicate_request_id",
|
|
117
|
+
message: "A Site tool request with this id is already running",
|
|
118
|
+
retryable: false
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
void handleSiteBridgeRequest(
|
|
124
|
+
this.source.tools(),
|
|
125
|
+
message,
|
|
126
|
+
controller.signal,
|
|
127
|
+
this.source.viewer?.()
|
|
128
|
+
).then((value) => {
|
|
129
|
+
if (!controller.signal.aborted) {
|
|
130
|
+
port.postMessage({
|
|
131
|
+
type: OPENGENI_SITE_BRIDGE_RESPONSE,
|
|
132
|
+
version: OPENGENI_SITE_BRIDGE_VERSION,
|
|
133
|
+
requestId: message.requestId,
|
|
134
|
+
ok: true,
|
|
135
|
+
value
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}).catch((error) => {
|
|
139
|
+
if (!controller.signal.aborted) {
|
|
140
|
+
port.postMessage({
|
|
141
|
+
type: OPENGENI_SITE_BRIDGE_RESPONSE,
|
|
142
|
+
version: OPENGENI_SITE_BRIDGE_VERSION,
|
|
143
|
+
requestId: message.requestId,
|
|
144
|
+
ok: false,
|
|
145
|
+
error: siteBridgeError(error, message.method === "call")
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}).finally(() => requests.complete(port, message.requestId, controller));
|
|
149
|
+
});
|
|
150
|
+
port.addEventListener("messageerror", () => requests.closePort(port));
|
|
151
|
+
port.start();
|
|
152
|
+
port.postMessage(siteBridgeReadyMessage(this.source.tools(), this.source.viewer?.()));
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
var SiteBridgeRequestRegistry = class {
|
|
156
|
+
controllersByPort = /* @__PURE__ */ new Map();
|
|
157
|
+
addPort(port) {
|
|
158
|
+
if (!this.controllersByPort.has(port)) this.controllersByPort.set(port, /* @__PURE__ */ new Map());
|
|
159
|
+
}
|
|
160
|
+
start(port, requestId) {
|
|
161
|
+
const controllers = this.controllersByPort.get(port);
|
|
162
|
+
if (!controllers || controllers.has(requestId)) return null;
|
|
163
|
+
const controller = new AbortController();
|
|
164
|
+
controllers.set(requestId, controller);
|
|
165
|
+
return controller;
|
|
166
|
+
}
|
|
167
|
+
cancel(port, requestId) {
|
|
168
|
+
const controllers = this.controllersByPort.get(port);
|
|
169
|
+
const controller = controllers?.get(requestId);
|
|
170
|
+
if (!controller) return;
|
|
171
|
+
controller.abort(new Error("Site tool request cancelled"));
|
|
172
|
+
controllers.delete(requestId);
|
|
173
|
+
}
|
|
174
|
+
complete(port, requestId, controller) {
|
|
175
|
+
const controllers = this.controllersByPort.get(port);
|
|
176
|
+
if (controllers?.get(requestId) === controller) controllers.delete(requestId);
|
|
177
|
+
}
|
|
178
|
+
closePort(port) {
|
|
179
|
+
const controllers = this.controllersByPort.get(port);
|
|
180
|
+
if (!controllers) return;
|
|
181
|
+
for (const controller of controllers.values()) {
|
|
182
|
+
controller.abort(new Error("Site tool bridge port closed"));
|
|
183
|
+
}
|
|
184
|
+
controllers.clear();
|
|
185
|
+
this.controllersByPort.delete(port);
|
|
186
|
+
port.close();
|
|
187
|
+
}
|
|
188
|
+
closeAll() {
|
|
189
|
+
for (const port of [...this.controllersByPort.keys()]) this.closePort(port);
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
var SiteBridgeDocumentLease = class {
|
|
193
|
+
constructor(attachToolPort, closeActivePorts, createMessageChannel = () => new MessageChannel()) {
|
|
194
|
+
this.attachToolPort = attachToolPort;
|
|
195
|
+
this.closeActivePorts = closeActivePorts;
|
|
196
|
+
this.createMessageChannel = createMessageChannel;
|
|
197
|
+
}
|
|
198
|
+
loaded = false;
|
|
199
|
+
bootstrapPort = null;
|
|
200
|
+
load(frameWindow) {
|
|
201
|
+
if (this.loaded) {
|
|
202
|
+
this.close();
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
this.loaded = true;
|
|
206
|
+
const channel = this.createMessageChannel();
|
|
207
|
+
this.bootstrapPort = channel.port1;
|
|
208
|
+
channel.port1.addEventListener("message", (event) => {
|
|
209
|
+
this.attachToolPort(event.data, event.ports);
|
|
210
|
+
});
|
|
211
|
+
channel.port1.start();
|
|
212
|
+
frameWindow.postMessage(
|
|
213
|
+
{
|
|
214
|
+
type: OPENGENI_SITE_BRIDGE_READY,
|
|
215
|
+
version: OPENGENI_SITE_BRIDGE_VERSION
|
|
216
|
+
},
|
|
217
|
+
"*",
|
|
218
|
+
[channel.port2]
|
|
219
|
+
);
|
|
220
|
+
return true;
|
|
221
|
+
}
|
|
222
|
+
close() {
|
|
223
|
+
this.bootstrapPort?.close();
|
|
224
|
+
this.bootstrapPort = null;
|
|
225
|
+
this.closeActivePorts();
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
function openGeniSiteBridgePortFromBootstrap(data, ports) {
|
|
229
|
+
if (!isOpenGeniSiteBridgeConnectMessage(data)) return null;
|
|
230
|
+
return ports.length === 1 ? ports[0] : null;
|
|
231
|
+
}
|
|
232
|
+
async function handleSiteBridgeRequest(bridge, message, signal, viewer) {
|
|
233
|
+
if (message.method === OPENGENI_SITE_BRIDGE_VIEWER_METHOD) {
|
|
234
|
+
if (!viewer) throw siteBridgeHostError("viewer_unavailable", "This Site host has no viewer");
|
|
235
|
+
return await viewer.viewer({ signal });
|
|
236
|
+
}
|
|
237
|
+
if (message.method === OPENGENI_SITE_BRIDGE_SIGN_IN_METHOD) {
|
|
238
|
+
if (!viewer?.signIn) return { started: false };
|
|
239
|
+
const result = await viewer.signIn({ signal });
|
|
240
|
+
return { started: result?.started === true };
|
|
241
|
+
}
|
|
242
|
+
if (!bridge) throw new Error("Site tool bridge is unavailable");
|
|
243
|
+
if (message.method === "resolve") {
|
|
244
|
+
if (!bridge.resolve) throw new Error("Targeted Site tools are unavailable");
|
|
245
|
+
return await bridge.resolve({ target: message.payload.target }, { signal });
|
|
246
|
+
}
|
|
247
|
+
if (message.method === "invoke") {
|
|
248
|
+
if (!bridge.invoke) throw new Error("Targeted Site tools are unavailable");
|
|
249
|
+
return await bridge.invoke(sanitizeOpenGeniSiteToolInvokeRequest(message.payload), { signal });
|
|
250
|
+
}
|
|
251
|
+
if (message.method === "catalog") return await bridge.catalog({ signal });
|
|
252
|
+
if (message.method === "declarations") {
|
|
253
|
+
if (!bridge.declarations) throw new Error("Site tool declarations are unavailable");
|
|
254
|
+
return await bridge.declarations({ signal });
|
|
255
|
+
}
|
|
256
|
+
return await bridge.call(sanitizeOpenGeniSiteToolCallRequest(message.payload), { signal });
|
|
257
|
+
}
|
|
258
|
+
function siteBridgeHostError(code, message) {
|
|
259
|
+
return Object.assign(new Error(message), { code });
|
|
260
|
+
}
|
|
261
|
+
function siteBridgeError(error, legacyCall = false) {
|
|
262
|
+
const candidate = error;
|
|
263
|
+
const nestedCode = candidate?.details?.code;
|
|
264
|
+
const knownPreexecution = candidate?.retryable === true && candidate?.outcomeUnknown === false;
|
|
265
|
+
const stale = knownPreexecution && (nestedCode === "tool_definition_stale" || nestedCode === "catalog_stale");
|
|
266
|
+
const unsafeControl = legacyCall && !knownPreexecution && (candidate?.code === "catalog_stale" || candidate?.code === "tool_definition_stale");
|
|
267
|
+
const message = typeof candidate?.message === "string" ? candidate.message : "Site tool request failed";
|
|
268
|
+
return {
|
|
269
|
+
code: stale ? nestedCode : unsafeControl ? "site_tool_call_failed" : typeof candidate?.code === "string" ? candidate.code : "site_tool_call_failed",
|
|
270
|
+
message: unsafeControl ? `[${candidate.code}] ${message}` : message,
|
|
271
|
+
retryable: candidate?.retryable === true,
|
|
272
|
+
outcomeUnknown: candidate?.outcomeUnknown === true
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
export {
|
|
276
|
+
SITE_BRIDGE_BOOTSTRAP_SCRIPT,
|
|
277
|
+
SiteBridgeDocumentLease,
|
|
278
|
+
SiteBridgeHost,
|
|
279
|
+
SiteBridgeRequestRegistry,
|
|
280
|
+
handleSiteBridgeRequest,
|
|
281
|
+
injectSiteBridgeBootstrap,
|
|
282
|
+
openGeniSiteBridgePortFromBootstrap,
|
|
283
|
+
siteBridgeError,
|
|
284
|
+
siteBridgeReadyMessage
|
|
285
|
+
};
|
|
286
|
+
//# sourceMappingURL=site-bridge-host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/site-bridge-host.ts"],"sourcesContent":["/**\n * Framework-free host side of the Site MessagePort bridge. The console's\n * `PublishedHtmlArtifactFrame` and the published-Site gateway shell both run\n * this code; each injects its own tool transport, Site HTTP handler, viewer\n * provider and sign-in action.\n *\n * Protocol (v2): the host posts a ready message with a bootstrap port to the\n * frame window once per document load; each SDK client connects through that\n * port with its own MessagePort. Requests are tracked per port so a cancel or\n * a document teardown aborts exactly the requests it owns. A second load of\n * the same frame (a navigation inside the Site) revokes the bridge instead of\n * handing a fresh port to an unknown document.\n */\nimport type { SiteViewer } from \"@opengeni/contracts\";\nimport {\n OPENGENI_SITE_BRIDGE_BOOTSTRAP_GLOBAL,\n OPENGENI_SITE_BRIDGE_READY,\n OPENGENI_SITE_BRIDGE_RESPONSE,\n OPENGENI_SITE_BRIDGE_SIGN_IN_METHOD,\n OPENGENI_SITE_BRIDGE_VERSION,\n OPENGENI_SITE_BRIDGE_VIEWER_METHOD,\n isOpenGeniSiteBridgeCancelMessage,\n isOpenGeniSiteBridgeConnectMessage,\n isOpenGeniSiteBridgeRequestMessage,\n sanitizeOpenGeniSiteToolCallRequest,\n sanitizeOpenGeniSiteToolInvokeRequest,\n type OpenGeniSiteBridgeReadyMessage,\n type OpenGeniSiteBridgeRequestMessage,\n type OpenGeniSiteBridgeResponseMessage,\n type OpenGeniSiteSignInResult,\n type OpenGeniSiteToolCatalog,\n} from \"./site\";\nimport { isSiteHttpRequest, serveSiteHttp, type SiteHttpRequest } from \"./site-http\";\nimport type {\n ToolGatewayCallRequest,\n ToolGatewayCallResponse,\n ToolGatewayDeclarationsResponse,\n ToolGatewayInvokeRequest,\n ToolGatewayInvokeResponse,\n ToolGatewayResolveRequest,\n ToolGatewayResolvedTool,\n} from \"./types\";\n\nexport type { SiteHttpRequest } from \"./site-http\";\n\n/** Tool and Site HTTP handlers a host supplies. Credentials stay inside these functions. */\nexport type SiteBridgeToolHandlers = {\n resolve?: (\n request: ToolGatewayResolveRequest,\n options: { signal: AbortSignal },\n ) => Promise<ToolGatewayResolvedTool>;\n invoke?: (\n request: ToolGatewayInvokeRequest,\n options: { signal: AbortSignal },\n ) => Promise<ToolGatewayInvokeResponse>;\n /** Serves the ordinary SDK's HTTP requests (sessions, Site Data) over the Site HTTP channel. */\n fetch?: (request: SiteHttpRequest, signal: AbortSignal) => Promise<Response>;\n /**\n * Advertise Site Data and Site SQL: `fetch` serves `published-artifacts/current`\n * routes (data, files and `sql/queries/<name>`) for the pinned Site.\n */\n siteData?: boolean;\n catalog: (options: { signal: AbortSignal }) => Promise<OpenGeniSiteToolCatalog>;\n call: (\n request: ToolGatewayCallRequest,\n options: { signal: AbortSignal },\n ) => Promise<ToolGatewayCallResponse>;\n declarations?: (options: { signal: AbortSignal }) => Promise<ToolGatewayDeclarationsResponse>;\n};\n\n/** Viewer identity and sign-in, answered by the host itself (advertised as `viewer: 1`). */\nexport type SiteBridgeViewerHandlers = {\n viewer: (options: { signal: AbortSignal }) => Promise<SiteViewer> | SiteViewer;\n /** Defaults to `{ started: false }`: the viewer is already signed in or the host has no sign-in. */\n signIn?: (options: {\n signal: AbortSignal;\n }) => Promise<OpenGeniSiteSignInResult> | OpenGeniSiteSignInResult;\n};\n\nexport type SiteBridgeRequestValue =\n | OpenGeniSiteToolCatalog\n | ToolGatewayCallResponse\n | ToolGatewayDeclarationsResponse\n | ToolGatewayResolvedTool\n | ToolGatewayInvokeResponse\n | SiteViewer\n | OpenGeniSiteSignInResult;\n\n/** Capabilities the host advertises when a Site connects; Sites never ask for more. */\nexport function siteBridgeReadyMessage(\n bridge: SiteBridgeToolHandlers | undefined,\n viewer?: SiteBridgeViewerHandlers,\n): OpenGeniSiteBridgeReadyMessage {\n return {\n type: OPENGENI_SITE_BRIDGE_READY,\n version: OPENGENI_SITE_BRIDGE_VERSION,\n ...(bridge?.resolve && bridge?.invoke ? { targetTools: 1 as const } : {}),\n ...(bridge?.fetch && bridge.siteData ? { siteData: 1 as const } : {}),\n ...(viewer ? { viewer: 1 as const } : {}),\n };\n}\n\n/**\n * The inline script a host puts at the top of Site HTML. It accepts exactly\n * one ready message with one port from the parent window and keeps that port\n * on a window global so SDK clients created later can still connect.\n */\nexport const SITE_BRIDGE_BOOTSTRAP_SCRIPT = `<script>(()=>{const key=${JSON.stringify(\n OPENGENI_SITE_BRIDGE_BOOTSTRAP_GLOBAL,\n)};const parentWindow=window.parent;if(parentWindow===window)return;window.addEventListener(\"message\",event=>{const data=event.data;if(event.source!==parentWindow||!data||data.type!==${JSON.stringify(\n OPENGENI_SITE_BRIDGE_READY,\n)}||data.version!==${OPENGENI_SITE_BRIDGE_VERSION}||event.ports.length!==1)return;const port=event.ports[0];const previous=window[key]?.port;if(previous&&previous!==port)previous.close();Object.defineProperty(window,key,{configurable:true,value:{port}});port.start();});})();</script>`;\n\n/** Insert the bootstrap script right after a leading doctype (or at the start). */\nexport function injectSiteBridgeBootstrap(html: string): string {\n const doctypeEnd = leadingDoctypeEnd(html);\n if (doctypeEnd >= 0) {\n return `${html.slice(0, doctypeEnd + 1)}${SITE_BRIDGE_BOOTSTRAP_SCRIPT}${html.slice(doctypeEnd + 1)}`;\n }\n return `${SITE_BRIDGE_BOOTSTRAP_SCRIPT}${html}`;\n}\n\nfunction leadingDoctypeEnd(html: string): number {\n const lower = html.toLowerCase();\n let cursor = html.charCodeAt(0) === 0xfeff ? 1 : 0;\n while (cursor < html.length) {\n while (/\\s/.test(html[cursor] ?? \"\")) cursor += 1;\n if (!html.startsWith(\"<!--\", cursor)) break;\n const commentEnd = html.indexOf(\"-->\", cursor + 4);\n if (commentEnd < 0) return -1;\n cursor = commentEnd + 3;\n }\n if (!lower.startsWith(\"<!doctype\", cursor)) return -1;\n return html.indexOf(\">\", cursor + 9);\n}\n\nexport type SiteBridgeHostSource = {\n /** Read on every request, so a host can swap handlers without reconnecting the Site. */\n tools: () => SiteBridgeToolHandlers | undefined;\n viewer?: () => SiteBridgeViewerHandlers | undefined;\n};\n\n/**\n * One frame's bridge host. Call `load(frame.contentWindow)` from the frame's\n * load event and `close()` when the frame goes away.\n */\nexport class SiteBridgeHost {\n private readonly requests = new SiteBridgeRequestRegistry();\n private readonly lease: SiteBridgeDocumentLease;\n\n constructor(\n private readonly source: SiteBridgeHostSource,\n options: { createMessageChannel?: () => MessageChannel } = {},\n ) {\n this.lease = new SiteBridgeDocumentLease(\n (data, ports) => this.attachToolPort(data, ports),\n () => this.requests.closeAll(),\n options.createMessageChannel,\n );\n }\n\n /** Offer the bootstrap port to a freshly loaded document. Returns false (and revokes) on reload. */\n load(frameWindow: Pick<Window, \"postMessage\">): boolean {\n return this.lease.load(frameWindow);\n }\n\n close(): void {\n this.lease.close();\n }\n\n private attachToolPort(data: unknown, ports: readonly MessagePort[]): void {\n const port = openGeniSiteBridgePortFromBootstrap(data, ports);\n if (!port) return;\n const requests = this.requests;\n requests.addPort(port);\n port.addEventListener(\"message\", (portEvent: MessageEvent<unknown>) => {\n const message = portEvent.data;\n if (isOpenGeniSiteBridgeCancelMessage(message)) {\n requests.cancel(port, message.requestId);\n return;\n }\n if (isSiteHttpRequest(message) && portEvent.ports.length === 1) {\n const controller = requests.start(port, message.requestId);\n if (!controller) {\n portEvent.ports[0]!.close();\n return;\n }\n void serveSiteHttp(\n message,\n portEvent.ports[0]!,\n async (request, signal) => {\n const fetch = this.source.tools()?.fetch;\n if (!fetch) throw new Error(\"This Site host does not support the session SDK\");\n return fetch(request, signal);\n },\n controller.signal,\n ).finally(() => requests.complete(port, message.requestId, controller));\n return;\n }\n if (!isOpenGeniSiteBridgeRequestMessage(message)) return;\n const controller = requests.start(port, message.requestId);\n if (!controller) {\n port.postMessage({\n type: OPENGENI_SITE_BRIDGE_RESPONSE,\n version: OPENGENI_SITE_BRIDGE_VERSION,\n requestId: message.requestId,\n ok: false,\n error: {\n code: \"duplicate_request_id\",\n message: \"A Site tool request with this id is already running\",\n retryable: false,\n },\n } satisfies OpenGeniSiteBridgeResponseMessage);\n return;\n }\n void handleSiteBridgeRequest(\n this.source.tools(),\n message,\n controller.signal,\n this.source.viewer?.(),\n )\n .then((value) => {\n if (!controller.signal.aborted) {\n port.postMessage({\n type: OPENGENI_SITE_BRIDGE_RESPONSE,\n version: OPENGENI_SITE_BRIDGE_VERSION,\n requestId: message.requestId,\n ok: true,\n value,\n } satisfies OpenGeniSiteBridgeResponseMessage);\n }\n })\n .catch((error) => {\n if (!controller.signal.aborted) {\n port.postMessage({\n type: OPENGENI_SITE_BRIDGE_RESPONSE,\n version: OPENGENI_SITE_BRIDGE_VERSION,\n requestId: message.requestId,\n ok: false,\n error: siteBridgeError(error, message.method === \"call\"),\n } satisfies OpenGeniSiteBridgeResponseMessage);\n }\n })\n .finally(() => requests.complete(port, message.requestId, controller));\n });\n port.addEventListener(\"messageerror\", () => requests.closePort(port));\n port.start();\n port.postMessage(siteBridgeReadyMessage(this.source.tools(), this.source.viewer?.()));\n }\n}\n\nexport class SiteBridgeRequestRegistry {\n private readonly controllersByPort = new Map<MessagePort, Map<string, AbortController>>();\n\n addPort(port: MessagePort): void {\n // Several SDK clients may share one document bootstrap. Document teardown,\n // not another client connecting, revokes all of that document's ports.\n if (!this.controllersByPort.has(port)) this.controllersByPort.set(port, new Map());\n }\n\n start(port: MessagePort, requestId: string): AbortController | null {\n const controllers = this.controllersByPort.get(port);\n if (!controllers || controllers.has(requestId)) return null;\n const controller = new AbortController();\n controllers.set(requestId, controller);\n return controller;\n }\n\n cancel(port: MessagePort, requestId: string): void {\n const controllers = this.controllersByPort.get(port);\n const controller = controllers?.get(requestId);\n if (!controller) return;\n controller.abort(new Error(\"Site tool request cancelled\"));\n controllers!.delete(requestId);\n }\n\n complete(port: MessagePort, requestId: string, controller: AbortController): void {\n const controllers = this.controllersByPort.get(port);\n if (controllers?.get(requestId) === controller) controllers.delete(requestId);\n }\n\n closePort(port: MessagePort): void {\n const controllers = this.controllersByPort.get(port);\n if (!controllers) return;\n for (const controller of controllers.values()) {\n controller.abort(new Error(\"Site tool bridge port closed\"));\n }\n controllers.clear();\n this.controllersByPort.delete(port);\n port.close();\n }\n\n closeAll(): void {\n for (const port of [...this.controllersByPort.keys()]) this.closePort(port);\n }\n}\n\nexport class SiteBridgeDocumentLease {\n private loaded = false;\n private bootstrapPort: MessagePort | null = null;\n\n constructor(\n private readonly attachToolPort: (data: unknown, ports: readonly MessagePort[]) => void,\n private readonly closeActivePorts: () => void,\n private readonly createMessageChannel: () => MessageChannel = () => new MessageChannel(),\n ) {}\n\n load(frameWindow: Pick<Window, \"postMessage\">): boolean {\n if (this.loaded) {\n this.close();\n return false;\n }\n this.loaded = true;\n const channel = this.createMessageChannel();\n this.bootstrapPort = channel.port1;\n channel.port1.addEventListener(\"message\", (event: MessageEvent<unknown>) => {\n this.attachToolPort(event.data, event.ports);\n });\n channel.port1.start();\n frameWindow.postMessage(\n {\n type: OPENGENI_SITE_BRIDGE_READY,\n version: OPENGENI_SITE_BRIDGE_VERSION,\n },\n \"*\",\n [channel.port2],\n );\n return true;\n }\n\n close(): void {\n this.bootstrapPort?.close();\n this.bootstrapPort = null;\n this.closeActivePorts();\n }\n}\n\nexport function openGeniSiteBridgePortFromBootstrap(\n data: unknown,\n ports: readonly MessagePort[],\n): MessagePort | null {\n if (!isOpenGeniSiteBridgeConnectMessage(data)) return null;\n return ports.length === 1 ? ports[0]! : null;\n}\n\nexport async function handleSiteBridgeRequest(\n bridge: SiteBridgeToolHandlers | undefined,\n message: OpenGeniSiteBridgeRequestMessage,\n signal: AbortSignal,\n viewer?: SiteBridgeViewerHandlers,\n): Promise<SiteBridgeRequestValue> {\n if (message.method === OPENGENI_SITE_BRIDGE_VIEWER_METHOD) {\n if (!viewer) throw siteBridgeHostError(\"viewer_unavailable\", \"This Site host has no viewer\");\n return await viewer.viewer({ signal });\n }\n if (message.method === OPENGENI_SITE_BRIDGE_SIGN_IN_METHOD) {\n if (!viewer?.signIn) return { started: false };\n const result = await viewer.signIn({ signal });\n return { started: result?.started === true };\n }\n if (!bridge) throw new Error(\"Site tool bridge is unavailable\");\n if (message.method === \"resolve\") {\n if (!bridge.resolve) throw new Error(\"Targeted Site tools are unavailable\");\n return await bridge.resolve({ target: message.payload.target }, { signal });\n }\n if (message.method === \"invoke\") {\n if (!bridge.invoke) throw new Error(\"Targeted Site tools are unavailable\");\n return await bridge.invoke(sanitizeOpenGeniSiteToolInvokeRequest(message.payload), { signal });\n }\n if (message.method === \"catalog\") return await bridge.catalog({ signal });\n if (message.method === \"declarations\") {\n if (!bridge.declarations) throw new Error(\"Site tool declarations are unavailable\");\n return await bridge.declarations({ signal });\n }\n return await bridge.call(sanitizeOpenGeniSiteToolCallRequest(message.payload!), { signal });\n}\n\nfunction siteBridgeHostError(code: string, message: string): Error & { code: string } {\n return Object.assign(new Error(message), { code });\n}\n\nexport function siteBridgeError(\n error: unknown,\n legacyCall = false,\n): {\n code: string;\n message: string;\n retryable: boolean;\n outcomeUnknown: boolean;\n} {\n const candidate = error as {\n code?: unknown;\n message?: unknown;\n retryable?: unknown;\n outcomeUnknown?: unknown;\n details?: { code?: unknown };\n };\n const nestedCode = candidate?.details?.code;\n const knownPreexecution = candidate?.retryable === true && candidate?.outcomeUnknown === false;\n const stale =\n knownPreexecution && (nestedCode === \"tool_definition_stale\" || nestedCode === \"catalog_stale\");\n // Historical saved bundles inspect code alone. A stale-named transport error\n // without known pre-execution proof must remain an error, not invite replay.\n const unsafeControl =\n legacyCall &&\n !knownPreexecution &&\n (candidate?.code === \"catalog_stale\" || candidate?.code === \"tool_definition_stale\");\n const message =\n typeof candidate?.message === \"string\" ? candidate.message : \"Site tool request failed\";\n return {\n code: stale\n ? (nestedCode as string)\n : unsafeControl\n ? \"site_tool_call_failed\"\n : typeof candidate?.code === \"string\"\n ? candidate.code\n : \"site_tool_call_failed\",\n message: unsafeControl ? `[${candidate.code}] ${message}` : message,\n retryable: candidate?.retryable === true,\n outcomeUnknown: candidate?.outcomeUnknown === true,\n };\n}\n"],"mappings":"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","names":["controller"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|