@opengeni/sdk 0.52.1 → 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 +1078 -33
- 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-KIHGPM7H.js → chunk-2UXZUCEZ.js} +309 -46
- 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-FHI4DFIG.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-ILQZR5N6.js → chunk-FG3OO5LM.js} +3484 -750
- 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-DXDL7EEW.js → chunk-KWADQ227.js} +198 -114
- package/dist/chunk-KWADQ227.js.map +1 -0
- 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-MZWTWOX6.js → chunk-NC57YMUO.js} +447 -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-FRJFNDIR.js → chunk-YIKA2QT4.js} +37 -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 +843 -107
- package/dist/codex-realtime-controller.d.ts +6 -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 +28 -9
- package/dist/deprecation.d.ts +47 -0
- package/dist/desktop.d.ts +8 -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 +243 -124
- 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.d.ts +1 -0
- package/dist/gateway-realtime-transport.js +5 -3
- 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 -12
- package/dist/index.js +277 -126
- package/dist/index.js.map +1 -1
- package/dist/interaction-revision-stream.d.ts +11 -0
- package/dist/interaction.d.ts +687 -5
- package/dist/interaction.js +32 -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 +6 -4
- package/dist/realtime.js +10 -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 +3048 -406
- 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-live-stream.d.ts +14 -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 +5162 -792
- package/src/codex-realtime-controller.ts +260 -12
- package/src/codex-realtime-lifecycle.ts +1 -0
- 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/desktop.ts +11 -1
- 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 +185 -4
- package/src/feedback.ts +20 -0
- package/src/gateway-realtime-transport.ts +253 -110
- package/src/github-repositories.ts +60 -0
- package/src/index.ts +603 -54
- package/src/interaction-revision-stream.ts +117 -0
- package/src/interaction.ts +1367 -51
- 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 +15 -4
- 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 +3607 -493
- 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-live-stream.ts +137 -0
- package/src/workspace-state.ts +8 -82
- package/dist/chunk-DXDL7EEW.js.map +0 -1
- package/dist/chunk-FHI4DFIG.js.map +0 -1
- package/dist/chunk-FRJFNDIR.js.map +0 -1
- package/dist/chunk-ILQZR5N6.js.map +0 -1
- package/dist/chunk-KIHGPM7H.js.map +0 -1
- package/dist/chunk-MZWTWOX6.js.map +0 -1
- package/dist/chunk-V5F253OG.js +0 -116
- package/dist/chunk-V5F253OG.js.map +0 -1
- package/dist/chunk-VWE2QIVO.js.map +0 -1
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var OpenGeniApiError = class extends Error {
|
|
3
|
+
status;
|
|
4
|
+
code;
|
|
5
|
+
retryable;
|
|
6
|
+
correlationId;
|
|
7
|
+
/** True only when an uncontrolled transport failed after a mutation may have been accepted. */
|
|
8
|
+
outcomeUnknown;
|
|
9
|
+
body;
|
|
10
|
+
details;
|
|
11
|
+
constructor(status, body, options = {}) {
|
|
12
|
+
const decoded = decodeApiErrorBody(body);
|
|
13
|
+
const correlationId = decoded?.requestId ?? boundedCorrelationId(options.correlationId);
|
|
14
|
+
const gatewayFailure = status >= 502 && status <= 504;
|
|
15
|
+
const fromResponse = options.mutation !== void 0;
|
|
16
|
+
const message = decoded?.message ?? (fromResponse ? "Request failed." : body || "(empty body)");
|
|
17
|
+
const displayMessage = options.displayMessage ?? (gatewayFailure && fromResponse ? decoded?.message ?? "Opengeni is temporarily unavailable \u2014 retry." : `OpenGeni API ${status}: ${message}`);
|
|
18
|
+
super(correlationId ? `${displayMessage} Reference: ${correlationId}.` : displayMessage);
|
|
19
|
+
this.name = "OpenGeniApiError";
|
|
20
|
+
this.status = status;
|
|
21
|
+
this.code = options.code ?? decoded?.code ?? (gatewayFailure && fromResponse ? "upstream_unavailable" : void 0);
|
|
22
|
+
this.retryable = options.retryable ?? decoded?.retryable ?? retryableApiStatus(status);
|
|
23
|
+
this.correlationId = correlationId;
|
|
24
|
+
this.outcomeUnknown = options.outcomeUnknown ?? decoded?.outcomeUnknown ?? (gatewayFailure && !!options.mutation && !decoded);
|
|
25
|
+
this.body = !fromResponse || decoded ? body : "";
|
|
26
|
+
this.details = decoded?.details;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
var OpenGeniSetupError = class extends OpenGeniApiError {
|
|
30
|
+
constructor(error) {
|
|
31
|
+
super(error.status, error.body, {
|
|
32
|
+
code: "OPENGENI_SETUP_REQUIRED",
|
|
33
|
+
retryable: false,
|
|
34
|
+
correlationId: error.correlationId,
|
|
35
|
+
displayMessage: "Private chats require organization_private_session_settings.enabled (migration 0323). An organization owner or admin can enable Only me chats in the web app under Organization settings > Security & data, or use updateOrganizationPrivateSessionSettings from @opengeni/sdk/organization-private-session-settings with enabled: true, the current expectedVersion and a stable operationId (PATCH /v1/organizations/:organizationId/private-session-settings; an organization key needs workspace:admin). If platform readiness is unavailable, ask the deployment operator to activate session tenancy first."
|
|
36
|
+
});
|
|
37
|
+
this.name = "OpenGeniSetupError";
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
var OpenGeniAllowanceExhaustedError = class extends OpenGeniApiError {
|
|
41
|
+
scope;
|
|
42
|
+
resetsAt;
|
|
43
|
+
subjectId;
|
|
44
|
+
constructor(status, body, options = {}) {
|
|
45
|
+
super(status, body, {
|
|
46
|
+
...options,
|
|
47
|
+
code: "allowance_exhausted",
|
|
48
|
+
retryable: false,
|
|
49
|
+
outcomeUnknown: false
|
|
50
|
+
});
|
|
51
|
+
this.name = "OpenGeniAllowanceExhaustedError";
|
|
52
|
+
const refusal = allowanceExhaustedFields(body);
|
|
53
|
+
this.scope = refusal?.scope ?? "workspace";
|
|
54
|
+
this.resetsAt = refusal?.resetsAt ?? null;
|
|
55
|
+
this.subjectId = refusal?.subjectId;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
function allowanceExhaustedFields(body) {
|
|
59
|
+
try {
|
|
60
|
+
const parsed = JSON.parse(body);
|
|
61
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
62
|
+
const root = parsed;
|
|
63
|
+
const error = root.error && typeof root.error === "object" && !Array.isArray(root.error) ? root.error : root;
|
|
64
|
+
if (error.code !== "allowance_exhausted") return null;
|
|
65
|
+
const fields = error.details && typeof error.details === "object" && !Array.isArray(error.details) ? error.details : error;
|
|
66
|
+
if (fields.scope !== "workspace" && fields.scope !== "member") return null;
|
|
67
|
+
if (fields.resetsAt !== null && typeof fields.resetsAt !== "string") return null;
|
|
68
|
+
return {
|
|
69
|
+
scope: fields.scope,
|
|
70
|
+
resetsAt: fields.resetsAt,
|
|
71
|
+
...typeof fields.subjectId === "string" ? { subjectId: fields.subjectId } : {}
|
|
72
|
+
};
|
|
73
|
+
} catch {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
var OpenGeniSecureContextRequiredError = class extends Error {
|
|
78
|
+
code = "secure_context_required";
|
|
79
|
+
retryable = false;
|
|
80
|
+
reason;
|
|
81
|
+
constructor(reason) {
|
|
82
|
+
super(
|
|
83
|
+
reason === "insecure_context" ? "Couldn\u2019t attach this file because Opengeni is open over HTTP. Attachments require a secure HTTPS connection. Open the secure site or configure HTTPS for this deployment." : "Couldn\u2019t attach this file because secure browser cryptography is unavailable. Attachments require HTTPS and Web Crypto support. Open a secure site in a supported browser or configure HTTPS for this deployment."
|
|
84
|
+
);
|
|
85
|
+
this.name = "OpenGeniSecureContextRequiredError";
|
|
86
|
+
this.reason = reason;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
function decodeApiErrorBody(body) {
|
|
90
|
+
if (!body) return null;
|
|
91
|
+
try {
|
|
92
|
+
const decoded = JSON.parse(body);
|
|
93
|
+
if (!decoded || typeof decoded !== "object" || Array.isArray(decoded)) return null;
|
|
94
|
+
const record = decoded;
|
|
95
|
+
const nested = record.error && typeof record.error === "object" && !Array.isArray(record.error) ? record.error : record;
|
|
96
|
+
const code = boundedApiField(nested.code);
|
|
97
|
+
const message = boundedApiField(nested.message);
|
|
98
|
+
const requestId = boundedCorrelationId(nested.requestId);
|
|
99
|
+
const retryable = typeof nested.retryable === "boolean" ? nested.retryable : void 0;
|
|
100
|
+
const outcomeUnknown = typeof nested.outcomeUnknown === "boolean" ? nested.outcomeUnknown : void 0;
|
|
101
|
+
const details = boundedApiDetails(nested.details);
|
|
102
|
+
if (!code && !message && !requestId && retryable === void 0 && outcomeUnknown === void 0 && !details)
|
|
103
|
+
return null;
|
|
104
|
+
return {
|
|
105
|
+
code,
|
|
106
|
+
message,
|
|
107
|
+
requestId,
|
|
108
|
+
retryable,
|
|
109
|
+
outcomeUnknown,
|
|
110
|
+
details
|
|
111
|
+
};
|
|
112
|
+
} catch {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function boundedApiDetails(value) {
|
|
117
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return;
|
|
118
|
+
const entries = Object.entries(value).slice(0, 16);
|
|
119
|
+
const details = {};
|
|
120
|
+
for (const [key, entry] of entries) {
|
|
121
|
+
if (!/^[a-zA-Z][\w.-]{0,63}$/.test(key)) continue;
|
|
122
|
+
if (typeof entry === "string") {
|
|
123
|
+
const bounded = boundedApiField(entry);
|
|
124
|
+
if (bounded !== void 0) details[key] = bounded;
|
|
125
|
+
} else if (typeof entry === "number" || typeof entry === "boolean" || entry === null) {
|
|
126
|
+
details[key] = entry;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return Object.keys(details).length > 0 ? details : void 0;
|
|
130
|
+
}
|
|
131
|
+
function boundedApiField(value) {
|
|
132
|
+
if (typeof value !== "string") return;
|
|
133
|
+
const bytes = new TextEncoder().encode(value);
|
|
134
|
+
return bytes.byteLength <= 512 ? value : new TextDecoder().decode(bytes.slice(0, 512));
|
|
135
|
+
}
|
|
136
|
+
function retryableApiStatus(status) {
|
|
137
|
+
return status === 408 || status === 409 || status === 425 || status === 429 || status >= 500;
|
|
138
|
+
}
|
|
139
|
+
function boundedCorrelationId(value) {
|
|
140
|
+
if (typeof value !== "string" || value.length > 128 || !/^[\w.:-]+$/.test(value)) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
return value;
|
|
144
|
+
}
|
|
145
|
+
var OpenGeniSessionListCursorError = class extends OpenGeniApiError {
|
|
146
|
+
};
|
|
147
|
+
var OpenGeniApiContractMismatchError = class extends Error {
|
|
148
|
+
expected;
|
|
149
|
+
actual;
|
|
150
|
+
constructor(expected, actual) {
|
|
151
|
+
super(`OpenGeni API contract mismatch: client expects ${expected}, API serves ${actual}`);
|
|
152
|
+
this.name = "OpenGeniApiContractMismatchError";
|
|
153
|
+
this.expected = expected;
|
|
154
|
+
this.actual = actual;
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
var OpenGeniStreamError = class extends Error {
|
|
158
|
+
constructor(message) {
|
|
159
|
+
super(message);
|
|
160
|
+
this.name = "OpenGeniStreamError";
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
function formatErrorMessage(error, fallback = "The request could not be completed.") {
|
|
164
|
+
if (error instanceof OpenGeniApiError) {
|
|
165
|
+
let message;
|
|
166
|
+
if (error.outcomeUnknown) {
|
|
167
|
+
message = "The request could not be confirmed. Check its status before retrying.";
|
|
168
|
+
} else if (error instanceof OpenGeniSetupError || error.code === "OPENGENI_SETUP_REQUIRED" || error.code === "SESSION_TENANCY_NOT_ACTIVATED") {
|
|
169
|
+
message = "Private conversations are unavailable. Ask an administrator to enable them.";
|
|
170
|
+
} else if (error.code === "allowance_exhausted") {
|
|
171
|
+
message = "Usage limit reached. Wait for the reset or ask an administrator for more usage.";
|
|
172
|
+
} else if (error instanceof OpenGeniSessionListCursorError) {
|
|
173
|
+
message = "The conversation list changed. Refresh and try again.";
|
|
174
|
+
} else if (error.status === 401) {
|
|
175
|
+
message = "Sign in to continue.";
|
|
176
|
+
} else if (error.status === 403) {
|
|
177
|
+
message = "You don\u2019t have permission to do that.";
|
|
178
|
+
} else if (error.status === 404) {
|
|
179
|
+
message = "The requested item is unavailable.";
|
|
180
|
+
} else if (error.status === 402 || error.code === "payment_required") {
|
|
181
|
+
message = "There are not enough credits to continue.";
|
|
182
|
+
} else if (error.status === 429 || error.code === "rate_limited") {
|
|
183
|
+
message = error.retryable ? "Too many requests. Wait a moment and try again." : "This request is unavailable. Ask an administrator for help.";
|
|
184
|
+
} else if (error.status === 409) {
|
|
185
|
+
message = "The request conflicts with the current state. Refresh and try again.";
|
|
186
|
+
} else if (error.status === 400 || error.status === 422) {
|
|
187
|
+
message = "The request could not be accepted. Check your input and try again.";
|
|
188
|
+
} else if (error.status === 408 || error.status === 425 || error.status === 0) {
|
|
189
|
+
message = error.retryable ? "The connection could not be completed. Try again later." : fallback;
|
|
190
|
+
} else if (error.status >= 500) {
|
|
191
|
+
message = error.retryable ? "The service is temporarily unavailable. Try again later." : "The service is unavailable. Ask an administrator for help.";
|
|
192
|
+
} else {
|
|
193
|
+
message = fallback;
|
|
194
|
+
}
|
|
195
|
+
return error.correlationId ? `${message} Reference: ${error.correlationId}.` : message;
|
|
196
|
+
}
|
|
197
|
+
if (error instanceof OpenGeniSecureContextRequiredError || error instanceof Error && "code" in error && error.code === "secure_context_required") {
|
|
198
|
+
return "reason" in error && error.reason === "insecure_context" ? "Attachments require HTTPS. Open this page over a secure connection." : "Attachments require secure browser cryptography. Use a supported browser over HTTPS.";
|
|
199
|
+
}
|
|
200
|
+
if (error instanceof OpenGeniApiContractMismatchError) {
|
|
201
|
+
return "This page is out of date. Reload it before trying again.";
|
|
202
|
+
}
|
|
203
|
+
if (error instanceof OpenGeniStreamError) {
|
|
204
|
+
return "The live connection could not be restored. Refresh to check the latest state.";
|
|
205
|
+
}
|
|
206
|
+
return fallback;
|
|
207
|
+
}
|
|
208
|
+
function isAbortError(error) {
|
|
209
|
+
return error instanceof DOMException && error.name === "AbortError" || error instanceof Error && error.name === "AbortError";
|
|
210
|
+
}
|
|
211
|
+
function isRetryableStreamError(error) {
|
|
212
|
+
if (error instanceof OpenGeniApiError) return error.retryable;
|
|
213
|
+
return error instanceof TypeError;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export {
|
|
217
|
+
OpenGeniApiError,
|
|
218
|
+
OpenGeniSetupError,
|
|
219
|
+
OpenGeniAllowanceExhaustedError,
|
|
220
|
+
allowanceExhaustedFields,
|
|
221
|
+
OpenGeniSecureContextRequiredError,
|
|
222
|
+
OpenGeniSessionListCursorError,
|
|
223
|
+
OpenGeniApiContractMismatchError,
|
|
224
|
+
OpenGeniStreamError,
|
|
225
|
+
formatErrorMessage,
|
|
226
|
+
isAbortError,
|
|
227
|
+
isRetryableStreamError
|
|
228
|
+
};
|
|
229
|
+
//# sourceMappingURL=chunk-V6GIY62B.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts"],"sourcesContent":["/** Error for a non-2xx OpenGeni API response. */\nexport class OpenGeniApiError extends Error {\n readonly status: number;\n readonly code: string | undefined;\n readonly retryable: boolean;\n readonly correlationId: string | undefined;\n /** True only when an uncontrolled transport failed after a mutation may have been accepted. */\n readonly outcomeUnknown: boolean;\n readonly body: string;\n readonly details: Record<string, unknown> | undefined;\n\n constructor(\n status: number,\n body: string,\n options: {\n code?: string | undefined;\n retryable?: boolean | undefined;\n correlationId?: string | undefined;\n outcomeUnknown?: boolean | undefined;\n displayMessage?: string | undefined;\n mutation?: boolean | undefined;\n } = {},\n ) {\n const decoded = decodeApiErrorBody(body);\n const correlationId = decoded?.requestId ?? boundedCorrelationId(options.correlationId);\n const gatewayFailure = status >= 502 && status <= 504;\n const fromResponse = options.mutation !== undefined;\n const message = decoded?.message ?? (fromResponse ? \"Request failed.\" : body || \"(empty body)\");\n const displayMessage =\n options.displayMessage ??\n (gatewayFailure && fromResponse\n ? (decoded?.message ?? \"Opengeni is temporarily unavailable — retry.\")\n : `OpenGeni API ${status}: ${message}`);\n super(correlationId ? `${displayMessage} Reference: ${correlationId}.` : displayMessage);\n this.name = \"OpenGeniApiError\";\n this.status = status;\n this.code =\n options.code ??\n decoded?.code ??\n (gatewayFailure && fromResponse ? \"upstream_unavailable\" : undefined);\n this.retryable = options.retryable ?? decoded?.retryable ?? retryableApiStatus(status);\n this.correlationId = correlationId;\n this.outcomeUnknown =\n options.outcomeUnknown ??\n decoded?.outcomeUnknown ??\n (gatewayFailure && !!options.mutation && !decoded);\n this.body = !fromResponse || decoded ? body : \"\";\n this.details = decoded?.details;\n }\n}\n\n/** Deployment or organization setup must be completed before private chats can be created. */\nexport class OpenGeniSetupError extends OpenGeniApiError {\n constructor(error: OpenGeniApiError) {\n super(error.status, error.body, {\n code: \"OPENGENI_SETUP_REQUIRED\",\n retryable: false,\n correlationId: error.correlationId,\n displayMessage:\n \"Private chats require organization_private_session_settings.enabled (migration 0323). \" +\n \"An organization owner or admin can enable Only me chats in the web app under Organization settings > Security & data, \" +\n \"or use updateOrganizationPrivateSessionSettings from @opengeni/sdk/organization-private-session-settings \" +\n \"with enabled: true, the current expectedVersion and a stable operationId \" +\n \"(PATCH /v1/organizations/:organizationId/private-session-settings; an organization key needs workspace:admin). \" +\n \"If platform readiness is unavailable, ask the deployment operator to activate session tenancy first.\",\n });\n this.name = \"OpenGeniSetupError\";\n }\n}\n\n/** A settled usage ceiling refuses the next call; retry after reset or an authorized grant. */\nexport class OpenGeniAllowanceExhaustedError extends OpenGeniApiError {\n readonly scope: \"workspace\" | \"member\";\n readonly resetsAt: string | null;\n readonly subjectId: string | undefined;\n\n constructor(\n status: number,\n body: string,\n options: ConstructorParameters<typeof OpenGeniApiError>[2] = {},\n ) {\n super(status, body, {\n ...options,\n code: \"allowance_exhausted\",\n retryable: false,\n outcomeUnknown: false,\n });\n this.name = \"OpenGeniAllowanceExhaustedError\";\n const refusal = allowanceExhaustedFields(body);\n this.scope = refusal?.scope ?? \"workspace\";\n this.resetsAt = refusal?.resetsAt ?? null;\n this.subjectId = refusal?.subjectId;\n }\n}\n\n/** Accept both the API error envelope and the standalone admission refusal. */\nexport function allowanceExhaustedFields(body: string): {\n scope: \"workspace\" | \"member\";\n resetsAt: string | null;\n subjectId?: string;\n} | null {\n try {\n const parsed: unknown = JSON.parse(body);\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) return null;\n const root = parsed as Record<string, unknown>;\n const error =\n root.error && typeof root.error === \"object\" && !Array.isArray(root.error)\n ? (root.error as Record<string, unknown>)\n : root;\n if (error.code !== \"allowance_exhausted\") return null;\n const fields =\n error.details && typeof error.details === \"object\" && !Array.isArray(error.details)\n ? (error.details as Record<string, unknown>)\n : error;\n if (fields.scope !== \"workspace\" && fields.scope !== \"member\") return null;\n if (fields.resetsAt !== null && typeof fields.resetsAt !== \"string\") return null;\n return {\n scope: fields.scope,\n resetsAt: fields.resetsAt,\n ...(typeof fields.subjectId === \"string\" ? { subjectId: fields.subjectId } : {}),\n };\n } catch {\n return null;\n }\n}\n\nexport type OpenGeniSecureContextRequiredReason = \"insecure_context\" | \"web_crypto_unavailable\";\n\n/**\n * A browser operation requires secure-context-only platform capabilities.\n * Callers may key UI behavior on the stable `secure_context_required` code;\n * `reason` exists only to keep the human guidance truthful.\n */\nexport class OpenGeniSecureContextRequiredError extends Error {\n readonly code = \"secure_context_required\" as const;\n readonly retryable = false;\n readonly reason: OpenGeniSecureContextRequiredReason;\n\n constructor(reason: OpenGeniSecureContextRequiredReason) {\n super(\n reason === \"insecure_context\"\n ? \"Couldn’t attach this file because Opengeni is open over HTTP. Attachments require a secure HTTPS connection. Open the secure site or configure HTTPS for this deployment.\"\n : \"Couldn’t attach this file because secure browser cryptography is unavailable. Attachments require HTTPS and Web Crypto support. Open a secure site in a supported browser or configure HTTPS for this deployment.\",\n );\n this.name = \"OpenGeniSecureContextRequiredError\";\n this.reason = reason;\n }\n}\n\nfunction decodeApiErrorBody(body: string): {\n code: string | undefined;\n message: string | undefined;\n requestId: string | undefined;\n retryable: boolean | undefined;\n outcomeUnknown: boolean | undefined;\n details: Record<string, unknown> | undefined;\n} | null {\n if (!body) return null;\n try {\n const decoded: unknown = JSON.parse(body);\n if (!decoded || typeof decoded !== \"object\" || Array.isArray(decoded)) return null;\n const record = decoded as Record<string, unknown>;\n const nested =\n record.error && typeof record.error === \"object\" && !Array.isArray(record.error)\n ? (record.error as Record<string, unknown>)\n : record;\n const code = boundedApiField(nested.code);\n const message = boundedApiField(nested.message);\n const requestId = boundedCorrelationId(nested.requestId);\n const retryable = typeof nested.retryable === \"boolean\" ? nested.retryable : undefined;\n const outcomeUnknown =\n typeof nested.outcomeUnknown === \"boolean\" ? nested.outcomeUnknown : undefined;\n const details = boundedApiDetails(nested.details);\n if (\n !code &&\n !message &&\n !requestId &&\n retryable === undefined &&\n outcomeUnknown === undefined &&\n !details\n )\n return null;\n return {\n code,\n message,\n requestId,\n retryable,\n outcomeUnknown,\n details,\n };\n } catch {\n return null;\n }\n}\n\nfunction boundedApiDetails(value: unknown): Record<string, unknown> | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return;\n const entries = Object.entries(value as Record<string, unknown>).slice(0, 16);\n const details: Record<string, unknown> = {};\n for (const [key, entry] of entries) {\n if (!/^[a-zA-Z][\\w.-]{0,63}$/.test(key)) continue;\n if (typeof entry === \"string\") {\n const bounded = boundedApiField(entry);\n if (bounded !== undefined) details[key] = bounded;\n } else if (typeof entry === \"number\" || typeof entry === \"boolean\" || entry === null) {\n details[key] = entry;\n }\n }\n return Object.keys(details).length > 0 ? details : undefined;\n}\n\nfunction boundedApiField(value: unknown): string | undefined {\n if (typeof value !== \"string\") return;\n const bytes = new TextEncoder().encode(value);\n return bytes.byteLength <= 512 ? value : new TextDecoder().decode(bytes.slice(0, 512));\n}\n\nfunction retryableApiStatus(status: number): boolean {\n return status === 408 || status === 409 || status === 425 || status === 429 || status >= 500;\n}\n\nfunction boundedCorrelationId(value: unknown): string | undefined {\n if (typeof value !== \"string\" || value.length > 128 || !/^[\\w.:-]+$/.test(value)) {\n return;\n }\n return value;\n}\n\n/** A legacy short-lived session-list snapshot cursor can no longer be continued. */\nexport class OpenGeniSessionListCursorError extends OpenGeniApiError {}\n\n/** The browser bundle and API disagree about their state-changing wire contract. */\nexport class OpenGeniApiContractMismatchError extends Error {\n readonly expected: string;\n readonly actual: string;\n\n constructor(expected: string, actual: string) {\n super(`OpenGeni API contract mismatch: client expects ${expected}, API serves ${actual}`);\n this.name = \"OpenGeniApiContractMismatchError\";\n this.expected = expected;\n this.actual = actual;\n }\n}\n\n/** Error for an unrecoverable event-stream condition (not a transient drop). */\nexport class OpenGeniStreamError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"OpenGeniStreamError\";\n }\n}\n\n/**\n * Brand-neutral end-user copy for a failed SDK operation. Error.message, body,\n * details and typed fields remain unchanged for diagnostics and host policy.\n * Never use this to rewrite user, assistant or tool content.\n */\nexport function formatErrorMessage(\n error: unknown,\n fallback = \"The request could not be completed.\",\n): string {\n if (error instanceof OpenGeniApiError) {\n let message: string;\n if (error.outcomeUnknown) {\n message = \"The request could not be confirmed. Check its status before retrying.\";\n } else if (\n error instanceof OpenGeniSetupError ||\n error.code === \"OPENGENI_SETUP_REQUIRED\" ||\n error.code === \"SESSION_TENANCY_NOT_ACTIVATED\"\n ) {\n message = \"Private conversations are unavailable. Ask an administrator to enable them.\";\n } else if (error.code === \"allowance_exhausted\") {\n message = \"Usage limit reached. Wait for the reset or ask an administrator for more usage.\";\n } else if (error instanceof OpenGeniSessionListCursorError) {\n message = \"The conversation list changed. Refresh and try again.\";\n } else if (error.status === 401) {\n message = \"Sign in to continue.\";\n } else if (error.status === 403) {\n message = \"You don’t have permission to do that.\";\n } else if (error.status === 404) {\n message = \"The requested item is unavailable.\";\n } else if (error.status === 402 || error.code === \"payment_required\") {\n message = \"There are not enough credits to continue.\";\n } else if (error.status === 429 || error.code === \"rate_limited\") {\n message = error.retryable\n ? \"Too many requests. Wait a moment and try again.\"\n : \"This request is unavailable. Ask an administrator for help.\";\n } else if (error.status === 409) {\n message = \"The request conflicts with the current state. Refresh and try again.\";\n } else if (error.status === 400 || error.status === 422) {\n message = \"The request could not be accepted. Check your input and try again.\";\n } else if (error.status === 408 || error.status === 425 || error.status === 0) {\n message = error.retryable\n ? \"The connection could not be completed. Try again later.\"\n : fallback;\n } else if (error.status >= 500) {\n message = error.retryable\n ? \"The service is temporarily unavailable. Try again later.\"\n : \"The service is unavailable. Ask an administrator for help.\";\n } else {\n message = fallback;\n }\n return error.correlationId ? `${message} Reference: ${error.correlationId}.` : message;\n }\n if (\n error instanceof OpenGeniSecureContextRequiredError ||\n (error instanceof Error && \"code\" in error && error.code === \"secure_context_required\")\n ) {\n return \"reason\" in error && error.reason === \"insecure_context\"\n ? \"Attachments require HTTPS. Open this page over a secure connection.\"\n : \"Attachments require secure browser cryptography. Use a supported browser over HTTPS.\";\n }\n if (error instanceof OpenGeniApiContractMismatchError) {\n return \"This page is out of date. Reload it before trying again.\";\n }\n if (error instanceof OpenGeniStreamError) {\n return \"The live connection could not be restored. Refresh to check the latest state.\";\n }\n return fallback;\n}\n\nexport function isAbortError(error: unknown): boolean {\n return (\n (error instanceof DOMException && error.name === \"AbortError\") ||\n (error instanceof Error && error.name === \"AbortError\")\n );\n}\n\n/**\n * Transient conditions worth a reconnect: network-level failures (`fetch`\n * rejects with `TypeError`) and HTTP statuses that signal a temporary server\n * or contention condition. Auth/validation failures (401/403/404/...) are\n * permanent and surface to the caller instead.\n */\nexport function isRetryableStreamError(error: unknown): boolean {\n if (error instanceof OpenGeniApiError) return error.retryable;\n return error instanceof TypeError;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
// ../contracts/src/workspace-integration-wire.ts
|
|
2
|
+
var WORKSPACE_WEBHOOK_EVENT_TYPES = [
|
|
3
|
+
"turn.completed",
|
|
4
|
+
"turn.failed",
|
|
5
|
+
"turn.cancelled",
|
|
6
|
+
"session.status.changed",
|
|
7
|
+
"session.requiresAction",
|
|
8
|
+
"session.humanInput.requested",
|
|
9
|
+
"usage.threshold_reached",
|
|
10
|
+
"usage.exhausted",
|
|
11
|
+
"usage.period_reset"
|
|
12
|
+
];
|
|
13
|
+
var OPENGENI_WEBHOOK_TEST_EVENT_TYPE = "webhook.test";
|
|
14
|
+
var OPENGENI_TEST_REQUEST_NIL_ID = "00000000-0000-0000-0000-000000000000";
|
|
15
|
+
var OPENGENI_SIGNATURE_HEADER = "OpenGeni-Signature";
|
|
16
|
+
var OPENGENI_EVENT_ID_HEADER = "OpenGeni-Event-Id";
|
|
17
|
+
var OPENGENI_DELIVERY_ID_HEADER = "OpenGeni-Delivery-Id";
|
|
18
|
+
var OPENGENI_SIGNATURE_TOLERANCE_SECONDS = 300;
|
|
19
|
+
var encoder = new TextEncoder();
|
|
20
|
+
async function hmacSha256Hex(secret, message) {
|
|
21
|
+
const key = await crypto.subtle.importKey(
|
|
22
|
+
"raw",
|
|
23
|
+
encoder.encode(secret),
|
|
24
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
25
|
+
false,
|
|
26
|
+
["sign"]
|
|
27
|
+
);
|
|
28
|
+
const signature = new Uint8Array(await crypto.subtle.sign("HMAC", key, encoder.encode(message)));
|
|
29
|
+
return Array.from(signature, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
30
|
+
}
|
|
31
|
+
function constantTimeEqualHex(left, right) {
|
|
32
|
+
if (left.length !== right.length) return false;
|
|
33
|
+
let difference = 0;
|
|
34
|
+
for (let index = 0; index < left.length; index += 1) {
|
|
35
|
+
difference |= left.charCodeAt(index) ^ right.charCodeAt(index);
|
|
36
|
+
}
|
|
37
|
+
return difference === 0;
|
|
38
|
+
}
|
|
39
|
+
async function signOpenGeniPayload(secret, body, timestampSeconds = Math.floor(Date.now() / 1e3)) {
|
|
40
|
+
return `t=${timestampSeconds},v1=${await hmacSha256Hex(secret, `${timestampSeconds}.${body}`)}`;
|
|
41
|
+
}
|
|
42
|
+
async function verifyOpenGeniSignature(input) {
|
|
43
|
+
if (!input.signature) return false;
|
|
44
|
+
let timestamp = null;
|
|
45
|
+
const candidates = [];
|
|
46
|
+
for (const part of input.signature.split(",")) {
|
|
47
|
+
const [key, value] = part.trim().split("=", 2);
|
|
48
|
+
if (key === "t" && value && /^\d{1,12}$/.test(value)) timestamp = Number(value);
|
|
49
|
+
if (key === "v1" && value && /^[0-9a-f]{64}$/.test(value)) candidates.push(value);
|
|
50
|
+
}
|
|
51
|
+
if (timestamp === null || candidates.length === 0) return false;
|
|
52
|
+
const now = input.nowSeconds ?? Math.floor(Date.now() / 1e3);
|
|
53
|
+
const tolerance = input.toleranceSeconds ?? OPENGENI_SIGNATURE_TOLERANCE_SECONDS;
|
|
54
|
+
if (Math.abs(now - timestamp) > tolerance) return false;
|
|
55
|
+
const expected = await hmacSha256Hex(input.secret, `${timestamp}.${input.body}`);
|
|
56
|
+
return candidates.some((candidate) => constantTimeEqualHex(candidate, expected));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// src/workspace-integrations.ts
|
|
60
|
+
var OpenGeniSignatureError = class extends Error {
|
|
61
|
+
constructor() {
|
|
62
|
+
super("Opengeni signature verification failed");
|
|
63
|
+
this.name = "OpenGeniSignatureError";
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
function header(headers, name) {
|
|
67
|
+
if (headers instanceof Headers) return headers.get(name);
|
|
68
|
+
const wanted = name.toLowerCase();
|
|
69
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
70
|
+
if (key.toLowerCase() === wanted) {
|
|
71
|
+
return Array.isArray(value) ? value[0] ?? null : value ?? null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
async function verifiedObject(input) {
|
|
77
|
+
const valid = await verifyOpenGeniSignature({
|
|
78
|
+
secret: input.secret,
|
|
79
|
+
body: input.body,
|
|
80
|
+
signature: header(input.headers, OPENGENI_SIGNATURE_HEADER),
|
|
81
|
+
...input.toleranceSeconds !== void 0 ? { toleranceSeconds: input.toleranceSeconds } : {}
|
|
82
|
+
});
|
|
83
|
+
if (!valid) throw new OpenGeniSignatureError();
|
|
84
|
+
const parsed = JSON.parse(input.body);
|
|
85
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
86
|
+
throw new OpenGeniSignatureError();
|
|
87
|
+
}
|
|
88
|
+
return parsed;
|
|
89
|
+
}
|
|
90
|
+
async function verifyWebhookEvent(input) {
|
|
91
|
+
const event = await verifiedObject(input);
|
|
92
|
+
const usageEvent = typeof event.type === "string" && event.type.startsWith("usage.");
|
|
93
|
+
const lane = event.lane === void 0 ? "workspace" : event.lane;
|
|
94
|
+
if (typeof event.id !== "string" || typeof event.type !== "string" || typeof event.workspaceId !== "string" || lane !== "workspace" && lane !== "organization" || usageEvent && lane !== "workspace" || !(typeof event.sessionId === "string" || (event.sessionId === null || event.sessionId === void 0) && [
|
|
95
|
+
"usage.threshold_reached",
|
|
96
|
+
"usage.exhausted",
|
|
97
|
+
"usage.period_reset",
|
|
98
|
+
OPENGENI_WEBHOOK_TEST_EVENT_TYPE
|
|
99
|
+
].includes(event.type))) {
|
|
100
|
+
throw new OpenGeniSignatureError();
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
event: { ...event, lane },
|
|
104
|
+
deliveryId: header(input.headers, OPENGENI_DELIVERY_ID_HEADER)
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
async function verifyCredentialProviderRequest(input) {
|
|
108
|
+
const parsed = await verifiedObject(input);
|
|
109
|
+
if (parsed.type !== "credentials.request" || typeof parsed.workspaceId !== "string") {
|
|
110
|
+
throw new OpenGeniSignatureError();
|
|
111
|
+
}
|
|
112
|
+
return parsed;
|
|
113
|
+
}
|
|
114
|
+
var OPENGENI_WEBHOOK_HEADERS = {
|
|
115
|
+
signature: OPENGENI_SIGNATURE_HEADER,
|
|
116
|
+
eventId: OPENGENI_EVENT_ID_HEADER,
|
|
117
|
+
deliveryId: OPENGENI_DELIVERY_ID_HEADER
|
|
118
|
+
};
|
|
119
|
+
async function getOrganizationCredentialProvider(client, organizationId) {
|
|
120
|
+
return client.requestJson(
|
|
121
|
+
"GET",
|
|
122
|
+
`/v1/organizations/${encodeURIComponent(organizationId)}/credential-provider`
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
async function putOrganizationCredentialProvider(client, organizationId, request) {
|
|
126
|
+
return client.requestJson(
|
|
127
|
+
"PUT",
|
|
128
|
+
`/v1/organizations/${encodeURIComponent(organizationId)}/credential-provider`,
|
|
129
|
+
request
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
async function deleteOrganizationCredentialProvider(client, organizationId) {
|
|
133
|
+
await client.requestJson(
|
|
134
|
+
"DELETE",
|
|
135
|
+
`/v1/organizations/${encodeURIComponent(organizationId)}/credential-provider`,
|
|
136
|
+
void 0,
|
|
137
|
+
{},
|
|
138
|
+
{ responseType: "void" }
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
async function listOrganizationWebhooks(client, organizationId) {
|
|
142
|
+
return client.requestJson(
|
|
143
|
+
"GET",
|
|
144
|
+
`/v1/organizations/${encodeURIComponent(organizationId)}/webhooks`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
async function createOrganizationWebhook(client, organizationId, request) {
|
|
148
|
+
return client.requestJson(
|
|
149
|
+
"POST",
|
|
150
|
+
`/v1/organizations/${encodeURIComponent(organizationId)}/webhooks`,
|
|
151
|
+
request
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
async function getOrganizationWebhook(client, organizationId, webhookId) {
|
|
155
|
+
return client.requestJson(
|
|
156
|
+
"GET",
|
|
157
|
+
`/v1/organizations/${encodeURIComponent(organizationId)}/webhooks/${encodeURIComponent(webhookId)}`
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
async function updateOrganizationWebhook(client, organizationId, webhookId, request) {
|
|
161
|
+
return client.requestJson(
|
|
162
|
+
"PATCH",
|
|
163
|
+
`/v1/organizations/${encodeURIComponent(organizationId)}/webhooks/${encodeURIComponent(webhookId)}`,
|
|
164
|
+
request
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
async function deleteOrganizationWebhook(client, organizationId, webhookId) {
|
|
168
|
+
await client.requestJson(
|
|
169
|
+
"DELETE",
|
|
170
|
+
`/v1/organizations/${encodeURIComponent(organizationId)}/webhooks/${encodeURIComponent(webhookId)}`,
|
|
171
|
+
void 0,
|
|
172
|
+
{},
|
|
173
|
+
{ responseType: "void" }
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
async function listOrganizationWebhookDeliveries(client, organizationId, webhookId, options = {}) {
|
|
177
|
+
return client.requestJson(
|
|
178
|
+
"GET",
|
|
179
|
+
`/v1/organizations/${encodeURIComponent(organizationId)}/webhooks/${encodeURIComponent(webhookId)}/deliveries`,
|
|
180
|
+
void 0,
|
|
181
|
+
options.limit !== void 0 ? { limit: String(options.limit) } : {}
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
async function redeliverOrganizationWebhookDelivery(client, organizationId, webhookId, deliveryId) {
|
|
185
|
+
return client.requestJson(
|
|
186
|
+
"POST",
|
|
187
|
+
`/v1/organizations/${encodeURIComponent(organizationId)}/webhooks/${encodeURIComponent(webhookId)}/deliveries/${encodeURIComponent(deliveryId)}/redeliver`
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
async function getWorkspaceWebhook(client, workspaceId, webhookId) {
|
|
191
|
+
return client.requestJson("GET", `/v1/workspaces/${workspaceId}/webhooks/${webhookId}`);
|
|
192
|
+
}
|
|
193
|
+
async function rotateWorkspaceCredentialProviderSecret(client, workspaceId) {
|
|
194
|
+
return client.requestJson(
|
|
195
|
+
"POST",
|
|
196
|
+
`/v1/workspaces/${encodeURIComponent(workspaceId)}/credential-provider/rotate-secret`
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
async function rotateOrganizationCredentialProviderSecret(client, organizationId) {
|
|
200
|
+
return client.requestJson(
|
|
201
|
+
"POST",
|
|
202
|
+
`/v1/organizations/${encodeURIComponent(organizationId)}/credential-provider/rotate-secret`
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
async function rotateOrganizationWebhookSecret(client, organizationId, webhookId) {
|
|
206
|
+
return client.requestJson(
|
|
207
|
+
"POST",
|
|
208
|
+
`/v1/organizations/${encodeURIComponent(organizationId)}/webhooks/${encodeURIComponent(webhookId)}/rotate-secret`
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
async function rotateWorkspaceWebhookSecret(client, workspaceId, webhookId) {
|
|
212
|
+
return client.requestJson(
|
|
213
|
+
"POST",
|
|
214
|
+
`/v1/workspaces/${encodeURIComponent(workspaceId)}/webhooks/${encodeURIComponent(webhookId)}/rotate-secret`
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
async function testWorkspaceWebhook(client, workspaceId, webhookId) {
|
|
218
|
+
return client.requestJson(
|
|
219
|
+
"POST",
|
|
220
|
+
`/v1/workspaces/${encodeURIComponent(workspaceId)}/webhooks/${encodeURIComponent(webhookId)}/test`
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
async function testWorkspaceCredentialProvider(client, workspaceId) {
|
|
224
|
+
return client.requestJson(
|
|
225
|
+
"POST",
|
|
226
|
+
`/v1/workspaces/${encodeURIComponent(workspaceId)}/credential-provider/test`
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
async function getWorkspaceInheritedIntegrations(client, workspaceId) {
|
|
230
|
+
return client.requestJson(
|
|
231
|
+
"GET",
|
|
232
|
+
`/v1/workspaces/${encodeURIComponent(workspaceId)}/inherited-integrations`
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export {
|
|
237
|
+
WORKSPACE_WEBHOOK_EVENT_TYPES,
|
|
238
|
+
OPENGENI_WEBHOOK_TEST_EVENT_TYPE,
|
|
239
|
+
OPENGENI_TEST_REQUEST_NIL_ID,
|
|
240
|
+
OPENGENI_SIGNATURE_HEADER,
|
|
241
|
+
OPENGENI_EVENT_ID_HEADER,
|
|
242
|
+
OPENGENI_DELIVERY_ID_HEADER,
|
|
243
|
+
signOpenGeniPayload,
|
|
244
|
+
verifyOpenGeniSignature,
|
|
245
|
+
OpenGeniSignatureError,
|
|
246
|
+
verifyWebhookEvent,
|
|
247
|
+
verifyCredentialProviderRequest,
|
|
248
|
+
OPENGENI_WEBHOOK_HEADERS,
|
|
249
|
+
getOrganizationCredentialProvider,
|
|
250
|
+
putOrganizationCredentialProvider,
|
|
251
|
+
deleteOrganizationCredentialProvider,
|
|
252
|
+
listOrganizationWebhooks,
|
|
253
|
+
createOrganizationWebhook,
|
|
254
|
+
getOrganizationWebhook,
|
|
255
|
+
updateOrganizationWebhook,
|
|
256
|
+
deleteOrganizationWebhook,
|
|
257
|
+
listOrganizationWebhookDeliveries,
|
|
258
|
+
redeliverOrganizationWebhookDelivery,
|
|
259
|
+
getWorkspaceWebhook,
|
|
260
|
+
rotateWorkspaceCredentialProviderSecret,
|
|
261
|
+
rotateOrganizationCredentialProviderSecret,
|
|
262
|
+
rotateOrganizationWebhookSecret,
|
|
263
|
+
rotateWorkspaceWebhookSecret,
|
|
264
|
+
testWorkspaceWebhook,
|
|
265
|
+
testWorkspaceCredentialProvider,
|
|
266
|
+
getWorkspaceInheritedIntegrations
|
|
267
|
+
};
|
|
268
|
+
//# sourceMappingURL=chunk-WU6GQG25.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../contracts/src/workspace-integration-wire.ts","../src/workspace-integrations.ts"],"sourcesContent":["/**\n * Dependency-free wire constants and the OpenGeni-Signature scheme shared by\n * workspace webhooks and credential providers. Kept free of zod so browser and\n * React Native bundles can verify signatures without the schema runtime.\n */\n\nexport const WORKSPACE_WEBHOOK_EVENT_TYPES = [\n \"turn.completed\",\n \"turn.failed\",\n \"turn.cancelled\",\n \"session.status.changed\",\n \"session.requiresAction\",\n \"session.humanInput.requested\",\n \"usage.threshold_reached\",\n \"usage.exhausted\",\n \"usage.period_reset\",\n] as const;\n\n/**\n * Sent only when an administrator presses \"Send test event\". It is never a\n * subscribable type: every endpoint can receive it, and a receiver that does\n * not care acknowledges it with any 2xx.\n */\nexport const OPENGENI_WEBHOOK_TEST_EVENT_TYPE = \"webhook.test\";\n\n/**\n * The session, turn and attempt ids of a credential-provider test request\n * (`purpose: \"test\"`). A test is not a run, so no real ids exist.\n */\nexport const OPENGENI_TEST_REQUEST_NIL_ID = \"00000000-0000-0000-0000-000000000000\";\n\nexport const OPENGENI_SIGNATURE_HEADER = \"OpenGeni-Signature\";\nexport const OPENGENI_EVENT_ID_HEADER = \"OpenGeni-Event-Id\";\nexport const OPENGENI_DELIVERY_ID_HEADER = \"OpenGeni-Delivery-Id\";\nexport const OPENGENI_SIGNATURE_TOLERANCE_SECONDS = 300;\n\nconst encoder = new TextEncoder();\n\nasync function hmacSha256Hex(secret: string, message: string): Promise<string> {\n const key = await crypto.subtle.importKey(\n \"raw\",\n encoder.encode(secret),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n const signature = new Uint8Array(await crypto.subtle.sign(\"HMAC\", key, encoder.encode(message)));\n return Array.from(signature, (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nfunction constantTimeEqualHex(left: string, right: string): boolean {\n if (left.length !== right.length) return false;\n let difference = 0;\n for (let index = 0; index < left.length; index += 1) {\n difference |= left.charCodeAt(index) ^ right.charCodeAt(index);\n }\n return difference === 0;\n}\n\n/**\n * `OpenGeni-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256(secret, \"<t>.<body>\")>`.\n * The timestamp is signed so a captured request cannot be replayed later.\n */\nexport async function signOpenGeniPayload(\n secret: string,\n body: string,\n timestampSeconds = Math.floor(Date.now() / 1000),\n): Promise<string> {\n return `t=${timestampSeconds},v1=${await hmacSha256Hex(secret, `${timestampSeconds}.${body}`)}`;\n}\n\nexport type VerifyOpenGeniSignatureInput = {\n secret: string;\n /** The exact raw request body, before JSON parsing. */\n body: string;\n /** The `OpenGeni-Signature` header value. */\n signature: string | null | undefined;\n toleranceSeconds?: number;\n nowSeconds?: number;\n};\n\nexport async function verifyOpenGeniSignature(\n input: VerifyOpenGeniSignatureInput,\n): Promise<boolean> {\n if (!input.signature) return false;\n let timestamp: number | null = null;\n const candidates: string[] = [];\n for (const part of input.signature.split(\",\")) {\n const [key, value] = part.trim().split(\"=\", 2);\n if (key === \"t\" && value && /^\\d{1,12}$/.test(value)) timestamp = Number(value);\n if (key === \"v1\" && value && /^[0-9a-f]{64}$/.test(value)) candidates.push(value);\n }\n if (timestamp === null || candidates.length === 0) return false;\n const now = input.nowSeconds ?? Math.floor(Date.now() / 1000);\n const tolerance = input.toleranceSeconds ?? OPENGENI_SIGNATURE_TOLERANCE_SECONDS;\n if (Math.abs(now - timestamp) > tolerance) return false;\n const expected = await hmacSha256Hex(input.secret, `${timestamp}.${input.body}`);\n return candidates.some((candidate) => constantTimeEqualHex(candidate, expected));\n}\n","import {\n OPENGENI_DELIVERY_ID_HEADER,\n OPENGENI_EVENT_ID_HEADER,\n OPENGENI_SIGNATURE_HEADER,\n OPENGENI_WEBHOOK_TEST_EVENT_TYPE,\n verifyOpenGeniSignature,\n} from \"@opengeni/contracts/workspace-integration-wire\";\nimport type { CredentialProviderRequest, WorkspaceWebhookEvent } from \"@opengeni/contracts\";\nimport type { OpenGeniClient } from \"./client\";\nimport type {\n CreateOrganizationWebhookRequest,\n CreateOrganizationWebhookResponse,\n GetOrganizationCredentialProviderResponse,\n ListOrganizationWebhookDeliveriesResponse,\n ListOrganizationWebhooksResponse,\n OrganizationWebhook,\n OrganizationWebhookDelivery,\n PutOrganizationCredentialProviderRequest,\n PutOrganizationCredentialProviderResponse,\n RotateWorkspaceCredentialProviderSecretResponse,\n RotateOrganizationCredentialProviderSecretResponse,\n RotateWorkspaceWebhookSecretResponse,\n RotateOrganizationWebhookSecretResponse,\n TestWorkspaceCredentialProviderResponse,\n TestWorkspaceWebhookResponse,\n UpdateOrganizationWebhookRequest,\n WorkspaceInheritedIntegrationsResponse,\n WorkspaceWebhook,\n} from \"@opengeni/contracts\";\n\nexport type {\n CreateOrganizationWebhookRequest,\n CreateOrganizationWebhookResponse,\n CreateWorkspaceWebhookRequest,\n CreateWorkspaceWebhookResponse,\n CredentialProviderRequest,\n CredentialProviderInitiatorContext,\n CredentialProviderResponse,\n CredentialProviderMcpHeaders,\n CredentialProviderMcpMaterial,\n GetOrganizationCredentialProviderResponse,\n GetWorkspaceCredentialProviderResponse,\n InitiatingHuman,\n IntegrationEndpointTestResult,\n IntegrationWorkspaceFilter,\n ListOrganizationWebhookDeliveriesResponse,\n ListOrganizationWebhooksResponse,\n ListWorkspaceWebhookDeliveriesResponse,\n ListWorkspaceWebhooksResponse,\n PutWorkspaceCredentialProviderRequest,\n PutWorkspaceCredentialProviderResponse,\n PutOrganizationCredentialProviderRequest,\n PutOrganizationCredentialProviderResponse,\n RotateWorkspaceCredentialProviderSecretResponse,\n RotateOrganizationCredentialProviderSecretResponse,\n RotateWorkspaceWebhookSecretResponse,\n RotateOrganizationWebhookSecretResponse,\n TestWorkspaceCredentialProviderResponse,\n TestWorkspaceWebhookResponse,\n OrganizationCredentialProvider,\n OrganizationWebhook,\n OrganizationWebhookDelivery,\n UpdateOrganizationWebhookRequest,\n UpdateWorkspaceWebhookRequest,\n WorkspaceCredentialProvider,\n WorkspaceInheritedIntegrationsResponse,\n WorkspaceTestWebhookEvent,\n WorkspaceWebhook,\n WorkspaceWebhookDelivery,\n WorkspaceWebhookEvent,\n WorkspaceWebhookEventType,\n SessionWorkspaceWebhookEvent,\n WorkspaceUsageWebhookEvent,\n} from \"@opengeni/contracts\";\nexport {\n OPENGENI_DELIVERY_ID_HEADER,\n OPENGENI_EVENT_ID_HEADER,\n OPENGENI_SIGNATURE_HEADER,\n OPENGENI_TEST_REQUEST_NIL_ID,\n OPENGENI_WEBHOOK_TEST_EVENT_TYPE,\n WORKSPACE_WEBHOOK_EVENT_TYPES,\n signOpenGeniPayload,\n verifyOpenGeniSignature,\n} from \"@opengeni/contracts/workspace-integration-wire\";\n\nexport type WorkspaceSandboxImages = { images: string[]; selected: string | null };\n\nexport class OpenGeniSignatureError extends Error {\n constructor() {\n super(\"Opengeni signature verification failed\");\n this.name = \"OpenGeniSignatureError\";\n }\n}\n\ntype SignedRequest = {\n /** The exact raw request body. Parse it only after verification. */\n body: string;\n headers: Headers | Record<string, string | string[] | undefined>;\n secret: string;\n toleranceSeconds?: number;\n};\n\nfunction header(headers: SignedRequest[\"headers\"], name: string): string | null {\n if (headers instanceof Headers) return headers.get(name);\n const wanted = name.toLowerCase();\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === wanted) {\n return Array.isArray(value) ? (value[0] ?? null) : (value ?? null);\n }\n }\n return null;\n}\n\nasync function verifiedObject(input: SignedRequest): Promise<Record<string, unknown>> {\n const valid = await verifyOpenGeniSignature({\n secret: input.secret,\n body: input.body,\n signature: header(input.headers, OPENGENI_SIGNATURE_HEADER),\n ...(input.toleranceSeconds !== undefined ? { toleranceSeconds: input.toleranceSeconds } : {}),\n });\n if (!valid) throw new OpenGeniSignatureError();\n const parsed: unknown = JSON.parse(input.body);\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new OpenGeniSignatureError();\n }\n return parsed as Record<string, unknown>;\n}\n\n/**\n * Verify and parse one webhook delivery. Delivery is at least once: dedupe on\n * `event.id` (also sent as the `OpenGeni-Event-Id` header). A `webhook.test`\n * event (from \"Send test event\") names no session: acknowledge it with 2xx.\n */\nexport async function verifyWebhookEvent(input: SignedRequest): Promise<{\n event: WorkspaceWebhookEvent;\n deliveryId: string | null;\n}> {\n const event = await verifiedObject(input);\n const usageEvent = typeof event.type === \"string\" && event.type.startsWith(\"usage.\");\n const lane = event.lane === undefined ? \"workspace\" : event.lane;\n if (\n typeof event.id !== \"string\" ||\n typeof event.type !== \"string\" ||\n typeof event.workspaceId !== \"string\" ||\n (lane !== \"workspace\" && lane !== \"organization\") ||\n (usageEvent && lane !== \"workspace\") ||\n !(\n typeof event.sessionId === \"string\" ||\n ((event.sessionId === null || event.sessionId === undefined) &&\n [\n \"usage.threshold_reached\",\n \"usage.exhausted\",\n \"usage.period_reset\",\n OPENGENI_WEBHOOK_TEST_EVENT_TYPE,\n ].includes(event.type))\n )\n ) {\n throw new OpenGeniSignatureError();\n }\n return {\n event: { ...event, lane } as WorkspaceWebhookEvent,\n deliveryId: header(input.headers, OPENGENI_DELIVERY_ID_HEADER),\n };\n}\n\n/**\n * Verify the exact bytes and parse a provider request, including its frozen\n * initiatorContext when sent by an upgraded worker. Provenance grants no access.\n */\nexport async function verifyCredentialProviderRequest(\n input: SignedRequest,\n): Promise<CredentialProviderRequest> {\n const parsed = await verifiedObject(input);\n if (parsed.type !== \"credentials.request\" || typeof parsed.workspaceId !== \"string\") {\n throw new OpenGeniSignatureError();\n }\n return parsed as CredentialProviderRequest;\n}\n\n/** Identity header names, for receivers that log or dedupe. */\nexport const OPENGENI_WEBHOOK_HEADERS = {\n signature: OPENGENI_SIGNATURE_HEADER,\n eventId: OPENGENI_EVENT_ID_HEADER,\n deliveryId: OPENGENI_DELIVERY_ID_HEADER,\n} as const;\n\n/** Server-side integration administration is opt-in, outside the eager browser client. */\nexport async function getOrganizationCredentialProvider(\n client: Pick<OpenGeniClient, \"requestJson\">,\n organizationId: string,\n): Promise<GetOrganizationCredentialProviderResponse> {\n return client.requestJson(\n \"GET\",\n `/v1/organizations/${encodeURIComponent(organizationId)}/credential-provider`,\n );\n}\n\n/** Replace configuration; explicit filter required. Store the first returned signing secret. */\nexport async function putOrganizationCredentialProvider(\n client: Pick<OpenGeniClient, \"requestJson\">,\n organizationId: string,\n request: PutOrganizationCredentialProviderRequest,\n): Promise<PutOrganizationCredentialProviderResponse> {\n return client.requestJson(\n \"PUT\",\n `/v1/organizations/${encodeURIComponent(organizationId)}/credential-provider`,\n request,\n );\n}\n\nexport async function deleteOrganizationCredentialProvider(\n client: Pick<OpenGeniClient, \"requestJson\">,\n organizationId: string,\n): Promise<void> {\n await client.requestJson<void>(\n \"DELETE\",\n `/v1/organizations/${encodeURIComponent(organizationId)}/credential-provider`,\n undefined,\n {},\n { responseType: \"void\" },\n );\n}\n\nexport async function listOrganizationWebhooks(\n client: Pick<OpenGeniClient, \"requestJson\">,\n organizationId: string,\n): Promise<ListOrganizationWebhooksResponse> {\n return client.requestJson(\n \"GET\",\n `/v1/organizations/${encodeURIComponent(organizationId)}/webhooks`,\n );\n}\n\n/** Create a webhook and return its signing secret once. */\nexport async function createOrganizationWebhook(\n client: Pick<OpenGeniClient, \"requestJson\">,\n organizationId: string,\n request: CreateOrganizationWebhookRequest,\n): Promise<CreateOrganizationWebhookResponse> {\n return client.requestJson(\n \"POST\",\n `/v1/organizations/${encodeURIComponent(organizationId)}/webhooks`,\n request,\n );\n}\n\nexport async function getOrganizationWebhook(\n client: Pick<OpenGeniClient, \"requestJson\">,\n organizationId: string,\n webhookId: string,\n): Promise<OrganizationWebhook> {\n return client.requestJson(\n \"GET\",\n `/v1/organizations/${encodeURIComponent(organizationId)}/webhooks/${encodeURIComponent(webhookId)}`,\n );\n}\n\nexport async function updateOrganizationWebhook(\n client: Pick<OpenGeniClient, \"requestJson\">,\n organizationId: string,\n webhookId: string,\n request: UpdateOrganizationWebhookRequest,\n): Promise<OrganizationWebhook> {\n return client.requestJson(\n \"PATCH\",\n `/v1/organizations/${encodeURIComponent(organizationId)}/webhooks/${encodeURIComponent(webhookId)}`,\n request,\n );\n}\n\nexport async function deleteOrganizationWebhook(\n client: Pick<OpenGeniClient, \"requestJson\">,\n organizationId: string,\n webhookId: string,\n): Promise<void> {\n await client.requestJson<void>(\n \"DELETE\",\n `/v1/organizations/${encodeURIComponent(organizationId)}/webhooks/${encodeURIComponent(webhookId)}`,\n undefined,\n {},\n { responseType: \"void\" },\n );\n}\n\nexport async function listOrganizationWebhookDeliveries(\n client: Pick<OpenGeniClient, \"requestJson\">,\n organizationId: string,\n webhookId: string,\n options: { limit?: number } = {},\n): Promise<ListOrganizationWebhookDeliveriesResponse> {\n return client.requestJson(\n \"GET\",\n `/v1/organizations/${encodeURIComponent(organizationId)}/webhooks/${encodeURIComponent(webhookId)}/deliveries`,\n undefined,\n options.limit !== undefined ? { limit: String(options.limit) } : {},\n );\n}\n\n/** Requeue a settled delivery with a fresh attempt budget. */\nexport async function redeliverOrganizationWebhookDelivery(\n client: Pick<OpenGeniClient, \"requestJson\">,\n organizationId: string,\n webhookId: string,\n deliveryId: string,\n): Promise<OrganizationWebhookDelivery> {\n return client.requestJson(\n \"POST\",\n `/v1/organizations/${encodeURIComponent(organizationId)}/webhooks/${encodeURIComponent(webhookId)}/deliveries/${encodeURIComponent(deliveryId)}/redeliver`,\n );\n}\n\nexport async function getWorkspaceWebhook(\n client: Pick<OpenGeniClient, \"requestJson\">,\n workspaceId: string,\n webhookId: string,\n): Promise<WorkspaceWebhook> {\n return client.requestJson(\"GET\", `/v1/workspaces/${workspaceId}/webhooks/${webhookId}`);\n}\n\n/** Rotate immediately. Store the new secret; the old signing secret stops working. */\nexport async function rotateWorkspaceCredentialProviderSecret(\n client: Pick<OpenGeniClient, \"requestJson\">,\n workspaceId: string,\n): Promise<RotateWorkspaceCredentialProviderSecretResponse> {\n return client.requestJson(\n \"POST\",\n `/v1/workspaces/${encodeURIComponent(workspaceId)}/credential-provider/rotate-secret`,\n );\n}\n\nexport async function rotateOrganizationCredentialProviderSecret(\n client: Pick<OpenGeniClient, \"requestJson\">,\n organizationId: string,\n): Promise<RotateOrganizationCredentialProviderSecretResponse> {\n return client.requestJson(\n \"POST\",\n `/v1/organizations/${encodeURIComponent(organizationId)}/credential-provider/rotate-secret`,\n );\n}\n\nexport async function rotateOrganizationWebhookSecret(\n client: Pick<OpenGeniClient, \"requestJson\">,\n organizationId: string,\n webhookId: string,\n): Promise<RotateOrganizationWebhookSecretResponse> {\n return client.requestJson(\n \"POST\",\n `/v1/organizations/${encodeURIComponent(organizationId)}/webhooks/${encodeURIComponent(webhookId)}/rotate-secret`,\n );\n}\n\nexport async function rotateWorkspaceWebhookSecret(\n client: Pick<OpenGeniClient, \"requestJson\">,\n workspaceId: string,\n webhookId: string,\n): Promise<RotateWorkspaceWebhookSecretResponse> {\n return client.requestJson(\n \"POST\",\n `/v1/workspaces/${encodeURIComponent(workspaceId)}/webhooks/${encodeURIComponent(webhookId)}/rotate-secret`,\n );\n}\n\n/**\n * Send one signed `webhook.test` event to a workspace webhook now and return\n * what the endpoint answered. Nothing is queued or retried.\n */\nexport async function testWorkspaceWebhook(\n client: Pick<OpenGeniClient, \"requestJson\">,\n workspaceId: string,\n webhookId: string,\n): Promise<TestWorkspaceWebhookResponse> {\n return client.requestJson(\n \"POST\",\n `/v1/workspaces/${encodeURIComponent(workspaceId)}/webhooks/${encodeURIComponent(webhookId)}/test`,\n );\n}\n\n/**\n * Send one signed `purpose: \"test\"` request to the credential provider this\n * workspace's runs use (its own, else the organization's). Only the names of\n * returned credentials come back, never their values.\n */\nexport async function testWorkspaceCredentialProvider(\n client: Pick<OpenGeniClient, \"requestJson\">,\n workspaceId: string,\n): Promise<TestWorkspaceCredentialProviderResponse> {\n return client.requestJson(\n \"POST\",\n `/v1/workspaces/${encodeURIComponent(workspaceId)}/credential-provider/test`,\n );\n}\n\n/** Organization registrations that reach this workspace. Workspace administrators only. */\nexport async function getWorkspaceInheritedIntegrations(\n client: Pick<OpenGeniClient, \"requestJson\">,\n workspaceId: string,\n): Promise<WorkspaceInheritedIntegrationsResponse> {\n return client.requestJson(\n \"GET\",\n `/v1/workspaces/${encodeURIComponent(workspaceId)}/inherited-integrations`,\n );\n}\n"],"mappings":"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","names":[]}
|