@opengeni/sdk 3.3.2 → 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 +7 -2
- package/dist/browser.js +27 -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-JUS2UYRP.js → chunk-NCU5OAN7.js} +27 -2
- package/dist/chunk-NCU5OAN7.js.map +1 -0
- package/dist/{chunk-YXQX7RQT.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-TRNI7KEO.js → chunk-S2NLS3ES.js} +3669 -1281
- 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-QT3KFVDP.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-C2H7HBNP.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-KKRO2VCP.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 +1068 -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 +7 -2
- package/dist/core.js +25 -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 +76 -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 +62 -11
- package/dist/index.js +557 -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/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/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 +2807 -583
- 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 +103 -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 +37 -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 +5697 -1833
- 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 +20 -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 +303 -4
- 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 +603 -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/model-picker-order.ts +6 -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 +3170 -582
- 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-C2H7HBNP.js.map +0 -1
- package/dist/chunk-C4DJPZRU.js +0 -119
- package/dist/chunk-C4DJPZRU.js.map +0 -1
- package/dist/chunk-JUS2UYRP.js.map +0 -1
- package/dist/chunk-KKRO2VCP.js.map +0 -1
- package/dist/chunk-QT3KFVDP.js.map +0 -1
- package/dist/chunk-TRNI7KEO.js.map +0 -1
- package/dist/chunk-VYCTL62C.js.map +0 -1
- package/dist/chunk-YXQX7RQT.js.map +0 -1
package/src/app-links.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// Opengeni web links that a native app (phone or desktop) can show itself, and
|
|
2
|
+
// the account each belongs to. Pure: no platform modules, so every app shares it.
|
|
3
|
+
|
|
4
|
+
/** A deployment address as typed: trimmed, https by default, no trailing slash. */
|
|
5
|
+
export function normalizeServerUrl(input: string): string | null {
|
|
6
|
+
const raw = input.trim();
|
|
7
|
+
if (!raw) return null;
|
|
8
|
+
const withScheme = /^[a-z][a-z0-9+.-]*:\/\//iu.test(raw) ? raw : `https://${raw}`;
|
|
9
|
+
const match = /^(https?):\/\/([a-z0-9.-]+(?::\d{1,5})?)(?:[/?#].*)?$/iu.exec(withScheme);
|
|
10
|
+
return match ? `${match[1]!.toLowerCase()}://${match[2]!.toLowerCase()}` : null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** The host a person recognizes, e.g. app.opengeni.ai. */
|
|
14
|
+
export function serverLabel(baseUrl: string): string {
|
|
15
|
+
return baseUrl.replace(/^https?:\/\//iu, "");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** The part of a signed-in app account that link routing reads. */
|
|
19
|
+
export interface AppLinkAccount {
|
|
20
|
+
id: string;
|
|
21
|
+
/** The deployment's web origin, e.g. https://app.opengeni.ai. */
|
|
22
|
+
baseUrl: string;
|
|
23
|
+
/** The workspace last used with this account. */
|
|
24
|
+
workspaceId: string | null;
|
|
25
|
+
/** Set when the deployment rejected the credential. */
|
|
26
|
+
signedOut?: boolean;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* A web link the app can show itself: a conversation or a workspace on some
|
|
31
|
+
* deployment. Everything else on the web (settings, organization, artifacts)
|
|
32
|
+
* stays in the browser.
|
|
33
|
+
*/
|
|
34
|
+
export interface AppLink {
|
|
35
|
+
/** The deployment's origin, normalized like a stored account's baseUrl. */
|
|
36
|
+
origin: string;
|
|
37
|
+
/** Absent for the web's workspace-less `/sessions/:id` links. */
|
|
38
|
+
workspaceId: string | null;
|
|
39
|
+
/** Absent for a link to the workspace itself. */
|
|
40
|
+
sessionId: string | null;
|
|
41
|
+
/** The session moment the link points at (`?at=`). */
|
|
42
|
+
at: number | null;
|
|
43
|
+
/** The web address the link came from, for the browser fallback. */
|
|
44
|
+
webUrl: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** The app's own scheme for links handed over from the web: opengeni://open?url=… */
|
|
48
|
+
const HANDOFF = /^opengeni:\/\/open\/?\?(.*)$/iu;
|
|
49
|
+
const WEB_URL = /^(https?:\/\/[^/?#]+)(\/[^?#]*)?(\?[^#]*)?(#.*)?$/iu;
|
|
50
|
+
const ID = "([A-Za-z0-9][A-Za-z0-9_-]{0,127})";
|
|
51
|
+
const SESSION_PATH = new RegExp(`^/workspaces/${ID}/sessions/${ID}/?$`, "u");
|
|
52
|
+
const WORKSPACE_PATH = new RegExp(`^/workspaces/${ID}(?:/sessions)?/?$`, "u");
|
|
53
|
+
const BARE_SESSION_PATH = new RegExp(`^/sessions/${ID}/?$`, "u");
|
|
54
|
+
|
|
55
|
+
function queryParam(query: string | undefined, name: string): string | null {
|
|
56
|
+
for (const part of (query ?? "").replace(/^\?/u, "").split("&")) {
|
|
57
|
+
const [key, value = ""] = part.split("=");
|
|
58
|
+
if (key !== name) continue;
|
|
59
|
+
try {
|
|
60
|
+
return decodeURIComponent(value.replace(/\+/gu, " "));
|
|
61
|
+
} catch {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** The web link a raw URL points at, unwrapping the web's "Open in app" handoff. */
|
|
69
|
+
export function parseAppLink(raw: string): AppLink | null {
|
|
70
|
+
const trimmed = raw.trim();
|
|
71
|
+
const handoff = HANDOFF.exec(trimmed);
|
|
72
|
+
const webUrl = handoff ? queryParam(handoff[1], "url") : trimmed;
|
|
73
|
+
if (!webUrl) return null;
|
|
74
|
+
const match = WEB_URL.exec(webUrl);
|
|
75
|
+
if (!match) return null;
|
|
76
|
+
const origin = normalizeServerUrl(match[1]!);
|
|
77
|
+
if (!origin) return null;
|
|
78
|
+
const path = match[2] ?? "/";
|
|
79
|
+
const atRaw = queryParam(match[3], "at");
|
|
80
|
+
const at = atRaw && /^[1-9][0-9]{0,15}$/u.test(atRaw) ? Number(atRaw) : null;
|
|
81
|
+
const session = SESSION_PATH.exec(path);
|
|
82
|
+
if (session) return { origin, workspaceId: session[1]!, sessionId: session[2]!, at, webUrl };
|
|
83
|
+
const bare = BARE_SESSION_PATH.exec(path);
|
|
84
|
+
if (bare) return { origin, workspaceId: null, sessionId: bare[1]!, at, webUrl };
|
|
85
|
+
const workspace = WORKSPACE_PATH.exec(path);
|
|
86
|
+
if (workspace) return { origin, workspaceId: workspace[1]!, sessionId: null, at: null, webUrl };
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The signed-in account a link belongs to, or null when the app has none on
|
|
92
|
+
* that deployment (the browser opens it instead). With several accounts on the
|
|
93
|
+
* same deployment: the one last used in the link's workspace, else the active
|
|
94
|
+
* one, else the first.
|
|
95
|
+
*/
|
|
96
|
+
export function accountForAppLink<Account extends AppLinkAccount>(
|
|
97
|
+
link: AppLink,
|
|
98
|
+
accounts: readonly Account[],
|
|
99
|
+
activeId: string | null,
|
|
100
|
+
): Account | null {
|
|
101
|
+
const candidates = accounts.filter(
|
|
102
|
+
(account) => !account.signedOut && normalizeServerUrl(account.baseUrl) === link.origin,
|
|
103
|
+
);
|
|
104
|
+
return (
|
|
105
|
+
(link.workspaceId
|
|
106
|
+
? candidates.find((account) => account.workspaceId === link.workspaceId)
|
|
107
|
+
: undefined) ??
|
|
108
|
+
candidates.find((account) => account.id === activeId) ??
|
|
109
|
+
candidates[0] ??
|
|
110
|
+
null
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** The web's handoff link that opens a web page in the app. */
|
|
115
|
+
export function appHandoffUrl(webUrl: string): string {
|
|
116
|
+
return `opengeni://open?url=${encodeURIComponent(webUrl)}`;
|
|
117
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { RetainedArtifactReference } from "./types";
|
|
2
|
+
|
|
3
|
+
export type ArtifactCatalogKind =
|
|
4
|
+
| "site"
|
|
5
|
+
| "document"
|
|
6
|
+
| "spreadsheet"
|
|
7
|
+
| "presentation"
|
|
8
|
+
| "image"
|
|
9
|
+
| "file";
|
|
10
|
+
|
|
11
|
+
/** Native IDs are unique within a kind; use `${kind}:${id}` as a UI key. */
|
|
12
|
+
export type ArtifactCatalogItem = {
|
|
13
|
+
id: string;
|
|
14
|
+
kind: ArtifactCatalogKind;
|
|
15
|
+
title: string;
|
|
16
|
+
createdAt: string;
|
|
17
|
+
updatedAt: string;
|
|
18
|
+
status: "active" | "archived";
|
|
19
|
+
/** Shared workspace pin; absent on older servers. Never grants content access. */
|
|
20
|
+
pinned?: boolean;
|
|
21
|
+
/** Sites only: "private" when only its owner (the viewer) can see it. */
|
|
22
|
+
visibility?: "private" | "workspace";
|
|
23
|
+
/** Present only when the viewer can read this session. */
|
|
24
|
+
sourceSessionId?: string;
|
|
25
|
+
versionId?: string;
|
|
26
|
+
file?: RetainedArtifactReference;
|
|
27
|
+
filename?: string;
|
|
28
|
+
contentType?: string;
|
|
29
|
+
sizeBytes?: number;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export type ArtifactCatalogListOptions = {
|
|
33
|
+
sourceSessionId?: string;
|
|
34
|
+
q?: string;
|
|
35
|
+
kind?: ArtifactCatalogKind;
|
|
36
|
+
sort?: "updated" | "newest" | "title";
|
|
37
|
+
status?: "active" | "archived";
|
|
38
|
+
limit?: number;
|
|
39
|
+
cursor?: string;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export type ArtifactCatalogListResponse = {
|
|
43
|
+
items: ArtifactCatalogItem[];
|
|
44
|
+
nextCursor: string | null;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export type ArtifactPinResponse = {
|
|
48
|
+
kind: ArtifactCatalogKind;
|
|
49
|
+
artifactId: string;
|
|
50
|
+
pinned: boolean;
|
|
51
|
+
};
|
package/src/artifact-client.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import { OpenGeniDocumentAuthorityClient } from "./document-authority-client";
|
|
2
|
+
import type { FetchResponse } from "./client";
|
|
3
|
+
import type { SiteToolCallRequest } from "./site-tool-bridge";
|
|
4
|
+
import type { ToolGatewayCallResponse } from "./types";
|
|
5
|
+
import type {
|
|
6
|
+
CreateWorkspaceArtifactRequest,
|
|
7
|
+
PublishWorkspaceArtifactVersionRequest,
|
|
8
|
+
WorkspaceArtifactContentResponse,
|
|
9
|
+
WorkspaceArtifactMutationResponse,
|
|
10
|
+
} from "./workspace-artifacts";
|
|
2
11
|
import type {
|
|
3
12
|
CreateEditableArtifactMaterializationRequest,
|
|
4
13
|
CreateEditableArtifactResourceRequest,
|
|
@@ -12,16 +21,6 @@ import type {
|
|
|
12
21
|
ReadEditableArtifactMaterializationOptions,
|
|
13
22
|
ReadEditableArtifactResourceOptions,
|
|
14
23
|
} from "./editable-artifact-resources";
|
|
15
|
-
import type {
|
|
16
|
-
CreateWorkspaceArtifactRequest,
|
|
17
|
-
PublishWorkspaceArtifactVersionRequest,
|
|
18
|
-
RollbackWorkspaceArtifactRequest,
|
|
19
|
-
WorkspaceArtifactContentResponse,
|
|
20
|
-
WorkspaceArtifactDetailResponse,
|
|
21
|
-
WorkspaceArtifactListOptions,
|
|
22
|
-
WorkspaceArtifactListResponse,
|
|
23
|
-
WorkspaceArtifactMutationResponse,
|
|
24
|
-
} from "./workspace-artifacts";
|
|
25
24
|
|
|
26
25
|
/** Public SDK client. Optional operator and artifact operations stay out of the console core. */
|
|
27
26
|
export class OpenGeniClient extends OpenGeniDocumentAuthorityClient {
|
|
@@ -132,7 +131,7 @@ export class OpenGeniClient extends OpenGeniDocumentAuthorityClient {
|
|
|
132
131
|
artifactId: string,
|
|
133
132
|
jobId: string,
|
|
134
133
|
options: ReadEditableArtifactMaterializationOptions,
|
|
135
|
-
): Promise<
|
|
134
|
+
): Promise<FetchResponse> {
|
|
136
135
|
return await this.requestResponse(
|
|
137
136
|
"GET",
|
|
138
137
|
`/v1/workspaces/${encodeURIComponent(workspaceId)}/editable-artifacts/${encodeURIComponent(artifactId)}/materializations/${encodeURIComponent(jobId)}/download`,
|
|
@@ -140,51 +139,52 @@ export class OpenGeniClient extends OpenGeniDocumentAuthorityClient {
|
|
|
140
139
|
options,
|
|
141
140
|
);
|
|
142
141
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
options: WorkspaceArtifactListOptions = {},
|
|
147
|
-
): Promise<WorkspaceArtifactListResponse> {
|
|
148
|
-
const query = new URLSearchParams();
|
|
149
|
-
if (options.limit !== undefined) query.set("limit", String(options.limit));
|
|
150
|
-
if (options.cursor) query.set("cursor", options.cursor);
|
|
151
|
-
const suffix = query.size > 0 ? `?${query.toString()}` : "";
|
|
152
|
-
return await this.requestJson<WorkspaceArtifactListResponse>(
|
|
153
|
-
"GET",
|
|
154
|
-
`/v1/workspaces/${workspaceId}/published-artifacts${suffix}`,
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
async getWorkspaceArtifact(
|
|
142
|
+
/** Exact Site-version gateway call. Keep this client on the authenticated host;
|
|
143
|
+
* the API enforces live viewer access and the version's declared tool allowlist. */
|
|
144
|
+
async callWorkspaceSiteTool(
|
|
159
145
|
workspaceId: string,
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
146
|
+
request: SiteToolCallRequest,
|
|
147
|
+
options: { signal?: AbortSignal } = {},
|
|
148
|
+
): Promise<ToolGatewayCallResponse> {
|
|
149
|
+
return this.requestJson<ToolGatewayCallResponse>(
|
|
150
|
+
"POST",
|
|
151
|
+
`/v1/workspaces/${encodeURIComponent(workspaceId)}/tools/calls`,
|
|
152
|
+
request,
|
|
153
|
+
undefined,
|
|
154
|
+
options,
|
|
165
155
|
);
|
|
166
156
|
}
|
|
167
157
|
|
|
168
158
|
async getWorkspaceArtifactContent(
|
|
169
159
|
workspaceId: string,
|
|
170
160
|
artifactId: string,
|
|
171
|
-
versionId?: string,
|
|
161
|
+
versionOrOptions?: string | { versionId?: string; signal?: AbortSignal },
|
|
172
162
|
): Promise<WorkspaceArtifactContentResponse> {
|
|
173
|
-
const
|
|
163
|
+
const options =
|
|
164
|
+
typeof versionOrOptions === "string"
|
|
165
|
+
? { versionId: versionOrOptions }
|
|
166
|
+
: (versionOrOptions ?? {});
|
|
167
|
+
const query = options.versionId ? `?versionId=${encodeURIComponent(options.versionId)}` : "";
|
|
174
168
|
return await this.requestJson<WorkspaceArtifactContentResponse>(
|
|
175
169
|
"GET",
|
|
176
|
-
`/v1/workspaces/${workspaceId}/published-artifacts/${encodeURIComponent(artifactId)}/content${query}`,
|
|
170
|
+
`/v1/workspaces/${encodeURIComponent(workspaceId)}/published-artifacts/${encodeURIComponent(artifactId)}/content${query}`,
|
|
171
|
+
undefined,
|
|
172
|
+
undefined,
|
|
173
|
+
options,
|
|
177
174
|
);
|
|
178
175
|
}
|
|
179
176
|
|
|
180
177
|
async createWorkspaceArtifact(
|
|
181
178
|
workspaceId: string,
|
|
182
179
|
request: CreateWorkspaceArtifactRequest,
|
|
180
|
+
options: { signal?: AbortSignal } = {},
|
|
183
181
|
): Promise<WorkspaceArtifactMutationResponse> {
|
|
184
182
|
return await this.requestJson<WorkspaceArtifactMutationResponse>(
|
|
185
183
|
"POST",
|
|
186
|
-
`/v1/workspaces/${workspaceId}/published-artifacts`,
|
|
184
|
+
`/v1/workspaces/${encodeURIComponent(workspaceId)}/published-artifacts`,
|
|
187
185
|
request,
|
|
186
|
+
undefined,
|
|
187
|
+
options,
|
|
188
188
|
);
|
|
189
189
|
}
|
|
190
190
|
|
|
@@ -192,23 +192,14 @@ export class OpenGeniClient extends OpenGeniDocumentAuthorityClient {
|
|
|
192
192
|
workspaceId: string,
|
|
193
193
|
artifactId: string,
|
|
194
194
|
request: PublishWorkspaceArtifactVersionRequest,
|
|
195
|
+
options: { signal?: AbortSignal } = {},
|
|
195
196
|
): Promise<WorkspaceArtifactMutationResponse> {
|
|
196
197
|
return await this.requestJson<WorkspaceArtifactMutationResponse>(
|
|
197
198
|
"POST",
|
|
198
|
-
`/v1/workspaces/${workspaceId}/published-artifacts/${encodeURIComponent(artifactId)}/versions`,
|
|
199
|
-
request,
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
async rollbackWorkspaceArtifact(
|
|
204
|
-
workspaceId: string,
|
|
205
|
-
artifactId: string,
|
|
206
|
-
request: RollbackWorkspaceArtifactRequest,
|
|
207
|
-
): Promise<WorkspaceArtifactMutationResponse> {
|
|
208
|
-
return await this.requestJson<WorkspaceArtifactMutationResponse>(
|
|
209
|
-
"POST",
|
|
210
|
-
`/v1/workspaces/${workspaceId}/published-artifacts/${encodeURIComponent(artifactId)}/rollback`,
|
|
199
|
+
`/v1/workspaces/${encodeURIComponent(workspaceId)}/published-artifacts/${encodeURIComponent(artifactId)}/versions`,
|
|
211
200
|
request,
|
|
201
|
+
undefined,
|
|
202
|
+
options,
|
|
212
203
|
);
|
|
213
204
|
}
|
|
214
205
|
}
|
package/src/artifacts.ts
CHANGED
|
@@ -48,9 +48,12 @@ export class OpenGeniAutomationsClient {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
async disableSource(workspaceId: string, sourceId: string): Promise<void> {
|
|
51
|
-
await this.client.requestJson(
|
|
51
|
+
await this.client.requestJson<void>(
|
|
52
52
|
"DELETE",
|
|
53
53
|
`/v1/workspaces/${encodeURIComponent(workspaceId)}/automations/sources/${encodeURIComponent(sourceId)}`,
|
|
54
|
+
undefined,
|
|
55
|
+
{},
|
|
56
|
+
{ responseType: "void" },
|
|
54
57
|
);
|
|
55
58
|
}
|
|
56
59
|
|
|
@@ -90,9 +93,12 @@ export class OpenGeniAutomationsClient {
|
|
|
90
93
|
triggerId: string,
|
|
91
94
|
expectedRevision: number,
|
|
92
95
|
): Promise<void> {
|
|
93
|
-
await this.client.requestJson(
|
|
96
|
+
await this.client.requestJson<void>(
|
|
94
97
|
"DELETE",
|
|
95
98
|
`/v1/workspaces/${encodeURIComponent(workspaceId)}/automations/triggers/${encodeURIComponent(triggerId)}?expectedRevision=${expectedRevision}`,
|
|
99
|
+
undefined,
|
|
100
|
+
{},
|
|
101
|
+
{ responseType: "void" },
|
|
96
102
|
);
|
|
97
103
|
}
|
|
98
104
|
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import { startCodexRealtimeWebrtc, type StartCodexRealtimeWebrtcOptions } from "./codex-realtime";
|
|
2
|
+
import type { RealtimeControllerTransportStarter } from "./codex-realtime-controller";
|
|
3
|
+
|
|
4
|
+
type Envelope = Record<string, unknown>;
|
|
5
|
+
const MAX_FRAGMENT_BYTES = 64_000;
|
|
6
|
+
|
|
7
|
+
/** The most recent speech wins when the user talks for a long time between delegations. */
|
|
8
|
+
function takeUtf8Tail(text: string, maxBytes = MAX_FRAGMENT_BYTES): string {
|
|
9
|
+
const encoder = new TextEncoder();
|
|
10
|
+
if (encoder.encode(text).byteLength <= maxBytes) return text;
|
|
11
|
+
let tail = text.slice(-maxBytes);
|
|
12
|
+
while (encoder.encode(tail).byteLength > maxBytes) tail = tail.slice(1);
|
|
13
|
+
return tail;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Azure Live has timed transcript fragments, not provider-finalized turns. */
|
|
17
|
+
export class AzureLiveDataChannel extends EventTarget {
|
|
18
|
+
private pending: {
|
|
19
|
+
role: "user" | "assistant";
|
|
20
|
+
text: string;
|
|
21
|
+
startMs: number;
|
|
22
|
+
endMs: number;
|
|
23
|
+
} | null = null;
|
|
24
|
+
private timer: ReturnType<typeof setTimeout> | null = null;
|
|
25
|
+
private ordinal = 0;
|
|
26
|
+
private readonly prefix = crypto.randomUUID();
|
|
27
|
+
private closed = false;
|
|
28
|
+
private closeSent = false;
|
|
29
|
+
private providerClosed = false;
|
|
30
|
+
private readonly delegations = new Set<string>();
|
|
31
|
+
// Azure delegations carry no content, so the user's words since the previous
|
|
32
|
+
// delegation become the delegation input.
|
|
33
|
+
private userSinceDelegation = "";
|
|
34
|
+
private draining: Promise<void> | null = null;
|
|
35
|
+
private finishDrain: ((error?: Error) => void) | null = null;
|
|
36
|
+
private readonly onOpen = () => this.dispatchEvent(new Event("open"));
|
|
37
|
+
private readonly onClose = () => {
|
|
38
|
+
this.providerClosed = true;
|
|
39
|
+
this.flush();
|
|
40
|
+
this.finishDrain?.();
|
|
41
|
+
this.dispatchEvent(new Event("close"));
|
|
42
|
+
};
|
|
43
|
+
private readonly onError = () => this.dispatchEvent(new Event("error"));
|
|
44
|
+
private readonly onMessage = (event: MessageEvent) => {
|
|
45
|
+
if (typeof event.data !== "string" || event.data.length > 1_048_576) return;
|
|
46
|
+
let value: unknown;
|
|
47
|
+
try {
|
|
48
|
+
value = JSON.parse(event.data);
|
|
49
|
+
} catch {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (!value || typeof value !== "object") return;
|
|
53
|
+
this.receive(value as Envelope);
|
|
54
|
+
};
|
|
55
|
+
constructor(
|
|
56
|
+
private readonly raw: RTCDataChannel,
|
|
57
|
+
private readonly drainTimeoutMs = 5_000,
|
|
58
|
+
) {
|
|
59
|
+
super();
|
|
60
|
+
raw.addEventListener("open", this.onOpen);
|
|
61
|
+
raw.addEventListener("close", this.onClose);
|
|
62
|
+
raw.addEventListener("error", this.onError);
|
|
63
|
+
raw.addEventListener("message", this.onMessage);
|
|
64
|
+
}
|
|
65
|
+
get readyState(): RTCDataChannelState {
|
|
66
|
+
return this.closed || this.providerClosed
|
|
67
|
+
? "closed"
|
|
68
|
+
: this.closeSent
|
|
69
|
+
? "closing"
|
|
70
|
+
: this.raw.readyState;
|
|
71
|
+
}
|
|
72
|
+
asRtcDataChannel(): RTCDataChannel {
|
|
73
|
+
return this as unknown as RTCDataChannel;
|
|
74
|
+
}
|
|
75
|
+
private emit(value: Envelope): void {
|
|
76
|
+
if (!this.closed)
|
|
77
|
+
this.dispatchEvent(new MessageEvent("message", { data: JSON.stringify(value) }));
|
|
78
|
+
}
|
|
79
|
+
private flush(): void {
|
|
80
|
+
if (this.timer) clearTimeout(this.timer);
|
|
81
|
+
this.timer = null;
|
|
82
|
+
const pending = this.pending;
|
|
83
|
+
this.pending = null;
|
|
84
|
+
if (!pending?.text) return;
|
|
85
|
+
this.emit({
|
|
86
|
+
type: "transcript.segment",
|
|
87
|
+
turn: {
|
|
88
|
+
id: `${this.prefix}:${++this.ordinal}`,
|
|
89
|
+
role: pending.role,
|
|
90
|
+
transcript: pending.text,
|
|
91
|
+
},
|
|
92
|
+
start_ms: pending.startMs,
|
|
93
|
+
end_ms: pending.endMs,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
private receive(value: Envelope): void {
|
|
97
|
+
if (this.closed) return;
|
|
98
|
+
if (
|
|
99
|
+
value.type === "session.input_transcript.delta" ||
|
|
100
|
+
value.type === "session.output_transcript.delta"
|
|
101
|
+
) {
|
|
102
|
+
if (
|
|
103
|
+
typeof value.delta !== "string" ||
|
|
104
|
+
typeof value.start_ms !== "number" ||
|
|
105
|
+
typeof value.end_ms !== "number"
|
|
106
|
+
)
|
|
107
|
+
return;
|
|
108
|
+
const role = value.type === "session.input_transcript.delta" ? "user" : "assistant";
|
|
109
|
+
if (role === "user")
|
|
110
|
+
this.userSinceDelegation = takeUtf8Tail(this.userSinceDelegation + value.delta);
|
|
111
|
+
if (
|
|
112
|
+
this.pending &&
|
|
113
|
+
(this.pending.role !== role ||
|
|
114
|
+
new TextEncoder().encode(this.pending.text + value.delta).byteLength > MAX_FRAGMENT_BYTES)
|
|
115
|
+
)
|
|
116
|
+
this.flush();
|
|
117
|
+
if (new TextEncoder().encode(value.delta).byteLength > MAX_FRAGMENT_BYTES) {
|
|
118
|
+
this.emit({
|
|
119
|
+
type: "error",
|
|
120
|
+
error: { message: "Voice transcript fragment exceeded the supported size" },
|
|
121
|
+
});
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
this.pending = {
|
|
125
|
+
role,
|
|
126
|
+
text: (this.pending?.text ?? "") + value.delta,
|
|
127
|
+
startMs: this.pending?.startMs ?? value.start_ms,
|
|
128
|
+
endMs: value.end_ms,
|
|
129
|
+
};
|
|
130
|
+
// Application grouping only: never present silence as a provider turn boundary.
|
|
131
|
+
if (!this.timer) this.timer = setTimeout(() => this.flush(), 1_000);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (value.type === "session.delegation.created") {
|
|
135
|
+
const delegation = value.delegation as Envelope | undefined;
|
|
136
|
+
if (delegation?.target !== "client" || typeof delegation.id !== "string") return;
|
|
137
|
+
this.delegations.add(delegation.id);
|
|
138
|
+
this.flush();
|
|
139
|
+
const spoken = this.userSinceDelegation.trim();
|
|
140
|
+
this.userSinceDelegation = "";
|
|
141
|
+
this.emit({
|
|
142
|
+
type: "delegation.created",
|
|
143
|
+
item: {
|
|
144
|
+
id: delegation.id,
|
|
145
|
+
type: "delegation",
|
|
146
|
+
target: "client",
|
|
147
|
+
content: spoken ? [{ type: "input_text", text: spoken }] : [],
|
|
148
|
+
},
|
|
149
|
+
offset_ms: value.offset_ms,
|
|
150
|
+
});
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (value.type === "session.closed") {
|
|
154
|
+
this.providerClosed = true;
|
|
155
|
+
this.flush();
|
|
156
|
+
this.finishDrain?.();
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (
|
|
160
|
+
value.type === "session.started" ||
|
|
161
|
+
value.type === "session.updated" ||
|
|
162
|
+
value.type === "error"
|
|
163
|
+
)
|
|
164
|
+
this.emit(value);
|
|
165
|
+
}
|
|
166
|
+
send(payload: string): void {
|
|
167
|
+
if (this.readyState !== "open") throw Error("Hosted voice channel is not open");
|
|
168
|
+
const value = JSON.parse(payload) as Envelope;
|
|
169
|
+
if (value.type !== "session.context.append" && value.type !== "delegation.context.append")
|
|
170
|
+
throw Error("Unsupported hosted voice context event");
|
|
171
|
+
const content = Array.isArray(value.content)
|
|
172
|
+
? value.content.map((part) => (typeof part?.text === "string" ? part.text : "")).join("")
|
|
173
|
+
: "";
|
|
174
|
+
// Existing bridge chunks are <=500 UTF-8 bytes, below Live's 500-token bound.
|
|
175
|
+
this.raw.send(
|
|
176
|
+
JSON.stringify({
|
|
177
|
+
type:
|
|
178
|
+
value.channel === "speakable" ? "session.commentary.append" : "session.thinking.append",
|
|
179
|
+
content,
|
|
180
|
+
// Replayed tasks from an earlier provider session are general context.
|
|
181
|
+
delegation_id:
|
|
182
|
+
value.type === "delegation.context.append" &&
|
|
183
|
+
typeof value.delegation_item_id === "string" &&
|
|
184
|
+
this.delegations.has(value.delegation_item_id)
|
|
185
|
+
? value.delegation_item_id
|
|
186
|
+
: null,
|
|
187
|
+
}),
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
drain(): Promise<void> {
|
|
191
|
+
if (this.draining) return this.draining;
|
|
192
|
+
if (this.providerClosed || this.raw.readyState === "closed") {
|
|
193
|
+
this.flush();
|
|
194
|
+
return Promise.resolve();
|
|
195
|
+
}
|
|
196
|
+
if (this.closed || this.raw.readyState !== "open") {
|
|
197
|
+
return Promise.reject(new Error("Hosted voice close is not confirmed"));
|
|
198
|
+
}
|
|
199
|
+
const pending = new Promise<void>((resolve, reject) => {
|
|
200
|
+
const timeout = setTimeout(() => {
|
|
201
|
+
this.flush();
|
|
202
|
+
this.finishDrain?.(
|
|
203
|
+
new Error("Hosted voice is still closing; retry to preserve final speech"),
|
|
204
|
+
);
|
|
205
|
+
}, this.drainTimeoutMs);
|
|
206
|
+
this.finishDrain = (error) => {
|
|
207
|
+
clearTimeout(timeout);
|
|
208
|
+
this.finishDrain = null;
|
|
209
|
+
if (error) reject(error);
|
|
210
|
+
else resolve();
|
|
211
|
+
};
|
|
212
|
+
if (!this.closeSent) {
|
|
213
|
+
this.closeSent = true;
|
|
214
|
+
try {
|
|
215
|
+
this.raw.send(JSON.stringify({ type: "session.close" }));
|
|
216
|
+
} catch {
|
|
217
|
+
this.finishDrain(new Error("Hosted voice close could not be sent"));
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
this.draining = pending;
|
|
222
|
+
// An uncertain close remains retryable; never resend the provider mutation.
|
|
223
|
+
void pending.then(
|
|
224
|
+
() => {
|
|
225
|
+
if (this.draining === pending) this.draining = null;
|
|
226
|
+
},
|
|
227
|
+
() => {
|
|
228
|
+
if (this.draining === pending) this.draining = null;
|
|
229
|
+
},
|
|
230
|
+
);
|
|
231
|
+
return pending;
|
|
232
|
+
}
|
|
233
|
+
close(): void {
|
|
234
|
+
if (this.closed) return;
|
|
235
|
+
if (this.timer) clearTimeout(this.timer);
|
|
236
|
+
this.timer = null;
|
|
237
|
+
this.pending = null;
|
|
238
|
+
this.finishDrain?.(new Error("Hosted voice channel was disposed before close confirmation"));
|
|
239
|
+
this.closed = true;
|
|
240
|
+
this.raw.removeEventListener("open", this.onOpen);
|
|
241
|
+
this.raw.removeEventListener("close", this.onClose);
|
|
242
|
+
this.raw.removeEventListener("error", this.onError);
|
|
243
|
+
this.raw.removeEventListener("message", this.onMessage);
|
|
244
|
+
this.dispatchEvent(new Event("close"));
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export function createAzureLiveTransportStarter(
|
|
249
|
+
options: Pick<StartCodexRealtimeWebrtcOptions, "remoteAudio" | "createPeerConnection"> = {},
|
|
250
|
+
): RealtimeControllerTransportStarter {
|
|
251
|
+
return async (input) => {
|
|
252
|
+
let channel: AzureLiveDataChannel | undefined;
|
|
253
|
+
try {
|
|
254
|
+
const transport = await startCodexRealtimeWebrtc({
|
|
255
|
+
...input,
|
|
256
|
+
...options,
|
|
257
|
+
activateRemoteAudio: false,
|
|
258
|
+
expectedModel: "opengeni-azure/gpt-live-1",
|
|
259
|
+
onEventsCreated(raw) {
|
|
260
|
+
channel = new AzureLiveDataChannel(raw);
|
|
261
|
+
input.onEventsCreated(channel.asRtcDataChannel());
|
|
262
|
+
},
|
|
263
|
+
negotiate: (request, requestOptions) =>
|
|
264
|
+
input.client.negotiateCodexRealtimeWebrtc(
|
|
265
|
+
input.workspaceId,
|
|
266
|
+
input.sessionId,
|
|
267
|
+
request,
|
|
268
|
+
requestOptions,
|
|
269
|
+
),
|
|
270
|
+
});
|
|
271
|
+
const events = channel!;
|
|
272
|
+
return {
|
|
273
|
+
...transport,
|
|
274
|
+
events: events.asRtcDataChannel(),
|
|
275
|
+
drain: () => events.drain(),
|
|
276
|
+
stop() {
|
|
277
|
+
events.close();
|
|
278
|
+
transport.stop();
|
|
279
|
+
},
|
|
280
|
+
};
|
|
281
|
+
} catch (error) {
|
|
282
|
+
channel?.close();
|
|
283
|
+
throw error;
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
}
|
package/src/browser.ts
CHANGED
|
@@ -1,7 +1,28 @@
|
|
|
1
1
|
/** Browser-console client. Optional SDK surfaces must not enter this eager graph. */
|
|
2
2
|
export { OpenGeniClient as OpenGeniBrowserClient } from "./client";
|
|
3
|
+
export type {
|
|
4
|
+
SessionMessageSearchRequest,
|
|
5
|
+
SessionMessageSearchMatch,
|
|
6
|
+
SessionMessageSearchResponse,
|
|
7
|
+
SessionMessagePreview,
|
|
8
|
+
SessionMessagePreviewReference,
|
|
9
|
+
} from "./session-message-search";
|
|
10
|
+
export {
|
|
11
|
+
OpenGeniToolCallError,
|
|
12
|
+
OpenGeniToolReapprovalRequiredError,
|
|
13
|
+
OpenGeniToolsClient,
|
|
14
|
+
} from "./tools";
|
|
15
|
+
export type {
|
|
16
|
+
OpenGeniGeneratedTools,
|
|
17
|
+
OpenGeniDynamicToolNode,
|
|
18
|
+
OpenGeniToolCallOptions,
|
|
19
|
+
OpenGeniToolFunction,
|
|
20
|
+
OpenGeniToolsFacade,
|
|
21
|
+
OpenGeniWorkspaceTools,
|
|
22
|
+
} from "./tools";
|
|
3
23
|
export type {
|
|
4
24
|
FetchLike,
|
|
25
|
+
FetchResponse,
|
|
5
26
|
GetSessionOptions,
|
|
6
27
|
OpenGeniClientOptions,
|
|
7
28
|
OpenGeniRequestOptions,
|
|
@@ -13,9 +34,25 @@ export type {
|
|
|
13
34
|
export {
|
|
14
35
|
OpenGeniApiContractMismatchError,
|
|
15
36
|
OpenGeniApiError,
|
|
37
|
+
OpenGeniSetupError,
|
|
38
|
+
OpenGeniAllowanceExhaustedError,
|
|
39
|
+
OpenGeniSessionUsageLimitReachedError,
|
|
40
|
+
OpenGeniSessionUsageLimitUnsupportedError,
|
|
41
|
+
OpenGeniSecureContextRequiredError,
|
|
16
42
|
OpenGeniSessionListCursorError,
|
|
17
43
|
OpenGeniStreamError,
|
|
44
|
+
formatErrorMessage,
|
|
18
45
|
isRetryableStreamError,
|
|
19
46
|
} from "./errors";
|
|
47
|
+
export type { OpenGeniSecureContextRequiredReason } from "./errors";
|
|
20
48
|
export { resolveWorkspaceVoiceInputEnabled } from "./transcription";
|
|
21
49
|
export { OPENGENI_API_CONTRACT_HEADER, OPENGENI_API_CONTRACT_REVISION } from "./types";
|
|
50
|
+
|
|
51
|
+
export type {
|
|
52
|
+
ConnectorToolPermission,
|
|
53
|
+
ConnectorToolPermissionEntry,
|
|
54
|
+
ConnectorToolPermissionsResponse,
|
|
55
|
+
UpdateConnectorToolPermissionsRequest,
|
|
56
|
+
SessionMcpToolPermissionsResponse,
|
|
57
|
+
UpdateSessionMcpToolPermissionsRequest,
|
|
58
|
+
} from "./types";
|