@opengeni/sdk 7.4.0 → 7.5.0-canary.36927100590001
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 +153 -0
- package/dist/adapters/next.js +5 -4
- package/dist/adapters/next.js.map +1 -1
- 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/artifacts.js +7 -7
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +10 -6
- package/dist/chat/fold.d.ts +1 -0
- package/dist/chat/index.d.ts +2 -0
- package/dist/chat/index.js +104 -82
- package/dist/chat/index.js.map +1 -1
- package/dist/chat/opengeni.d.ts +10 -3
- package/dist/chat/types.d.ts +27 -3
- package/dist/chats.d.ts +8 -0
- package/dist/{chunk-HZH5DJNN.js → chunk-472T6U2J.js} +4 -4
- package/dist/{chunk-GT2I4X7R.js → chunk-5VTRBY4Z.js} +40 -5
- package/dist/chunk-5VTRBY4Z.js.map +1 -0
- package/dist/{chunk-BX5ETUM7.js → chunk-7GR6TOEV.js} +2 -2
- package/dist/{chunk-MV2PNVU4.js → chunk-7WJL2ZWY.js} +6 -1
- package/dist/chunk-7WJL2ZWY.js.map +1 -0
- package/dist/{chunk-7HIA2AI3.js → chunk-ASMIDUEA.js} +2 -2
- package/dist/{chunk-FLOL2IES.js → chunk-CKOUDEOS.js} +2 -2
- package/dist/{chunk-VF2IW4M5.js → chunk-CLWOTPX5.js} +100 -3
- package/dist/chunk-CLWOTPX5.js.map +1 -0
- package/dist/{chunk-OO5LPTO7.js → chunk-LQCTDGG6.js} +52 -1
- package/dist/chunk-LQCTDGG6.js.map +1 -0
- package/dist/chunk-N2LADGI4.js +124 -0
- package/dist/chunk-N2LADGI4.js.map +1 -0
- package/dist/{chunk-HGGK2BW2.js → chunk-PH56JDUM.js} +2 -2
- package/dist/{chunk-A73QXCBW.js → chunk-U3RYSV5N.js} +430 -17
- package/dist/chunk-U3RYSV5N.js.map +1 -0
- package/dist/{chunk-6NEPJ7NC.js → chunk-ULUWGJBH.js} +2 -2
- package/dist/chunk-UM4ZXXJR.js +9 -0
- package/dist/chunk-UM4ZXXJR.js.map +1 -0
- package/dist/{chunk-FMLDFJ2Q.js → chunk-YTJK64EV.js} +2 -2
- package/dist/{chunk-QSCQUITU.js → chunk-ZKKWTOIZ.js} +120 -20
- package/dist/chunk-ZKKWTOIZ.js.map +1 -0
- package/dist/client.d.ts +44 -3
- package/dist/codex-realtime-controller.js +2 -2
- package/dist/core.d.ts +1 -1
- package/dist/core.js +9 -7
- package/dist/document-authority.js +6 -6
- package/dist/editable-artifacts.js +1 -1
- package/dist/embedding-client.d.ts +39 -0
- package/dist/errors.d.ts +17 -0
- package/dist/index.d.ts +11 -7
- package/dist/index.js +50 -141
- package/dist/index.js.map +1 -1
- package/dist/interaction.js +2 -2
- package/dist/message-links.d.ts +5 -0
- package/dist/model-context.d.ts +9 -1
- package/dist/realtime.js +2 -2
- 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-proxy-client.d.ts +24 -0
- package/dist/session-proxy.d.ts +53 -2
- package/dist/session-proxy.js +23 -0
- package/dist/site-browser-runtime.gen.d.ts +1 -1
- package/dist/site-document.js +1 -1
- package/dist/site-document.js.map +1 -1
- package/dist/site.js +7 -7
- package/dist/tenant-workspaces.d.ts +33 -0
- package/dist/tenant-workspaces.js +8 -0
- package/dist/tenant-workspaces.js.map +1 -0
- package/dist/{tools-FSTY4FAY.js → tools-IWJHYNZE.js} +3 -3
- package/dist/tools-IWJHYNZE.js.map +1 -0
- package/dist/types.d.ts +303 -12
- 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-integrations.d.ts +22 -5
- package/dist/workspace-integrations.js +11 -1
- package/package.json +23 -3
- package/src/allowance-refusal.ts +5 -0
- package/src/browser.ts +2 -0
- package/src/chat/fold.ts +12 -0
- package/src/chat/index.ts +2 -0
- package/src/chat/opengeni.ts +114 -34
- package/src/chat/types.ts +27 -2
- package/src/chats.ts +16 -0
- package/src/client.ts +165 -15
- package/src/core.ts +1 -0
- package/src/embedding-client.ts +130 -0
- package/src/errors.ts +75 -0
- package/src/index.ts +68 -1
- package/src/message-links.ts +6 -0
- package/src/model-context.ts +27 -1
- package/src/session-history-import.ts +84 -0
- package/src/session-proxy-client.ts +64 -0
- package/src/session-proxy.ts +360 -17
- package/src/site-browser-runtime.gen.ts +1 -1
- package/src/tenant-workspaces.ts +120 -0
- package/src/types.ts +343 -10
- package/src/usage-allowances.ts +189 -0
- package/src/workspace-integrations.ts +76 -4
- package/dist/chunk-A73QXCBW.js.map +0 -1
- package/dist/chunk-GT2I4X7R.js.map +0 -1
- package/dist/chunk-MV2PNVU4.js.map +0 -1
- package/dist/chunk-OO5LPTO7.js.map +0 -1
- package/dist/chunk-QSCQUITU.js.map +0 -1
- package/dist/chunk-VF2IW4M5.js.map +0 -1
- /package/dist/{chunk-HZH5DJNN.js.map → chunk-472T6U2J.js.map} +0 -0
- /package/dist/{chunk-BX5ETUM7.js.map → chunk-7GR6TOEV.js.map} +0 -0
- /package/dist/{chunk-7HIA2AI3.js.map → chunk-ASMIDUEA.js.map} +0 -0
- /package/dist/{chunk-FLOL2IES.js.map → chunk-CKOUDEOS.js.map} +0 -0
- /package/dist/{chunk-HGGK2BW2.js.map → chunk-PH56JDUM.js.map} +0 -0
- /package/dist/{chunk-6NEPJ7NC.js.map → chunk-ULUWGJBH.js.map} +0 -0
- /package/dist/{chunk-FMLDFJ2Q.js.map → chunk-YTJK64EV.js.map} +0 -0
- /package/dist/{tools-FSTY4FAY.js.map → session-proxy.js.map} +0 -0
package/README.md
CHANGED
|
@@ -25,6 +25,31 @@ bearer design, but an organization API key belongs on the product server.
|
|
|
25
25
|
Browser cookies are accepted cross-origin only from operator-configured trusted
|
|
26
26
|
origins; arbitrary embedding origins never receive credentialed CORS responses.
|
|
27
27
|
|
|
28
|
+
## Allowance lifecycle recovery
|
|
29
|
+
|
|
30
|
+
`getWorkspaceAllowance(workspaceId)` still returns nullable configuration.
|
|
31
|
+
Use `getWorkspaceAllowanceState(workspaceId)` when you also need the lifecycle
|
|
32
|
+
version: `{ version: 0, config: null }` means never configured, while a positive
|
|
33
|
+
version with null configuration means cleared. Recreation uses that exact
|
|
34
|
+
version as `expectedVersion`.
|
|
35
|
+
|
|
36
|
+
`clearWorkspaceAllowance(workspaceId, { expectedVersion, operationId })` returns
|
|
37
|
+
`{ version }`. The optional operation ID makes a lost response recoverable:
|
|
38
|
+
reuse the same actor, operation ID and exact request. Replay rechecks current
|
|
39
|
+
authority and returns 409 after any later allowance lifecycle change. On 409,
|
|
40
|
+
read the current state and decide whether a new operation is intended; never
|
|
41
|
+
guess a CAS version. The SDK does not automatically retry mutations.
|
|
42
|
+
|
|
43
|
+
The same reads and administration are free functions on the
|
|
44
|
+
`@opengeni/sdk/usage-allowances` subpath for browser code that only has the
|
|
45
|
+
narrow `OpenGeniBrowserClient` (`getMyUsage(client, workspaceId)`,
|
|
46
|
+
`getAllUsage`, `setMemberAllowance`, ...); they call the same routes as the root methods.
|
|
47
|
+
|
|
48
|
+
State reads require the same budget-read authority as configuration reads.
|
|
49
|
+
Full usage additionally requires target workspace access; organization budget
|
|
50
|
+
authority alone does not expose the member roster. Agents cannot read or
|
|
51
|
+
change allowances.
|
|
52
|
+
|
|
28
53
|
## Embed the conversation (default)
|
|
29
54
|
|
|
30
55
|
The default product integration is the full OpenGeni conversation:
|
|
@@ -71,6 +96,48 @@ const client = new OpenGeniClient({ baseUrl: "/api/opengeni" });
|
|
|
71
96
|
</OpenGeniProvider>;
|
|
72
97
|
```
|
|
73
98
|
|
|
99
|
+
The proxy and `@opengeni/sdk/chat` facade accept `chats`. The proxy defaults to
|
|
100
|
+
`"private"`; the facade does too when a `user` is present. Without a user and with
|
|
101
|
+
`chats` omitted, the facade keeps workspace visibility, session-only agent reach
|
|
102
|
+
and Knowledge authoring off. Explicit `"private"` requires an authenticated user.
|
|
103
|
+
Private chats use private visibility, session-only agent reach and personal
|
|
104
|
+
Knowledge; `"shared"` uses workspace visibility, agent reach and Knowledge.
|
|
105
|
+
The API wire values are `visibility: "private" | "workspace"`; stored visibility
|
|
106
|
+
is `user_private | workspace_shared`. Explicit hook/create fields override defaults.
|
|
107
|
+
|
|
108
|
+
For `"isolated"`, pass the facade and return `{ tenant, user }` from `resolve`.
|
|
109
|
+
`og.workspaceIdFor({ tenant, user }, { isolation: "user" })` provisions a separate
|
|
110
|
+
workspace and that user's external membership. It uses stable onboarding keys,
|
|
111
|
+
so retries do not restore revoked access. Other modes need explicit onboarding.
|
|
112
|
+
The standalone resolver is on the server-only `@opengeni/sdk/tenant-workspaces`
|
|
113
|
+
subpath. Keep tenant and user values host-authenticated.
|
|
114
|
+
|
|
115
|
+
Isolated members get only workspace read, session create/read/control (including
|
|
116
|
+
sending messages), file upload/read, and `mcp_servers:attach` for host-provided
|
|
117
|
+
per-session servers. No admin permissions are included. Pass `memberPermissions`
|
|
118
|
+
to the `OpenGeni` constructor or `createWorkspaceIdResolver` options to replace
|
|
119
|
+
that list, for example to disable file uploads or MCP attachment. The organization
|
|
120
|
+
key must also permit each operation. This is initial onboarding, not a membership
|
|
121
|
+
update: changing the option does not update existing grants or restore revoked access.
|
|
122
|
+
Keep MCP URLs and credentials in the server's `createSession` hook; the browser
|
|
123
|
+
cannot choose them through the proxy.
|
|
124
|
+
An existing onboarding conflict returns the workspace address without retrying
|
|
125
|
+
or changing the grant. The address is not authorization: later `asUser` calls
|
|
126
|
+
still enforce current permissions. Existing isolated users need an explicit
|
|
127
|
+
`updateExternalWorkspaceMember` to gain newly added permissions such as MCP attachment.
|
|
128
|
+
|
|
129
|
+
The facade also accepts `agent` (identity, capabilities, instructions, renderer)
|
|
130
|
+
and defaults its renderer to `"markdown"` when the server admits agent configuration.
|
|
131
|
+
Only an implicit renderer retries once without `agent` on `422 agent_config_not_enabled`,
|
|
132
|
+
and that refusal is cached per facade instance. This avoids a bootstrap request
|
|
133
|
+
and supports older servers that cannot advertise admission. Explicit agent settings
|
|
134
|
+
are never stripped: the 422 names `OPENGENI_AGENT_CONFIG_ADMISSION_ENABLED` for the
|
|
135
|
+
deployment operator. The private default with a user now turns personal Knowledge
|
|
136
|
+
on; pass `memory: false` to keep authoring off.
|
|
137
|
+
Missing organization private-session enablement raises `OpenGeniSetupError`,
|
|
138
|
+
with owner/admin API, SDK and web-app instructions; the proxy preserves that
|
|
139
|
+
actionable error for browser clients.
|
|
140
|
+
|
|
74
141
|
Framework adapters are thin wrappers over the same web-standard handler (they
|
|
75
142
|
also accept `createChatHandler` or any `(Request) => Promise<Response>`):
|
|
76
143
|
|
|
@@ -547,6 +614,83 @@ personal grant, Variable Set, Sandbox Environment, MCP server configuration, pro
|
|
|
547
614
|
identity, pin, or workflow. Destination visibility and acknowledgement are
|
|
548
615
|
idempotency-bound.
|
|
549
616
|
|
|
617
|
+
## Archived session history import (server only)
|
|
618
|
+
|
|
619
|
+
Use `@opengeni/sdk/session-history-import` to migrate historical conversations
|
|
620
|
+
into read-only archives. These functions take `client` first, use its ordinary
|
|
621
|
+
`requestJson` transport, and are not eager client methods or root helper exports:
|
|
622
|
+
|
|
623
|
+
Create requires `sessions:create`; append requires `sessions:control` and the same
|
|
624
|
+
authenticated importer. With `asUser`, the user's permissions apply rather than
|
|
625
|
+
the organization key's permissions.
|
|
626
|
+
|
|
627
|
+
```ts
|
|
628
|
+
import { OpenGeniClient } from "@opengeni/sdk";
|
|
629
|
+
import {
|
|
630
|
+
importArchivedSession,
|
|
631
|
+
appendArchivedSessionEvents,
|
|
632
|
+
} from "@opengeni/sdk/session-history-import";
|
|
633
|
+
|
|
634
|
+
const og = new OpenGeniClient({
|
|
635
|
+
baseUrl: process.env.OPENGENI_API_BASE_URL!,
|
|
636
|
+
apiKey: process.env.OPENGENI_API_KEY!,
|
|
637
|
+
});
|
|
638
|
+
// Existing tenant mapping + explicitly onboarded original creator.
|
|
639
|
+
const actor = og.asUser(originalExternalUserId, { source });
|
|
640
|
+
const imported = await importArchivedSession(actor, workspaceId, {
|
|
641
|
+
importId: "embedded:thread-42", // Stable; persist the exact request before sending.
|
|
642
|
+
title: "Original conversation",
|
|
643
|
+
createdAt: "2025-04-01T09:30:00Z",
|
|
644
|
+
visibility: "user_private",
|
|
645
|
+
});
|
|
646
|
+
const appended = await appendArchivedSessionEvents(actor, workspaceId, imported.importId, {
|
|
647
|
+
batchId: "thread-42:batch-0001", // Stable; also persist this exact body first.
|
|
648
|
+
offset: imported.nextOffset,
|
|
649
|
+
events: [{
|
|
650
|
+
type: "agent.message.completed",
|
|
651
|
+
createdAt: "2025-04-01T09:31:00Z",
|
|
652
|
+
payload: { text: "Historical answer", channel: "final" },
|
|
653
|
+
}],
|
|
654
|
+
});
|
|
655
|
+
// Persist imported.session.id and appended.nextOffset in the migration ledger.
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
External mapping equivalents take `(client, source, externalId, ...)`:
|
|
659
|
+
`importExternalWorkspaceArchivedSession` and
|
|
660
|
+
`appendExternalWorkspaceArchivedSessionEvents`. These resolve an existing
|
|
661
|
+
mapping; neither import form creates a workspace or grants membership. A bare
|
|
662
|
+
organization key creates a shared, ownerless archive. Use `asUser` for the
|
|
663
|
+
verified creator/owner; private imports require existing private-session
|
|
664
|
+
enablement. Preserve source visibility rather than widening it on failure.
|
|
665
|
+
|
|
666
|
+
The subpath exports `ImportArchivedSessionRequest/Response`,
|
|
667
|
+
`AppendArchivedSessionEventsRequest/Response`, `ArchivedSessionImportEvent` and
|
|
668
|
+
`SessionImportedArchive` types. Requests accept at most 100 events / 1 MiB
|
|
669
|
+
serialized UTF-8 JSON and 256 KiB per event. IDs and titles are bounded to 200
|
|
670
|
+
characters. Import events default to `[]`; append batches must be non-empty.
|
|
671
|
+
Events carry `{ type, createdAt, turnId?, payload }`: a finite supported historical
|
|
672
|
+
type, ISO timestamp, optional UUID/null correlation and JSON-object payload.
|
|
673
|
+
Source timestamps support at most millisecond precision; normalize finer dates
|
|
674
|
+
explicitly and retain originals in the ledger. Negative-zero JSON is rejected.
|
|
675
|
+
|
|
676
|
+
Exact create replay returns `created: false`; exact append replay returns
|
|
677
|
+
`replayed: true`. `offset` is a zero-based imported-event count, not a timeline
|
|
678
|
+
sequence. Retain the exact actor, mapping, IDs, offset and bodies for uncertain
|
|
679
|
+
retries; new batches use the acknowledged `nextOffset`. Changed key reuse or
|
|
680
|
+
an out-of-order new offset returns 409. Helpers propagate `OpenGeniApiError`,
|
|
681
|
+
including `outcomeUnknown`, and do not automatically retry mutations.
|
|
682
|
+
|
|
683
|
+
Import is timeline-only: completed messages, calls/results and goals may be
|
|
684
|
+
historical facts, but no model-facing history, live goal, pending decision or
|
|
685
|
+
execution is restored. `session.importedArchive` has
|
|
686
|
+
`{ importId, importedAt, readOnly: true }`, independent of personal archive state.
|
|
687
|
+
Render through the unchanged `SessionConversation` and session proxy; never
|
|
688
|
+
offer Send or Steer. Continuing an imported archive is unsupported in v1.
|
|
689
|
+
The proxy does not expose import routes. Re-upload files through existing APIs
|
|
690
|
+
and replace references before import; preserve additional source metadata and
|
|
691
|
+
source/destination IDs in the host ledger. See
|
|
692
|
+
[Migrating from embedded OpenGeni](../../docs/product-integration.md#migrating-from-embedded-opengeni).
|
|
693
|
+
|
|
550
694
|
## Connected accounts
|
|
551
695
|
|
|
552
696
|
Authenticated messages use the initiating user's eligible connected accounts.
|
|
@@ -588,6 +732,12 @@ const request = await verifyCredentialProviderRequest({
|
|
|
588
732
|
});
|
|
589
733
|
```
|
|
590
734
|
|
|
735
|
+
To check an endpoint now, `testWorkspaceWebhook(client, workspaceId, webhookId)` sends a
|
|
736
|
+
signed `webhook.test` event (acknowledge it with any 2xx) and
|
|
737
|
+
`testWorkspaceCredentialProvider(client, workspaceId)` sends a request with
|
|
738
|
+
`purpose: "test"`; both come from `@opengeni/sdk/workspace-integrations` and return
|
|
739
|
+
what the endpoint answered, naming returned credentials but never their values.
|
|
740
|
+
|
|
591
741
|
`listWorkspaceSandboxImages` returns the deployment's allowlisted images; set one
|
|
592
742
|
with `updateWorkspaceSettings(workspaceId, { defaultSandboxImage })`.
|
|
593
743
|
|
|
@@ -1062,6 +1212,9 @@ await client.cancelSession(workspaceId, sessionId, {
|
|
|
1062
1212
|
reason: "host record deleted",
|
|
1063
1213
|
clientEventId: crypto.randomUUID(),
|
|
1064
1214
|
});
|
|
1215
|
+
// approvalId is `approvals[].id` from the latest `session.requiresAction`
|
|
1216
|
+
// event (type SessionApprovalRequest: { id, name, arguments }); it is the
|
|
1217
|
+
// pending tool call id, not the event id.
|
|
1065
1218
|
await client.sendApprovalDecision(workspaceId, sessionId, { approvalId, decision: "approve" });
|
|
1066
1219
|
```
|
|
1067
1220
|
|
package/dist/adapters/next.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createSessionProxyHandler
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-U3RYSV5N.js";
|
|
4
|
+
import "../chunk-UM4ZXXJR.js";
|
|
5
|
+
import "../chunk-7GR6TOEV.js";
|
|
6
|
+
import "../chunk-7WJL2ZWY.js";
|
|
7
|
+
import "../chunk-LQCTDGG6.js";
|
|
7
8
|
|
|
8
9
|
// src/adapters/next.ts
|
|
9
10
|
function toNextRouteHandlers(handler) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/adapters/next.ts"],"sourcesContent":["import { createSessionProxyHandler, type SessionProxyHandlerOptions } from \"../session-proxy\";\n\n/** Any web-standard handler: `createSessionProxyHandler`, `createChatHandler`, or your own. */\nexport type WebHandler = (request: Request) => Promise<Response>;\n\n/** Route handlers for a Next.js App Router catch-all route. */\nexport type NextRouteHandlers = {\n GET: WebHandler;\n POST: WebHandler;\n PUT: WebHandler;\n PATCH: WebHandler;\n DELETE: WebHandler;\n};\n\n/**\n * Expose a web-standard handler as Next.js App Router route handlers.\n *\n * ```ts\n * // app/api/opengeni/[...path]/route.ts\n * export const dynamic = \"force-dynamic\";\n * export const { GET, POST, PUT, PATCH, DELETE } = toNextRouteHandlers(handler);\n * ```\n *\n * Next passes the full request URL (including any `basePath`), so the proxy's\n * own `/v1/` detection routes it; responses, including SSE, stream as-is.\n */\nexport function toNextRouteHandlers(handler: WebHandler): NextRouteHandlers {\n // Next calls route handlers with (request, context); only the request matters.\n const route: WebHandler = async (request) => await handler(request);\n return { GET: route, POST: route, PUT: route, PATCH: route, DELETE: route };\n}\n\n/**\n * `createSessionProxyHandler` as Next.js App Router route handlers, for\n * `app/<mount>/[...path]/route.ts`.\n */\nexport function createSessionProxyRoute(\n target: Parameters<typeof createSessionProxyHandler>[0],\n options: SessionProxyHandlerOptions,\n): NextRouteHandlers {\n return toNextRouteHandlers(createSessionProxyHandler(target, options));\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/next.ts"],"sourcesContent":["import { createSessionProxyHandler, type SessionProxyHandlerOptions } from \"../session-proxy\";\n\n/** Any web-standard handler: `createSessionProxyHandler`, `createChatHandler`, or your own. */\nexport type WebHandler = (request: Request) => Promise<Response>;\n\n/** Route handlers for a Next.js App Router catch-all route. */\nexport type NextRouteHandlers = {\n GET: WebHandler;\n POST: WebHandler;\n PUT: WebHandler;\n PATCH: WebHandler;\n DELETE: WebHandler;\n};\n\n/**\n * Expose a web-standard handler as Next.js App Router route handlers.\n *\n * ```ts\n * // app/api/opengeni/[...path]/route.ts\n * export const dynamic = \"force-dynamic\";\n * export const { GET, POST, PUT, PATCH, DELETE } = toNextRouteHandlers(handler);\n * ```\n *\n * Next passes the full request URL (including any `basePath`), so the proxy's\n * own `/v1/` detection routes it; responses, including SSE, stream as-is.\n */\nexport function toNextRouteHandlers(handler: WebHandler): NextRouteHandlers {\n // Next calls route handlers with (request, context); only the request matters.\n const route: WebHandler = async (request) => await handler(request);\n return { GET: route, POST: route, PUT: route, PATCH: route, DELETE: route };\n}\n\n/**\n * `createSessionProxyHandler` as Next.js App Router route handlers, for\n * `app/<mount>/[...path]/route.ts`.\n */\nexport function createSessionProxyRoute(\n target: Parameters<typeof createSessionProxyHandler>[0],\n options: SessionProxyHandlerOptions,\n): NextRouteHandlers {\n return toNextRouteHandlers(createSessionProxyHandler(target, options));\n}\n"],"mappings":";;;;;;;;;AA0BO,SAAS,oBAAoB,SAAwC;AAE1E,QAAM,QAAoB,OAAO,YAAY,MAAM,QAAQ,OAAO;AAClE,SAAO,EAAE,KAAK,OAAO,MAAM,OAAO,KAAK,OAAO,OAAO,OAAO,QAAQ,MAAM;AAC5E;AAMO,SAAS,wBACd,QACA,SACmB;AACnB,SAAO,oBAAoB,0BAA0B,QAAQ,OAAO,CAAC;AACvE;","names":[]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// ../contracts/src/allowance-refusal.ts
|
|
2
|
+
var MESSAGE_MAX_UTF8_BYTES = 1024;
|
|
3
|
+
function record(value) {
|
|
4
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
5
|
+
}
|
|
6
|
+
function resetTimestamp(value) {
|
|
7
|
+
if (value === null) return true;
|
|
8
|
+
if (typeof value !== "string" || value.length > 64) return false;
|
|
9
|
+
const parts = /^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])T(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.exec(
|
|
10
|
+
value
|
|
11
|
+
);
|
|
12
|
+
if (!parts || !Number.isFinite(Date.parse(value))) return false;
|
|
13
|
+
const year = Number(parts[1]);
|
|
14
|
+
const month = Number(parts[2]);
|
|
15
|
+
const day = Number(parts[3]);
|
|
16
|
+
const leapYear = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
17
|
+
const days = [31, leapYear ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
18
|
+
return day <= days[month - 1];
|
|
19
|
+
}
|
|
20
|
+
function parseAllowanceExhaustedRefusal(value) {
|
|
21
|
+
const source = record(value);
|
|
22
|
+
if (source?.code !== "allowance_exhausted") return null;
|
|
23
|
+
const fields = record(source.details) ?? source;
|
|
24
|
+
const scope = fields.scope;
|
|
25
|
+
const subjectId = scope === "member" ? fields.subjectId : void 0;
|
|
26
|
+
if (typeof source.message !== "string" || scope !== "workspace" && scope !== "member" || !resetTimestamp(fields.resetsAt) || subjectId !== void 0 && (typeof subjectId !== "string" || subjectId.length === 0 || subjectId.length > 1024 || subjectId.includes("\0"))) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const normalized = source.message.slice(0, MESSAGE_MAX_UTF8_BYTES * 2).replace(/[\u0000-\u001f\u007f]+/g, " ").trim();
|
|
30
|
+
const bytes = new TextEncoder().encode(normalized.slice(0, MESSAGE_MAX_UTF8_BYTES * 2));
|
|
31
|
+
let end = Math.min(bytes.length, MESSAGE_MAX_UTF8_BYTES);
|
|
32
|
+
while (end > 0 && end < bytes.length && (bytes[end] & 192) === 128) end -= 1;
|
|
33
|
+
return {
|
|
34
|
+
code: "allowance_exhausted",
|
|
35
|
+
scope,
|
|
36
|
+
resetsAt: fields.resetsAt,
|
|
37
|
+
...typeof subjectId === "string" ? { subjectId } : {},
|
|
38
|
+
message: new TextDecoder().decode(bytes.slice(0, end)).trim()
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function allowanceExhaustedMessage(refusal) {
|
|
42
|
+
const remedy = refusal.scope === "workspace" ? "The workspace usage allowance is exhausted. An organization administrator or a full-access organization API key can raise the workspace ceiling or add an allowance grant." : "The member usage allowance is exhausted. A workspace administrator or a full-access organization API key can adjust the member ceiling.";
|
|
43
|
+
const reset = refusal.resetsAt === null ? "This allowance has no automatic reset." : `It resets at ${new Date(refusal.resetsAt).toISOString().slice(0, 16).replace("T", " ")} UTC.`;
|
|
44
|
+
return `${remedy} ${reset}`;
|
|
45
|
+
}
|
|
46
|
+
export {
|
|
47
|
+
allowanceExhaustedMessage,
|
|
48
|
+
parseAllowanceExhaustedRefusal
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=allowance-refusal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../contracts/src/allowance-refusal.ts"],"sourcesContent":["import type { AllowanceExhaustedRefusal } from \"./usage-allowances\";\n\nconst MESSAGE_MAX_UTF8_BYTES = 1_024;\n\nfunction record(value: unknown): Record<string, unknown> | null {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\n/** Mirror the canonical offset datetime's calendar/time bounds without loading\n * the schema runtime into synchronous browser/React Native session projection.\n * Contract-parity tests guard this deliberately small, bounded wire leaf.\n */\nfunction resetTimestamp(value: unknown): value is string | null {\n if (value === null) return true;\n if (typeof value !== \"string\" || value.length > 64) return false;\n const parts =\n /^(\\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])T(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|[+-](?:[01]\\d|2[0-3]):[0-5]\\d)$/.exec(\n value,\n );\n if (!parts || !Number.isFinite(Date.parse(value))) return false;\n const year = Number(parts[1]);\n const month = Number(parts[2]);\n const day = Number(parts[3]);\n const leapYear = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);\n const days = [31, leapYear ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n return day <= days[month - 1]!;\n}\n\n/** Select only public refusal fields, including from an API error's details.\n * LimitDecision's allowed:false and transport/SQL diagnostics never cross out.\n */\nexport function parseAllowanceExhaustedRefusal(value: unknown): AllowanceExhaustedRefusal | null {\n const source = record(value);\n if (source?.code !== \"allowance_exhausted\") return null;\n const fields = record(source.details) ?? source;\n const scope = fields.scope;\n const subjectId = scope === \"member\" ? fields.subjectId : undefined;\n if (\n typeof source.message !== \"string\" ||\n (scope !== \"workspace\" && scope !== \"member\") ||\n !resetTimestamp(fields.resetsAt) ||\n (subjectId !== undefined &&\n (typeof subjectId !== \"string\" ||\n subjectId.length === 0 ||\n subjectId.length > 1_024 ||\n subjectId.includes(\"\\0\")))\n ) {\n return null;\n }\n const normalized = source.message\n .slice(0, MESSAGE_MAX_UTF8_BYTES * 2)\n .replace(/[\\u0000-\\u001f\\u007f]+/g, \" \")\n .trim();\n const bytes = new TextEncoder().encode(normalized.slice(0, MESSAGE_MAX_UTF8_BYTES * 2));\n let end = Math.min(bytes.length, MESSAGE_MAX_UTF8_BYTES);\n while (end > 0 && end < bytes.length && (bytes[end]! & 0xc0) === 0x80) end -= 1;\n return {\n code: \"allowance_exhausted\",\n scope,\n resetsAt: fields.resetsAt,\n ...(typeof subjectId === \"string\" ? { subjectId } : {}),\n message: new TextDecoder().decode(bytes.slice(0, end)).trim(),\n };\n}\n\n/** Bounded, fixed remedies: a ceiling is not an exhausted billing source.\n * Never interpolate arbitrary exception prose or a member identifier.\n */\nexport function allowanceExhaustedMessage(refusal: AllowanceExhaustedRefusal): string {\n const remedy =\n refusal.scope === \"workspace\"\n ? \"The workspace usage allowance is exhausted. An organization administrator or a full-access organization API key can raise the workspace ceiling or add an allowance grant.\"\n : \"The member usage allowance is exhausted. A workspace administrator or a full-access organization API key can adjust the member ceiling.\";\n const reset =\n refusal.resetsAt === null\n ? \"This allowance has no automatic reset.\"\n : `It resets at ${new Date(refusal.resetsAt).toISOString().slice(0, 16).replace(\"T\", \" \")} UTC.`;\n return `${remedy} ${reset}`;\n}\n"],"mappings":";AAEA,IAAM,yBAAyB;AAE/B,SAAS,OAAO,OAAgD;AAC9D,SAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IACrE,QACD;AACN;AAMA,SAAS,eAAe,OAAwC;AAC9D,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,OAAO,UAAU,YAAY,MAAM,SAAS,GAAI,QAAO;AAC3D,QAAM,QACJ,sIAAsI;AAAA,IACpI;AAAA,EACF;AACF,MAAI,CAAC,SAAS,CAAC,OAAO,SAAS,KAAK,MAAM,KAAK,CAAC,EAAG,QAAO;AAC1D,QAAM,OAAO,OAAO,MAAM,CAAC,CAAC;AAC5B,QAAM,QAAQ,OAAO,MAAM,CAAC,CAAC;AAC7B,QAAM,MAAM,OAAO,MAAM,CAAC,CAAC;AAC3B,QAAM,WAAW,OAAO,MAAM,MAAM,OAAO,QAAQ,KAAK,OAAO,QAAQ;AACvE,QAAM,OAAO,CAAC,IAAI,WAAW,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE;AAC5E,SAAO,OAAO,KAAK,QAAQ,CAAC;AAC9B;AAKO,SAAS,+BAA+B,OAAkD;AAC/F,QAAM,SAAS,OAAO,KAAK;AAC3B,MAAI,QAAQ,SAAS,sBAAuB,QAAO;AACnD,QAAM,SAAS,OAAO,OAAO,OAAO,KAAK;AACzC,QAAM,QAAQ,OAAO;AACrB,QAAM,YAAY,UAAU,WAAW,OAAO,YAAY;AAC1D,MACE,OAAO,OAAO,YAAY,YACzB,UAAU,eAAe,UAAU,YACpC,CAAC,eAAe,OAAO,QAAQ,KAC9B,cAAc,WACZ,OAAO,cAAc,YACpB,UAAU,WAAW,KACrB,UAAU,SAAS,QACnB,UAAU,SAAS,IAAI,IAC3B;AACA,WAAO;AAAA,EACT;AACA,QAAM,aAAa,OAAO,QACvB,MAAM,GAAG,yBAAyB,CAAC,EACnC,QAAQ,2BAA2B,GAAG,EACtC,KAAK;AACR,QAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,WAAW,MAAM,GAAG,yBAAyB,CAAC,CAAC;AACtF,MAAI,MAAM,KAAK,IAAI,MAAM,QAAQ,sBAAsB;AACvD,SAAO,MAAM,KAAK,MAAM,MAAM,WAAW,MAAM,GAAG,IAAK,SAAU,IAAM,QAAO;AAC9E,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,UAAU,OAAO;AAAA,IACjB,GAAI,OAAO,cAAc,WAAW,EAAE,UAAU,IAAI,CAAC;AAAA,IACrD,SAAS,IAAI,YAAY,EAAE,OAAO,MAAM,MAAM,GAAG,GAAG,CAAC,EAAE,KAAK;AAAA,EAC9D;AACF;AAKO,SAAS,0BAA0B,SAA4C;AACpF,QAAM,SACJ,QAAQ,UAAU,cACd,+KACA;AACN,QAAM,QACJ,QAAQ,aAAa,OACjB,2CACA,gBAAgB,IAAI,KAAK,QAAQ,QAAQ,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,EAAE,QAAQ,KAAK,GAAG,CAAC;AAC7F,SAAO,GAAG,MAAM,IAAI,KAAK;AAC3B;","names":[]}
|
package/dist/artifacts.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
OpenGeniClient
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-ASMIDUEA.js";
|
|
4
|
+
import "./chunk-PH56JDUM.js";
|
|
5
|
+
import "./chunk-ZKKWTOIZ.js";
|
|
6
|
+
import "./chunk-7GR6TOEV.js";
|
|
7
|
+
import "./chunk-7WJL2ZWY.js";
|
|
8
|
+
import "./chunk-CKOUDEOS.js";
|
|
9
|
+
import "./chunk-LQCTDGG6.js";
|
|
10
10
|
export {
|
|
11
11
|
OpenGeniClient
|
|
12
12
|
};
|
package/dist/browser.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export type { SessionMessageSearchRequest, SessionMessageSearchMatch, SessionMes
|
|
|
4
4
|
export { OpenGeniToolCallError, OpenGeniToolReapprovalRequiredError, OpenGeniToolsClient, } from "./tools.js";
|
|
5
5
|
export type { OpenGeniGeneratedTools, OpenGeniDynamicToolNode, OpenGeniToolCallOptions, OpenGeniToolFunction, OpenGeniToolsFacade, OpenGeniWorkspaceTools, } from "./tools.js";
|
|
6
6
|
export type { FetchLike, FetchResponse, GetSessionOptions, OpenGeniClientOptions, OpenGeniRequestOptions, SendMessageInput, SteerMessageResult, TranscribeAudioInput, WorkspaceControlEventPage, } from "./client.js";
|
|
7
|
-
export { OpenGeniApiContractMismatchError, OpenGeniApiError, OpenGeniSecureContextRequiredError, OpenGeniSessionListCursorError, OpenGeniStreamError, isRetryableStreamError, } from "./errors.js";
|
|
7
|
+
export { OpenGeniApiContractMismatchError, OpenGeniApiError, OpenGeniSetupError, OpenGeniAllowanceExhaustedError, OpenGeniSecureContextRequiredError, OpenGeniSessionListCursorError, OpenGeniStreamError, isRetryableStreamError, } from "./errors.js";
|
|
8
8
|
export type { OpenGeniSecureContextRequiredReason } from "./errors.js";
|
|
9
9
|
export { resolveWorkspaceVoiceInputEnabled } from "./transcription.js";
|
|
10
10
|
export { OPENGENI_API_CONTRACT_HEADER, OPENGENI_API_CONTRACT_REVISION } from "./types.js";
|
package/dist/browser.js
CHANGED
|
@@ -5,32 +5,36 @@ import {
|
|
|
5
5
|
OpenGeniToolCallError,
|
|
6
6
|
OpenGeniToolReapprovalRequiredError,
|
|
7
7
|
OpenGeniToolsClient
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-YTJK64EV.js";
|
|
9
9
|
import {
|
|
10
10
|
OpenGeniClient
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-ZKKWTOIZ.js";
|
|
12
|
+
import "./chunk-7GR6TOEV.js";
|
|
13
13
|
import {
|
|
14
14
|
OPENGENI_API_CONTRACT_HEADER,
|
|
15
15
|
OPENGENI_API_CONTRACT_REVISION
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import "./chunk-
|
|
16
|
+
} from "./chunk-7WJL2ZWY.js";
|
|
17
|
+
import "./chunk-CKOUDEOS.js";
|
|
18
18
|
import {
|
|
19
|
+
OpenGeniAllowanceExhaustedError,
|
|
19
20
|
OpenGeniApiContractMismatchError,
|
|
20
21
|
OpenGeniApiError,
|
|
21
22
|
OpenGeniSecureContextRequiredError,
|
|
22
23
|
OpenGeniSessionListCursorError,
|
|
24
|
+
OpenGeniSetupError,
|
|
23
25
|
OpenGeniStreamError,
|
|
24
26
|
isRetryableStreamError
|
|
25
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-LQCTDGG6.js";
|
|
26
28
|
export {
|
|
27
29
|
OPENGENI_API_CONTRACT_HEADER,
|
|
28
30
|
OPENGENI_API_CONTRACT_REVISION,
|
|
31
|
+
OpenGeniAllowanceExhaustedError,
|
|
29
32
|
OpenGeniApiContractMismatchError,
|
|
30
33
|
OpenGeniApiError,
|
|
31
34
|
OpenGeniClient as OpenGeniBrowserClient,
|
|
32
35
|
OpenGeniSecureContextRequiredError,
|
|
33
36
|
OpenGeniSessionListCursorError,
|
|
37
|
+
OpenGeniSetupError,
|
|
34
38
|
OpenGeniStreamError,
|
|
35
39
|
OpenGeniToolCallError,
|
|
36
40
|
OpenGeniToolReapprovalRequiredError,
|
package/dist/chat/fold.d.ts
CHANGED
|
@@ -39,6 +39,7 @@ export declare class ChatTurnFold {
|
|
|
39
39
|
turnId: string | null;
|
|
40
40
|
pending: ChatPending | null;
|
|
41
41
|
failure: SessionEvent | null;
|
|
42
|
+
private emptyFinalReply;
|
|
42
43
|
private readonly segments;
|
|
43
44
|
private readonly openTools;
|
|
44
45
|
constructor(workspaceId: string, sessionId: string, expectedTurnId: string | null);
|
package/dist/chat/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export type { Chats } from "../chats.js";
|
|
2
|
+
export { OpenGeniSetupError } from "../errors.js";
|
|
1
3
|
export { Chat, DEFAULT_CHAT_SOURCE, DEFAULT_OPENGENI_BASE_URL, IMPORTED_HISTORY_MAX_CHARS, OpenGeni, formatImportedHistory, } from "./opengeni.js";
|
|
2
4
|
export { OpenGeniChatError, type ChatAgentAccess, type ChatChunk, type ChatImportedMessage, type ChatMemory, type ChatMessage, type ChatOptions, type ChatPending, type ChatReply, type ChatReplyStatus, type ChatRespondInput, type ChatSendOptions, type ChatSessionListOptions, type ChatSnapshot, type ChatTarget, type ChatToolStatus, type OpenGeniOptions, } from "./types.js";
|
|
3
5
|
export { CHAT_SESSION_NAMESPACE, chatIdempotencyKey, chatIdentityName, chatSessionId, uuidV5, type ChatUserLabel, } from "./ids.js";
|