@opengeni/sdk 3.2.2 → 3.3.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 +21 -0
- package/dist/artifacts.js +4 -4
- package/dist/browser.js +2 -2
- package/dist/chat/index.js +15 -349
- package/dist/chat/index.js.map +1 -1
- package/dist/{chunk-JKG75TTU.js → chunk-BWAJPU5S.js} +12 -2
- package/dist/chunk-BWAJPU5S.js.map +1 -0
- package/dist/{chunk-PBVUAXSU.js → chunk-F4OXWFCU.js} +217 -7
- package/dist/chunk-F4OXWFCU.js.map +1 -0
- package/dist/{chunk-N2I422X4.js → chunk-HP7NVCAX.js} +3 -11
- package/dist/chunk-HP7NVCAX.js.map +1 -0
- package/dist/{chunk-JP62FZSI.js → chunk-MJWC6GTA.js} +2 -2
- package/dist/chunk-OV3POE62.js +359 -0
- package/dist/chunk-OV3POE62.js.map +1 -0
- package/dist/{chunk-PDU6EU2M.js → chunk-S5XTUA7L.js} +2 -2
- package/dist/{chunk-VPVMLM7Q.js → chunk-X5ITQVXE.js} +1 -1
- package/dist/chunk-X5ITQVXE.js.map +1 -0
- package/dist/client.d.ts +3 -0
- package/dist/core.js +3 -3
- package/dist/document-authority.js +3 -3
- package/dist/index.js +11 -9
- package/dist/index.js.map +1 -1
- package/dist/insights-usage.d.ts +1 -1
- package/dist/insights-usage.js +1 -1
- package/dist/site-ai.d.ts +35 -0
- package/dist/site-bridge-host.js +4 -3
- package/dist/site-bridge-host.js.map +1 -1
- 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.d.ts +4 -0
- package/dist/site.js +4 -3
- package/package.json +3 -3
- package/src/client.ts +19 -0
- package/src/insights-usage.ts +3 -0
- package/src/site-ai.ts +284 -0
- package/src/site-browser-runtime.gen.ts +1 -1
- package/src/site.ts +16 -5
- package/dist/chunk-JKG75TTU.js.map +0 -1
- package/dist/chunk-N2I422X4.js.map +0 -1
- package/dist/chunk-PBVUAXSU.js.map +0 -1
- package/dist/chunk-VPVMLM7Q.js.map +0 -1
- /package/dist/{chunk-JP62FZSI.js.map → chunk-MJWC6GTA.js.map} +0 -0
- /package/dist/{chunk-PDU6EU2M.js.map → chunk-S5XTUA7L.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/embedding-client.ts"],"sourcesContent":["import { OpenGeniClient as OpenGeniArtifactClient } from \"./artifact-client\";\nimport type { OpenGeniClientOptions } from \"./client\";\nimport type { AddWorkspaceMemberRequest } from \"./types\";\nimport type {\n ExternalIdentityLink,\n BeginExternalIdentityLinkRequest,\n BeginExternalIdentityLinkResponse,\n ConfirmExternalIdentityLinkRequest,\n ExternalIdentityLinkPreview,\n ExternalIdentityLinkPage,\n} from \"@opengeni/contracts/external-identities\";\n\n/** Non-secret service attribution, serialized as a flat JSON object of at most 2 KiB. */\nexport type ServiceContext = Record<string, string | number | boolean>;\n\nfunction hasStaticHeader(options: OpenGeniClientOptions, names: string[]): boolean {\n return (\n typeof options.headers !== \"function\" &&\n Object.keys(options.headers ?? {}).some((key) => names.includes(key.toLowerCase()))\n );\n}\n\nfunction serializeServiceContext(context: ServiceContext): string {\n if (\n !context ||\n typeof context !== \"object\" ||\n Array.isArray(context) ||\n (Object.getPrototypeOf(context) !== Object.prototype && Object.getPrototypeOf(context) !== null)\n )\n throw new Error(\"Invalid service context: expected a flat JSON object\");\n const snapshot: ServiceContext = Object.create(null);\n for (const [key, value] of Object.entries(context)) {\n if (\n typeof value !== \"string\" &&\n typeof value !== \"boolean\" &&\n !(typeof value === \"number\" && Number.isFinite(value))\n )\n throw new Error(\n \"Invalid service context: values must be strings, finite numbers, or booleans\",\n );\n snapshot[key] = value;\n }\n // HTTP Headers require byte strings. JSON escapes preserve Unicode without\n // percent-encoding the object or passing non-byte characters to fetch.\n const json = JSON.stringify(snapshot).replace(\n /[\\u007f-\\uffff]/g,\n (character) => `\\\\u${character.charCodeAt(0).toString(16).padStart(4, \"0\")}`,\n );\n if (new TextEncoder().encode(json).byteLength > 2048)\n throw new Error(\"Invalid service context: serialized JSON must not exceed 2 KiB\");\n return json;\n}\n\n/** Public product embedding administration, kept out of the native browser client. */\nexport class OpenGeniEmbeddingClient extends OpenGeniArtifactClient {\n /** Read configuration (null means no configured ceiling). Requires admin or organization-key read authority. */\n async getWorkspaceAllowance(\n workspaceId: string,\n ): Promise<import(\"@opengeni/contracts/usage-allowances\").WorkspaceAllowance | null> {\n return this.requestJson(\"GET\", `/v1/workspaces/${encodeURIComponent(workspaceId)}/allowance`);\n }\n\n /**\n * Read the lifecycle version even after clear (config=null). version=0 means\n * never configured. Use the returned version to recreate or reconcile a 409;\n * do not guess a CAS version or silently retry a new mutation.\n * Requires the same budget-read authority as getWorkspaceAllowance.\n */\n async getWorkspaceAllowanceState(\n workspaceId: string,\n ): Promise<import(\"@opengeni/contracts/usage-allowances\").WorkspaceAllowanceState> {\n return this.requestJson(\n \"GET\",\n `/v1/workspaces/${encodeURIComponent(workspaceId)}/allowance/state`,\n );\n }\n\n /**\n * Set a USD-micro ceiling with exact-version CAS (0 only for first creation;\n * after clear reuse its returned version or getWorkspaceAllowanceState). Requires\n * organization key-control authority or account:admin, never workspace admin\n * alone. Shares may oversubscribe the pool; actual post-call settlement can\n * overshoot before the next admission check.\n */\n async setWorkspaceAllowance(\n workspaceId: string,\n request: import(\"@opengeni/contracts/usage-allowances\").SetWorkspaceAllowanceRequest,\n ): Promise<import(\"@opengeni/contracts/usage-allowances\").WorkspaceAllowance> {\n return this.requestJson(\n \"PUT\",\n `/v1/workspaces/${encodeURIComponent(workspaceId)}/allowance`,\n request,\n );\n }\n\n /**\n * Clear with the exact version; grants and settled usage are not a billing\n * refund. Supply operationId and replay the exact request after a lost response.\n * Replays recheck authority and conflict after a later lifecycle change.\n * On 409 read getWorkspaceAllowanceState before deciding on a new operation.\n */\n async clearWorkspaceAllowance(\n workspaceId: string,\n request: import(\"@opengeni/contracts/usage-allowances\").ClearWorkspaceAllowanceRequest,\n ): Promise<import(\"@opengeni/contracts/usage-allowances\").ClearWorkspaceAllowanceResponse> {\n return this.requestJson(\n \"DELETE\",\n `/v1/workspaces/${encodeURIComponent(workspaceId)}/allowance`,\n request,\n );\n }\n\n /** Grant USD micros once. Reuse the operationId and exact request after an uncertain response. */\n async grantWorkspaceCredits(\n workspaceId: string,\n request: import(\"@opengeni/contracts/usage-allowances\").GrantWorkspaceCreditsRequest,\n ): Promise<import(\"@opengeni/contracts/usage-allowances\").WorkspaceCreditGrant> {\n return this.requestJson(\n \"POST\",\n `/v1/workspaces/${encodeURIComponent(workspaceId)}/allowance/grants`,\n request,\n );\n }\n\n /**\n * Administer an existing member by canonical subject or external identity.\n * null restores memberDefault; shares >1 are valid ceilings, not reservations.\n * Concurrent calls may exceed the ceiling until their actual cost settles.\n */\n async setMemberAllowance(\n workspaceId: string,\n member: string | { source: string; externalId: string },\n request: import(\"@opengeni/contracts/usage-allowances\").SetMemberAllowanceRequest,\n ): Promise<import(\"@opengeni/contracts/usage-allowances\").MemberAllowance> {\n const path =\n typeof member === \"string\"\n ? encodeURIComponent(member)\n : `external/${encodeURIComponent(member.source)}/${encodeURIComponent(member.externalId)}`;\n return this.requestJson(\n \"PUT\",\n `/v1/workspaces/${encodeURIComponent(workspaceId)}/members/${path}/allowance`,\n request,\n );\n }\n\n /** Paginated settled usage, current or YYYY-MM. Requires admin or organization-key read authority. */\n async getUsage(\n workspaceId: string,\n query: import(\"@opengeni/contracts/usage-allowances\").GetUsageRequest = {},\n options: import(\"./client\").OpenGeniRequestOptions = {},\n ): Promise<import(\"@opengeni/contracts/usage-allowances\").WorkspaceUsageResponse> {\n return this.requestJson(\n \"GET\",\n `/v1/workspaces/${encodeURIComponent(workspaceId)}/usage`,\n undefined,\n usageQuery(query),\n options,\n );\n }\n\n /** Own usage only. On your backend use asUser(authenticatedUser); subject selectors are not accepted. */\n async getMyUsage(\n workspaceId: string,\n query: import(\"@opengeni/contracts/usage-allowances\").GetMyUsageRequest = {},\n options: import(\"./client\").OpenGeniRequestOptions = {},\n ): Promise<import(\"@opengeni/contracts/usage-allowances\").WorkspaceUsageResponse> {\n return this.requestJson(\n \"GET\",\n `/v1/workspaces/${encodeURIComponent(workspaceId)}/usage/me`,\n undefined,\n usageQuery(query),\n options,\n );\n }\n\n /** Recover this actor's connection creation result without resending secrets.\n * A 404 means no visible committed result, not proof that an in-flight write failed. */\n async getConnectionCreationResult(\n workspaceId: string,\n operationId: string,\n ): Promise<import(\"./types\").ConnectionMetadata> {\n const response = await this.requestJson<import(\"./types\").ConnectionResponse>(\n \"GET\",\n `/v1/workspaces/${encodeURIComponent(workspaceId)}/connections/operations/${encodeURIComponent(operationId)}`,\n );\n return response.connection;\n }\n\n /** Rotate existing inline credentials only while no credential-consuming work\n * is pending or active. Reuse the operation key and exact request to reconcile\n * a lost response. This operation never schedules or retries model work. */\n async rotateSessionMcpCredentials(\n workspaceId: string,\n sessionId: string,\n request: import(\"./types\").RotateSessionMcpCredentialsRequest,\n ): Promise<import(\"./types\").RotateSessionMcpCredentialsReceipt> {\n return this.requestJson(\n \"POST\",\n `/v1/workspaces/${workspaceId}/sessions/${sessionId}/mcp-credentials/rotate`,\n request,\n );\n }\n\n /** Contract-checked successful JSON GET with its headers intact, for same-origin\n * proxies that must forward paging metadata. Non-2xx responses throw. */\n async requestJsonResponse(\n path: string,\n query: Record<string, string> = {},\n options: import(\"./client\").OpenGeniRequestOptions = {},\n ): Promise<import(\"./client\").FetchResponse> {\n return await this.requestResponse(\"GET\", path, query, {\n ...options,\n accept: \"application/json\",\n });\n }\n\n /** Server-side organization-key client scoped to one host-authenticated user.\n * Does not mutate this client, provision workspace membership, or link native\n * identities. The API verifies key and membership authority on each request. */\n asUser(externalId: string, options: { source?: string } = {}): this {\n if (typeof window !== \"undefined\")\n throw new Error(\"asUser is a server-side API; keep organization keys on your backend\");\n if (\n this.serviceInitiatorHeader !== undefined ||\n hasStaticHeader(this.options, [\"x-opengeni-service-initiator\", \"x-opengeni-service-context\"])\n )\n throw new Error(\n \"asUser and asService are mutually exclusive; start from the unscoped client\",\n );\n const source = options.source ?? \"default\";\n const validOpaqueText = (value: unknown, maxBytes: number): value is string =>\n typeof value === \"string\" &&\n value.length > 0 &&\n value.length <= maxBytes &&\n !value.includes(\"\\0\") &&\n !/[\\uD800-\\uDFFF]/u.test(value) &&\n new TextEncoder().encode(value).byteLength <= maxBytes;\n if (!validOpaqueText(externalId, 1024) || !validOpaqueText(source, 200)) {\n throw new Error(\"Invalid external identity reference\");\n }\n const Client = this.constructor as new (options: OpenGeniClientOptions) => this;\n const client = new Client({ ...this.options });\n client.externalActorHeader = encodeURIComponent(\n JSON.stringify({ mode: \"external\", identity: { externalId, source } }),\n );\n return client;\n }\n\n /** Server-side automation attribution under this client's existing credential.\n * Returns a new client of the same class; grants no permissions or human/personal\n * resource authority. Cannot be combined with asUser or asLinkedUser.\n * Reapplying asService replaces the name and context rather than merging them. */\n asService(name: string, context?: ServiceContext): this {\n if (typeof window !== \"undefined\")\n throw new Error(\"asService is a server-side API; keep API keys on your backend\");\n if (\n this.externalActorHeader !== undefined ||\n hasStaticHeader(this.options, [\"x-opengeni-external-actor\"])\n )\n throw new Error(\n \"asUser and asService are mutually exclusive; start from the unscoped client\",\n );\n if (\n typeof name !== \"string\" ||\n !/^[a-z0-9][a-z0-9:._-]{0,63}$/.test(name) ||\n name.trim() !== name\n )\n throw new Error(\"Invalid service initiator name\");\n const serializedContext = context === undefined ? undefined : serializeServiceContext(context);\n const Client = this.constructor as new (options: OpenGeniClientOptions) => this;\n const client = new Client({ ...this.options });\n client.serviceInitiatorHeader = name;\n client.serviceContextHeader = serializedContext;\n return client;\n }\n\n /** Explicitly use a confirmed native delegation. Unlike asUser, new resources\n * belong to the native user. Existing external resources are never reassigned.\n * A stale, expired or revoked link is rejected by the server on every request. */\n asLinkedUser(\n externalId: string,\n options: { source?: string; linkId: string; expectedLinkRevision: number },\n ): this {\n if (\n !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(options.linkId) ||\n !Number.isSafeInteger(options.expectedLinkRevision) ||\n options.expectedLinkRevision < 1\n )\n throw new Error(\"A confirmed identity link and its exact revision are required\");\n const client = this.asUser(\n externalId,\n options.source === undefined ? {} : { source: options.source },\n );\n const identity = JSON.parse(decodeURIComponent(client.externalActorHeader!)).identity;\n client.externalActorHeader = encodeURIComponent(\n JSON.stringify({\n mode: \"linked_native\",\n identity,\n linkId: options.linkId,\n expectedLinkRevision: options.expectedLinkRevision,\n }),\n );\n return client;\n }\n\n /** Optional native-account delegation. Invoke on a server-side asUser client.\n * Pass the one-time challenge to the native consent screen, never a URL query\n * or analytics event. Ordinary external embedding needs none of this. */\n async beginIdentityLink(\n workspaceId: string,\n input: BeginExternalIdentityLinkRequest,\n ): Promise<BeginExternalIdentityLinkResponse> {\n return this.requestJson(\n \"POST\",\n `/v1/workspaces/${encodeURIComponent(workspaceId)}/identity-links`,\n input,\n );\n }\n\n async getIdentityLink(workspaceId: string, linkId: string): Promise<ExternalIdentityLink> {\n return this.requestJson(\n \"GET\",\n `/v1/workspaces/${encodeURIComponent(workspaceId)}/identity-links/${encodeURIComponent(linkId)}`,\n );\n }\n\n /** Only links belonging to the effective participant; no organization-wide directory. */\n async listIdentityLinks(workspaceId: string, cursor?: string): Promise<ExternalIdentityLinkPage> {\n return this.requestJson(\n \"GET\",\n `/v1/workspaces/${encodeURIComponent(workspaceId)}/identity-links${cursor ? `?cursor=${encodeURIComponent(cursor)}` : \"\"}`,\n );\n }\n\n /** Requires a canonical native browser session, not an organization API key. */\n async previewIdentityLink(\n workspaceId: string,\n linkId: string,\n challenge: string,\n ): Promise<ExternalIdentityLinkPreview> {\n return this.requestJson(\n \"POST\",\n `/v1/workspaces/${encodeURIComponent(workspaceId)}/identity-links/${encodeURIComponent(linkId)}/preview`,\n { challenge },\n );\n }\n\n async confirmIdentityLink(\n workspaceId: string,\n linkId: string,\n input: ConfirmExternalIdentityLinkRequest,\n ): Promise<ExternalIdentityLink> {\n return this.requestJson(\n \"POST\",\n `/v1/workspaces/${encodeURIComponent(workspaceId)}/identity-links/${encodeURIComponent(linkId)}/confirm`,\n input,\n );\n }\n\n async revokeIdentityLink(\n workspaceId: string,\n linkId: string,\n expectedRevision: number,\n ): Promise<ExternalIdentityLink> {\n return this.requestJson(\n \"POST\",\n `/v1/workspaces/${encodeURIComponent(workspaceId)}/identity-links/${encodeURIComponent(linkId)}/revoke`,\n { expectedRevision },\n );\n }\n\n /** Service-only lifecycle for an external actor's organization membership.\n * A successful reactivation does not restore revoked workspace grants. */\n async updateExternalIdentityMembership(\n organizationId: string,\n membershipId: string,\n request: import(\"@opengeni/contracts/external-identities\").UpdateExternalIdentityMembershipRequest,\n options: { signal?: AbortSignal } = {},\n ): Promise<import(\"@opengeni/contracts\").OrganizationMember> {\n return this.requestJson(\n \"PATCH\",\n `/v1/organizations/${encodeURIComponent(organizationId)}/external-members/${encodeURIComponent(membershipId)}`,\n request,\n undefined,\n options,\n );\n }\n\n /** Non-provisioning, content-free service lookup, including inactive identities. */\n async lookupExternalIdentity(\n organizationId: string,\n identity: import(\"@opengeni/contracts/external-identities\").ExternalIdentityReference,\n ): Promise<import(\"@opengeni/contracts/external-identities\").ExternalIdentityLookup> {\n return this.requestJson(\n \"POST\",\n `/v1/organizations/${encodeURIComponent(organizationId)}/external-identities/lookup`,\n identity,\n );\n }\n\n /** Withdraw an external member's shared-workspace access and fence an exact\n * pending keyed grant. Reuse the exact cancellation body after response loss. */\n async cancelExternalWorkspaceMemberGrant(\n organizationId: string,\n workspaceId: string,\n membershipId: string,\n request: import(\"@opengeni/contracts/external-identities\").CancelExternalWorkspaceMemberGrantRequest,\n ): Promise<\n import(\"@opengeni/contracts/external-identities\").CancelExternalWorkspaceMemberGrantResponse\n > {\n return this.requestJson(\n \"POST\",\n `/v1/organizations/${encodeURIComponent(organizationId)}/workspaces/${encodeURIComponent(workspaceId)}/members/${encodeURIComponent(membershipId)}/revoke`,\n request,\n );\n }\n\n /** Replace an existing external member's permissions in one shared\n * workspace. Keyed by `operationId`: reuse the exact body after response\n * loss. Narrowing makes live authority re-check; nothing is cancelled. */\n async updateExternalWorkspaceMember(\n organizationId: string,\n workspaceId: string,\n membershipId: string,\n request: import(\"@opengeni/contracts/external-identities\").UpdateExternalWorkspaceMemberRequest,\n ): Promise<\n import(\"@opengeni/contracts/external-identities\").UpdateExternalWorkspaceMemberResponse\n > {\n return this.requestJson(\n \"PATCH\",\n `/v1/organizations/${encodeURIComponent(organizationId)}/workspaces/${encodeURIComponent(workspaceId)}/external-members/${encodeURIComponent(membershipId)}`,\n request,\n );\n }\n\n async listConnectProviders(\n workspaceId: string,\n ): Promise<import(\"@opengeni/contracts/connect\").ConnectProvider[]> {\n return this.requestJson(\"GET\", `/v1/workspaces/${workspaceId}/connect/catalog`);\n }\n\n async listConnectAccounts(\n workspaceId: string,\n ): Promise<import(\"@opengeni/contracts/connect\").ConnectAccount[]> {\n return this.requestJson(\"GET\", `/v1/workspaces/${workspaceId}/connect/accounts`);\n }\n\n async getConnectAttempt(\n workspaceId: string,\n attemptId: string,\n ): Promise<import(\"@opengeni/contracts/connect\").ConnectAttempt> {\n return this.requestJson(\"GET\", `/v1/workspaces/${workspaceId}/connect/attempts/${attemptId}`);\n }\n\n async listPendingConnectAttempts(\n workspaceId: string,\n ): Promise<import(\"@opengeni/contracts/connect\").ConnectAttempt[]> {\n return this.requestJson(\"GET\", `/v1/workspaces/${workspaceId}/connect/attempts`);\n }\n\n async advanceConnectAttempt(\n workspaceId: string,\n attemptId: string,\n request: {\n expectedRevision: number;\n idempotencyKey: string;\n action: import(\"@opengeni/contracts/connect\").ConnectAdvance;\n },\n ): Promise<import(\"@opengeni/contracts/connect\").ConnectAttempt> {\n return this.requestJson(\n \"POST\",\n `/v1/workspaces/${workspaceId}/connect/attempts/${attemptId}/advance`,\n request,\n );\n }\n\n /** Stops setup; does not revoke already committed provider credentials. */\n async cancelConnectAttempt(\n workspaceId: string,\n attemptId: string,\n request: {\n expectedRevision: number;\n idempotencyKey: string;\n },\n ): Promise<import(\"@opengeni/contracts/connect\").ConnectAttempt> {\n return this.requestJson(\n \"POST\",\n `/v1/workspaces/${workspaceId}/connect/attempts/${attemptId}/cancel`,\n request,\n );\n }\n\n /**\n * Explicit organization-service-key onboarding with chosen permissions. Not\n * needed for the default path: an `asUser` request through a key with\n * `members:manage` adds a missing member with conversation permissions on\n * first use. Change an existing member with `updateExternalWorkspaceMember`.\n */\n async addExternalWorkspaceMember(\n workspaceId: string,\n request: {\n identity: { externalId: string; source?: string };\n permissions: AddWorkspaceMemberRequest[\"permissions\"];\n operationId?: string;\n },\n ): Promise<import(\"@opengeni/contracts/external-identities\").ExternalIdentity> {\n return this.requestJson(\"POST\", `/v1/workspaces/${workspaceId}/external-members`, request);\n }\n}\n\nfunction usageQuery(\n query: import(\"@opengeni/contracts/usage-allowances\").GetUsageRequest,\n): Record<string, string> {\n return Object.fromEntries(\n Object.entries(query)\n .filter(([, value]) => value !== undefined)\n .map(([key, value]) => [key, String(value)]),\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
OpenGeniClient
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-BWAJPU5S.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-
|
|
150
|
+
//# sourceMappingURL=chunk-MJWC6GTA.js.map
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
// ../contracts/src/session-final-reply.ts
|
|
2
|
+
var EMPTY_FINAL_REPLY_NOTICE = "The model returned no final reply after a reply reminder. Completed work is preserved; the goal and later updates are unaffected.";
|
|
3
|
+
function turnCompletedWithEmptyFinalReply(payload) {
|
|
4
|
+
return payload !== null && typeof payload === "object" && !Array.isArray(payload) && payload.emptyFinalReply === true;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
// src/chat/types.ts
|
|
8
|
+
var OpenGeniChatError = class extends Error {
|
|
9
|
+
code;
|
|
10
|
+
event;
|
|
11
|
+
constructor(code, message, event = null) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = "OpenGeniChatError";
|
|
14
|
+
this.code = code;
|
|
15
|
+
this.event = event;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// src/chat/fold.ts
|
|
20
|
+
var ChatPendingFold = class {
|
|
21
|
+
requests = /* @__PURE__ */ new Map();
|
|
22
|
+
push(event) {
|
|
23
|
+
const payload = asRecord(event.payload);
|
|
24
|
+
if (event.type === "session.requiresAction") {
|
|
25
|
+
for (const [key, request] of this.requests) {
|
|
26
|
+
if (request.pending.kind === "approval") this.requests.delete(key);
|
|
27
|
+
}
|
|
28
|
+
for (const approval of Array.isArray(payload.approvals) ? payload.approvals : []) {
|
|
29
|
+
const pending = approvalPending({ approvals: [approval] });
|
|
30
|
+
if (pending) this.put(pending, event.turnId ?? null);
|
|
31
|
+
}
|
|
32
|
+
} else if (event.type === "session.humanInput.requested") {
|
|
33
|
+
const pending = humanInputPending(payload);
|
|
34
|
+
if (pending) this.put(pending, event.turnId ?? null);
|
|
35
|
+
} else if (event.type === "user.approvalDecision") {
|
|
36
|
+
this.requests.delete(`approval:${payload.approvalId}`);
|
|
37
|
+
} else if (event.type === "user.humanInputResponse") {
|
|
38
|
+
this.requests.delete(`human_input:${payload.requestId}`);
|
|
39
|
+
} else if (["turn.completed", "turn.failed", "turn.cancelled"].includes(event.type)) {
|
|
40
|
+
for (const [key, request] of this.requests) {
|
|
41
|
+
if (request.turnId === null || event.turnId == null || request.turnId === event.turnId) {
|
|
42
|
+
this.requests.delete(key);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
pending(now = Date.now()) {
|
|
48
|
+
return [...this.requests.values()].map((request) => request.pending).filter((pending) => {
|
|
49
|
+
if (pending.kind !== "human_input") return true;
|
|
50
|
+
const expiresAt = asRecord(pending.payload).expiresAt;
|
|
51
|
+
return expiresAt == null || typeof expiresAt === "string" && Date.parse(expiresAt) > now;
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
put(pending, turnId) {
|
|
55
|
+
this.requests.set(`${pending.kind}:${pending.requestId}`, { pending, turnId });
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
function noStep() {
|
|
59
|
+
return { chunks: [], terminal: null };
|
|
60
|
+
}
|
|
61
|
+
var ChatTurnFold = class {
|
|
62
|
+
constructor(workspaceId, sessionId, expectedTurnId) {
|
|
63
|
+
this.workspaceId = workspaceId;
|
|
64
|
+
this.sessionId = sessionId;
|
|
65
|
+
this.turnId = expectedTurnId;
|
|
66
|
+
}
|
|
67
|
+
events = [];
|
|
68
|
+
turnId;
|
|
69
|
+
pending = null;
|
|
70
|
+
failure = null;
|
|
71
|
+
emptyFinalReply = false;
|
|
72
|
+
segments = [];
|
|
73
|
+
openTools = /* @__PURE__ */ new Map();
|
|
74
|
+
get text() {
|
|
75
|
+
return this.segments.filter((segment) => !segment.commentary).map((segment) => segment.text).filter((text) => text.length > 0).join("\n\n");
|
|
76
|
+
}
|
|
77
|
+
push(event) {
|
|
78
|
+
const eventTurnId = typeof event.turnId === "string" ? event.turnId : null;
|
|
79
|
+
if (this.turnId && eventTurnId && eventTurnId !== this.turnId) {
|
|
80
|
+
return { chunks: [], terminal: null };
|
|
81
|
+
}
|
|
82
|
+
if (!this.turnId && eventTurnId && isTurnScopedType(event.type)) {
|
|
83
|
+
this.turnId = eventTurnId;
|
|
84
|
+
}
|
|
85
|
+
this.events.push(event);
|
|
86
|
+
const payload = asRecord(event.payload);
|
|
87
|
+
switch (event.type) {
|
|
88
|
+
case "agent.message.delta": {
|
|
89
|
+
const text = stringValue(payload.text);
|
|
90
|
+
if (!text) return noStep();
|
|
91
|
+
const messageId = stringValue(payload.messageId) || null;
|
|
92
|
+
if (messageId) return this.messageDelta(messageId, text, isCommentary(payload));
|
|
93
|
+
const open = this.segments.at(-1);
|
|
94
|
+
if (isCommentary(payload)) {
|
|
95
|
+
if (open?.open && open.commentary) {
|
|
96
|
+
open.text += text;
|
|
97
|
+
} else {
|
|
98
|
+
this.closeSegments();
|
|
99
|
+
this.segments.push({ text, open: true, commentary: true, messageId: null });
|
|
100
|
+
}
|
|
101
|
+
return noStep();
|
|
102
|
+
}
|
|
103
|
+
if (open?.open && !open.commentary) {
|
|
104
|
+
open.text += text;
|
|
105
|
+
} else {
|
|
106
|
+
this.closeSegments();
|
|
107
|
+
return { chunks: [this.startSegment(text, true, null)], terminal: null };
|
|
108
|
+
}
|
|
109
|
+
return { chunks: [{ type: "text", text }], terminal: null };
|
|
110
|
+
}
|
|
111
|
+
case "agent.message.completed": {
|
|
112
|
+
const text = stringValue(payload.text) ?? "";
|
|
113
|
+
const messageId = stringValue(payload.messageId) || null;
|
|
114
|
+
if (messageId) return this.messageCompleted(messageId, text, isCommentary(payload));
|
|
115
|
+
const last = this.segments.at(-1);
|
|
116
|
+
if (isCommentary(payload)) {
|
|
117
|
+
if (last?.commentary && (last.open || text.startsWith(last.text))) {
|
|
118
|
+
last.open = false;
|
|
119
|
+
if (text) last.text = text;
|
|
120
|
+
return noStep();
|
|
121
|
+
}
|
|
122
|
+
const streamed = last && !last.commentary && last.open && text.startsWith(last.text);
|
|
123
|
+
if (!streamed) {
|
|
124
|
+
if (text) {
|
|
125
|
+
this.closeSegments();
|
|
126
|
+
this.segments.push({ text, open: false, commentary: true, messageId: null });
|
|
127
|
+
}
|
|
128
|
+
return noStep();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const target = last?.commentary ? void 0 : last;
|
|
132
|
+
if (!target || !target.open && target.text && !text.startsWith(target.text)) {
|
|
133
|
+
if (!text) return noStep();
|
|
134
|
+
if (payload.phase === void 0 && this.latestAnswer()?.text === text) return noStep();
|
|
135
|
+
this.closeSegments();
|
|
136
|
+
return { chunks: [this.startSegment(text, false, null)], terminal: null };
|
|
137
|
+
}
|
|
138
|
+
target.open = false;
|
|
139
|
+
return { chunks: this.extendAnswer(target, text), terminal: null };
|
|
140
|
+
}
|
|
141
|
+
case "agent.toolCall.created": {
|
|
142
|
+
this.closeSegments();
|
|
143
|
+
const name = stringValue(payload.name) ?? "tool";
|
|
144
|
+
const callId = stringValue(payload.id);
|
|
145
|
+
if (callId) this.openTools.set(callId, name);
|
|
146
|
+
return {
|
|
147
|
+
chunks: [
|
|
148
|
+
{
|
|
149
|
+
type: "tool",
|
|
150
|
+
name,
|
|
151
|
+
status: "started",
|
|
152
|
+
...callId ? { callId } : {},
|
|
153
|
+
..."arguments" in payload ? { input: payload.arguments } : {}
|
|
154
|
+
}
|
|
155
|
+
],
|
|
156
|
+
terminal: null
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
case "agent.toolCall.output": {
|
|
160
|
+
const callId = stringValue(payload.id);
|
|
161
|
+
const name = (callId ? this.openTools.get(callId) : void 0) ?? "tool";
|
|
162
|
+
if (callId) this.openTools.delete(callId);
|
|
163
|
+
return {
|
|
164
|
+
chunks: [
|
|
165
|
+
{
|
|
166
|
+
type: "tool",
|
|
167
|
+
name,
|
|
168
|
+
status: isErrorOutput(payload) ? "failed" : "completed",
|
|
169
|
+
...callId ? { callId } : {}
|
|
170
|
+
}
|
|
171
|
+
],
|
|
172
|
+
terminal: null
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
case "session.requiresAction": {
|
|
176
|
+
const pending = approvalPending(payload);
|
|
177
|
+
if (!pending) return { chunks: [], terminal: null };
|
|
178
|
+
this.pending = pending;
|
|
179
|
+
return {
|
|
180
|
+
chunks: [...this.settleSegments(), { type: "pending", pending }],
|
|
181
|
+
terminal: "pending"
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
case "session.humanInput.requested": {
|
|
185
|
+
const pending = humanInputPending(payload);
|
|
186
|
+
if (!pending) return { chunks: [], terminal: null };
|
|
187
|
+
this.pending = pending;
|
|
188
|
+
return {
|
|
189
|
+
chunks: [...this.settleSegments(), { type: "pending", pending }],
|
|
190
|
+
terminal: "pending"
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
case "turn.completed":
|
|
194
|
+
this.emptyFinalReply = turnCompletedWithEmptyFinalReply(payload);
|
|
195
|
+
return { chunks: this.settleSegments(), terminal: "completed" };
|
|
196
|
+
case "turn.failed":
|
|
197
|
+
this.failure = event;
|
|
198
|
+
return { chunks: this.settleSegments(), terminal: "failed" };
|
|
199
|
+
case "turn.cancelled":
|
|
200
|
+
return { chunks: this.settleSegments(), terminal: "cancelled" };
|
|
201
|
+
default:
|
|
202
|
+
return { chunks: [], terminal: null };
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
reply(terminal) {
|
|
206
|
+
const text = this.text;
|
|
207
|
+
return {
|
|
208
|
+
text,
|
|
209
|
+
sessionId: this.sessionId,
|
|
210
|
+
workspaceId: this.workspaceId,
|
|
211
|
+
turnId: this.turnId,
|
|
212
|
+
status: terminal === "pending" ? "pending" : terminal === "cancelled" ? "cancelled" : "completed",
|
|
213
|
+
pending: this.pending,
|
|
214
|
+
...this.emptyFinalReply ? { emptyFinalReply: true, notice: EMPTY_FINAL_REPLY_NOTICE } : {},
|
|
215
|
+
events: [...this.events],
|
|
216
|
+
toString: () => text
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
/** The error to throw for a `turn.failed` settlement. */
|
|
220
|
+
failureError() {
|
|
221
|
+
const payload = asRecord(this.failure?.payload);
|
|
222
|
+
const code = stringValue(payload.code) ?? "turn_failed";
|
|
223
|
+
const message = stringValue(payload.error) ?? stringValue(payload.message) ?? "The turn failed.";
|
|
224
|
+
return new OpenGeniChatError(code, message, this.failure);
|
|
225
|
+
}
|
|
226
|
+
messageDelta(messageId, text, commentary) {
|
|
227
|
+
const segment = this.segmentOf(messageId);
|
|
228
|
+
if (segment?.open) {
|
|
229
|
+
segment.text += text;
|
|
230
|
+
return segment.commentary ? noStep() : { chunks: [{ type: "text", text }], terminal: null };
|
|
231
|
+
}
|
|
232
|
+
this.closeSegments();
|
|
233
|
+
if (commentary) {
|
|
234
|
+
this.segments.push({ text, open: true, commentary: true, messageId });
|
|
235
|
+
return noStep();
|
|
236
|
+
}
|
|
237
|
+
return { chunks: [this.startSegment(text, true, messageId)], terminal: null };
|
|
238
|
+
}
|
|
239
|
+
messageCompleted(messageId, text, commentary) {
|
|
240
|
+
const segment = this.segmentOf(messageId) ?? this.unidentifiedStreamingSegment(text);
|
|
241
|
+
if (segment) {
|
|
242
|
+
segment.messageId = messageId;
|
|
243
|
+
segment.open = false;
|
|
244
|
+
if (segment.commentary) {
|
|
245
|
+
if (text) segment.text = text;
|
|
246
|
+
return noStep();
|
|
247
|
+
}
|
|
248
|
+
return { chunks: this.extendAnswer(segment, text), terminal: null };
|
|
249
|
+
}
|
|
250
|
+
if (!text) return noStep();
|
|
251
|
+
if (commentary) {
|
|
252
|
+
this.segments.push({ text, open: false, commentary: true, messageId });
|
|
253
|
+
return noStep();
|
|
254
|
+
}
|
|
255
|
+
return { chunks: [this.startSegment(text, false, messageId)], terminal: null };
|
|
256
|
+
}
|
|
257
|
+
segmentOf(messageId) {
|
|
258
|
+
return this.findLastSegment((segment) => segment.messageId === messageId);
|
|
259
|
+
}
|
|
260
|
+
/** Deltas that carried no identity, still streaming the text this completion names. */
|
|
261
|
+
unidentifiedStreamingSegment(text) {
|
|
262
|
+
const last = this.segments.at(-1);
|
|
263
|
+
return last?.open && last.messageId === null && text.startsWith(last.text) ? last : void 0;
|
|
264
|
+
}
|
|
265
|
+
latestAnswer() {
|
|
266
|
+
return this.findLastSegment((segment) => !segment.commentary);
|
|
267
|
+
}
|
|
268
|
+
findLastSegment(predicate) {
|
|
269
|
+
for (let index = this.segments.length - 1; index >= 0; index -= 1) {
|
|
270
|
+
const segment = this.segments[index];
|
|
271
|
+
if (predicate(segment)) return segment;
|
|
272
|
+
}
|
|
273
|
+
return void 0;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Complete an answer segment. Only the newest answer can grow: a remainder
|
|
277
|
+
* for an earlier one would land after later text for append-only consumers.
|
|
278
|
+
*/
|
|
279
|
+
extendAnswer(segment, text) {
|
|
280
|
+
if (text.length <= segment.text.length || !text.startsWith(segment.text)) return [];
|
|
281
|
+
if (segment !== this.latestAnswer()) return [];
|
|
282
|
+
const remainder = text.slice(segment.text.length);
|
|
283
|
+
segment.text = text;
|
|
284
|
+
return [{ type: "text", text: remainder }];
|
|
285
|
+
}
|
|
286
|
+
closeSegments() {
|
|
287
|
+
for (const segment of this.segments) segment.open = false;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Close the turn's text. A turn that produced commentary but no answer text
|
|
291
|
+
* (for example one that ends waiting for a worker) replies with its latest
|
|
292
|
+
* commentary rather than nothing.
|
|
293
|
+
*/
|
|
294
|
+
settleSegments() {
|
|
295
|
+
this.closeSegments();
|
|
296
|
+
if (this.emptyFinalReply) return [];
|
|
297
|
+
if (this.segments.some((segment) => !segment.commentary)) return [];
|
|
298
|
+
const latest = [...this.segments].reverse().find((segment) => segment.commentary && segment.text);
|
|
299
|
+
if (!latest) return [];
|
|
300
|
+
latest.commentary = false;
|
|
301
|
+
return [{ type: "text", text: latest.text }];
|
|
302
|
+
}
|
|
303
|
+
startSegment(text, open, messageId) {
|
|
304
|
+
const separator = this.segments.some((segment) => !segment.commentary) ? "\n\n" : "";
|
|
305
|
+
this.segments.push({ text, open, commentary: false, messageId });
|
|
306
|
+
return { type: "text", text: separator + text };
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
function isCommentary(payload) {
|
|
310
|
+
return payload.phase === "commentary";
|
|
311
|
+
}
|
|
312
|
+
function isTurnScopedType(type) {
|
|
313
|
+
return type.startsWith("turn.") || type.startsWith("agent.") || type === "user.message";
|
|
314
|
+
}
|
|
315
|
+
function approvalPending(payload) {
|
|
316
|
+
const approvals = Array.isArray(payload.approvals) ? payload.approvals : [];
|
|
317
|
+
const first = approvals[0];
|
|
318
|
+
if (!first) return null;
|
|
319
|
+
const raw = asRecord(first);
|
|
320
|
+
const rawItem = asRecord(raw.rawItem);
|
|
321
|
+
const requestId = stringValue(rawItem.callId) ?? stringValue(rawItem.id) ?? stringValue(raw.id) ?? stringValue(raw.callId);
|
|
322
|
+
if (!requestId) return null;
|
|
323
|
+
return {
|
|
324
|
+
kind: "approval",
|
|
325
|
+
requestId,
|
|
326
|
+
name: stringValue(raw.name) ?? stringValue(raw.toolName) ?? stringValue(rawItem.name) ?? null,
|
|
327
|
+
payload: first
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
function humanInputPending(payload) {
|
|
331
|
+
const request = asRecord(payload.request);
|
|
332
|
+
const requestId = stringValue(request.id);
|
|
333
|
+
if (!requestId || !Array.isArray(request.questions)) return null;
|
|
334
|
+
return { kind: "human_input", requestId, name: null, payload: payload.request };
|
|
335
|
+
}
|
|
336
|
+
function asRecord(value) {
|
|
337
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
338
|
+
}
|
|
339
|
+
function stringValue(value) {
|
|
340
|
+
return typeof value === "string" ? value : void 0;
|
|
341
|
+
}
|
|
342
|
+
function isErrorOutput(payload) {
|
|
343
|
+
if (payload.error === true || payload.failed === true) return true;
|
|
344
|
+
const output = payload.output;
|
|
345
|
+
return !!output && typeof output === "object" && output.isError === true;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
export {
|
|
349
|
+
EMPTY_FINAL_REPLY_NOTICE,
|
|
350
|
+
turnCompletedWithEmptyFinalReply,
|
|
351
|
+
OpenGeniChatError,
|
|
352
|
+
ChatPendingFold,
|
|
353
|
+
ChatTurnFold,
|
|
354
|
+
approvalPending,
|
|
355
|
+
humanInputPending,
|
|
356
|
+
asRecord,
|
|
357
|
+
stringValue
|
|
358
|
+
};
|
|
359
|
+
//# sourceMappingURL=chunk-OV3POE62.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../contracts/src/session-final-reply.ts","../src/chat/types.ts","../src/chat/fold.ts"],"sourcesContent":["/** A response-quality notice, not a failed turn or a completed deliverable. */\nexport const EMPTY_FINAL_REPLY_NOTICE =\n \"The model returned no final reply after a reply reminder. Completed work is preserved; the goal and later updates are unaffected.\";\n\nexport type EmptyFinalReplyCompletion = {\n emptyFinalReply: true;\n};\n\nexport function turnCompletedWithEmptyFinalReply(payload: unknown): boolean {\n return (\n payload !== null &&\n typeof payload === \"object\" &&\n !Array.isArray(payload) &&\n (payload as { emptyFinalReply?: unknown }).emptyFinalReply === true\n );\n}\n","import type { FetchLike } from \"../client\";\nimport type { Chats } from \"../chats\";\nimport type { WorkspaceIdResolverOptions } from \"../tenant-workspaces\";\nimport type {\n CreateSessionRequest,\n AgentConfigRequest,\n HumanInputAnswer,\n LatencyMode,\n ReasoningEffort,\n SessionEvent,\n Session,\n SessionSkill,\n ToolRef,\n} from \"../types\";\n\n/** Which other sessions the agent may reach from this one. */\nexport type ChatAgentAccess = \"session\" | \"user\" | \"workspace\";\n\n/**\n * Compatibility option for personal or workspace Knowledge. `false` initializes\n * Knowledge authoring to Off; authorized retrieval remains available. Omitted\n * follows `chats`: private with a user, or legacy reach-based defaults without one.\n * Task notes cover temporary session-tree data.\n */\nexport type ChatMemory = \"user\" | \"workspace\" | false;\n\nexport type OpenGeniOptions = {\n /** Organization API key. Keep it on the server. */\n apiKey: string;\n /**\n * The organization (account) id that owns every workspace. Optional: when\n * omitted it is read once from the API key.\n */\n organizationId?: string | undefined;\n /** Defaults to `https://app.opengeni.ai`. */\n baseUrl?: string | undefined;\n /**\n * The product identity used as the external-source label for tenant\n * workspaces and end users. Defaults to `\"app\"`.\n */\n source?: string | undefined;\n fetch?: FetchLike | undefined;\n /** Display name for a tenant workspace created on first use. Defaults to the tenant id. */\n workspaceName?: ((tenant: string) => string) | undefined;\n /**\n * Per-user workspaces only (`{ user }` alone, or `chats: \"isolated\"`):\n * permissions for the one owner the SDK adds explicitly. Tenant workspaces\n * rely on Opengeni, which adds a user on their first request. Both default\n * to workspace read, session create/read/control (including sending\n * messages), file upload/read, and per-session MCP attachment; no admin\n * permissions. Never updates an existing membership: use\n * `client.updateExternalWorkspaceMember` for that.\n */\n memberPermissions?: WorkspaceIdResolverOptions[\"memberPermissions\"];\n};\n\n/**\n * Which workspace, in your own ids: `tenant` (one workspace per tenant),\n * neither (the `user`'s own workspace), or an explicit `workspaceId`.\n */\nexport type ChatTarget =\n | { tenant: string; workspaceId?: undefined }\n | { workspaceId: string; tenant?: undefined }\n | { user: string; tenant?: undefined; workspaceId?: undefined };\n\n/**\n * A workspace in your own ids, for `og.workspaceId(...)`: `{ tenant }` (one\n * workspace per tenant), `{ user }` (one workspace per user), or\n * `{ workspaceId }`. Precedence: workspaceId, then tenant, then user.\n */\nexport type WorkspaceTarget = {\n tenant?: string | undefined;\n user?: string | undefined;\n workspaceId?: string | undefined;\n};\n\nexport type ChatOptions = ChatTarget & {\n /**\n * Host-authenticated external user; resolved through server-side asUser().\n * Without a tenant or workspaceId, the user gets one workspace of their own.\n */\n user?: string | undefined;\n /** Stable conversation id; the session id is derived from it deterministically. */\n conversation: string;\n /** Prefer the actual Opengeni session ID for shared or existing conversations.\n * The acting user is independent of the conversation's identity. */\n sessionId?: string | undefined;\n /**\n * Private (default with a user) uses personal Knowledge and session-only reach;\n * shared uses workspace Knowledge/reach, isolated adds a workspace per tenant/user.\n * Without a user, omission keeps workspace visibility, session reach and Knowledge off.\n */\n chats?: Chats | undefined;\n /** Agent identity, capabilities and instructions; implicit markdown falls back on older servers. */\n agent?: AgentConfigRequest | undefined;\n /** Explicit agent reach overrides the `chats` default. */\n agentAccess?: ChatAgentAccess | undefined;\n memory?: ChatMemory | undefined;\n model?: string | undefined;\n instructions?: string | undefined;\n skills?: SessionSkill[] | undefined;\n tools?: ToolRef[] | undefined;\n /**\n * Raw create-request passthrough (for example `sandboxBackend: \"none\"` for a\n * pure chat). Explicit values win over facade-derived ones; the message and\n * identity/idempotency fields always come from the facade.\n */\n create?: Partial<CreateSessionRequest> | undefined;\n};\n\n/** A turn stopped to wait for a human decision. */\nexport type ChatPending = {\n kind: \"approval\" | \"human_input\";\n /** The id to pass back through `chat.respond`. */\n requestId: string;\n /** Tool name for an approval; null for structured human input. */\n name: string | null;\n /** The producer's exact payload (approval entry or human-input request). */\n payload: unknown;\n};\n\nexport type ChatReplyStatus = \"completed\" | \"pending\" | \"cancelled\";\n\nexport type ChatReply = {\n text: string;\n sessionId: string;\n workspaceId: string;\n turnId: string | null;\n /** `pending` waits on `chat.respond`; `cancelled` carries the text produced before the cancel. */\n status: ChatReplyStatus;\n /** Set when the turn is waiting on `chat.respond` instead of finished. */\n pending: ChatPending | null;\n /** A non-destructive completion without a model-authored final answer. */\n emptyFinalReply?: true;\n /** Display this informational notice when emptyFinalReply is present. */\n notice?: string;\n /** Every event consumed while folding this turn. */\n events: SessionEvent[];\n toString(): string;\n};\n\nexport type ChatToolStatus = \"started\" | \"completed\" | \"failed\";\n\nexport type ChatChunk =\n | { type: \"text\"; text: string }\n | {\n type: \"tool\";\n name: string;\n status: ChatToolStatus;\n callId?: string | undefined;\n input?: unknown;\n }\n | { type: \"pending\"; pending: ChatPending }\n | { type: \"done\"; reply: ChatReply };\n\nexport type ChatMessage = {\n role: \"user\" | \"assistant\";\n text: string;\n sequence: number;\n};\n\n/** Durable text and unresolved decisions restored when a chat is reopened. */\nexport type ChatSnapshot = {\n messages: ChatMessage[];\n pending: ChatPending[];\n status: Session[\"status\"] | null;\n};\n\nexport type ChatRespondInput =\n | { requestId: string; decision: \"approve\" | \"reject\"; message?: string | undefined }\n | { requestId: string; answers: HumanInputAnswer[] }\n | { requestId: string; skip: true };\n\n/** One earlier message from the product's own history, imported as context on the first send. */\nexport type ChatImportedMessage = { role: \"user\" | \"assistant\" | \"system\"; text: string };\n\nexport type ChatSendOptions = {\n signal?: AbortSignal | undefined;\n /** Supersede the current inference instead of queueing behind it. */\n steer?: boolean | undefined;\n /**\n * Earlier messages the product already holds, oldest first. Used only when\n * this send creates the session: they become the first message's\n * `modelContext` (skipped when `create.modelContext` was supplied), trimmed\n * from the oldest end to 30,000 characters. Never resent on later turns:\n * after the first message Opengeni owns the history.\n */\n importedHistory?: ChatImportedMessage[] | undefined;\n /** Model for this message's turn; omitted keeps the session's current policy. */\n model?: string | undefined;\n reasoningEffort?: ReasoningEffort | undefined;\n latencyMode?: LatencyMode | undefined;\n /**\n * Model-visible application context for this one message (for example the\n * page or record the user is looking at). Not shown in the transcript and not\n * secret. On the creating message it is combined with imported history.\n */\n modelContext?: string | undefined;\n};\n\nexport type ChatSessionListOptions = ChatTarget & {\n user?: string | undefined;\n /** Match the chat's mode; isolated lists that user's separate workspace. */\n chats?: Chats | undefined;\n limit?: number | undefined;\n};\n\n/** A turn ended without a usable reply, or the facade was misused. */\nexport class OpenGeniChatError extends Error {\n readonly code: string;\n readonly event: SessionEvent | null;\n\n constructor(code: string, message: string, event: SessionEvent | null = null) {\n super(message);\n this.name = \"OpenGeniChatError\";\n this.code = code;\n this.event = event;\n }\n}\n","import type { SessionEvent } from \"../types\";\nimport {\n EMPTY_FINAL_REPLY_NOTICE,\n turnCompletedWithEmptyFinalReply,\n} from \"@opengeni/contracts/session-final-reply\";\nimport { OpenGeniChatError, type ChatChunk, type ChatPending, type ChatReply } from \"./types\";\n\n/**\n * Event folding shared by `send`, `stream`, and every protocol adapter.\n *\n * One fold covers one logical turn: text deltas accumulate into message\n * segments (a tool call closes the current segment, the completed event\n * reconciles it), tool call/output pairs become tool chunks, and the turn\n * settles on a terminal event or a human wait. Events that carry a different\n * turn id than the expected one are ignored so a queued follow-up never ends\n * early on the previous turn's settlement.\n *\n * A segment belongs to one provider message when events carry `messageId`: a\n * delta for another message starts a new segment, and a completion reconciles\n * only the segment of its own message. Completions may arrive after later\n * messages already streamed, so matching by position would let one message's\n * completion close another's segment and repeat its text.\n *\n * Commentary (`phase: \"commentary\"`) narrates the work, like a tool chunk, so\n * it is held back from the reply text. Only a turn that settles without any\n * answer text falls back to its latest commentary, emitted at settlement.\n */\n\nexport type ChatTurnTerminal = \"completed\" | \"failed\" | \"cancelled\" | \"pending\";\n\nexport type ChatFoldStep = {\n chunks: ChatChunk[];\n terminal: ChatTurnTerminal | null;\n};\n\n/** Incremental replay of unresolved requests, without retaining the event log. */\nexport class ChatPendingFold {\n private readonly requests = new Map<string, { pending: ChatPending; turnId: string | null }>();\n\n push(event: SessionEvent): void {\n const payload = asRecord(event.payload);\n if (event.type === \"session.requiresAction\") {\n for (const [key, request] of this.requests) {\n if (request.pending.kind === \"approval\") this.requests.delete(key);\n }\n for (const approval of Array.isArray(payload.approvals) ? payload.approvals : []) {\n const pending = approvalPending({ approvals: [approval] });\n if (pending) this.put(pending, event.turnId ?? null);\n }\n } else if (event.type === \"session.humanInput.requested\") {\n const pending = humanInputPending(payload);\n if (pending) this.put(pending, event.turnId ?? null);\n } else if (event.type === \"user.approvalDecision\") {\n this.requests.delete(`approval:${payload.approvalId}`);\n } else if (event.type === \"user.humanInputResponse\") {\n this.requests.delete(`human_input:${payload.requestId}`);\n } else if ([\"turn.completed\", \"turn.failed\", \"turn.cancelled\"].includes(event.type)) {\n for (const [key, request] of this.requests) {\n if (request.turnId === null || event.turnId == null || request.turnId === event.turnId) {\n this.requests.delete(key);\n }\n }\n }\n }\n\n pending(now = Date.now()): ChatPending[] {\n return [...this.requests.values()]\n .map((request) => request.pending)\n .filter((pending) => {\n if (pending.kind !== \"human_input\") return true;\n const expiresAt = asRecord(pending.payload).expiresAt;\n return expiresAt == null || (typeof expiresAt === \"string\" && Date.parse(expiresAt) > now);\n });\n }\n\n private put(pending: ChatPending, turnId: string | null): void {\n this.requests.set(`${pending.kind}:${pending.requestId}`, { pending, turnId });\n }\n}\n\ntype Segment = {\n text: string;\n open: boolean;\n commentary: boolean;\n /** Provider message identity; `null` for events that carry none. */\n messageId: string | null;\n};\n\nfunction noStep(): ChatFoldStep {\n return { chunks: [], terminal: null };\n}\n\nexport class ChatTurnFold {\n readonly events: SessionEvent[] = [];\n turnId: string | null;\n pending: ChatPending | null = null;\n failure: SessionEvent | null = null;\n private emptyFinalReply = false;\n private readonly segments: Segment[] = [];\n private readonly openTools = new Map<string, string>();\n\n constructor(\n private readonly workspaceId: string,\n private readonly sessionId: string,\n expectedTurnId: string | null,\n ) {\n this.turnId = expectedTurnId;\n }\n\n get text(): string {\n return this.segments\n .filter((segment) => !segment.commentary)\n .map((segment) => segment.text)\n .filter((text) => text.length > 0)\n .join(\"\\n\\n\");\n }\n\n push(event: SessionEvent): ChatFoldStep {\n const eventTurnId = typeof event.turnId === \"string\" ? event.turnId : null;\n if (this.turnId && eventTurnId && eventTurnId !== this.turnId) {\n return { chunks: [], terminal: null };\n }\n if (!this.turnId && eventTurnId && isTurnScopedType(event.type)) {\n this.turnId = eventTurnId;\n }\n this.events.push(event);\n const payload = asRecord(event.payload);\n switch (event.type) {\n case \"agent.message.delta\": {\n const text = stringValue(payload.text);\n if (!text) return noStep();\n const messageId = stringValue(payload.messageId) || null;\n if (messageId) return this.messageDelta(messageId, text, isCommentary(payload));\n const open = this.segments.at(-1);\n if (isCommentary(payload)) {\n if (open?.open && open.commentary) {\n open.text += text;\n } else {\n this.closeSegments();\n this.segments.push({ text, open: true, commentary: true, messageId: null });\n }\n return noStep();\n }\n if (open?.open && !open.commentary) {\n open.text += text;\n } else {\n this.closeSegments();\n return { chunks: [this.startSegment(text, true, null)], terminal: null };\n }\n return { chunks: [{ type: \"text\", text }], terminal: null };\n }\n case \"agent.message.completed\": {\n const text = stringValue(payload.text) ?? \"\";\n const messageId = stringValue(payload.messageId) || null;\n if (messageId) return this.messageCompleted(messageId, text, isCommentary(payload));\n const last = this.segments.at(-1);\n if (isCommentary(payload)) {\n if (last?.commentary && (last.open || text.startsWith(last.text))) {\n last.open = false;\n if (text) last.text = text;\n return noStep();\n }\n // Undeclared deltas that the completion reveals as commentary were\n // already streamed as reply text; keep the reply equal to the stream.\n const streamed = last && !last.commentary && last.open && text.startsWith(last.text);\n if (!streamed) {\n if (text) {\n this.closeSegments();\n this.segments.push({ text, open: false, commentary: true, messageId: null });\n }\n return noStep();\n }\n }\n const target = last?.commentary ? undefined : last;\n if (!target || (!target.open && target.text && !text.startsWith(target.text))) {\n if (!text) return noStep();\n // The phase-less settlement copy of an answer this turn already\n // completed message by message.\n if (payload.phase === undefined && this.latestAnswer()?.text === text) return noStep();\n this.closeSegments();\n return { chunks: [this.startSegment(text, false, null)], terminal: null };\n }\n target.open = false;\n return { chunks: this.extendAnswer(target, text), terminal: null };\n }\n case \"agent.toolCall.created\": {\n this.closeSegments();\n const name = stringValue(payload.name) ?? \"tool\";\n const callId = stringValue(payload.id);\n if (callId) this.openTools.set(callId, name);\n return {\n chunks: [\n {\n type: \"tool\",\n name,\n status: \"started\",\n ...(callId ? { callId } : {}),\n ...(\"arguments\" in payload ? { input: payload.arguments } : {}),\n },\n ],\n terminal: null,\n };\n }\n case \"agent.toolCall.output\": {\n const callId = stringValue(payload.id);\n const name = (callId ? this.openTools.get(callId) : undefined) ?? \"tool\";\n if (callId) this.openTools.delete(callId);\n return {\n chunks: [\n {\n type: \"tool\",\n name,\n status: isErrorOutput(payload) ? \"failed\" : \"completed\",\n ...(callId ? { callId } : {}),\n },\n ],\n terminal: null,\n };\n }\n case \"session.requiresAction\": {\n const pending = approvalPending(payload);\n if (!pending) return { chunks: [], terminal: null };\n this.pending = pending;\n return {\n chunks: [...this.settleSegments(), { type: \"pending\", pending }],\n terminal: \"pending\",\n };\n }\n case \"session.humanInput.requested\": {\n const pending = humanInputPending(payload);\n if (!pending) return { chunks: [], terminal: null };\n this.pending = pending;\n return {\n chunks: [...this.settleSegments(), { type: \"pending\", pending }],\n terminal: \"pending\",\n };\n }\n case \"turn.completed\":\n this.emptyFinalReply = turnCompletedWithEmptyFinalReply(payload);\n return { chunks: this.settleSegments(), terminal: \"completed\" };\n case \"turn.failed\":\n this.failure = event;\n return { chunks: this.settleSegments(), terminal: \"failed\" };\n case \"turn.cancelled\":\n return { chunks: this.settleSegments(), terminal: \"cancelled\" };\n default:\n return { chunks: [], terminal: null };\n }\n }\n\n reply(terminal: ChatTurnTerminal): ChatReply {\n const text = this.text;\n return {\n text,\n sessionId: this.sessionId,\n workspaceId: this.workspaceId,\n turnId: this.turnId,\n status:\n terminal === \"pending\" ? \"pending\" : terminal === \"cancelled\" ? \"cancelled\" : \"completed\",\n pending: this.pending,\n ...(this.emptyFinalReply\n ? { emptyFinalReply: true as const, notice: EMPTY_FINAL_REPLY_NOTICE }\n : {}),\n events: [...this.events],\n toString: () => text,\n };\n }\n\n /** The error to throw for a `turn.failed` settlement. */\n failureError(): OpenGeniChatError {\n const payload = asRecord(this.failure?.payload);\n const code = stringValue(payload.code) ?? \"turn_failed\";\n const message =\n stringValue(payload.error) ?? stringValue(payload.message) ?? \"The turn failed.\";\n return new OpenGeniChatError(code, message, this.failure);\n }\n\n private messageDelta(messageId: string, text: string, commentary: boolean): ChatFoldStep {\n const segment = this.segmentOf(messageId);\n if (segment?.open) {\n segment.text += text;\n return segment.commentary ? noStep() : { chunks: [{ type: \"text\", text }], terminal: null };\n }\n // Providers stream messages one after another: every earlier one is done.\n this.closeSegments();\n if (commentary) {\n this.segments.push({ text, open: true, commentary: true, messageId });\n return noStep();\n }\n return { chunks: [this.startSegment(text, true, messageId)], terminal: null };\n }\n\n private messageCompleted(messageId: string, text: string, commentary: boolean): ChatFoldStep {\n const segment = this.segmentOf(messageId) ?? this.unidentifiedStreamingSegment(text);\n if (segment) {\n segment.messageId = messageId;\n segment.open = false;\n if (segment.commentary) {\n if (text) segment.text = text;\n return noStep();\n }\n // Streamed as reply text, even when the completion reveals commentary:\n // the reply stays equal to what append-only consumers already have.\n return { chunks: this.extendAnswer(segment, text), terminal: null };\n }\n if (!text) return noStep();\n if (commentary) {\n this.segments.push({ text, open: false, commentary: true, messageId });\n return noStep();\n }\n return { chunks: [this.startSegment(text, false, messageId)], terminal: null };\n }\n\n private segmentOf(messageId: string): Segment | undefined {\n return this.findLastSegment((segment) => segment.messageId === messageId);\n }\n\n /** Deltas that carried no identity, still streaming the text this completion names. */\n private unidentifiedStreamingSegment(text: string): Segment | undefined {\n const last = this.segments.at(-1);\n return last?.open && last.messageId === null && text.startsWith(last.text) ? last : undefined;\n }\n\n private latestAnswer(): Segment | undefined {\n return this.findLastSegment((segment) => !segment.commentary);\n }\n\n private findLastSegment(predicate: (segment: Segment) => boolean): Segment | undefined {\n for (let index = this.segments.length - 1; index >= 0; index -= 1) {\n const segment = this.segments[index]!;\n if (predicate(segment)) return segment;\n }\n return undefined;\n }\n\n /**\n * Complete an answer segment. Only the newest answer can grow: a remainder\n * for an earlier one would land after later text for append-only consumers.\n */\n private extendAnswer(segment: Segment, text: string): ChatChunk[] {\n if (text.length <= segment.text.length || !text.startsWith(segment.text)) return [];\n if (segment !== this.latestAnswer()) return [];\n const remainder = text.slice(segment.text.length);\n segment.text = text;\n return [{ type: \"text\", text: remainder }];\n }\n\n private closeSegments(): void {\n for (const segment of this.segments) segment.open = false;\n }\n\n /**\n * Close the turn's text. A turn that produced commentary but no answer text\n * (for example one that ends waiting for a worker) replies with its latest\n * commentary rather than nothing.\n */\n private settleSegments(): ChatChunk[] {\n this.closeSegments();\n // A typed missing-final notice must not turn progress commentary into\n // the missing answer. Ordinary waits retain their historical fallback.\n if (this.emptyFinalReply) return [];\n if (this.segments.some((segment) => !segment.commentary)) return [];\n const latest = [...this.segments]\n .reverse()\n .find((segment) => segment.commentary && segment.text);\n if (!latest) return [];\n latest.commentary = false;\n return [{ type: \"text\", text: latest.text }];\n }\n\n private startSegment(text: string, open: boolean, messageId: string | null): ChatChunk {\n // Match the separator used by `text` before exposing the next segment to\n // append-only consumers (React and both protocol adapters).\n const separator = this.segments.some((segment) => !segment.commentary) ? \"\\n\\n\" : \"\";\n this.segments.push({ text, open, commentary: false, messageId });\n return { type: \"text\", text: separator + text };\n }\n}\n\nfunction isCommentary(payload: Record<string, unknown>): boolean {\n return payload.phase === \"commentary\";\n}\n\nfunction isTurnScopedType(type: string): boolean {\n return type.startsWith(\"turn.\") || type.startsWith(\"agent.\") || type === \"user.message\";\n}\n\nexport function approvalPending(payload: Record<string, unknown>): ChatPending | null {\n const approvals = Array.isArray(payload.approvals) ? payload.approvals : [];\n const first = approvals[0];\n if (!first) return null;\n const raw = asRecord(first);\n const rawItem = asRecord(raw.rawItem);\n const requestId =\n stringValue(rawItem.callId) ??\n stringValue(rawItem.id) ??\n stringValue(raw.id) ??\n stringValue(raw.callId);\n if (!requestId) return null;\n return {\n kind: \"approval\",\n requestId,\n name: stringValue(raw.name) ?? stringValue(raw.toolName) ?? stringValue(rawItem.name) ?? null,\n payload: first,\n };\n}\n\nexport function humanInputPending(payload: Record<string, unknown>): ChatPending | null {\n const request = asRecord(payload.request);\n const requestId = stringValue(request.id);\n if (!requestId || !Array.isArray(request.questions)) return null;\n return { kind: \"human_input\", requestId, name: null, payload: payload.request };\n}\n\nexport function asRecord(value: unknown): Record<string, unknown> {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n}\n\nexport function stringValue(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction isErrorOutput(payload: Record<string, unknown>): boolean {\n if (payload.error === true || payload.failed === true) return true;\n const output = payload.output;\n return (\n !!output && typeof output === \"object\" && (output as { isError?: unknown }).isError === true\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
OpenGeniDocumentAuthorityClient
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-MJWC6GTA.js";
|
|
4
4
|
|
|
5
5
|
// src/artifact-client.ts
|
|
6
6
|
var OpenGeniClient = class extends OpenGeniDocumentAuthorityClient {
|
|
@@ -121,4 +121,4 @@ var OpenGeniClient = class extends OpenGeniDocumentAuthorityClient {
|
|
|
121
121
|
export {
|
|
122
122
|
OpenGeniClient
|
|
123
123
|
};
|
|
124
|
-
//# sourceMappingURL=chunk-
|
|
124
|
+
//# sourceMappingURL=chunk-S5XTUA7L.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/insights-usage.ts"],"sourcesContent":["// Type-only references keep this opt-in SDK leaf free of zod/root contracts.\nimport type {\n OrganizationInsightsUsageQueryInput,\n OrganizationInsightsCallsQueryInput,\n InsightsUsageRange,\n InsightsUsagePayer,\n InsightsUsageSource,\n} from \"@opengeni/contracts/insights-usage\";\n\nexport type {\n InsightsSiteUsageQuery,\n InsightsSiteUsageRow,\n InsightsSiteUsageResponse,\n InsightsUsageRange,\n InsightsUsageGroupBy,\n InsightsUsagePayer,\n InsightsUsageSource,\n InsightsUsageTokens,\n InsightsUsageClassMicros,\n InsightsUsageMeasures,\n InsightsUsageScope,\n InsightsUsageGroup,\n InsightsUsageSeriesPoint,\n InsightsUsageFacets,\n InsightsUsageResponse,\n InsightsCall,\n InsightsCallsResponse,\n} from \"@opengeni/contracts/insights-usage\";\n\n/** Custom selections require both inclusive UTC calendar days. */\nexport type InsightsUsageWindowOptions =\n | { range?: Exclude<InsightsUsageRange, \"custom\">; from?: never; to?: never }\n | { range: \"custom\"; from: string; to: string };\n\ntype FilterOptions<T> = Omit<T, \"range\" | \"from\" | \"to\" | \"limit\" | \"payer\" | \"source\"> &\n InsightsUsageWindowOptions & {\n limit?: number;\n payer?: InsightsUsagePayer | InsightsUsagePayer[];\n source?: InsightsUsageSource | InsightsUsageSource[];\n };\n\nexport type OrganizationInsightsUsageOptions = FilterOptions<\n Omit<OrganizationInsightsUsageQueryInput, \"seriesGroups\">\n> & { seriesGroups?: boolean };\n/** workspaceId is intersected with the path workspace by the existing server gate. */\nexport type WorkspaceInsightsUsageOptions = OrganizationInsightsUsageOptions;\nexport type OrganizationInsightsCallsOptions = FilterOptions<OrganizationInsightsCallsQueryInput>;\nexport type WorkspaceInsightsCallsOptions = OrganizationInsightsCallsOptions;\nexport type InsightsCallsScope =\n | { kind: \"workspace\"; workspaceId: string }\n | { kind: \"organization\"; accountId: string };\n\n/** Arrays repeat; comma strings, false and opaque values round-trip unchanged. */\nexport function insightsUsageQueryString(\n options: OrganizationInsightsUsageOptions | OrganizationInsightsCallsOptions,\n): string {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(options)) {\n if (value === undefined) continue;\n for (const item of Array.isArray(value) ? value : [value]) params.append(key, String(item));\n }\n const query = params.toString();\n return query ? `?${query}` : \"\";\n}\n"],"mappings":";AAqDO,SAAS,yBACd,SACQ;AACR,QAAM,SAAS,IAAI,gBAAgB;AACnC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,QAAI,UAAU,OAAW;AACzB,eAAW,QAAQ,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK,EAAG,QAAO,OAAO,KAAK,OAAO,IAAI,CAAC;AAAA,EAC5F;AACA,QAAM,QAAQ,OAAO,SAAS;AAC9B,SAAO,QAAQ,IAAI,KAAK,KAAK;AAC/B;","names":[]}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ComputerNativeCallRequest, ComputerNativeReceipt } from "@opengeni/contracts";
|
|
2
|
+
import type { InsightsSiteUsageQuery, InsightsSiteUsageResponse } from "@opengeni/contracts/insights-usage";
|
|
2
3
|
import type { ClaudeSubscriptionAccountsResponse, ClaudeSubscriptionAccount, ClaudeSubscriptionOAuthStartRequest, ClaudeSubscriptionSetupTokenRequest, SubscriptionPoolSettings } from "@opengeni/contracts";
|
|
3
4
|
import { type WorkspaceInsightsUsageOptions, type OrganizationInsightsUsageOptions, type WorkspaceInsightsCallsOptions, type OrganizationInsightsCallsOptions, type InsightsCallsScope, type InsightsUsageResponse, type InsightsCallsResponse } from "./insights-usage.js";
|
|
4
5
|
import type { ArtifactCatalogKind, ArtifactCatalogListOptions, ArtifactCatalogListResponse, ArtifactPinResponse } from "./artifact-catalog.js";
|
|
@@ -1895,6 +1896,8 @@ export declare class OpenGeniClient {
|
|
|
1895
1896
|
signal?: AbortSignal;
|
|
1896
1897
|
}): Promise<WorkspaceInsightsResponse>;
|
|
1897
1898
|
/** Shared usage under the existing workspace access gate. */
|
|
1899
|
+
getWorkspaceInsightsSiteUsage(workspaceId: string, options?: Partial<InsightsSiteUsageQuery>, requestOptions?: OpenGeniRequestOptions): Promise<InsightsSiteUsageResponse>;
|
|
1900
|
+
/** Shared usage under the existing workspace access gate. */
|
|
1898
1901
|
getWorkspaceInsightsUsage(workspaceId: string, options?: WorkspaceInsightsUsageOptions, requestOptions?: OpenGeniRequestOptions): Promise<InsightsUsageResponse>;
|
|
1899
1902
|
/** Shared usage under the existing organization access gate. */
|
|
1900
1903
|
getOrganizationInsightsUsage(accountId: string, options?: OrganizationInsightsUsageOptions, requestOptions?: OpenGeniRequestOptions): Promise<InsightsUsageResponse>;
|
package/dist/core.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
OpenGeniDocumentAuthorityClient
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-MJWC6GTA.js";
|
|
4
4
|
import {
|
|
5
5
|
resolveWorkspaceVoiceInputEnabled
|
|
6
6
|
} from "./chunk-GZQSWAKD.js";
|
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
} from "./chunk-P7UWKORG.js";
|
|
12
12
|
import {
|
|
13
13
|
parseDeprecationNotice
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import "./chunk-
|
|
14
|
+
} from "./chunk-BWAJPU5S.js";
|
|
15
|
+
import "./chunk-X5ITQVXE.js";
|
|
16
16
|
import "./chunk-4AHR4KGA.js";
|
|
17
17
|
import {
|
|
18
18
|
OPENGENI_API_CONTRACT_HEADER,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
OpenGeniDocumentAuthorityClient
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-MJWC6GTA.js";
|
|
4
|
+
import "./chunk-BWAJPU5S.js";
|
|
5
|
+
import "./chunk-X5ITQVXE.js";
|
|
6
6
|
import "./chunk-4AHR4KGA.js";
|
|
7
7
|
import "./chunk-KADZ5PGG.js";
|
|
8
8
|
import "./chunk-O7KANXC3.js";
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import "./chunk-PDU6EU2M.js";
|
|
7
|
-
import "./chunk-JP62FZSI.js";
|
|
2
|
+
OpenGeniEmbeddingClient
|
|
3
|
+
} from "./chunk-HP7NVCAX.js";
|
|
4
|
+
import "./chunk-S5XTUA7L.js";
|
|
5
|
+
import "./chunk-MJWC6GTA.js";
|
|
8
6
|
import {
|
|
9
7
|
humanizeModelSlug,
|
|
10
8
|
isRawModelLabel,
|
|
@@ -96,7 +94,11 @@ import {
|
|
|
96
94
|
isOpenGeniSiteBridgeRequestMessage,
|
|
97
95
|
isSiteCatalogStaleError,
|
|
98
96
|
sanitizeOpenGeniSiteToolCallRequest
|
|
99
|
-
} from "./chunk-
|
|
97
|
+
} from "./chunk-F4OXWFCU.js";
|
|
98
|
+
import {
|
|
99
|
+
EMPTY_FINAL_REPLY_NOTICE,
|
|
100
|
+
turnCompletedWithEmptyFinalReply
|
|
101
|
+
} from "./chunk-OV3POE62.js";
|
|
100
102
|
import {
|
|
101
103
|
OpenGeniToolCallError,
|
|
102
104
|
OpenGeniToolReapprovalRequiredError,
|
|
@@ -120,8 +122,8 @@ import {
|
|
|
120
122
|
vaultErrorCode,
|
|
121
123
|
vaultErrorDetail,
|
|
122
124
|
vaultsApi
|
|
123
|
-
} from "./chunk-
|
|
124
|
-
import "./chunk-
|
|
125
|
+
} from "./chunk-BWAJPU5S.js";
|
|
126
|
+
import "./chunk-X5ITQVXE.js";
|
|
125
127
|
import {
|
|
126
128
|
parseSseStream,
|
|
127
129
|
sessionEventStreamCoveredThrough,
|