@opengeni/sdk 1.3.0 → 1.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.
Files changed (59) hide show
  1. package/README.md +13 -3
  2. package/dist/adapters/next.js +2 -2
  3. package/dist/artifacts.js +4 -4
  4. package/dist/azure-live-transport.d.ts +32 -0
  5. package/dist/browser.js +3 -3
  6. package/dist/chat/index.js +5 -5
  7. package/dist/{chunk-RSKO3CMZ.js → chunk-BVIIRSJY.js} +2 -2
  8. package/dist/{chunk-G5NZGPTB.js → chunk-CA2T7QT4.js} +2 -2
  9. package/dist/{chunk-ZBICMU4Z.js → chunk-D534PIXF.js} +2 -2
  10. package/dist/{chunk-CNSPJYF6.js → chunk-FYQAMXDW.js} +104 -5
  11. package/dist/chunk-FYQAMXDW.js.map +1 -0
  12. package/dist/{chunk-IB6SUE3R.js → chunk-GYM54GKM.js} +1 -1
  13. package/dist/chunk-GYM54GKM.js.map +1 -0
  14. package/dist/{chunk-VYCTL62C.js → chunk-GZQSWAKD.js} +1 -1
  15. package/dist/chunk-GZQSWAKD.js.map +1 -0
  16. package/dist/{chunk-CREM7YRK.js → chunk-LEBDXYMA.js} +2 -2
  17. package/dist/{chunk-YVH2PH4X.js → chunk-MXV5O25O.js} +2 -2
  18. package/dist/{chunk-2UXZUCEZ.js → chunk-ZNC44QEX.js} +77 -7
  19. package/dist/chunk-ZNC44QEX.js.map +1 -0
  20. package/dist/codex-realtime-controller.d.ts +13 -0
  21. package/dist/codex-realtime-controller.js +3 -1
  22. package/dist/codex-realtime-v3-wire.d.ts +3 -2
  23. package/dist/codex-realtime.d.ts +4 -0
  24. package/dist/core.js +4 -4
  25. package/dist/document-authority.js +3 -3
  26. package/dist/editable-artifacts.js +1 -1
  27. package/dist/index.d.ts +3 -2
  28. package/dist/index.js +55 -18
  29. package/dist/index.js.map +1 -1
  30. package/dist/realtime.d.ts +1 -1
  31. package/dist/realtime.js +248 -2
  32. package/dist/realtime.js.map +1 -1
  33. package/dist/session-proxy-client.d.ts +7 -3
  34. package/dist/session-proxy.d.ts +9 -1
  35. package/dist/session-proxy.js +2 -2
  36. package/dist/site.js +3 -3
  37. package/dist/transcription.d.ts +1 -1
  38. package/dist/types.d.ts +30 -8
  39. package/package.json +3 -3
  40. package/src/azure-live-transport.ts +286 -0
  41. package/src/codex-realtime-controller.ts +95 -2
  42. package/src/codex-realtime-v3-wire.ts +4 -3
  43. package/src/codex-realtime-v3.ts +11 -2
  44. package/src/codex-realtime.ts +9 -1
  45. package/src/index.ts +3 -0
  46. package/src/realtime.ts +15 -6
  47. package/src/session-proxy-client.ts +7 -3
  48. package/src/session-proxy.ts +137 -4
  49. package/src/transcription.ts +3 -0
  50. package/src/types.ts +34 -5
  51. package/dist/chunk-2UXZUCEZ.js.map +0 -1
  52. package/dist/chunk-CNSPJYF6.js.map +0 -1
  53. package/dist/chunk-IB6SUE3R.js.map +0 -1
  54. package/dist/chunk-VYCTL62C.js.map +0 -1
  55. /package/dist/{chunk-RSKO3CMZ.js.map → chunk-BVIIRSJY.js.map} +0 -0
  56. /package/dist/{chunk-G5NZGPTB.js.map → chunk-CA2T7QT4.js.map} +0 -0
  57. /package/dist/{chunk-ZBICMU4Z.js.map → chunk-D534PIXF.js.map} +0 -0
  58. /package/dist/{chunk-CREM7YRK.js.map → chunk-LEBDXYMA.js.map} +0 -0
  59. /package/dist/{chunk-YVH2PH4X.js.map → chunk-MXV5O25O.js.map} +0 -0
package/README.md CHANGED
@@ -188,7 +188,11 @@ and, unless `modelSelection: false`, the user's explicit model choices, so it
188
188
  needs the `createSession` hook. The hook sees them as input; the proxy adds the
189
189
  files and applies those choices to the request the hook returns. Voice input
190
190
  (`POST .../transcriptions`) is forwarded as the resolved user unless
191
- `voiceInput: false`.
191
+ `voiceInput: false`. The client config the proxy serves reports what it can do:
192
+ `sessionCreation` (a `createSession` hook exists), `archive`, and `artifacts`
193
+ (`false` unless `artifacts: true`). The stock UI hides "New chat" and
194
+ "Archive" when they are off, shows Site previews as unavailable without a
195
+ request, and shows the composer microphone only when `voiceInput.available`.
192
196
 
193
197
  `listSessionPage` includes personal pinned details by default. A caller with a
194
198
  separate `pinsOnly: true` read can pass `includePinned: false` on ordinary pages
@@ -209,8 +213,14 @@ workspace. Only the native routes `OpenGeniProvider` and the conversation use
209
213
  are served: client config; workspace read, model catalog, live control stream,
210
214
  and workspace Resume; session read/rename, events (list and SSE with
211
215
  `Last-Event-ID` resume), send/steer/approval/human-input, queue, composer
212
- draft, pause/resume; and, unless `files: false`, attachment upload and download
213
- URLs. Every other route or method is a 404 (cancel and workspace Pause are
216
+ draft, pause/resume, and the session goal (read; pause/resume, forwarding only
217
+ `{ status: "paused" | "active" }`; and clear, the proxy's only `DELETE`); and, unless `files: false`, attachment upload and download
218
+ URLs plus the media the session produced (generated images and video,
219
+ published files, and browser or computer screenshots). Workspace-level
220
+ artifact reads (`artifacts/:id/content` with `Range`, `artifacts/:id/playback-source`)
221
+ must name their session in `x-opengeni-session-id`; the proxy runs
222
+ `authorizeSession` and forwards only an artifact OpenGeni proves that session
223
+ produced. Every other route or method is a 404 (cancel and workspace Pause are
214
224
  refused); unknown query parameters on served reads pass through. Browser session creation is disabled
215
225
  unless you supply `createSession`; the browser may then send only
216
226
  `initialMessage` and `idempotencyKey`, and your hook returns the full request
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  createSessionProxyHandler
3
- } from "../chunk-CNSPJYF6.js";
3
+ } from "../chunk-FYQAMXDW.js";
4
4
  import "../chunk-UM4ZXXJR.js";
5
5
  import "../chunk-U6CV2SXO.js";
6
6
  import "../chunk-APXVSSSY.js";
7
- import "../chunk-IB6SUE3R.js";
7
+ import "../chunk-GYM54GKM.js";
8
8
  import "../chunk-V6GIY62B.js";
9
9
 
10
10
  // src/adapters/next.ts
package/dist/artifacts.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  OpenGeniClient
3
- } from "./chunk-YVH2PH4X.js";
4
- import "./chunk-G5NZGPTB.js";
5
- import "./chunk-RSKO3CMZ.js";
3
+ } from "./chunk-MXV5O25O.js";
4
+ import "./chunk-CA2T7QT4.js";
5
+ import "./chunk-BVIIRSJY.js";
6
6
  import "./chunk-VPVMLM7Q.js";
7
7
  import "./chunk-APXVSSSY.js";
8
- import "./chunk-IB6SUE3R.js";
8
+ import "./chunk-GYM54GKM.js";
9
9
  import "./chunk-NC57YMUO.js";
10
10
  import "./chunk-V6GIY62B.js";
11
11
  export {
@@ -0,0 +1,32 @@
1
+ import { type StartCodexRealtimeWebrtcOptions } from "./codex-realtime.js";
2
+ import type { RealtimeControllerTransportStarter } from "./codex-realtime-controller.js";
3
+ /** Azure Live has timed transcript fragments, not provider-finalized turns. */
4
+ export declare class AzureLiveDataChannel extends EventTarget {
5
+ private readonly raw;
6
+ private readonly drainTimeoutMs;
7
+ private pending;
8
+ private timer;
9
+ private ordinal;
10
+ private readonly prefix;
11
+ private closed;
12
+ private closeSent;
13
+ private providerClosed;
14
+ private readonly delegations;
15
+ private userSinceDelegation;
16
+ private draining;
17
+ private finishDrain;
18
+ private readonly onOpen;
19
+ private readonly onClose;
20
+ private readonly onError;
21
+ private readonly onMessage;
22
+ constructor(raw: RTCDataChannel, drainTimeoutMs?: number);
23
+ get readyState(): RTCDataChannelState;
24
+ asRtcDataChannel(): RTCDataChannel;
25
+ private emit;
26
+ private flush;
27
+ private receive;
28
+ send(payload: string): void;
29
+ drain(): Promise<void>;
30
+ close(): void;
31
+ }
32
+ export declare function createAzureLiveTransportStarter(options?: Pick<StartCodexRealtimeWebrtcOptions, "remoteAudio" | "createPeerConnection">): RealtimeControllerTransportStarter;
package/dist/browser.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveWorkspaceVoiceInputEnabled
3
- } from "./chunk-VYCTL62C.js";
3
+ } from "./chunk-GZQSWAKD.js";
4
4
  import {
5
5
  OpenGeniToolCallError,
6
6
  OpenGeniToolReapprovalRequiredError,
@@ -8,13 +8,13 @@ import {
8
8
  } from "./chunk-4SMEOV3P.js";
9
9
  import {
10
10
  OpenGeniClient
11
- } from "./chunk-RSKO3CMZ.js";
11
+ } from "./chunk-BVIIRSJY.js";
12
12
  import "./chunk-VPVMLM7Q.js";
13
13
  import "./chunk-APXVSSSY.js";
14
14
  import {
15
15
  OPENGENI_API_CONTRACT_HEADER,
16
16
  OPENGENI_API_CONTRACT_REVISION
17
- } from "./chunk-IB6SUE3R.js";
17
+ } from "./chunk-GYM54GKM.js";
18
18
  import "./chunk-NC57YMUO.js";
19
19
  import {
20
20
  OpenGeniAllowanceExhaustedError,
@@ -11,18 +11,18 @@ import {
11
11
  EMPTY_FINAL_REPLY_NOTICE,
12
12
  OpenGeniEmbeddingClient,
13
13
  turnCompletedWithEmptyFinalReply
14
- } from "../chunk-ZBICMU4Z.js";
15
- import "../chunk-YVH2PH4X.js";
16
- import "../chunk-G5NZGPTB.js";
14
+ } from "../chunk-D534PIXF.js";
15
+ import "../chunk-MXV5O25O.js";
16
+ import "../chunk-CA2T7QT4.js";
17
17
  import {
18
18
  chatDefaults
19
19
  } from "../chunk-UM4ZXXJR.js";
20
- import "../chunk-RSKO3CMZ.js";
20
+ import "../chunk-BVIIRSJY.js";
21
21
  import "../chunk-VPVMLM7Q.js";
22
22
  import {
23
23
  parseSseStream
24
24
  } from "../chunk-APXVSSSY.js";
25
- import "../chunk-IB6SUE3R.js";
25
+ import "../chunk-GYM54GKM.js";
26
26
  import "../chunk-NC57YMUO.js";
27
27
  import {
28
28
  OpenGeniApiError,
@@ -15,7 +15,7 @@ import {
15
15
  OPENGENI_API_CONTRACT_REVISION,
16
16
  OPENGENI_CORRELATION_HEADER,
17
17
  RETAINED_OUTPUT_MAX_PAGE_BYTES
18
- } from "./chunk-IB6SUE3R.js";
18
+ } from "./chunk-GYM54GKM.js";
19
19
  import {
20
20
  OpenGeniInteractionClient,
21
21
  decodeComputerFrameMetadataHeader,
@@ -6840,4 +6840,4 @@ export {
6840
6840
  parseMediaGenerationResult,
6841
6841
  OpenGeniClient
6842
6842
  };
6843
- //# sourceMappingURL=chunk-RSKO3CMZ.js.map
6843
+ //# sourceMappingURL=chunk-BVIIRSJY.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  OpenGeniClient
3
- } from "./chunk-RSKO3CMZ.js";
3
+ } from "./chunk-BVIIRSJY.js";
4
4
 
5
5
  // src/document-authority-client.ts
6
6
  var OpenGeniDocumentAuthorityClient = class extends OpenGeniClient {
@@ -147,4 +147,4 @@ var OpenGeniDocumentAuthorityClient = class extends OpenGeniClient {
147
147
  export {
148
148
  OpenGeniDocumentAuthorityClient
149
149
  };
150
- //# sourceMappingURL=chunk-G5NZGPTB.js.map
150
+ //# sourceMappingURL=chunk-CA2T7QT4.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  OpenGeniClient
3
- } from "./chunk-YVH2PH4X.js";
3
+ } from "./chunk-MXV5O25O.js";
4
4
 
5
5
  // src/embedding-client.ts
6
6
  function hasStaticHeader(options, names) {
@@ -337,4 +337,4 @@ export {
337
337
  EMPTY_FINAL_REPLY_NOTICE,
338
338
  turnCompletedWithEmptyFinalReply
339
339
  };
340
- //# sourceMappingURL=chunk-ZBICMU4Z.js.map
340
+ //# sourceMappingURL=chunk-D534PIXF.js.map
@@ -11,7 +11,7 @@ import {
11
11
  import {
12
12
  OPENGENI_API_CONTRACT_HEADER,
13
13
  OPENGENI_API_CONTRACT_REVISION
14
- } from "./chunk-IB6SUE3R.js";
14
+ } from "./chunk-GYM54GKM.js";
15
15
  import {
16
16
  OpenGeniApiError,
17
17
  OpenGeniSetupError
@@ -336,10 +336,10 @@ function createSessionProxyHandler(target, options) {
336
336
  return async (request) => {
337
337
  try {
338
338
  const method = request.method;
339
- if (!["GET", "POST", "PUT", "PATCH"].includes(method)) {
339
+ if (!PROXY_METHODS.includes(method)) {
340
340
  return new Response(null, {
341
341
  status: 405,
342
- headers: { Allow: "GET, POST, PUT, PATCH" }
342
+ headers: { Allow: PROXY_METHODS.join(", ") }
343
343
  });
344
344
  }
345
345
  const resolved = await options.resolve(request);
@@ -501,7 +501,12 @@ function createSessionProxyHandler(target, options) {
501
501
  // reads it here instead of knowing any Opengeni id.
502
502
  workspaceId,
503
503
  sandboxFiles: sandboxFilesEnabled,
504
- ...artifacts ? { artifacts } : {},
504
+ // Stock UIs show Site previews and the artifact viewer only when
505
+ // this proxy serves them; `false` keeps them from failing on click.
506
+ artifacts: artifacts ?? false,
507
+ // Whether the stock "New chat" and "Archive" actions can succeed.
508
+ sessionCreation: options.createSession !== void 0,
509
+ archive: archiveEnabled,
505
510
  // Explicit true also tells stock UIs to offer end users the model picker.
506
511
  ...modelSelection ? options.modelSelection === true ? { modelSelection: true } : {} : { modelSelection: false }
507
512
  });
@@ -562,6 +567,45 @@ function createSessionProxyHandler(target, options) {
562
567
  }
563
568
  return errorJson(404, "route_not_allowed", "Not found.");
564
569
  }
570
+ if (area === "artifacts") {
571
+ const [artifactId, ...artifactOp] = tail;
572
+ const route2 = `${method} ${artifactOp.join("/")}`;
573
+ if (!filesEnabled || !artifactId || !SEGMENT.test(artifactId) || route2 !== "GET content" && route2 !== "POST playback-source") {
574
+ return errorJson(404, "route_not_allowed", "Not found.");
575
+ }
576
+ const sessionId2 = request.headers.get(SESSION_SCOPE_HEADER)?.trim() ?? "";
577
+ if (!SEGMENT.test(sessionId2)) {
578
+ reject(400, "session_scope_required", "Artifact reads must name their session.");
579
+ }
580
+ if (options.authorizeSession && !await options.authorizeSession(sessionId2, context)) {
581
+ return errorJson(404, "session_not_found", "Session not found.");
582
+ }
583
+ await getSessionProxyArtifactAssociation(
584
+ client,
585
+ workspaceId,
586
+ sessionId2,
587
+ "retained",
588
+ artifactId,
589
+ call
590
+ );
591
+ if (route2 === "POST playback-source") {
592
+ return json(
593
+ await client.requestJson(
594
+ "POST",
595
+ `${base}/artifacts/${artifactId}/playback-source`,
596
+ void 0,
597
+ {},
598
+ call
599
+ )
600
+ );
601
+ }
602
+ return retainedContent(
603
+ await client.getRetainedArtifactContent(workspaceId, artifactId, {
604
+ ...retainedRange(request),
605
+ signal: request.signal
606
+ })
607
+ );
608
+ }
565
609
  if (area === "transcriptions" && tail.length === 0 && method === "POST") {
566
610
  if (!voiceInputEnabled) return errorJson(404, "route_not_allowed", "Not found.");
567
611
  return json(await client.transcribeAudio(workspaceId, await transcriptionInput(request)));
@@ -765,6 +809,22 @@ function createSessionProxyHandler(target, options) {
765
809
  }
766
810
  case "GET human-input-requests":
767
811
  return await read(`${session}/human-input-requests`);
812
+ case "GET goal":
813
+ return await read(`${session}/goal`);
814
+ case "PATCH goal": {
815
+ const status = body?.status;
816
+ if (status !== "paused" && status !== "active" || Object.keys(body ?? {}).some((key) => key !== "status" && key !== "rationale")) {
817
+ reject(
818
+ 403,
819
+ "goal_update_not_allowed",
820
+ "Only { status: paused | active } is available."
821
+ );
822
+ }
823
+ return json(await client.requestJson("PATCH", `${session}/goal`, { status }));
824
+ }
825
+ case "DELETE goal":
826
+ await client.deleteGoal(workspaceId, sessionId);
827
+ return new Response(null, { status: 204 });
768
828
  case "POST fs/read":
769
829
  case "POST fs/read-workspace": {
770
830
  if (!sandboxFilesEnabled) return errorJson(404, "route_not_allowed", "Not found.");
@@ -773,6 +833,19 @@ function createSessionProxyHandler(target, options) {
773
833
  );
774
834
  }
775
835
  }
836
+ if (op[0] === "artifacts" && (op.length === 2 || op[2] === "content") && method === "GET") {
837
+ if (!filesEnabled || op.length > 3) {
838
+ return errorJson(404, "route_not_allowed", "Not found.");
839
+ }
840
+ await client.getSession(workspaceId, sessionId, call);
841
+ if (op.length === 2) return await read(`${session}/artifacts/${op[1]}`);
842
+ return retainedContent(
843
+ await client.getSessionRetainedArtifactContent(workspaceId, sessionId, op[1], {
844
+ ...retainedRange(request),
845
+ signal: request.signal
846
+ })
847
+ );
848
+ }
776
849
  if (op.length === 2 && op[0] === "human-input-requests" && method === "GET") {
777
850
  return await read(`${session}/human-input-requests/${op[1]}`);
778
851
  }
@@ -785,6 +858,7 @@ function createSessionProxyHandler(target, options) {
785
858
  }
786
859
  };
787
860
  }
861
+ var PROXY_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE"];
788
862
  var UPLOAD_FIELDS = ["scope", "filename", "contentType", "sizeBytes", "sha256"];
789
863
  function normalizeToolServer(toolServer) {
790
864
  const configured = toolServer.url ?? globalThis.process?.env?.OPENGENI_TOOL_SERVER_URL;
@@ -976,6 +1050,31 @@ async function legacyViewerGrant(client, workspaceId) {
976
1050
  if (!grant) reject(403, "workspace_not_allowed", "This workspace is not available.");
977
1051
  return grant;
978
1052
  }
1053
+ function retainedRange(request) {
1054
+ const range = request.headers.get("range");
1055
+ if (range === null) return {};
1056
+ if (range.length > 128 || /[^\x20-\x7e]/.test(range)) {
1057
+ reject(400, "invalid_range", "Range must be at most 128 printable ASCII bytes.");
1058
+ }
1059
+ return { range };
1060
+ }
1061
+ function retainedContent(content) {
1062
+ return new Response(content.bytes, {
1063
+ status: content.status,
1064
+ headers: {
1065
+ "Content-Type": content.contentType,
1066
+ "Content-Length": String(content.contentLength),
1067
+ ...content.contentRange ? { "Content-Range": content.contentRange } : {},
1068
+ "Accept-Ranges": "bytes",
1069
+ "Cache-Control": "private, no-store",
1070
+ // Bytes for the conversation's own reader; never rendered on this origin.
1071
+ "Content-Security-Policy": "sandbox",
1072
+ "Content-Disposition": "attachment",
1073
+ "Cross-Origin-Resource-Policy": "same-origin",
1074
+ "X-Content-Type-Options": "nosniff"
1075
+ }
1076
+ });
1077
+ }
979
1078
  function sandboxRead(body) {
980
1079
  const path = body?.path;
981
1080
  const encoding = body?.encoding;
@@ -1365,4 +1464,4 @@ export {
1365
1464
  createSessionProxyHandler,
1366
1465
  artifactViewerCapability
1367
1466
  };
1368
- //# sourceMappingURL=chunk-CNSPJYF6.js.map
1467
+ //# sourceMappingURL=chunk-FYQAMXDW.js.map