@opengeni/sdk 0.57.0 → 1.0.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 +1017 -26
- package/dist/accounts.d.ts +153 -0
- package/dist/accounts.js +307 -0
- package/dist/accounts.js.map +1 -0
- 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/artifact-catalog.d.ts +31 -0
- package/dist/artifact-client.d.ts +23 -11
- package/dist/artifacts.d.ts +1 -1
- package/dist/artifacts.js +7 -5
- package/dist/automations-client.d.ts +17 -0
- package/dist/automations.d.ts +3 -0
- package/dist/automations.js +84 -0
- package/dist/automations.js.map +1 -0
- package/dist/browser.d.ts +11 -0
- package/dist/browser.js +47 -0
- package/dist/browser.js.map +1 -0
- 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 +1694 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat/openai.d.ts +30 -0
- package/dist/chat/opengeni.d.ts +128 -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-JDLDDRNE.js → chunk-2UXZUCEZ.js} +291 -34
- package/dist/chunk-2UXZUCEZ.js.map +1 -0
- package/dist/chunk-4SMEOV3P.js +246 -0
- package/dist/chunk-4SMEOV3P.js.map +1 -0
- package/dist/{chunk-JRPFWI6T.js → chunk-AH5D5Q5V.js} +31 -35
- package/dist/chunk-AH5D5Q5V.js.map +1 -0
- package/dist/chunk-APXVSSSY.js +301 -0
- package/dist/chunk-APXVSSSY.js.map +1 -0
- package/dist/chunk-DUVIYER4.js +639 -0
- package/dist/chunk-DUVIYER4.js.map +1 -0
- package/dist/{chunk-PKQ377ED.js → chunk-FG3OO5LM.js} +2686 -611
- package/dist/chunk-FG3OO5LM.js.map +1 -0
- package/dist/chunk-GZYZT22T.js +260 -0
- package/dist/chunk-GZYZT22T.js.map +1 -0
- package/dist/chunk-HMGADJGZ.js +150 -0
- package/dist/chunk-HMGADJGZ.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-LY2K6ELJ.js +126 -0
- package/dist/chunk-LY2K6ELJ.js.map +1 -0
- package/dist/chunk-MOTJYIYL.js +340 -0
- package/dist/chunk-MOTJYIYL.js.map +1 -0
- package/dist/{chunk-ST5DDKJP.js → chunk-NC57YMUO.js} +121 -3
- package/dist/chunk-NC57YMUO.js.map +1 -0
- package/dist/chunk-RWKB6YZG.js +1270 -0
- package/dist/chunk-RWKB6YZG.js.map +1 -0
- package/dist/chunk-U6CV2SXO.js +195 -0
- package/dist/chunk-U6CV2SXO.js.map +1 -0
- package/dist/chunk-UM4ZXXJR.js +9 -0
- package/dist/chunk-UM4ZXXJR.js.map +1 -0
- package/dist/chunk-V6GIY62B.js +229 -0
- package/dist/chunk-V6GIY62B.js.map +1 -0
- package/dist/chunk-WU6GQG25.js +268 -0
- package/dist/chunk-WU6GQG25.js.map +1 -0
- package/dist/{chunk-VWE2QIVO.js → chunk-XNG7YGR3.js} +23 -6
- package/dist/chunk-XNG7YGR3.js.map +1 -0
- package/dist/{chunk-HJ3HHUT5.js → chunk-YIKA2QT4.js} +33 -2
- package/dist/chunk-YIKA2QT4.js.map +1 -0
- package/dist/chunk-ZKPY6YAJ.js +135 -0
- package/dist/chunk-ZKPY6YAJ.js.map +1 -0
- package/dist/client.d.ts +740 -94
- package/dist/codex-realtime-controller.d.ts +3 -0
- package/dist/codex-realtime-controller.js +2 -2
- package/dist/codex-realtime-v3.d.ts +13 -2
- package/dist/company-brain.d.ts +22 -0
- package/dist/company-profile.d.ts +14 -1
- package/dist/core.d.ts +9 -3
- package/dist/core.js +25 -6
- package/dist/deprecation.d.ts +47 -0
- package/dist/document-authority-client.d.ts +51 -0
- package/dist/document-authority.d.ts +2 -0
- package/dist/document-authority.js +12 -0
- package/dist/document-authority.js.map +1 -0
- package/dist/editable-artifacts/browser-session.d.ts +7 -3
- package/dist/editable-artifacts/controller.d.ts +4 -1
- package/dist/editable-artifacts/errors.d.ts +1 -1
- package/dist/editable-artifacts/http-live-transport.d.ts +6 -2
- package/dist/editable-artifacts/index.d.ts +2 -0
- package/dist/editable-artifacts/open-failure.d.ts +9 -0
- package/dist/editable-artifacts/types.d.ts +6 -3
- package/dist/editable-artifacts/worker/kernel-adapter.d.ts +1 -1
- package/dist/editable-artifacts-worker.js +44 -17
- package/dist/editable-artifacts-worker.js.map +1 -1
- package/dist/editable-artifacts.js +240 -121
- package/dist/editable-artifacts.js.map +1 -1
- package/dist/embedding-client.d.ts +129 -0
- package/dist/errors.d.ts +36 -1
- 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 +56 -11
- package/dist/index.js +242 -125
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +84 -1
- package/dist/interaction.js +6 -1
- package/dist/knowledge.d.ts +7 -0
- package/dist/knowledge.js +20 -0
- package/dist/knowledge.js.map +1 -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 +15 -0
- package/dist/model-display.js.map +1 -0
- package/dist/model-picker-order.d.ts +1 -0
- package/dist/model-picker-order.js +10 -0
- package/dist/model-picker-order.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/organization-private-session-settings.d.ts +6 -0
- package/dist/organization-private-session-settings.js +22 -0
- package/dist/organization-private-session-settings.js.map +1 -0
- package/dist/organization-user-setup.d.ts +8 -0
- package/dist/organization-user-setup.js +16 -0
- package/dist/organization-user-setup.js.map +1 -0
- package/dist/pr-review-client.d.ts +16 -0
- package/dist/pr-review.d.ts +4 -0
- package/dist/pr-review.js +62 -0
- package/dist/pr-review.js.map +1 -0
- package/dist/preference-registry.d.ts +9 -1
- package/dist/proxy.d.ts +7 -5
- package/dist/realtime.d.ts +3 -1
- package/dist/realtime.js +6 -6
- package/dist/realtime.js.map +1 -1
- package/dist/retained-artifacts.d.ts +5 -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 +24 -0
- package/dist/session-proxy.d.ts +245 -0
- package/dist/session-proxy.js +24 -0
- package/dist/session-proxy.js.map +1 -0
- package/dist/session-titles.d.ts +2 -0
- package/dist/site-browser-entry.d.ts +1 -0
- package/dist/site-browser-runtime.gen.d.ts +1 -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 +16 -0
- package/dist/site-tool-bridge.d.ts +44 -0
- package/dist/site.d.ts +101 -0
- package/dist/site.js +49 -0
- package/dist/site.js.map +1 -0
- package/dist/skills.d.ts +75 -0
- 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-FXBLUWAE.js +12 -0
- package/dist/tools-FXBLUWAE.js.map +1 -0
- package/dist/tools.d.ts +61 -0
- package/dist/types.d.ts +2863 -424
- 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/workspace-artifacts.d.ts +33 -5
- package/dist/workspace-instruction-policies.d.ts +24 -2
- package/dist/workspace-integrations.d.ts +74 -0
- package/dist/workspace-integrations.js +65 -0
- package/dist/workspace-integrations.js.map +1 -0
- package/dist/workspace-learning.d.ts +124 -0
- package/dist/workspace-state.d.ts +8 -71
- package/package.json +108 -3
- package/src/accounts.ts +443 -0
- 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/artifact-catalog.ts +41 -0
- package/src/artifact-client.ts +43 -52
- package/src/artifacts.ts +7 -1
- package/src/automations-client.ts +124 -0
- package/src/automations.ts +15 -0
- package/src/browser.ts +54 -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 +87 -0
- package/src/chat/openai.ts +439 -0
- package/src/chat/opengeni.ts +722 -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 +4084 -515
- package/src/codex-realtime-controller.ts +235 -5
- package/src/codex-realtime-v3.ts +162 -31
- package/src/codex-realtime.ts +1 -1
- package/src/company-brain.ts +59 -0
- package/src/company-profile.ts +17 -1
- package/src/core.ts +23 -1
- package/src/deprecation.ts +149 -0
- package/src/document-authority-client.ts +219 -0
- package/src/document-authority.ts +17 -0
- package/src/editable-artifacts/browser-session.ts +36 -22
- package/src/editable-artifacts/controller.ts +102 -47
- package/src/editable-artifacts/errors.ts +2 -0
- package/src/editable-artifacts/http-live-transport.ts +62 -37
- package/src/editable-artifacts/index.ts +6 -0
- package/src/editable-artifacts/open-failure.ts +79 -0
- package/src/editable-artifacts/storage.ts +31 -40
- package/src/editable-artifacts/types.ts +6 -3
- package/src/editable-artifacts/worker/kernel-adapter.ts +23 -7
- package/src/editable-artifacts/worker/runtime.ts +26 -13
- package/src/editable-artifacts/worker/wire-codec.ts +23 -5
- package/src/embedding-client.ts +519 -0
- package/src/errors.ts +169 -2
- 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 +561 -41
- package/src/interaction.ts +276 -4
- package/src/knowledge.ts +72 -0
- package/src/message-links.ts +178 -0
- package/src/model-context.ts +112 -0
- package/src/model-display.ts +10 -0
- package/src/model-picker-order.ts +6 -0
- package/src/organization-integration-policy.ts +54 -0
- package/src/organization-private-session-settings.ts +33 -0
- package/src/organization-user-setup.ts +31 -0
- package/src/pr-review-client.ts +92 -0
- package/src/pr-review.ts +17 -0
- package/src/preference-registry.ts +11 -0
- package/src/proxy.ts +17 -6
- package/src/realtime.ts +1 -0
- package/src/retained-artifacts.ts +101 -0
- 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 +64 -0
- package/src/session-proxy.ts +1473 -0
- package/src/session-titles.ts +10 -0
- package/src/site-browser-entry.ts +6 -0
- package/src/site-browser-runtime.gen.ts +2 -0
- package/src/site-document.test.ts +64 -0
- package/src/site-document.ts +18 -0
- package/src/site-http.ts +162 -0
- package/src/site-tool-bridge.ts +146 -0
- package/src/site.ts +585 -0
- package/src/skills.ts +69 -0
- package/src/sse.ts +8 -2
- package/src/stream.ts +38 -4
- package/src/tenant-workspaces.ts +148 -0
- package/src/tool-auth.ts +301 -0
- package/src/tool-display-metadata.ts +19 -0
- package/src/tools.ts +396 -0
- package/src/types.ts +3346 -501
- package/src/usage-allowances.ts +189 -0
- package/src/workspace-artifacts.ts +40 -6
- package/src/workspace-instruction-policies.ts +26 -1
- package/src/workspace-integrations.ts +402 -0
- package/src/workspace-learning.ts +138 -0
- package/src/workspace-state.ts +8 -82
- package/dist/chunk-GU6JF75T.js +0 -119
- package/dist/chunk-GU6JF75T.js.map +0 -1
- package/dist/chunk-HJ3HHUT5.js.map +0 -1
- package/dist/chunk-JDLDDRNE.js.map +0 -1
- package/dist/chunk-JRPFWI6T.js.map +0 -1
- package/dist/chunk-PKQ377ED.js.map +0 -1
- package/dist/chunk-ST5DDKJP.js.map +0 -1
- package/dist/chunk-VWE2QIVO.js.map +0 -1
package/src/site-http.ts
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/** HTTP transport for the ordinary SDK. One response port per request keeps
|
|
2
|
+
* event streams incremental and cancellation independent of other requests. */
|
|
3
|
+
export const SITE_HTTP = "opengeni.site.http";
|
|
4
|
+
export const SITE_WORKSPACE = "site-host";
|
|
5
|
+
export type SiteHttpRequest = {
|
|
6
|
+
type: typeof SITE_HTTP;
|
|
7
|
+
requestId: string;
|
|
8
|
+
path: string;
|
|
9
|
+
method: string;
|
|
10
|
+
headers: [string, string][];
|
|
11
|
+
body?: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
import { siteSessionPath } from "@opengeni/contracts/site-session-http";
|
|
15
|
+
export { siteSessionPath } from "@opengeni/contracts/site-session-http";
|
|
16
|
+
|
|
17
|
+
export function isSiteHttpRequest(value: unknown): value is SiteHttpRequest {
|
|
18
|
+
if (!value || typeof value !== "object") return false;
|
|
19
|
+
const v = value as SiteHttpRequest;
|
|
20
|
+
return (
|
|
21
|
+
v.type === SITE_HTTP &&
|
|
22
|
+
typeof v.requestId === "string" &&
|
|
23
|
+
typeof v.path === "string" &&
|
|
24
|
+
typeof v.method === "string" &&
|
|
25
|
+
/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/u.test(v.method) &&
|
|
26
|
+
(v.body === undefined || typeof v.body === "string") &&
|
|
27
|
+
Array.isArray(v.headers) &&
|
|
28
|
+
v.headers.every(
|
|
29
|
+
(h) => Array.isArray(h) && h.length === 2 && h.every((x) => typeof x === "string"),
|
|
30
|
+
)
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export async function serveSiteHttp(
|
|
35
|
+
message: SiteHttpRequest,
|
|
36
|
+
port: MessagePort,
|
|
37
|
+
fetchResponse: (request: SiteHttpRequest, signal: AbortSignal) => Promise<Response>,
|
|
38
|
+
signal: AbortSignal,
|
|
39
|
+
): Promise<void> {
|
|
40
|
+
let reader: ReadableStreamDefaultReader<Uint8Array> | undefined;
|
|
41
|
+
let wake: (() => void) | undefined;
|
|
42
|
+
let pulling = false;
|
|
43
|
+
const onMessage = (event: MessageEvent) => {
|
|
44
|
+
if (event.data === "pull") {
|
|
45
|
+
pulling = true;
|
|
46
|
+
wake?.();
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const abort = () => {
|
|
50
|
+
void reader?.cancel(signal.reason).catch(() => {});
|
|
51
|
+
wake?.();
|
|
52
|
+
};
|
|
53
|
+
port.addEventListener("message", onMessage);
|
|
54
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
55
|
+
port.start();
|
|
56
|
+
try {
|
|
57
|
+
if (signal.aborted) throw signal.reason;
|
|
58
|
+
const response = await fetchResponse(message, signal);
|
|
59
|
+
reader = response.body?.getReader();
|
|
60
|
+
port.postMessage({ status: response.status, headers: [...response.headers], body: !!reader });
|
|
61
|
+
if (reader)
|
|
62
|
+
while (!signal.aborted) {
|
|
63
|
+
if (!pulling)
|
|
64
|
+
await new Promise<void>((resolve) => {
|
|
65
|
+
wake = resolve;
|
|
66
|
+
});
|
|
67
|
+
wake = undefined;
|
|
68
|
+
if (signal.aborted) break;
|
|
69
|
+
pulling = false;
|
|
70
|
+
const part = await reader.read();
|
|
71
|
+
if (part.done) {
|
|
72
|
+
port.postMessage({ done: true });
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
port.postMessage({ chunk: part.value });
|
|
76
|
+
}
|
|
77
|
+
if (signal.aborted) throw signal.reason;
|
|
78
|
+
} catch (error) {
|
|
79
|
+
port.postMessage({ error: error instanceof Error ? error.message : "Site request failed" });
|
|
80
|
+
} finally {
|
|
81
|
+
signal.removeEventListener("abort", abort);
|
|
82
|
+
port.removeEventListener("message", onMessage);
|
|
83
|
+
await reader?.cancel().catch(() => {});
|
|
84
|
+
port.close();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export async function sitePortFetch(
|
|
89
|
+
port: MessagePort,
|
|
90
|
+
input: RequestInfo | URL,
|
|
91
|
+
init?: RequestInit,
|
|
92
|
+
): Promise<Response> {
|
|
93
|
+
const request = new Request(input, init);
|
|
94
|
+
const url = new URL(request.url);
|
|
95
|
+
const path = `${url.pathname}${url.search}`;
|
|
96
|
+
siteSessionPath(path, SITE_WORKSPACE, request.method);
|
|
97
|
+
const channel = new MessageChannel();
|
|
98
|
+
const requestId = crypto.randomUUID();
|
|
99
|
+
const body = request.body ? await request.text() : undefined;
|
|
100
|
+
return await new Promise<Response>((resolve, reject) => {
|
|
101
|
+
let controller: ReadableStreamDefaultController<Uint8Array> | undefined;
|
|
102
|
+
let finished = false;
|
|
103
|
+
const cleanup = () => {
|
|
104
|
+
finished = true;
|
|
105
|
+
request.signal.removeEventListener("abort", abort);
|
|
106
|
+
channel.port1.close();
|
|
107
|
+
};
|
|
108
|
+
const abort = () => {
|
|
109
|
+
if (finished) return;
|
|
110
|
+
port.postMessage({ type: "opengeni.site.cancel", version: 2, requestId });
|
|
111
|
+
const error = request.signal.reason ?? new DOMException("Cancelled", "AbortError");
|
|
112
|
+
controller?.error(error);
|
|
113
|
+
reject(error);
|
|
114
|
+
cleanup();
|
|
115
|
+
};
|
|
116
|
+
channel.port1.onmessage = (event) => {
|
|
117
|
+
const data = event.data;
|
|
118
|
+
if (data.error) {
|
|
119
|
+
const error = new Error(data.error);
|
|
120
|
+
controller?.error(error);
|
|
121
|
+
reject(error);
|
|
122
|
+
cleanup();
|
|
123
|
+
} else if (data.status) {
|
|
124
|
+
const stream = data.body
|
|
125
|
+
? new ReadableStream<Uint8Array>({
|
|
126
|
+
start(c) {
|
|
127
|
+
controller = c;
|
|
128
|
+
},
|
|
129
|
+
pull() {
|
|
130
|
+
channel.port1.postMessage("pull");
|
|
131
|
+
},
|
|
132
|
+
cancel() {
|
|
133
|
+
controller = undefined;
|
|
134
|
+
abort();
|
|
135
|
+
},
|
|
136
|
+
})
|
|
137
|
+
: null;
|
|
138
|
+
resolve(new Response(stream, { status: data.status, headers: data.headers }));
|
|
139
|
+
if (!data.body) cleanup();
|
|
140
|
+
} else if (data.done) {
|
|
141
|
+
controller?.close();
|
|
142
|
+
cleanup();
|
|
143
|
+
} else if (data.chunk) controller?.enqueue(data.chunk);
|
|
144
|
+
};
|
|
145
|
+
if (request.signal.aborted) {
|
|
146
|
+
abort();
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
request.signal.addEventListener("abort", abort, { once: true });
|
|
150
|
+
port.postMessage(
|
|
151
|
+
{
|
|
152
|
+
type: SITE_HTTP,
|
|
153
|
+
requestId,
|
|
154
|
+
path,
|
|
155
|
+
method: request.method,
|
|
156
|
+
headers: [...request.headers],
|
|
157
|
+
...(body === undefined ? {} : { body }),
|
|
158
|
+
} satisfies SiteHttpRequest,
|
|
159
|
+
[channel.port2],
|
|
160
|
+
);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { siteRequestHeaders } from "@opengeni/contracts/site-session-http";
|
|
2
|
+
import { OpenGeniApiError } from "./errors";
|
|
3
|
+
import { siteSessionPath, type SiteHttpRequest } from "./site-http";
|
|
4
|
+
import type { OpenGeniSiteToolCatalog } from "./site";
|
|
5
|
+
import type { OpenGeniWorkspaceTools } from "./tools";
|
|
6
|
+
import type { ToolGatewayCallRequest, ToolGatewayCallResponse, ToolGatewayIdentity } from "./types";
|
|
7
|
+
|
|
8
|
+
export type SiteToolCallRequest = ToolGatewayCallRequest & {
|
|
9
|
+
siteArtifactId: string;
|
|
10
|
+
siteVersionId: string;
|
|
11
|
+
};
|
|
12
|
+
export type SiteToolCaller = (input: {
|
|
13
|
+
workspaceId: string;
|
|
14
|
+
request: ToolGatewayCallRequest &
|
|
15
|
+
Partial<Pick<SiteToolCallRequest, "siteArtifactId" | "siteVersionId">>;
|
|
16
|
+
signal: AbortSignal;
|
|
17
|
+
}) => Promise<ToolGatewayCallResponse>;
|
|
18
|
+
export type SiteToolBridge = {
|
|
19
|
+
fetch?: (request: SiteHttpRequest, signal: AbortSignal) => Promise<Response>;
|
|
20
|
+
catalog: (options: { signal: AbortSignal }) => Promise<OpenGeniSiteToolCatalog>;
|
|
21
|
+
call: (
|
|
22
|
+
request: ToolGatewayCallRequest,
|
|
23
|
+
options: { signal: AbortSignal },
|
|
24
|
+
) => Promise<ToolGatewayCallResponse>;
|
|
25
|
+
};
|
|
26
|
+
export type CreateSiteToolBridgeOptions = {
|
|
27
|
+
workspaceTools: Pick<OpenGeniWorkspaceTools, "$catalog">;
|
|
28
|
+
workspaceId: string;
|
|
29
|
+
|
|
30
|
+
callTool: SiteToolCaller;
|
|
31
|
+
isCatalogStale?: (error: unknown) => boolean;
|
|
32
|
+
/** Optional authenticated host transport for the host-bound workspace API.
|
|
33
|
+
* Omit to expose tools only. Site-provided authorization headers are never forwarded. */
|
|
34
|
+
fetchResponse?: (path: string, init: RequestInit) => Promise<Response>;
|
|
35
|
+
} & (
|
|
36
|
+
| { artifactId: string; siteVersionId: string; requestedTools: readonly ToolGatewayIdentity[] }
|
|
37
|
+
| { artifactId?: never; siteVersionId?: never; requestedTools?: never }
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
/** Host-side bridge for the opaque Site frame. Supply an authenticated transport;
|
|
41
|
+
* the server independently checks live viewer access and the exact Site version.
|
|
42
|
+
* Recreate on actor/version change. Never take these pinned fields from HTML. */
|
|
43
|
+
export function createSiteToolBridge(input: CreateSiteToolBridgeOptions): SiteToolBridge {
|
|
44
|
+
const allowed = input.requestedTools ? new Set(input.requestedTools.map(identityKey)) : null;
|
|
45
|
+
let projectedCatalog: OpenGeniSiteToolCatalog | null = null;
|
|
46
|
+
const loadCatalog = async ({
|
|
47
|
+
signal,
|
|
48
|
+
refresh = false,
|
|
49
|
+
}: {
|
|
50
|
+
signal: AbortSignal;
|
|
51
|
+
refresh?: boolean;
|
|
52
|
+
}): Promise<OpenGeniSiteToolCatalog> => {
|
|
53
|
+
signal.throwIfAborted();
|
|
54
|
+
if (projectedCatalog && !refresh) return projectedCatalog;
|
|
55
|
+
const current = await input.workspaceTools.$catalog({
|
|
56
|
+
signal,
|
|
57
|
+
...(refresh ? { refresh } : {}),
|
|
58
|
+
});
|
|
59
|
+
signal.throwIfAborted();
|
|
60
|
+
if (current.workspaceId !== input.workspaceId)
|
|
61
|
+
throw new Error("Site catalog workspace mismatch");
|
|
62
|
+
projectedCatalog = {
|
|
63
|
+
version: current.version,
|
|
64
|
+
generation: current.generation,
|
|
65
|
+
digest: current.digest,
|
|
66
|
+
createdAt: current.createdAt,
|
|
67
|
+
entries: current.entries.filter(
|
|
68
|
+
(entry) => !allowed || allowed.has(identityKey(entry.identity)),
|
|
69
|
+
),
|
|
70
|
+
};
|
|
71
|
+
return projectedCatalog;
|
|
72
|
+
};
|
|
73
|
+
return {
|
|
74
|
+
...(input.fetchResponse
|
|
75
|
+
? {
|
|
76
|
+
fetch: async (message: SiteHttpRequest, signal: AbortSignal) => {
|
|
77
|
+
const path = siteSessionPath(
|
|
78
|
+
message.path,
|
|
79
|
+
input.workspaceId,
|
|
80
|
+
message.method,
|
|
81
|
+
input.artifactId,
|
|
82
|
+
);
|
|
83
|
+
const headers = siteRequestHeaders(message.headers);
|
|
84
|
+
if (input.artifactId) {
|
|
85
|
+
headers.set("x-opengeni-site-id", input.artifactId);
|
|
86
|
+
headers.set("x-opengeni-site-version", input.siteVersionId);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return input.fetchResponse!(path, {
|
|
90
|
+
method: message.method,
|
|
91
|
+
signal,
|
|
92
|
+
headers: Object.fromEntries(headers),
|
|
93
|
+
...(message.body === undefined ? {} : { body: message.body }),
|
|
94
|
+
});
|
|
95
|
+
},
|
|
96
|
+
}
|
|
97
|
+
: {}),
|
|
98
|
+
catalog: loadCatalog,
|
|
99
|
+
call: async (request, { signal }) => {
|
|
100
|
+
if (allowed && !allowed.has(identityKey(request.identity)))
|
|
101
|
+
throw new Error("This tool is not available to the Site");
|
|
102
|
+
const call = async (refresh = false) => {
|
|
103
|
+
const catalog = await loadCatalog({ signal, refresh });
|
|
104
|
+
if (
|
|
105
|
+
!catalog.entries.some(
|
|
106
|
+
(entry) => identityKey(entry.identity) === identityKey(request.identity),
|
|
107
|
+
)
|
|
108
|
+
)
|
|
109
|
+
throw new Error("This requested tool is not enabled in the workspace");
|
|
110
|
+
return input.callTool({
|
|
111
|
+
workspaceId: input.workspaceId,
|
|
112
|
+
signal,
|
|
113
|
+
request: {
|
|
114
|
+
...(request.operationId ? { operationId: request.operationId } : {}),
|
|
115
|
+
catalogDigest: catalog.digest,
|
|
116
|
+
identity: request.identity,
|
|
117
|
+
arguments: request.arguments,
|
|
118
|
+
...(input.artifactId
|
|
119
|
+
? { siteArtifactId: input.artifactId, siteVersionId: input.siteVersionId }
|
|
120
|
+
: {}),
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
try {
|
|
125
|
+
return await call();
|
|
126
|
+
} catch (error) {
|
|
127
|
+
// Only pre-execution catalog rejection permits one retry. Never retry
|
|
128
|
+
// transport failures, expired credentials or uncertain tool effects.
|
|
129
|
+
if (!(input.isCatalogStale ?? isSiteCatalogStaleError)(error)) throw error;
|
|
130
|
+
projectedCatalog = null;
|
|
131
|
+
return await call(true);
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function isSiteCatalogStaleError(error: unknown): boolean {
|
|
138
|
+
return (
|
|
139
|
+
error instanceof OpenGeniApiError &&
|
|
140
|
+
error.status === 409 &&
|
|
141
|
+
error.details?.code === "catalog_stale"
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
function identityKey(identity: ToolGatewayIdentity): string {
|
|
145
|
+
return `${identity.serverId}\u0000${identity.toolName}`;
|
|
146
|
+
}
|