@opengeni/sdk 3.3.2 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1007 -72
- package/dist/adapters/express.d.ts +31 -0
- package/dist/adapters/express.js +87 -0
- package/dist/adapters/express.js.map +1 -0
- package/dist/adapters/hono.d.ts +16 -0
- package/dist/adapters/hono.js +8 -0
- package/dist/adapters/hono.js.map +1 -0
- package/dist/adapters/next.d.ts +29 -0
- package/dist/adapters/next.js +22 -0
- package/dist/adapters/next.js.map +1 -0
- package/dist/allowance-refusal.d.ts +2 -0
- package/dist/allowance-refusal.js +50 -0
- package/dist/allowance-refusal.js.map +1 -0
- package/dist/app-links.d.ts +42 -0
- package/dist/app-links.js +66 -0
- package/dist/app-links.js.map +1 -0
- package/dist/artifact-catalog.d.ts +40 -0
- package/dist/artifact-client.d.ts +20 -8
- package/dist/artifacts.d.ts +1 -1
- package/dist/artifacts.js +8 -6
- package/dist/automations.js +8 -2
- package/dist/automations.js.map +1 -1
- package/dist/azure-live-transport.d.ts +32 -0
- package/dist/browser.d.ts +7 -2
- package/dist/browser.js +27 -5
- package/dist/chat/fold.d.ts +75 -0
- package/dist/chat/handler.d.ts +41 -0
- package/dist/chat/http.d.ts +67 -0
- package/dist/chat/ids.d.ts +34 -0
- package/dist/chat/index.d.ts +9 -0
- package/dist/chat/index.js +1369 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat/openai.d.ts +30 -0
- package/dist/chat/opengeni.d.ts +129 -0
- package/dist/chat/types.d.ts +207 -0
- package/dist/chat/vercel.d.ts +49 -0
- package/dist/chats.d.ts +8 -0
- package/dist/chunk-4AHR4KGA.js +301 -0
- package/dist/chunk-4AHR4KGA.js.map +1 -0
- package/dist/chunk-6GYGMLX4.js +332 -0
- package/dist/chunk-6GYGMLX4.js.map +1 -0
- package/dist/chunk-7EWT3PV6.js +368 -0
- package/dist/chunk-7EWT3PV6.js.map +1 -0
- package/dist/chunk-FTWVVPR6.js +1665 -0
- package/dist/chunk-FTWVVPR6.js.map +1 -0
- package/dist/{chunk-VYCTL62C.js → chunk-GZQSWAKD.js} +1 -1
- package/dist/chunk-GZQSWAKD.js.map +1 -0
- package/dist/chunk-KGEABAID.js +71 -0
- package/dist/chunk-KGEABAID.js.map +1 -0
- package/dist/{chunk-YKZME56C.js → chunk-KWADQ227.js} +3 -3
- package/dist/{chunk-YKZME56C.js.map → chunk-KWADQ227.js.map} +1 -1
- package/dist/{chunk-JUS2UYRP.js → chunk-NCU5OAN7.js} +27 -2
- package/dist/chunk-NCU5OAN7.js.map +1 -0
- package/dist/{chunk-YXQX7RQT.js → chunk-OI5YLASH.js} +73 -2
- package/dist/chunk-OI5YLASH.js.map +1 -0
- package/dist/chunk-OV3POE62.js +359 -0
- package/dist/chunk-OV3POE62.js.map +1 -0
- package/dist/chunk-P7UWKORG.js +561 -0
- package/dist/chunk-P7UWKORG.js.map +1 -0
- package/dist/chunk-QGEIL4TR.js +195 -0
- package/dist/chunk-QGEIL4TR.js.map +1 -0
- package/dist/{chunk-TRNI7KEO.js → chunk-S2NLS3ES.js} +3669 -1281
- package/dist/chunk-S2NLS3ES.js.map +1 -0
- package/dist/chunk-UM4ZXXJR.js +9 -0
- package/dist/chunk-UM4ZXXJR.js.map +1 -0
- package/dist/{chunk-QT3KFVDP.js → chunk-UME3X7CP.js} +28 -32
- package/dist/chunk-UME3X7CP.js.map +1 -0
- package/dist/chunk-VT4YM4XQ.js +210 -0
- package/dist/chunk-VT4YM4XQ.js.map +1 -0
- package/dist/chunk-WSYYXONG.js +1602 -0
- package/dist/chunk-WSYYXONG.js.map +1 -0
- package/dist/{chunk-C2H7HBNP.js → chunk-WVCJRSGJ.js} +119 -14
- package/dist/chunk-WVCJRSGJ.js.map +1 -0
- package/dist/chunk-X5ITQVXE.js +15 -0
- package/dist/chunk-X5ITQVXE.js.map +1 -0
- package/dist/chunk-XA7HVIHI.js +126 -0
- package/dist/chunk-XA7HVIHI.js.map +1 -0
- package/dist/{chunk-KKRO2VCP.js → chunk-YJCHB7R3.js} +60 -12
- package/dist/chunk-YJCHB7R3.js.map +1 -0
- package/dist/chunk-YKIHNLWD.js +153 -0
- package/dist/chunk-YKIHNLWD.js.map +1 -0
- package/dist/chunk-ZDUBPV33.js +277 -0
- package/dist/chunk-ZDUBPV33.js.map +1 -0
- package/dist/client.d.ts +1068 -118
- package/dist/codex-realtime-controller.d.ts +13 -0
- package/dist/codex-realtime-controller.js +4 -2
- package/dist/codex-realtime-v3-wire.d.ts +3 -2
- package/dist/codex-realtime.d.ts +5 -1
- package/dist/company-brain.d.ts +1 -11
- package/dist/core.d.ts +7 -2
- package/dist/core.js +25 -6
- package/dist/deprecation.d.ts +47 -0
- package/dist/document-authority-client.d.ts +24 -2
- package/dist/document-authority.js +7 -5
- package/dist/editable-artifacts/index.d.ts +1 -1
- package/dist/editable-artifacts/types.d.ts +12 -2
- package/dist/editable-artifacts.js +19 -3
- package/dist/editable-artifacts.js.map +1 -1
- package/dist/embedding-client.d.ts +129 -0
- package/dist/errors.d.ts +76 -1
- package/dist/external-vault-receiver.d.ts +203 -0
- package/dist/external-vault-receiver.js +564 -0
- package/dist/external-vault-receiver.js.map +1 -0
- package/dist/feedback.d.ts +23 -0
- package/dist/gateway-realtime-transport.js +1 -1
- package/dist/github-repositories.d.ts +10 -0
- package/dist/github-repositories.js +36 -0
- package/dist/github-repositories.js.map +1 -0
- package/dist/index.d.ts +62 -11
- package/dist/index.js +557 -338
- package/dist/index.js.map +1 -1
- package/dist/insights-usage.d.ts +33 -0
- package/dist/insights-usage.js +7 -0
- package/dist/insights-usage.js.map +1 -0
- package/dist/interaction.d.ts +165 -71
- package/dist/interaction.js +2 -2
- package/dist/knowledge.d.ts +7 -0
- package/dist/knowledge.js +20 -0
- package/dist/knowledge.js.map +1 -0
- package/dist/known-tools.d.ts +4 -0
- package/dist/message-links.d.ts +68 -0
- package/dist/model-context.d.ts +68 -0
- package/dist/model-display.d.ts +2 -0
- package/dist/model-display.js +17 -0
- package/dist/model-display.js.map +1 -0
- package/dist/model-picker-order.d.ts +1 -0
- package/dist/model-picker-order.js +10 -0
- package/dist/model-picker-order.js.map +1 -0
- package/dist/organization-integration-policy.d.ts +26 -0
- package/dist/organization-integration-policy.js +26 -0
- package/dist/organization-integration-policy.js.map +1 -0
- package/dist/pr-review-client.d.ts +1 -1
- package/dist/pr-review.d.ts +1 -1
- package/dist/pr-review.js.map +1 -1
- package/dist/preference-registry.d.ts +1 -1
- package/dist/prepared-mcp-setup.d.ts +5 -0
- package/dist/proxy.d.ts +13 -11
- package/dist/realtime.d.ts +1 -1
- package/dist/realtime.js +253 -7
- package/dist/realtime.js.map +1 -1
- package/dist/session-history-import.d.ts +22 -0
- package/dist/session-history-import.js +36 -0
- package/dist/session-history-import.js.map +1 -0
- package/dist/session-list-entries.d.ts +1 -0
- package/dist/session-list-entries.js +7 -0
- package/dist/session-list-entries.js.map +1 -0
- package/dist/session-message-search.d.ts +53 -0
- package/dist/session-proxy-client.d.ts +28 -0
- package/dist/session-proxy.d.ts +334 -0
- package/dist/session-proxy.js +24 -0
- package/dist/session-proxy.js.map +1 -0
- package/dist/session-titles.d.ts +2 -28
- package/dist/session-usage-limits.d.ts +10 -0
- package/dist/session-usage-limits.js +43 -0
- package/dist/session-usage-limits.js.map +1 -0
- package/dist/shared-catalog-loader.d.ts +34 -0
- package/dist/site-ai.d.ts +35 -0
- package/dist/site-bridge-host.d.ts +112 -0
- package/dist/site-bridge-host.js +286 -0
- package/dist/site-bridge-host.js.map +1 -0
- package/dist/site-browser-entry.d.ts +1 -0
- package/dist/site-browser-runtime.gen.d.ts +1 -0
- package/dist/site-data.d.ts +178 -0
- package/dist/site-document.d.ts +5 -0
- package/dist/site-document.js +20 -0
- package/dist/site-document.js.map +1 -0
- package/dist/site-document.test.d.ts +1 -0
- package/dist/site-http.d.ts +17 -0
- package/dist/site-sql.d.ts +31 -0
- package/dist/site-tool-bridge.d.ts +57 -0
- package/dist/site.d.ts +186 -0
- package/dist/site.js +63 -0
- package/dist/site.js.map +1 -0
- package/dist/skills.d.ts +75 -0
- package/dist/sse.d.ts +1 -1
- package/dist/stream.d.ts +2 -0
- package/dist/tenant-workspaces.d.ts +47 -0
- package/dist/tenant-workspaces.js +8 -0
- package/dist/tenant-workspaces.js.map +1 -0
- package/dist/tool-auth.d.ts +87 -0
- package/dist/tool-auth.js +23 -0
- package/dist/tool-auth.js.map +1 -0
- package/dist/tool-display-metadata.d.ts +3 -0
- package/dist/tools-37DCTCNZ.js +12 -0
- package/dist/tools-37DCTCNZ.js.map +1 -0
- package/dist/tools.d.ts +81 -0
- package/dist/transcription.d.ts +1 -1
- package/dist/types.d.ts +2807 -583
- package/dist/usage-allowances.d.ts +36 -0
- package/dist/usage-allowances.js +80 -0
- package/dist/usage-allowances.js.map +1 -0
- package/dist/vault-types.d.ts +324 -0
- package/dist/vaults-api.d.ts +65 -0
- package/dist/workspace-artifacts.d.ts +47 -5
- package/dist/workspace-instruction-policies.d.ts +2 -2
- package/dist/workspace-integrations.d.ts +74 -0
- package/dist/workspace-integrations.js +67 -0
- package/dist/workspace-integrations.js.map +1 -0
- package/dist/workspace-state.d.ts +8 -71
- package/package.json +103 -5
- package/src/adapters/express.ts +136 -0
- package/src/adapters/hono.ts +18 -0
- package/src/adapters/next.ts +42 -0
- package/src/allowance-refusal.ts +5 -0
- package/src/app-links.ts +117 -0
- package/src/artifact-catalog.ts +51 -0
- package/src/artifact-client.ts +40 -49
- package/src/artifacts.ts +1 -0
- package/src/automations-client.ts +8 -2
- package/src/azure-live-transport.ts +286 -0
- package/src/browser.ts +37 -0
- package/src/chat/fold.ts +431 -0
- package/src/chat/handler.ts +240 -0
- package/src/chat/http.ts +257 -0
- package/src/chat/ids.ts +85 -0
- package/src/chat/index.ts +88 -0
- package/src/chat/openai.ts +439 -0
- package/src/chat/opengeni.ts +737 -0
- package/src/chat/types.ts +219 -0
- package/src/chat/vercel.ts +204 -0
- package/src/chats.ts +16 -0
- package/src/client.ts +5697 -1833
- package/src/codex-realtime-controller.ts +163 -8
- package/src/codex-realtime-v3-wire.ts +4 -3
- package/src/codex-realtime-v3.ts +12 -3
- package/src/codex-realtime.ts +11 -3
- package/src/company-brain.ts +0 -40
- package/src/core.ts +20 -0
- package/src/deprecation.ts +149 -0
- package/src/document-authority-client.ts +104 -1
- package/src/editable-artifacts/controller.ts +36 -2
- package/src/editable-artifacts/index.ts +1 -0
- package/src/editable-artifacts/types.ts +29 -16
- package/src/embedding-client.ts +519 -0
- package/src/errors.ts +303 -4
- package/src/external-vault-receiver.ts +914 -0
- package/src/feedback.ts +20 -0
- package/src/gateway-realtime-transport.ts +3 -3
- package/src/github-repositories.ts +60 -0
- package/src/index.ts +603 -65
- package/src/insights-usage.ts +64 -0
- package/src/interaction.ts +315 -93
- package/src/knowledge.ts +72 -0
- package/src/known-tools.ts +279 -0
- package/src/message-links.ts +178 -0
- package/src/model-context.ts +113 -0
- package/src/model-display.ts +11 -0
- package/src/model-picker-order.ts +6 -0
- package/src/organization-integration-policy.ts +54 -0
- package/src/pr-review-client.ts +1 -1
- package/src/pr-review.ts +1 -1
- package/src/preference-registry.ts +2 -0
- package/src/prepared-mcp-setup.ts +123 -0
- package/src/proxy.ts +23 -12
- package/src/realtime.ts +15 -6
- package/src/session-history-import.ts +84 -0
- package/src/session-list-entries.ts +1 -0
- package/src/session-message-search.ts +47 -0
- package/src/session-proxy-client.ts +68 -0
- package/src/session-proxy.ts +2098 -0
- package/src/session-titles.ts +8 -82
- package/src/session-usage-limits.ts +71 -0
- package/src/shared-catalog-loader.ts +169 -0
- package/src/site-ai.ts +284 -0
- package/src/site-bridge-host.ts +422 -0
- package/src/site-browser-entry.ts +6 -0
- package/src/site-browser-runtime.gen.ts +2 -0
- package/src/site-data.ts +372 -0
- package/src/site-document.test.ts +64 -0
- package/src/site-document.ts +18 -0
- package/src/site-http.ts +171 -0
- package/src/site-sql.ts +153 -0
- package/src/site-tool-bridge.ts +401 -0
- package/src/site.ts +878 -0
- package/src/skills.ts +69 -0
- package/src/sse.ts +9 -3
- package/src/stream.ts +33 -10
- package/src/tenant-workspaces.ts +148 -0
- package/src/tool-auth.ts +301 -0
- package/src/tool-display-metadata.ts +27 -0
- package/src/tools.ts +452 -0
- package/src/transcription.ts +3 -0
- package/src/types.ts +3170 -582
- package/src/usage-allowances.ts +189 -0
- package/src/vault-types.ts +379 -0
- package/src/vaults-api.ts +339 -0
- package/src/workspace-artifacts.ts +55 -6
- package/src/workspace-instruction-policies.ts +2 -1
- package/src/workspace-integrations.ts +402 -0
- package/src/workspace-state.ts +8 -82
- package/dist/chunk-C2H7HBNP.js.map +0 -1
- package/dist/chunk-C4DJPZRU.js +0 -119
- package/dist/chunk-C4DJPZRU.js.map +0 -1
- package/dist/chunk-JUS2UYRP.js.map +0 -1
- package/dist/chunk-KKRO2VCP.js.map +0 -1
- package/dist/chunk-QT3KFVDP.js.map +0 -1
- package/dist/chunk-TRNI7KEO.js.map +0 -1
- package/dist/chunk-VYCTL62C.js.map +0 -1
- package/dist/chunk-YXQX7RQT.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/chat/opengeni.ts","../../src/chat/http.ts","../../src/chat/openai.ts","../../src/chat/vercel.ts","../../src/chat/handler.ts"],"sourcesContent":["import { OpenGeniEmbeddingClient as OpenGeniClient } from \"../embedding-client\";\nimport { OpenGeniApiError } from \"../errors\";\nimport { chatDefaults } from \"../chats\";\nimport {\n createWorkspaceIdResolver,\n type WorkspaceIdOptions,\n type WorkspaceIdTarget,\n} from \"../tenant-workspaces\";\nimport type { SendMessageInput } from \"../client\";\nimport type { CreateSessionRequest, CreateSessionResponse, Session, SessionEvent } from \"../types\";\nimport { ChatPendingFold, ChatTurnFold, asRecord, stringValue } from \"./fold\";\nimport { chatIdempotencyKey, chatSessionId } from \"./ids\";\nimport {\n OpenGeniChatError,\n type ChatChunk,\n type ChatImportedMessage,\n type ChatMessage,\n type ChatOptions,\n type ChatReply,\n type ChatRespondInput,\n type ChatSendOptions,\n type ChatSessionListOptions,\n type ChatSnapshot,\n type ChatTarget,\n type WorkspaceTarget,\n type OpenGeniOptions,\n} from \"./types\";\n\nexport const DEFAULT_OPENGENI_BASE_URL = \"https://app.opengeni.ai\";\nexport const DEFAULT_CHAT_SOURCE = \"app\";\n\ntype SubmittedTurn = { after: number; turnId: string | null };\n\nconst MISSING_API_KEY_MESSAGE =\n \"Opengeni requires an apiKey. Set OPENGENI_API_KEY in the server environment.\";\n\nasync function missingApiKeyFetch(): Promise<Response> {\n throw new TypeError(MISSING_API_KEY_MESSAGE);\n}\n\ntype BuildCreate = (text: string, send: ChatSendOptions) => CreateSessionRequest;\ntype SubmitCreate = (request: CreateSessionRequest) => Promise<CreateSessionResponse>;\n\ntype ChatInit = {\n workspaceId: string;\n sessionId: string;\n conversation: string | null;\n session: Session | null;\n buildCreate: BuildCreate | null;\n submitCreate?: SubmitCreate | undefined;\n};\n\n/** Upper bound on the `modelContext` built from `importedHistory`, header included. */\nexport const IMPORTED_HISTORY_MAX_CHARS = 30_000;\n/** Server limit for one message's `modelContext`. */\nconst MODEL_CONTEXT_MAX_CHARS = 32_768;\nconst IMPORTED_HISTORY_HEADER = \"Earlier conversation imported from the product, oldest first:\";\nconst IMPORTED_HISTORY_ROLES: ReadonlySet<string> = new Set([\"user\", \"assistant\", \"system\"]);\n\n/**\n * One-option-object entry point for products that already have a chat. Wraps\n * `OpenGeniClient` (exposed as `client`) with tenant workspaces, deterministic\n * conversation sessions, and text-first replies.\n */\nexport class OpenGeni {\n readonly client: OpenGeniClient;\n /**\n * The organization id: the one passed to the constructor, else the one\n * derived from the API key once {@link resolveOrganizationId} (or any\n * workspace lookup) has run. An empty string before that; prefer\n * `await og.resolveOrganizationId()`.\n */\n readonly organizationId: string;\n readonly source: string;\n readonly sessions: {\n /** Sessions visible to the selected canonical user, or explicit service caller. */\n list: (options: ChatSessionListOptions) => Promise<Session[]>;\n };\n private readonly resolveWorkspaceId: ReturnType<typeof createWorkspaceIdResolver>;\n private implicitAgentAdmission: boolean | undefined;\n private pendingOrganizationId: Promise<string> | undefined;\n\n constructor(options: OpenGeniOptions) {\n this.client = new OpenGeniClient({\n // An empty value (a blank `OPENGENI_API_BASE_URL=` in .env) means the default.\n baseUrl: options.baseUrl?.trim() || DEFAULT_OPENGENI_BASE_URL,\n // A missing key fails each request, not construction: a module-scope\n // `new Opengeni({ apiKey: process.env.OPENGENI_API_KEY! })` must not\n // break `next build` (or any import) where the secret only exists at\n // runtime.\n ...(options.apiKey\n ? { apiKey: options.apiKey, ...(options.fetch ? { fetch: options.fetch } : {}) }\n : { fetch: missingApiKeyFetch }),\n });\n this.organizationId = options.organizationId?.trim() ?? \"\";\n this.source = options.source ?? DEFAULT_CHAT_SOURCE;\n this.resolveWorkspaceId = createWorkspaceIdResolver(this.client, {\n organizationId: () => this.resolveOrganizationId(),\n source: this.source,\n workspaceName: options.workspaceName,\n memberPermissions: options.memberPermissions,\n });\n this.sessions = { list: (listOptions) => this.listSessions(listOptions) };\n }\n\n /**\n * The organization that owns every workspace this facade creates. Uses the\n * constructor's `organizationId`, else reads it once from the API key\n * (`GET /v1/access/me`) and caches it.\n */\n async resolveOrganizationId(): Promise<string> {\n if (this.organizationId) return this.organizationId;\n if (!this.pendingOrganizationId) {\n const pending = this.client.getAccessContext().then((access) => {\n const credential = access.credential;\n if (credential && credential.kind !== \"organization_api_key\") {\n throw new TypeError(\n \"Opengeni needs an organization API key to create workspaces; this is a workspace key.\",\n );\n }\n const organizationId = credential?.accountId ?? access.defaultAccountId;\n if (!organizationId) {\n throw new TypeError(\n \"Could not derive the organization from this API key. Pass organizationId.\",\n );\n }\n // Readonly to callers; set once here, from the key's own organization.\n (this as { organizationId: string }).organizationId = organizationId;\n return organizationId;\n });\n pending.catch(() => {\n if (this.pendingOrganizationId === pending) this.pendingOrganizationId = undefined;\n });\n this.pendingOrganizationId = pending;\n }\n return await this.pendingOrganizationId;\n }\n\n /**\n * Translate your own ids to the Opengeni workspace id, creating the\n * workspace on first use (cached per instance):\n * `{ tenant }` is one workspace per tenant, `{ user }` (no tenant) is one\n * workspace per user, and `{ workspaceId }` is returned as is. Opengeni adds\n * a tenant workspace's users on their first request; a per-user workspace\n * gets its one owner from the SDK and admits nobody else.\n */\n async workspaceId(\n target:\n | ChatTarget\n | { tenant?: string | undefined; workspaceId?: string | undefined }\n | WorkspaceTarget,\n ): Promise<string> {\n if (target.workspaceId === \"\" || target.tenant === \"\") {\n throw new TypeError(\"tenant and workspaceId must be non-empty ids.\");\n }\n if (target.workspaceId) return target.workspaceId;\n if (target.tenant) {\n return await this.workspaceIdFor({ tenant: target.tenant }, { isolation: \"tenant\" });\n }\n if (\"tenant\" in target || \"workspaceId\" in target) {\n // A tenant/workspaceId key with no value is a host bug: never silently\n // fall back to the user's own workspace.\n throw new TypeError(\n \"tenant or workspaceId is undefined. Pass a non-empty id, or omit the key for one workspace per user.\",\n );\n }\n const user = \"user\" in target ? target.user : undefined;\n if (user) {\n return await this.workspaceIdFor({ user }, { isolation: \"user\" });\n }\n throw new TypeError(\"Pass tenant, user, or workspaceId.\");\n }\n\n /**\n * Resolve a tenant workspace or a user's own workspace (user isolation, per\n * tenant when one is given). A user's own workspace is provisioned with that\n * user as its only explicit member.\n */\n async workspaceIdFor(target: WorkspaceIdTarget, options: WorkspaceIdOptions): Promise<string> {\n return await this.resolveWorkspaceId(target, options);\n }\n\n /** `chats: \"isolated\"` keeps its tenant-plus-user workspace; a user alone gets their own. */\n private async isolatedWorkspaceId(target: WorkspaceTarget): Promise<string> {\n if (target.workspaceId) {\n throw new TypeError('chats: \"isolated\" requires a tenant or user, not a workspaceId.');\n }\n return await this.workspaceIdFor(\n { tenant: target.tenant, user: target.user },\n { isolation: \"user\" },\n );\n }\n\n /**\n * Address one conversation; the session is created lazily on the first send.\n * Identity selects authority, not the conversation address. The workspace\n * is the tenant's, the user's own (user only), or the explicit id; Opengeni\n * adds the user to it on their first request.\n * Legacy user-namespaced conversations remain accessible by their session ID.\n */\n async chat(options: ChatOptions): Promise<Chat> {\n if (!options.conversation) throw new TypeError(\"chat() requires a conversation id.\");\n if (options.chats === \"private\" && !options.user) {\n throw new OpenGeniChatError(\n \"chats_requires_user\",\n 'chats: \"private\" requires an authenticated product user. Pass user or use chats: \"shared\".',\n );\n }\n const legacy = options.chats === undefined && !options.user;\n const defaults = legacy\n ? {\n visibility: \"workspace\" as const,\n agentAccess: \"session\" as const,\n memoryScope: \"off\" as const,\n }\n : chatDefaults(options.chats ?? \"private\");\n const explicitAgent = options.agent !== undefined || options.create?.agent !== undefined;\n const agentAccess = options.agentAccess ?? defaults.agentAccess;\n const memoryScope =\n options.memory === false\n ? \"off\"\n : (options.memory ??\n (legacy ? (agentAccess === \"session\" ? \"off\" : agentAccess) : defaults.memoryScope));\n if (memoryScope === \"user\" && !options.user) {\n throw new OpenGeniChatError(\n \"memory_scope_requires_user\",\n 'memory: \"user\" requires an authenticated product user.',\n );\n }\n const client = options.user\n ? this.client.asUser(options.user, { source: this.source })\n : this.client;\n const workspaceId =\n options.chats === \"isolated\"\n ? await this.isolatedWorkspaceId(options)\n : await this.workspaceId(options);\n const sessionId = options.sessionId ?? (await chatSessionId(workspaceId, options.conversation));\n const session = await this.findSession(client, workspaceId, sessionId);\n const buildCreate: BuildCreate = (text, send) => {\n const { modelContext: createContext, ...create } = options.create ?? {};\n const messageContext = send.modelContext?.trim() || undefined;\n const reserved = messageContext ? messageContext.length + 2 : 0;\n const baseContext =\n createContext ??\n (send.importedHistory\n ? formatImportedHistory(\n send.importedHistory,\n Math.min(IMPORTED_HISTORY_MAX_CHARS, MODEL_CONTEXT_MAX_CHARS - reserved),\n )\n : undefined);\n const context = [baseContext, messageContext].filter(Boolean).join(\"\\n\\n\") || undefined;\n return {\n ...(options.model !== undefined ? { model: options.model } : {}),\n ...(options.instructions !== undefined ? { instructions: options.instructions } : {}),\n ...(options.skills !== undefined ? { skills: options.skills } : {}),\n ...(options.tools !== undefined ? { tools: options.tools } : {}),\n ...create,\n visibility: create.visibility ?? defaults.visibility,\n agentAccess: create.agentAccess ?? agentAccess,\n memoryScope: create.memoryScope ?? memoryScope,\n agent: {\n capabilities: create.agent?.capabilities ?? options.agent?.capabilities,\n identity:\n create.agent?.identity !== undefined ? create.agent.identity : options.agent?.identity,\n instructions: create.agent?.instructions ?? options.agent?.instructions,\n renderer: create.agent?.renderer ?? options.agent?.renderer ?? \"markdown\",\n },\n ...(context !== undefined ? { modelContext: context } : {}),\n ...messagePolicy(send),\n initialMessage: text,\n requestedSessionId: sessionId,\n idempotencyKey: chatIdempotencyKey(sessionId),\n };\n };\n return new Chat(client, {\n workspaceId,\n sessionId,\n conversation: options.conversation,\n session,\n buildCreate,\n submitCreate: (request) =>\n this.createChatSession(client, workspaceId, request, explicitAgent),\n });\n }\n\n private async createChatSession(\n client: OpenGeniClient,\n workspaceId: string,\n request: CreateSessionRequest,\n explicitAgent: boolean,\n ): Promise<CreateSessionResponse> {\n const { agent, ...withoutAgent } = request;\n const implicitAgent = !explicitAgent && this.implicitAgentAdmission !== false;\n try {\n return await client.createSession(\n workspaceId,\n explicitAgent || implicitAgent ? { ...withoutAgent, agent } : withoutAgent,\n );\n } catch (error) {\n // Current servers always admit `agent`. This 422 comes only from older\n // servers that still had agent configuration behind a deployment flag.\n if (\n !(error instanceof OpenGeniApiError) ||\n error.status !== 422 ||\n !(\n error.code === \"agent_config_not_enabled\" ||\n (error.code === \"SESSION_CREATE_REJECTED\" &&\n error.details?.code === \"agent_config_not_enabled\")\n ) ||\n error.outcomeUnknown\n )\n throw error;\n if (explicitAgent) {\n throw new OpenGeniApiError(error.status, error.body, {\n code: error.code,\n retryable: false,\n correlationId: error.correlationId,\n displayMessage:\n \"Explicit agent configuration requires the deployment operator to set \" +\n \"OPENGENI_AGENT_CONFIG_ADMISSION_ENABLED=true. The SDK has kept your agent settings unchanged.\",\n });\n }\n if (!implicitAgent) throw error;\n // This exact 422 refused the create. Retry only the implicit renderer,\n // retaining the session/idempotency keys and every caller-owned field.\n this.implicitAgentAdmission = false;\n return await client.createSession(workspaceId, withoutAgent);\n }\n }\n\n /**\n * Address an existing session with native API authorization. The same shared\n * session can be opened by different authorized users. Pass null only for an\n * explicitly service-owned operation; the API still enforces service access.\n */\n async chatBySessionId(target: {\n workspaceId: string;\n sessionId: string;\n user: string | null;\n }): Promise<Chat> {\n const client =\n target.user !== null ? this.client.asUser(target.user, { source: this.source }) : this.client;\n const session = await client.getSession(target.workspaceId, target.sessionId);\n return new Chat(client, {\n workspaceId: target.workspaceId,\n sessionId: target.sessionId,\n conversation: null,\n session,\n buildCreate: null,\n });\n }\n\n private async findSession(\n client: OpenGeniClient,\n workspaceId: string,\n sessionId: string,\n ): Promise<Session | null> {\n try {\n return await client.getSession(workspaceId, sessionId);\n } catch (error) {\n if (error instanceof OpenGeniApiError && error.status === 404) return null;\n throw error;\n }\n }\n\n private async listSessions(options: ChatSessionListOptions): Promise<Session[]> {\n const workspaceId =\n options.chats === \"isolated\"\n ? await this.isolatedWorkspaceId(options)\n : await this.workspaceId(options);\n const client = options.user\n ? this.client.asUser(options.user, { source: this.source })\n : this.client;\n return await client.requestJson<Session[]>(\n \"GET\",\n `/v1/workspaces/${workspaceId}/sessions`,\n undefined,\n {\n ...(options.limit !== undefined ? { limit: String(options.limit) } : {}),\n },\n );\n }\n}\n\n/** One conversation bound to one deterministic session. */\nexport class Chat {\n readonly workspaceId: string;\n readonly sessionId: string;\n /** The conversation id this chat was opened with; null when addressed by session id. */\n readonly conversation: string | null;\n private session: Session | null;\n private readonly buildCreate: BuildCreate | null;\n private readonly submitCreate: SubmitCreate;\n private pendingTurnId: string | null = null;\n\n constructor(\n private readonly client: OpenGeniClient,\n init: ChatInit,\n ) {\n this.workspaceId = init.workspaceId;\n this.sessionId = init.sessionId;\n this.conversation = init.conversation;\n this.session = init.session;\n this.buildCreate = init.buildCreate;\n this.submitCreate =\n init.submitCreate ?? ((request) => this.client.createSession(this.workspaceId, request));\n }\n\n /** True once the session exists on the server. */\n get created(): boolean {\n return this.session !== null;\n }\n\n /** Send a message and wait for the agent's reply text. */\n async send(text: string, options: ChatSendOptions = {}): Promise<ChatReply> {\n return await settle(this.stream(text, options));\n }\n\n /** Send a message and observe the reply as it streams. Ends with a `done` chunk. */\n async *stream(\n text: string,\n options: ChatSendOptions = {},\n ): AsyncGenerator<ChatChunk, void, void> {\n const submitted = options.steer\n ? await this.submitSteer(text, options)\n : await this.submit(text, options);\n yield* this.streamTurn(submitted, options.signal);\n }\n\n /** Supersede the current inference with this message and wait for the reply. */\n async steer(text: string, options: Omit<ChatSendOptions, \"steer\"> = {}): Promise<ChatReply> {\n return await this.send(text, { ...options, steer: true });\n }\n\n /** Answer a pending approval or human-input request, then wait for the reply. */\n async respond(\n input: ChatRespondInput,\n options: Omit<ChatSendOptions, \"steer\"> = {},\n ): Promise<ChatReply> {\n return await settle(this.respondStream(input, options));\n }\n\n async *respondStream(\n input: ChatRespondInput,\n options: Omit<ChatSendOptions, \"steer\"> = {},\n ): AsyncGenerator<ChatChunk, void, void> {\n const submitted = await this.submitResponse(input);\n yield* this.streamTurn(submitted, options.signal);\n }\n\n /** User and assistant text in order, from the durable event log. */\n async history(): Promise<ChatMessage[]> {\n return (await this.snapshot()).messages;\n }\n\n /** Restore history and pending decisions from the complete ordered timeline. */\n async snapshot(): Promise<ChatSnapshot> {\n if (!this.session) return { messages: [], pending: [], status: null };\n const pending = new ChatPendingFold();\n let status = this.session.status;\n const messages: ChatMessage[] = [];\n let lastAssistantTurn: string | null = null;\n // Commentary is activity, not history. Like the live fold, a turn that\n // settles without an answer keeps only its latest commentary.\n let heldCommentary: { turnId: string | null; text: string; sequence: number } | null = null;\n const releaseHeldCommentary = (turnId: string | null) => {\n if (!heldCommentary || heldCommentary.turnId !== turnId) return;\n const held = heldCommentary;\n heldCommentary = null;\n const index = messages.findIndex((message) => message.sequence > held.sequence);\n const message: ChatMessage = { role: \"assistant\", text: held.text, sequence: held.sequence };\n if (index === -1) messages.push(message);\n else messages.splice(index, 0, message);\n };\n let after = 0;\n while (true) {\n const result = await this.client.listEventPage(this.workspaceId, this.sessionId, {\n after,\n includeTypes: [\n \"user.message\",\n \"agent.message.completed\",\n \"session.requiresAction\",\n \"session.humanInput.requested\",\n \"user.approvalDecision\",\n \"user.humanInputResponse\",\n \"turn.completed\",\n \"turn.failed\",\n \"turn.cancelled\",\n \"session.status.changed\",\n ],\n });\n for (const event of result.events) {\n pending.push(event);\n if (event.type === \"session.status.changed\") {\n const next = asRecord(event.payload).status;\n if (typeof next === \"string\") status = next as Session[\"status\"];\n }\n const turnId = typeof event.turnId === \"string\" ? event.turnId : null;\n if (\n event.type === \"turn.completed\" ||\n event.type === \"turn.failed\" ||\n event.type === \"turn.cancelled\" ||\n event.type === \"session.requiresAction\" ||\n event.type === \"session.humanInput.requested\"\n ) {\n releaseHeldCommentary(turnId);\n }\n const text = stringValue(asRecord(event.payload).text);\n if (!text) continue;\n if (event.type === \"user.message\") {\n messages.push({ role: \"user\", text, sequence: event.sequence });\n lastAssistantTurn = null;\n continue;\n }\n if (event.type !== \"agent.message.completed\") continue;\n if (asRecord(event.payload).phase === \"commentary\") {\n heldCommentary = { turnId, text, sequence: event.sequence };\n continue;\n }\n if (heldCommentary?.turnId === turnId) heldCommentary = null;\n const last = messages.at(-1);\n if (\n last?.role === \"assistant\" &&\n turnId !== null &&\n turnId === lastAssistantTurn &&\n text.startsWith(last.text)\n ) {\n last.text = text;\n last.sequence = event.sequence;\n continue;\n }\n messages.push({ role: \"assistant\", text, sequence: event.sequence });\n lastAssistantTurn = turnId;\n }\n if (!result.hasMore || result.nextAfter === null || result.events.length === 0) break;\n if (result.nextAfter <= after) {\n throw new OpenGeniChatError(\n \"history_cursor_stalled\",\n \"History pagination did not advance.\",\n );\n }\n after = result.nextAfter;\n }\n return { messages, pending: pending.pending(), status };\n }\n\n private async submit(text: string, send: ChatSendOptions): Promise<SubmittedTurn> {\n if (!this.session) {\n if (!this.buildCreate) {\n throw new OpenGeniChatError(\"session_missing\", \"This session no longer exists.\");\n }\n const created = await this.submitCreate(this.buildCreate(text, send));\n this.session = created;\n if (created.initialMessage === text) {\n return { after: 0, turnId: created.initialTurnId };\n }\n // The idempotent create replayed an earlier session; deliver this message too.\n }\n const event = await this.client.sendMessage(\n this.workspaceId,\n this.sessionId,\n messageInput(text, send),\n );\n return submittedFrom(event);\n }\n\n private async submitSteer(text: string, send: ChatSendOptions): Promise<SubmittedTurn> {\n if (!this.session) return await this.submit(text, send);\n const result = await this.client.steerMessage(\n this.workspaceId,\n this.sessionId,\n messageInput(text, send),\n );\n return { after: result.accepted.sequence, turnId: result.turn.id ?? null };\n }\n\n private async submitResponse(input: ChatRespondInput): Promise<SubmittedTurn> {\n let event: SessionEvent;\n if (\"decision\" in input) {\n event = await this.client.sendApprovalDecision(this.workspaceId, this.sessionId, {\n approvalId: input.requestId,\n decision: input.decision,\n ...(input.message !== undefined ? { message: input.message } : {}),\n });\n } else if (\"answers\" in input) {\n event = await this.client.submitHumanInputResponse(\n this.workspaceId,\n this.sessionId,\n input.requestId,\n { outcome: \"answered\", answers: input.answers },\n );\n } else {\n event = await this.client.submitHumanInputResponse(\n this.workspaceId,\n this.sessionId,\n input.requestId,\n { outcome: \"skipped\" },\n );\n }\n const submitted = submittedFrom(event);\n return { ...submitted, turnId: submitted.turnId ?? this.pendingTurnId };\n }\n\n private async *streamTurn(\n submitted: SubmittedTurn,\n signal: AbortSignal | undefined,\n ): AsyncGenerator<ChatChunk, void, void> {\n const upstream = new AbortController();\n const onAbort = (): void => upstream.abort();\n if (signal?.aborted) upstream.abort();\n else signal?.addEventListener(\"abort\", onAbort, { once: true });\n const fold = new ChatTurnFold(this.workspaceId, this.sessionId, submitted.turnId);\n // Iterate by hand rather than with for-await: leaving a for-await loop\n // awaits the inner iterator's return(), which awaits the SSE body's\n // cancel(), and some fetch implementations (Next.js on Node) settle that\n // cancel only after the request is aborted. The finally below aborts\n // first and never waits on the inner unwinding.\n const events = this.client.streamEvents(this.workspaceId, this.sessionId, {\n after: submitted.after,\n signal: upstream.signal,\n });\n try {\n while (true) {\n const next = await events.next();\n if (next.done) break;\n const event = next.value;\n const step = fold.push(event);\n for (const chunk of step.chunks) yield chunk;\n // Resuming one member of a parallel interruption group re-emits the\n // waiting status, but existing human-input requests are not recreated.\n // Recover the remaining decision instead of waiting forever for new text.\n if (\n !step.terminal &&\n event.type === \"session.status.changed\" &&\n asRecord(event.payload).status === \"requires_action\" &&\n (event.turnId == null || fold.turnId === null || event.turnId === fold.turnId)\n ) {\n const pending = (await this.snapshot()).pending[0];\n if (pending) {\n fold.pending = pending;\n this.pendingTurnId = fold.turnId;\n yield { type: \"pending\", pending };\n yield { type: \"done\", reply: fold.reply(\"pending\") };\n return;\n }\n }\n if (!step.terminal) continue;\n if (step.terminal === \"failed\") throw fold.failureError();\n this.pendingTurnId = step.terminal === \"pending\" ? fold.turnId : null;\n yield { type: \"done\", reply: fold.reply(step.terminal) };\n return;\n }\n if (signal?.aborted) throw abortError();\n throw new OpenGeniChatError(\n \"stream_ended\",\n \"The event stream ended before the turn settled.\",\n );\n } finally {\n signal?.removeEventListener(\"abort\", onAbort);\n upstream.abort();\n void Promise.resolve(events.return(undefined)).catch(() => undefined);\n }\n }\n}\n\nasync function settle(chunks: AsyncIterable<ChatChunk>): Promise<ChatReply> {\n for await (const chunk of chunks) {\n if (chunk.type === \"done\") return chunk.reply;\n }\n throw new OpenGeniChatError(\"stream_ended\", \"The event stream ended before the turn settled.\");\n}\n\n/** Per-message model policy fields that the send options carry. */\nfunction messagePolicy(send: ChatSendOptions): Partial<SendMessageInput> {\n return {\n ...(send.model !== undefined ? { model: send.model } : {}),\n ...(send.reasoningEffort !== undefined ? { reasoningEffort: send.reasoningEffort } : {}),\n ...(send.latencyMode !== undefined ? { latencyMode: send.latencyMode } : {}),\n };\n}\n\nfunction messageInput(text: string, send: ChatSendOptions): SendMessageInput {\n const modelContext = send.modelContext?.trim();\n return { text, ...messagePolicy(send), ...(modelContext ? { modelContext } : {}) };\n}\n\nfunction submittedFrom(event: SessionEvent): SubmittedTurn {\n return {\n after: event.sequence,\n turnId: typeof event.turnId === \"string\" ? event.turnId : null,\n };\n}\n\n/**\n * `modelContext` for imported history: a header line plus one `role: text`\n * line per message, oldest first, trimmed from the oldest end to\n * {@link IMPORTED_HISTORY_MAX_CHARS}. Undefined when nothing usable remains.\n */\nexport function formatImportedHistory(\n messages: ChatImportedMessage[],\n maxChars: number = IMPORTED_HISTORY_MAX_CHARS,\n): string | undefined {\n const lines = messages\n .filter(\n (message) =>\n IMPORTED_HISTORY_ROLES.has(message.role) &&\n typeof message.text === \"string\" &&\n message.text.trim().length > 0,\n )\n .map((message) => `${message.role}: ${message.text}`);\n if (lines.length === 0) return undefined;\n let budget = Math.min(maxChars, IMPORTED_HISTORY_MAX_CHARS) - IMPORTED_HISTORY_HEADER.length;\n const kept: string[] = [];\n for (let index = lines.length - 1; index >= 0; index -= 1) {\n const line = lines[index]!;\n const cost = line.length + 1;\n if (cost <= budget) {\n kept.unshift(line);\n budget -= cost;\n continue;\n }\n // The newest line alone overflows: keep its tail so the most recent text survives.\n if (kept.length === 0 && budget > 1) kept.unshift(line.slice(line.length - (budget - 1)));\n break;\n }\n if (kept.length === 0) return undefined;\n return `${IMPORTED_HISTORY_HEADER}\\n${kept.join(\"\\n\")}`;\n}\n\nfunction abortError(): Error {\n const error = new Error(\"The chat request was aborted.\");\n error.name = \"AbortError\";\n return error;\n}\n\n/** Current brand spelling; the established SDK export remains compatible. */\nexport { OpenGeni as Opengeni };\n","import { OpenGeniApiError } from \"../errors\";\nimport type { Opengeni } from \"./opengeni\";\nimport { OpenGeniChatError, type ChatImportedMessage, type ChatOptions } from \"./types\";\n\n/** Internal HTTP plumbing shared by the native handler and the protocol adapters. */\n\n/**\n * Header a client uses to name the conversation it is on. Every handler reads\n * the client conversation as: the host's resolution, else this header, else\n * the protocol's own field.\n */\nexport const CHAT_CONVERSATION_HEADER = \"x-opengeni-conversation\";\n\nconst CHAT_ERROR_STATUS: Readonly<Record<string, number>> = {\n memory_scope_requires_user: 400,\n conversation_not_authorized: 403,\n conversation_mismatch: 409,\n};\n\n/** What the host's auth hook returns: identity from the host, conversation optional per protocol. */\nexport type ChatResolution = Omit<ChatOptions, \"conversation\"> & {\n conversation?: string | undefined;\n};\n\n/**\n * The host's authentication hook. It receives the raw request and returns the\n * tenant/user/conversation the caller is allowed to use, or a `Response` to\n * reject the request. Never derive tenant or user from the request body.\n */\nexport type ChatResolve = (\n request: Request,\n) => Promise<ChatResolution | Response> | ChatResolution | Response;\n\nexport type ChatErrorSummary = { status: number; code: string; message: string };\n\nexport function jsonResponse(body: unknown, status = 200, headers: HeadersInit = {}): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: { \"Content-Type\": \"application/json; charset=utf-8\", ...headers },\n });\n}\n\nexport function errorResponse(status: number, message: string, code: string): Response {\n return jsonResponse(\n { error: { message, code, type: status >= 500 ? \"server_error\" : \"invalid_request_error\" } },\n status,\n );\n}\n\nexport async function readJsonObject(request: Request): Promise<Record<string, unknown> | null> {\n try {\n const parsed: unknown = await request.json();\n return parsed && typeof parsed === \"object\" && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : null;\n } catch {\n return null;\n }\n}\n\nexport async function resolveChatRequest(\n request: Request,\n resolve: ChatResolve,\n): Promise<{ resolution: ChatResolution; response?: undefined } | { response: Response }> {\n const resolved = await resolve(request);\n if (resolved instanceof Response) return { response: resolved };\n return { resolution: resolved };\n}\n\n/** The client-supplied conversation: the header, else the protocol's own field. */\nexport function clientConversation(request: Request, protocolField: unknown): string | undefined {\n const header = request.headers.get(CHAT_CONVERSATION_HEADER);\n if (header) return header;\n return typeof protocolField === \"string\" && protocolField ? protocolField : undefined;\n}\n\n/**\n * Open a chat from a resolution plus the conversation the client supplied.\n * The host names the conversation, or the host names the user and the client\n * conversation id is namespaced to that user; anything else is a 400, because\n * an unscoped client id could address any conversation in the workspace.\n */\nexport async function openResolvedChat(\n og: Opengeni,\n resolution: ChatResolution,\n clientConversationId: string | undefined,\n): Promise<\n { chat: Awaited<ReturnType<Opengeni[\"chat\"]>>; response?: undefined } | { response: Response }\n> {\n if (!resolution.conversation && !resolution.user) {\n return {\n response: errorResponse(\n 400,\n \"Return a conversation from resolve, or a user so client conversation ids are scoped to that user.\",\n \"conversation_required\",\n ),\n };\n }\n const conversationId = resolution.conversation ?? clientConversationId;\n if (!conversationId) {\n return {\n response: errorResponse(\n 400,\n `A conversation id is required: send the ${CHAT_CONVERSATION_HEADER} header or the protocol's conversation field.`,\n \"conversation_required\",\n ),\n };\n }\n try {\n const chat = await og.chat({ ...resolution, conversation: conversationId } as ChatOptions);\n return { chat };\n } catch (error) {\n const summary = chatErrorSummary(error);\n return { response: errorResponse(summary.status, summary.message, summary.code) };\n }\n}\n\nexport function chatErrorSummary(error: unknown): ChatErrorSummary {\n if (error instanceof OpenGeniChatError) {\n const status = CHAT_ERROR_STATUS[error.code] ?? 502;\n return { status, code: error.code, message: error.message };\n }\n if (error instanceof OpenGeniApiError) {\n return {\n status: error.status >= 500 ? 502 : error.status,\n code: error.code ?? \"opengeni_api_error\",\n message: error.message,\n };\n }\n if (error instanceof Error && error.name === \"AbortError\") {\n return { status: 499, code: \"aborted\", message: \"The chat request was aborted.\" };\n }\n return { status: 500, code: \"internal_error\", message: \"Chat request failed.\" };\n}\n\nexport function sseHeaders(extra: Record<string, string> = {}): Record<string, string> {\n return {\n \"Content-Type\": \"text/event-stream; charset=utf-8\",\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\",\n ...extra,\n };\n}\n\nexport function sseLine(data: string, event?: string): string {\n return `${event ? `event: ${event}\\n` : \"\"}data: ${data}\\n\\n`;\n}\n\n/**\n * Pull-based text-to-bytes stream over already-formatted SSE blocks. Upstream\n * consumption follows downstream demand; cancelling fires `onCancel` so the\n * producer can abort its Opengeni stream.\n */\nexport function sseByteStream(\n blocks: AsyncIterable<string>,\n onCancel?: () => void,\n): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n const iterator = blocks[Symbol.asyncIterator]();\n let cancelled = false;\n return new ReadableStream<Uint8Array>({\n pull: async (controller) => {\n const result = await iterator.next();\n if (cancelled) return;\n if (result.done) {\n controller.close();\n return;\n }\n controller.enqueue(encoder.encode(result.value));\n },\n cancel: () => {\n cancelled = true;\n onCancel?.();\n void Promise.resolve(iterator.return?.(undefined)).then(\n () => undefined,\n () => undefined,\n );\n },\n });\n}\n\n/** Text from an OpenAI-style message content: a string or `[{ type, text }]` parts. */\nexport function messageContentText(content: unknown, partTypes: string[]): string | null {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return null;\n const texts = content\n .map((part) => {\n if (!part || typeof part !== \"object\") return null;\n const record = part as Record<string, unknown>;\n return partTypes.includes(String(record.type)) && typeof record.text === \"string\"\n ? record.text\n : null;\n })\n .filter((text): text is string => text !== null);\n return texts.length > 0 ? texts.join(\"\\n\") : null;\n}\n\nfunction lastUserMessageIndex(messages: unknown[]): number {\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n const message = messages[index];\n if (message && typeof message === \"object\" && (message as { role?: unknown }).role === \"user\") {\n return index;\n }\n }\n return -1;\n}\n\nfunction messageText(\n message: unknown,\n partTypes: string[],\n partsField: \"parts\" | \"content\",\n): string | null {\n if (!message || typeof message !== \"object\") return null;\n const record = message as Record<string, unknown>;\n return (\n messageContentText(record[partsField], partTypes) ??\n messageContentText(record.content, partTypes)\n );\n}\n\n/** The last user-role message's text from an OpenAI/Vercel-style `messages` array. */\nexport function lastUserMessageText(\n messages: unknown,\n partTypes: string[],\n partsField: \"parts\" | \"content\",\n): string | null {\n if (!Array.isArray(messages)) return null;\n const index = lastUserMessageIndex(messages);\n return index < 0 ? null : messageText(messages[index], partTypes, partsField);\n}\n\n/**\n * Every user/assistant/system message before the last user message, as\n * imported history for the first create. Items without a role or text\n * (tool calls, files) are skipped.\n */\nexport function importedHistoryBefore(\n messages: unknown,\n partTypes: string[],\n partsField: \"parts\" | \"content\",\n): ChatImportedMessage[] {\n if (!Array.isArray(messages)) return [];\n const lastUser = lastUserMessageIndex(messages);\n if (lastUser < 0) return [];\n const imported: ChatImportedMessage[] = [];\n for (const message of messages.slice(0, lastUser)) {\n const role = (message as { role?: unknown } | null)?.role;\n if (role !== \"user\" && role !== \"assistant\" && role !== \"system\") continue;\n const text = messageText(message, partTypes, partsField);\n if (text) imported.push({ role, text });\n }\n return imported;\n}\n\nexport function unixSeconds(): number {\n return Math.floor(Date.now() / 1000);\n}\n","import {\n chatErrorSummary,\n clientConversation,\n errorResponse,\n importedHistoryBefore,\n jsonResponse,\n lastUserMessageText,\n messageContentText,\n openResolvedChat,\n readJsonObject,\n resolveChatRequest,\n sseByteStream,\n sseHeaders,\n sseLine,\n type ChatResolve,\n} from \"./http\";\nimport { isUuid } from \"./ids\";\nimport type { Chat, Opengeni } from \"./opengeni\";\nimport { OpenGeniChatError, type ChatChunk, type ChatReply } from \"./types\";\n\n/**\n * OpenAI-compatible adapters over the stable subset of the Chat Completions\n * and Responses wire formats. `model` and `user` in the body are echoed, never\n * trusted: identity comes from the host's `resolve` hook.\n */\n\nconst DEFAULT_MODEL_LABEL = \"opengeni\";\n\ntype ReplyExtension = {\n sessionId: string;\n workspaceId: string;\n turnId: string | null;\n status: ChatReply[\"status\"];\n pending: ChatReply[\"pending\"];\n};\n\nfunction replyExtension(reply: ChatReply): ReplyExtension {\n return {\n sessionId: reply.sessionId,\n workspaceId: reply.workspaceId,\n turnId: reply.turnId,\n status: reply.status,\n pending: reply.pending,\n };\n}\n\nfunction conversationFromBody(body: Record<string, unknown> | null): string | undefined {\n const conversation = body?.conversation;\n if (typeof conversation === \"string\" && conversation) return conversation;\n if (conversation && typeof conversation === \"object\") {\n const id = (conversation as { id?: unknown }).id;\n if (typeof id === \"string\" && id) return id;\n }\n return undefined;\n}\n\nfunction modelLabel(body: Record<string, unknown> | null): string {\n return typeof body?.model === \"string\" && body.model ? body.model : DEFAULT_MODEL_LABEL;\n}\n\nfunction wantsStream(body: Record<string, unknown> | null): boolean {\n return body?.stream === true;\n}\n\n// --- Chat Completions ---------------------------------------------------------\n\nconst CHAT_COMPLETION_PART_TYPES = [\"text\", \"input_text\"];\n\nfunction chatCompletionChunk(\n sessionId: string,\n model: string,\n created: number,\n delta: Record<string, unknown>,\n finishReason: \"stop\" | null,\n extension?: ReplyExtension,\n): string {\n return sseLine(\n JSON.stringify({\n id: `chatcmpl-${sessionId}`,\n object: \"chat.completion.chunk\",\n created,\n model,\n choices: [{ index: 0, delta, finish_reason: finishReason }],\n ...(extension ? { opengeni: extension } : {}),\n }),\n );\n}\n\nexport async function* chatCompletionBlocks(\n chat: Chat,\n chunks: AsyncIterable<ChatChunk>,\n model: string,\n): AsyncGenerator<string, void, void> {\n const created = Math.floor(Date.now() / 1000);\n yield chatCompletionChunk(\n chat.sessionId,\n model,\n created,\n { role: \"assistant\", content: \"\" },\n null,\n );\n try {\n for await (const chunk of chunks) {\n if (chunk.type === \"text\") {\n yield chatCompletionChunk(chat.sessionId, model, created, { content: chunk.text }, null);\n } else if (chunk.type === \"done\") {\n yield chatCompletionChunk(\n chat.sessionId,\n model,\n created,\n {},\n \"stop\",\n replyExtension(chunk.reply),\n );\n }\n }\n } catch (error) {\n const summary = chatErrorSummary(error);\n yield sseLine(\n JSON.stringify({\n error: { message: summary.message, code: summary.code, type: \"server_error\" },\n }),\n );\n }\n yield sseLine(\"[DONE]\");\n}\n\nexport function chatCompletionObject(reply: ChatReply, model: string): Record<string, unknown> {\n return {\n id: `chatcmpl-${reply.sessionId}`,\n object: \"chat.completion\",\n created: Math.floor(Date.now() / 1000),\n model,\n choices: [\n { index: 0, message: { role: \"assistant\", content: reply.text }, finish_reason: \"stop\" },\n ],\n opengeni: replyExtension(reply),\n };\n}\n\n/**\n * `POST /v1/chat/completions` shape: `{ messages, stream?, model?, user?, metadata? }`.\n * Conversation: the host's `resolve`, else the `x-opengeni-conversation` header,\n * else `metadata.conversation_id`; 400 when none. Only the last user message\n * is sent; the messages before it are imported once as context when this\n * request creates the session.\n */\nexport async function handleChatCompletionsRequest(\n og: Opengeni,\n request: Request,\n resolve: ChatResolve,\n): Promise<Response> {\n const body = await readJsonObject(request);\n const prompt =\n lastUserMessageText(body?.messages, CHAT_COMPLETION_PART_TYPES, \"content\")?.trim() ?? \"\";\n if (!prompt) {\n return errorResponse(400, \"The last user message has no text.\", \"message_required\");\n }\n const resolved = await resolveChatRequest(request, resolve);\n if (resolved.response) return resolved.response;\n const metadata = body?.metadata;\n const metadataConversation =\n metadata && typeof metadata === \"object\"\n ? (metadata as { conversation_id?: unknown }).conversation_id\n : undefined;\n const opened = await openResolvedChat(\n og,\n resolved.resolution,\n clientConversation(request, metadataConversation),\n );\n if (opened.response) return opened.response;\n const model = modelLabel(body);\n const importedHistory = importedHistoryBefore(\n body?.messages,\n CHAT_COMPLETION_PART_TYPES,\n \"content\",\n );\n if (wantsStream(body)) {\n const chunks = opened.chat.stream(prompt, { signal: request.signal, importedHistory });\n return new Response(sseByteStream(chatCompletionBlocks(opened.chat, chunks, model)), {\n headers: sseHeaders(),\n });\n }\n try {\n const reply = await opened.chat.send(prompt, { signal: request.signal, importedHistory });\n return jsonResponse(chatCompletionObject(reply, model));\n } catch (error) {\n const summary = chatErrorSummary(error);\n return errorResponse(summary.status, summary.message, summary.code);\n }\n}\n\n// --- Responses ----------------------------------------------------------------\n\n/** Non-streaming response id; the session id alone addresses the conversation. */\nexport function encodeResponseId(sessionId: string, sequence: number): string {\n return `resp_${sessionId}_${sequence}`;\n}\n\nexport function decodeResponseId(value: unknown): string | null {\n if (typeof value !== \"string\") return null;\n // Streams allocate a UUID before the final event sequence is known. Keep\n // accepting existing sequence-based response ids for conversation continuity.\n const match = /^resp_([0-9a-f-]{36})(?:_(\\d+|[0-9a-f-]{36}))?$/i.exec(value);\n const sessionId = match?.[1];\n const suffix = match?.[2];\n if (suffix && !/^\\d+$/.test(suffix) && !isUuid(suffix)) return null;\n return sessionId && isUuid(sessionId) ? sessionId : null;\n}\n\ntype ResponseIdentity = { responseId: string; itemId: string; createdAt: number };\ntype ResponseStatus = \"in_progress\" | \"completed\" | \"incomplete\";\n\nfunction responseOutputItem(itemId: string, status: ResponseStatus, text: string | null) {\n return {\n type: \"message\",\n id: itemId,\n status,\n role: \"assistant\",\n content: text === null ? [] : [{ type: \"output_text\", text, annotations: [] }],\n };\n}\n\nfunction responseObject(\n reply: ChatReply | null,\n chat: Chat,\n model: string,\n status: ResponseStatus,\n previousResponseId: string | null,\n text: string,\n identity?: ResponseIdentity,\n): Record<string, unknown> {\n const sequence = reply?.events.at(-1)?.sequence ?? 0;\n return {\n id: identity?.responseId ?? encodeResponseId(chat.sessionId, sequence),\n object: \"response\",\n created_at: identity?.createdAt ?? Math.floor(Date.now() / 1000),\n status,\n model,\n previous_response_id: previousResponseId,\n output:\n status === \"in_progress\"\n ? []\n : [\n responseOutputItem(\n identity?.itemId ?? `msg_${chat.sessionId}_${sequence}`,\n status,\n text,\n ),\n ],\n output_text: text,\n ...(reply ? { opengeni: replyExtension(reply) } : {}),\n };\n}\n\nexport async function* responsesBlocks(\n chat: Chat,\n chunks: AsyncIterable<ChatChunk>,\n model: string,\n previousResponseId: string | null,\n): AsyncGenerator<string, void, void> {\n let sequenceNumber = 0;\n const requestId = crypto.randomUUID();\n const identity: ResponseIdentity = {\n responseId: `resp_${chat.sessionId}_${requestId}`,\n itemId: `msg_${chat.sessionId}_${requestId}`,\n createdAt: Math.floor(Date.now() / 1000),\n };\n const { itemId } = identity;\n const event = (type: string, data: Record<string, unknown>): string =>\n sseLine(JSON.stringify({ type, sequence_number: sequenceNumber++, ...data }), type);\n const initial = responseObject(\n null,\n chat,\n model,\n \"in_progress\",\n previousResponseId,\n \"\",\n identity,\n );\n yield event(\"response.created\", { response: initial });\n yield event(\"response.in_progress\", { response: initial });\n yield event(\"response.output_item.added\", {\n output_index: 0,\n item: responseOutputItem(itemId, \"in_progress\", null),\n });\n yield event(\"response.content_part.added\", {\n item_id: itemId,\n output_index: 0,\n content_index: 0,\n part: { type: \"output_text\", text: \"\", annotations: [] },\n });\n try {\n for await (const chunk of chunks) {\n if (chunk.type === \"text\") {\n yield event(\"response.output_text.delta\", {\n item_id: itemId,\n output_index: 0,\n content_index: 0,\n delta: chunk.text,\n logprobs: [],\n });\n } else if (chunk.type === \"done\") {\n const status = chunk.reply.status === \"completed\" ? \"completed\" : \"incomplete\";\n const item = responseOutputItem(itemId, status, chunk.reply.text);\n yield event(\"response.output_text.done\", {\n item_id: itemId,\n output_index: 0,\n content_index: 0,\n text: chunk.reply.text,\n logprobs: [],\n });\n yield event(\"response.content_part.done\", {\n item_id: itemId,\n output_index: 0,\n content_index: 0,\n part: item.content[0]!,\n });\n yield event(\"response.output_item.done\", { output_index: 0, item });\n yield event(`response.${status}`, {\n response: responseObject(\n chunk.reply,\n chat,\n model,\n status,\n previousResponseId,\n chunk.reply.text,\n identity,\n ),\n });\n }\n }\n } catch (error) {\n const summary = chatErrorSummary(error);\n yield event(\"error\", { code: summary.code, message: summary.message, param: null });\n }\n}\n\n/** Text of the Responses `input`: a string, or the last user item's `input_text` parts. */\nexport function responsesInputText(input: unknown): string | null {\n if (typeof input === \"string\") return input;\n if (!Array.isArray(input)) return null;\n const fromRole = lastUserMessageText(input, [\"input_text\", \"text\"], \"content\");\n if (fromRole !== null) return fromRole;\n const last = input.at(-1);\n return last && typeof last === \"object\"\n ? messageContentText((last as { content?: unknown }).content, [\"input_text\", \"text\"])\n : null;\n}\n\n/**\n * `POST /v1/responses` shape: `{ input, previous_response_id?, conversation?, stream?, model?, user? }`.\n * Conversation: the host's `resolve`, else the `x-opengeni-conversation`\n * header, else `conversation` / `conversation.id`. A `previous_response_id`\n * may continue the session it encodes only when the host named the user that\n * session belongs to (403 otherwise); when a conversation is named as well,\n * the two must agree (409). 400 when nothing names a conversation. Only the\n * last user item is sent; earlier array items are imported once as context\n * when this request creates the session.\n */\nexport async function handleResponsesRequest(\n og: Opengeni,\n request: Request,\n resolve: ChatResolve,\n): Promise<Response> {\n const body = await readJsonObject(request);\n const prompt = responsesInputText(body?.input)?.trim() ?? \"\";\n if (!prompt) return errorResponse(400, \"The input has no user text.\", \"message_required\");\n const resolved = await resolveChatRequest(request, resolve);\n if (resolved.response) return resolved.response;\n const previousResponseId =\n typeof body?.previous_response_id === \"string\" ? body.previous_response_id : null;\n const conversation = clientConversation(request, conversationFromBody(body));\n const previousSessionId = decodeResponseId(previousResponseId);\n const namedConversation =\n resolved.resolution.conversation ?? (resolved.resolution.user ? conversation : undefined);\n let chat: Chat;\n if (previousSessionId && !namedConversation) {\n if (!resolved.resolution.user) {\n return errorResponse(\n 400,\n \"Return a conversation from resolve, or a user so client conversation ids are scoped to that user.\",\n \"conversation_required\",\n );\n }\n try {\n const workspaceId = await og.workspaceId(resolved.resolution);\n chat = await og.chatBySessionId({\n workspaceId,\n sessionId: previousSessionId,\n user: resolved.resolution.user,\n });\n } catch (error) {\n const summary = chatErrorSummary(error);\n return errorResponse(summary.status, summary.message, summary.code);\n }\n } else {\n const opened = await openResolvedChat(og, resolved.resolution, conversation);\n if (opened.response) return opened.response;\n chat = opened.chat;\n if (previousSessionId && previousSessionId !== chat.sessionId) {\n const summary = chatErrorSummary(\n new OpenGeniChatError(\n \"conversation_mismatch\",\n \"previous_response_id belongs to a different conversation than the one named for this request.\",\n ),\n );\n return errorResponse(summary.status, summary.message, summary.code);\n }\n }\n const model = modelLabel(body);\n const importedHistory = importedHistoryBefore(\n body?.input,\n [\"input_text\", \"text\", \"output_text\"],\n \"content\",\n );\n if (wantsStream(body)) {\n const chunks = chat.stream(prompt, { signal: request.signal, importedHistory });\n return new Response(sseByteStream(responsesBlocks(chat, chunks, model, previousResponseId)), {\n headers: sseHeaders(),\n });\n }\n try {\n const reply = await chat.send(prompt, { signal: request.signal, importedHistory });\n return jsonResponse(\n responseObject(\n reply,\n chat,\n model,\n reply.status === \"completed\" ? \"completed\" : \"incomplete\",\n previousResponseId,\n reply.text,\n ),\n );\n } catch (error) {\n const summary = chatErrorSummary(error);\n return errorResponse(summary.status, summary.message, summary.code);\n }\n}\n","import { asRecord } from \"./fold\";\nimport {\n chatErrorSummary,\n clientConversation,\n errorResponse,\n importedHistoryBefore,\n lastUserMessageText,\n openResolvedChat,\n readJsonObject,\n resolveChatRequest,\n sseByteStream,\n sseHeaders,\n sseLine,\n type ChatResolve,\n} from \"./http\";\nimport type { Opengeni } from \"./opengeni\";\nimport type { ChatChunk, ChatPending } from \"./types\";\n\n/**\n * Vercel AI SDK UI message stream (protocol v1, as consumed by `useChat` with\n * the default transport in AI SDK 5, 6, and 7; approval requests need 6+).\n * Parts are `data: <json>` SSE\n * lines terminated by `data: [DONE]`, under the\n * `x-vercel-ai-ui-message-stream: v1` header.\n */\n\nexport const UI_MESSAGE_STREAM_HEADER = \"x-vercel-ai-ui-message-stream\";\nexport const UI_MESSAGE_STREAM_VERSION = \"v1\";\n\nexport type UIMessageStreamOptions = {\n /** Assistant message id announced in the `start` part. Defaults to a random UUID. */\n messageId?: string | undefined;\n /**\n * Emit Opengeni's own tool activity as tool parts. Off by default: those\n * tools are not in the app's typed tool set. When on, parts are marked\n * `dynamic` and `providerExecuted`, so `useChat` renders them as\n * `dynamic-tool` parts and never tries to execute them. Approval requests\n * are always emitted (as dynamic tool parts) because answering them is part\n * of the conversation.\n */\n toolParts?: boolean | undefined;\n /**\n * Emit the `start` / `start-step` / `finish-step` / `finish` framing. Set to\n * false when writing into an existing AI SDK stream that owns its framing\n * (for example `createUIMessageStream({ execute: ({ writer }) => ... })`).\n * Defaults to true.\n */\n framing?: boolean | undefined;\n};\n\n/** Protocol parts for one reply, in order. */\nexport async function* uiMessageStreamParts(\n chunks: AsyncIterable<ChatChunk>,\n options: UIMessageStreamOptions = {},\n): AsyncGenerator<Record<string, unknown>, void, void> {\n const messageId = options.messageId ?? crypto.randomUUID();\n const textId = `text_${messageId}`;\n let textOpen = false;\n const closeText = (): Record<string, unknown>[] => {\n if (!textOpen) return [];\n textOpen = false;\n return [{ type: \"text-end\", id: textId }];\n };\n const framing = options.framing ?? true;\n if (framing) {\n yield { type: \"start\", messageId };\n yield { type: \"start-step\" };\n }\n try {\n for await (const chunk of chunks) {\n switch (chunk.type) {\n case \"text\":\n if (!textOpen) {\n textOpen = true;\n yield { type: \"text-start\", id: textId };\n }\n yield { type: \"text-delta\", id: textId, delta: chunk.text };\n break;\n case \"tool\": {\n if (!options.toolParts) break;\n yield* closeText();\n const toolCallId = chunk.callId ?? `call_${crypto.randomUUID()}`;\n const tool = { toolCallId, dynamic: true, providerExecuted: true };\n if (chunk.status === \"started\") {\n yield { type: \"tool-input-start\", ...tool, toolName: chunk.name };\n yield {\n type: \"tool-input-available\",\n ...tool,\n toolName: chunk.name,\n input: chunk.input ?? {},\n };\n } else if (chunk.status === \"failed\") {\n yield { type: \"tool-output-error\", ...tool, errorText: \"The tool call failed.\" };\n } else {\n yield { type: \"tool-output-available\", ...tool, output: { status: chunk.status } };\n }\n break;\n }\n case \"pending\":\n yield* closeText();\n yield* pendingParts(chunk.pending);\n break;\n case \"done\":\n yield* closeText();\n break;\n }\n }\n yield* closeText();\n if (framing) {\n yield { type: \"finish-step\" };\n yield { type: \"finish\" };\n }\n } catch (error) {\n yield* closeText();\n yield { type: \"error\", errorText: chatErrorSummary(error).message };\n }\n}\n\nfunction* pendingParts(pending: ChatPending): Generator<Record<string, unknown>> {\n if (pending.kind === \"approval\") {\n const raw = asRecord(pending.payload);\n const rawItem = asRecord(raw.rawItem);\n yield {\n type: \"tool-input-available\",\n toolCallId: pending.requestId,\n toolName: pending.name ?? \"tool\",\n dynamic: true,\n providerExecuted: true,\n input: raw.arguments ?? rawItem.arguments ?? {},\n };\n yield {\n type: \"tool-approval-request\",\n toolCallId: pending.requestId,\n approvalId: pending.requestId,\n };\n return;\n }\n yield { type: \"data-opengeni-pending\", data: pending };\n}\n\nexport async function* uiMessageStreamBlocks(\n chunks: AsyncIterable<ChatChunk>,\n options: UIMessageStreamOptions = {},\n): AsyncGenerator<string, void, void> {\n for await (const part of uiMessageStreamParts(chunks, options)) {\n yield sseLine(JSON.stringify(part));\n }\n yield sseLine(\"[DONE]\");\n}\n\nexport function chatChunksToUIMessageStream(\n chunks: AsyncIterable<ChatChunk>,\n options: UIMessageStreamOptions & { onCancel?: (() => void) | undefined } = {},\n): ReadableStream<Uint8Array> {\n return sseByteStream(uiMessageStreamBlocks(chunks, options), options.onCancel);\n}\n\nexport function uiMessageStreamResponse(\n chunks: AsyncIterable<ChatChunk>,\n options: UIMessageStreamOptions = {},\n): Response {\n return new Response(chatChunksToUIMessageStream(chunks, options), {\n headers: sseHeaders({ [UI_MESSAGE_STREAM_HEADER]: UI_MESSAGE_STREAM_VERSION }),\n });\n}\n\n/** Text of the last user `UIMessage` (`parts` of type `text`, joined). */\nexport function lastUIMessageText(messages: unknown): string | null {\n return lastUserMessageText(messages, [\"text\"], \"parts\");\n}\n\n/**\n * `useChat` request handler: body `{ id, messages, trigger, messageId }`.\n * Conversation: the host's `resolve`, else the `x-opengeni-conversation`\n * header, else the chat `id`. Only the last user message is sent; the\n * messages before it are imported once as context when this request creates\n * the session. `regenerate-message` steers instead of queueing.\n */\nexport async function handleVercelChatRequest(\n og: Opengeni,\n request: Request,\n resolve: ChatResolve,\n options: Pick<UIMessageStreamOptions, \"toolParts\"> = {},\n): Promise<Response> {\n const body = await readJsonObject(request);\n const prompt = lastUIMessageText(body?.messages)?.trim() ?? \"\";\n if (!prompt) {\n return errorResponse(400, \"The last user message has no text.\", \"message_required\");\n }\n const resolved = await resolveChatRequest(request, resolve);\n if (resolved.response) return resolved.response;\n const opened = await openResolvedChat(\n og,\n resolved.resolution,\n clientConversation(request, body?.id),\n );\n if (opened.response) return opened.response;\n const steer = body?.trigger === \"regenerate-message\";\n const importedHistory = importedHistoryBefore(body?.messages, [\"text\"], \"parts\");\n return uiMessageStreamResponse(\n opened.chat.stream(prompt, { signal: request.signal, steer, importedHistory }),\n options.toolParts ? { toolParts: true } : {},\n );\n}\n","import { parseSseStream } from \"../sse\";\nimport type { HumanInputAnswer } from \"../types\";\nimport {\n chatErrorSummary,\n clientConversation,\n errorResponse,\n jsonResponse,\n openResolvedChat,\n readJsonObject,\n resolveChatRequest,\n sseByteStream,\n sseHeaders,\n sseLine,\n type ChatResolve,\n} from \"./http\";\nimport { handleChatCompletionsRequest, handleResponsesRequest } from \"./openai\";\nimport type { Opengeni } from \"./opengeni\";\nimport { OpenGeniChatError, type ChatChunk, type ChatRespondInput } from \"./types\";\nimport { handleVercelChatRequest } from \"./vercel\";\n\nexport { CHAT_CONVERSATION_HEADER, type ChatResolution, type ChatResolve } from \"./http\";\n\nexport type ChatHandlerFormat = \"native\" | \"vercel\" | \"openai-chat\" | \"openai-responses\";\n\nexport type ChatHandlerOptions = {\n /** Mandatory host auth hook; see {@link ChatResolve}. */\n resolve: ChatResolve;\n /** Default wire format; a request may override it with the format header. */\n format?: ChatHandlerFormat | undefined;\n /** Vercel format only: also emit Opengeni's own tool activity (see `UIMessageStreamOptions.toolParts`). */\n toolParts?: boolean | undefined;\n};\n\n/** Per-request wire-format override header. */\nexport const CHAT_FORMAT_HEADER = \"x-opengeni-chat-format\";\n\nconst CHAT_FORMATS: ReadonlySet<string> = new Set([\n \"native\",\n \"vercel\",\n \"openai-chat\",\n \"openai-responses\",\n]);\n\nfunction methodNotAllowed(allow: string): Response {\n return new Response(\n JSON.stringify({ error: { message: `Use ${allow}.`, code: \"method_not_allowed\" } }),\n { status: 405, headers: { Allow: allow, \"Content-Type\": \"application/json; charset=utf-8\" } },\n );\n}\n\n/**\n * One request handler for a product's chat endpoint. `POST` with `{ message }`\n * streams the reply in the selected format; `POST .../respond` answers a\n * pending approval or human-input request and streams the continuation;\n * `GET` returns the conversation's history as JSON. Every other method is a\n * 405. The conversation is the host's resolution, else the\n * `x-opengeni-conversation` header, else the wire format's own field.\n */\nexport function createChatHandler(\n og: Opengeni,\n options: ChatHandlerOptions,\n): (request: Request) => Promise<Response> {\n return async (request) => {\n const isRespond = new URL(request.url).pathname.replace(/\\/+$/, \"\").endsWith(\"/respond\");\n if (isRespond) {\n if (request.method !== \"POST\") return methodNotAllowed(\"POST\");\n return await handleNativeRespondRequest(og, request, options.resolve);\n }\n if (request.method === \"GET\") {\n return await handleNativeHistoryRequest(og, request, options.resolve);\n }\n if (request.method !== \"POST\") return methodNotAllowed(\"GET, POST\");\n const headerFormat = request.headers.get(CHAT_FORMAT_HEADER);\n if (headerFormat !== null && !CHAT_FORMATS.has(headerFormat)) {\n return errorResponse(400, `Unknown chat format: ${headerFormat}`, \"unknown_format\");\n }\n const format = (headerFormat as ChatHandlerFormat | null) ?? options.format ?? \"native\";\n switch (format) {\n case \"vercel\":\n return await handleVercelChatRequest(og, request, options.resolve, {\n toolParts: options.toolParts,\n });\n case \"openai-chat\":\n return await handleChatCompletionsRequest(og, request, options.resolve);\n case \"openai-responses\":\n return await handleResponsesRequest(og, request, options.resolve);\n default:\n return await handleNativeChatRequest(og, request, options.resolve);\n }\n };\n}\n\n/** `POST { message }` -> native SSE of {@link ChatChunk} (`event: chunk`). */\nexport async function handleNativeChatRequest(\n og: Opengeni,\n request: Request,\n resolve: ChatResolve,\n): Promise<Response> {\n const body = await readJsonObject(request);\n const message = typeof body?.message === \"string\" ? body.message.trim() : \"\";\n if (!message) {\n return errorResponse(400, \"Body must carry a non-empty message.\", \"message_required\");\n }\n const resolved = await resolveChatRequest(request, resolve);\n if (resolved.response) return resolved.response;\n const opened = await openResolvedChat(og, resolved.resolution, clientConversation(request, null));\n if (opened.response) return opened.response;\n return chatChunksToSseResponse(opened.chat.stream(message, { signal: request.signal }));\n}\n\n/**\n * `GET` -> `{ conversation, sessionId, created, messages, pending, status }`: the user and\n * assistant text of the conversation so a client can restore it on reload\n * (`messages` is empty and `created` false before the first message).\n */\nexport async function handleNativeHistoryRequest(\n og: Opengeni,\n request: Request,\n resolve: ChatResolve,\n): Promise<Response> {\n const resolved = await resolveChatRequest(request, resolve);\n if (resolved.response) return resolved.response;\n const opened = await openResolvedChat(og, resolved.resolution, clientConversation(request, null));\n if (opened.response) return opened.response;\n try {\n const snapshot = await opened.chat.snapshot();\n return jsonResponse({\n conversation: opened.chat.conversation,\n sessionId: opened.chat.sessionId,\n created: opened.chat.created,\n ...snapshot,\n });\n } catch (error) {\n const summary = chatErrorSummary(error);\n return errorResponse(summary.status, summary.message, summary.code);\n }\n}\n\n/** `POST .../respond { requestId, decision | answers | skip }` -> native SSE of the continuation. */\nexport async function handleNativeRespondRequest(\n og: Opengeni,\n request: Request,\n resolve: ChatResolve,\n): Promise<Response> {\n const body = await readJsonObject(request);\n const input = respondInputFromBody(body);\n if (!input) {\n return errorResponse(\n 400,\n \"Body must carry requestId plus decision, answers, or skip.\",\n \"respond_input_invalid\",\n );\n }\n const resolved = await resolveChatRequest(request, resolve);\n if (resolved.response) return resolved.response;\n const opened = await openResolvedChat(og, resolved.resolution, clientConversation(request, null));\n if (opened.response) return opened.response;\n return chatChunksToSseResponse(opened.chat.respondStream(input, { signal: request.signal }));\n}\n\nexport function respondInputFromBody(\n body: Record<string, unknown> | null,\n): ChatRespondInput | null {\n const requestId = typeof body?.requestId === \"string\" ? body.requestId : \"\";\n if (!body || !requestId) return null;\n if (body.decision === \"approve\" || body.decision === \"reject\") {\n return {\n requestId,\n decision: body.decision,\n ...(typeof body.message === \"string\" ? { message: body.message } : {}),\n };\n }\n if (Array.isArray(body.answers)) {\n const answers = body.answers.filter(\n (answer): answer is HumanInputAnswer =>\n !!answer &&\n typeof answer === \"object\" &&\n typeof (answer as HumanInputAnswer).questionId === \"string\" &&\n Array.isArray((answer as HumanInputAnswer).values),\n );\n return { requestId, answers };\n }\n if (body.skip === true) return { requestId, skip: true };\n return null;\n}\n\n/** Native wire format: `event: chunk` per {@link ChatChunk}, `event: error` on failure. */\nexport async function* chatChunksToSseBlocks(\n chunks: AsyncIterable<ChatChunk>,\n): AsyncGenerator<string, void, void> {\n try {\n for await (const chunk of chunks) {\n yield sseLine(JSON.stringify(chunk), \"chunk\");\n }\n } catch (error) {\n const summary = chatErrorSummary(error);\n yield sseLine(JSON.stringify({ code: summary.code, message: summary.message }), \"error\");\n }\n}\n\nexport function chatChunksToSseStream(\n chunks: AsyncIterable<ChatChunk>,\n onCancel?: () => void,\n): ReadableStream<Uint8Array> {\n return sseByteStream(chatChunksToSseBlocks(chunks), onCancel);\n}\n\nexport function chatChunksToSseResponse(chunks: AsyncIterable<ChatChunk>): Response {\n return new Response(chatChunksToSseStream(chunks), {\n headers: sseHeaders({ [CHAT_FORMAT_HEADER]: \"native\" }),\n });\n}\n\n/** Browser-side reader for the native wire format. Throws {@link OpenGeniChatError} on `event: error`. */\nexport async function* parseChatChunkStream(\n stream: ReadableStream<Uint8Array>,\n): AsyncGenerator<ChatChunk, void, void> {\n for await (const message of parseSseStream(stream)) {\n let parsed: unknown;\n try {\n parsed = JSON.parse(message.data);\n } catch {\n continue;\n }\n if (message.event === \"error\") {\n const record = (parsed ?? {}) as { code?: unknown; message?: unknown };\n throw new OpenGeniChatError(\n typeof record.code === \"string\" ? record.code : \"chat_error\",\n typeof record.message === \"string\" ? record.message : \"Chat request failed.\",\n );\n }\n if (\n parsed &&\n typeof parsed === \"object\" &&\n typeof (parsed as { type?: unknown }).type === \"string\"\n ) {\n yield parsed as ChatChunk;\n }\n }\n}\n"],"mappings":"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","names":["message"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type ChatResolve } from "./http.js";
|
|
2
|
+
import type { Chat, Opengeni } from "./opengeni.js";
|
|
3
|
+
import { type ChatChunk, type ChatReply } from "./types.js";
|
|
4
|
+
export declare function chatCompletionBlocks(chat: Chat, chunks: AsyncIterable<ChatChunk>, model: string): AsyncGenerator<string, void, void>;
|
|
5
|
+
export declare function chatCompletionObject(reply: ChatReply, model: string): Record<string, unknown>;
|
|
6
|
+
/**
|
|
7
|
+
* `POST /v1/chat/completions` shape: `{ messages, stream?, model?, user?, metadata? }`.
|
|
8
|
+
* Conversation: the host's `resolve`, else the `x-opengeni-conversation` header,
|
|
9
|
+
* else `metadata.conversation_id`; 400 when none. Only the last user message
|
|
10
|
+
* is sent; the messages before it are imported once as context when this
|
|
11
|
+
* request creates the session.
|
|
12
|
+
*/
|
|
13
|
+
export declare function handleChatCompletionsRequest(og: Opengeni, request: Request, resolve: ChatResolve): Promise<Response>;
|
|
14
|
+
/** Non-streaming response id; the session id alone addresses the conversation. */
|
|
15
|
+
export declare function encodeResponseId(sessionId: string, sequence: number): string;
|
|
16
|
+
export declare function decodeResponseId(value: unknown): string | null;
|
|
17
|
+
export declare function responsesBlocks(chat: Chat, chunks: AsyncIterable<ChatChunk>, model: string, previousResponseId: string | null): AsyncGenerator<string, void, void>;
|
|
18
|
+
/** Text of the Responses `input`: a string, or the last user item's `input_text` parts. */
|
|
19
|
+
export declare function responsesInputText(input: unknown): string | null;
|
|
20
|
+
/**
|
|
21
|
+
* `POST /v1/responses` shape: `{ input, previous_response_id?, conversation?, stream?, model?, user? }`.
|
|
22
|
+
* Conversation: the host's `resolve`, else the `x-opengeni-conversation`
|
|
23
|
+
* header, else `conversation` / `conversation.id`. A `previous_response_id`
|
|
24
|
+
* may continue the session it encodes only when the host named the user that
|
|
25
|
+
* session belongs to (403 otherwise); when a conversation is named as well,
|
|
26
|
+
* the two must agree (409). 400 when nothing names a conversation. Only the
|
|
27
|
+
* last user item is sent; earlier array items are imported once as context
|
|
28
|
+
* when this request creates the session.
|
|
29
|
+
*/
|
|
30
|
+
export declare function handleResponsesRequest(og: Opengeni, request: Request, resolve: ChatResolve): Promise<Response>;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { OpenGeniEmbeddingClient as OpenGeniClient } from "../embedding-client.js";
|
|
2
|
+
import { type WorkspaceIdOptions, type WorkspaceIdTarget } from "../tenant-workspaces.js";
|
|
3
|
+
import type { CreateSessionRequest, CreateSessionResponse, Session } from "../types.js";
|
|
4
|
+
import { type ChatChunk, type ChatImportedMessage, type ChatMessage, type ChatOptions, type ChatReply, type ChatRespondInput, type ChatSendOptions, type ChatSessionListOptions, type ChatSnapshot, type ChatTarget, type WorkspaceTarget, type OpenGeniOptions } from "./types.js";
|
|
5
|
+
export declare const DEFAULT_OPENGENI_BASE_URL = "https://app.opengeni.ai";
|
|
6
|
+
export declare const DEFAULT_CHAT_SOURCE = "app";
|
|
7
|
+
type BuildCreate = (text: string, send: ChatSendOptions) => CreateSessionRequest;
|
|
8
|
+
type SubmitCreate = (request: CreateSessionRequest) => Promise<CreateSessionResponse>;
|
|
9
|
+
type ChatInit = {
|
|
10
|
+
workspaceId: string;
|
|
11
|
+
sessionId: string;
|
|
12
|
+
conversation: string | null;
|
|
13
|
+
session: Session | null;
|
|
14
|
+
buildCreate: BuildCreate | null;
|
|
15
|
+
submitCreate?: SubmitCreate | undefined;
|
|
16
|
+
};
|
|
17
|
+
/** Upper bound on the `modelContext` built from `importedHistory`, header included. */
|
|
18
|
+
export declare const IMPORTED_HISTORY_MAX_CHARS = 30000;
|
|
19
|
+
/**
|
|
20
|
+
* One-option-object entry point for products that already have a chat. Wraps
|
|
21
|
+
* `OpenGeniClient` (exposed as `client`) with tenant workspaces, deterministic
|
|
22
|
+
* conversation sessions, and text-first replies.
|
|
23
|
+
*/
|
|
24
|
+
export declare class OpenGeni {
|
|
25
|
+
readonly client: OpenGeniClient;
|
|
26
|
+
/**
|
|
27
|
+
* The organization id: the one passed to the constructor, else the one
|
|
28
|
+
* derived from the API key once {@link resolveOrganizationId} (or any
|
|
29
|
+
* workspace lookup) has run. An empty string before that; prefer
|
|
30
|
+
* `await og.resolveOrganizationId()`.
|
|
31
|
+
*/
|
|
32
|
+
readonly organizationId: string;
|
|
33
|
+
readonly source: string;
|
|
34
|
+
readonly sessions: {
|
|
35
|
+
/** Sessions visible to the selected canonical user, or explicit service caller. */
|
|
36
|
+
list: (options: ChatSessionListOptions) => Promise<Session[]>;
|
|
37
|
+
};
|
|
38
|
+
private readonly resolveWorkspaceId;
|
|
39
|
+
private implicitAgentAdmission;
|
|
40
|
+
private pendingOrganizationId;
|
|
41
|
+
constructor(options: OpenGeniOptions);
|
|
42
|
+
/**
|
|
43
|
+
* The organization that owns every workspace this facade creates. Uses the
|
|
44
|
+
* constructor's `organizationId`, else reads it once from the API key
|
|
45
|
+
* (`GET /v1/access/me`) and caches it.
|
|
46
|
+
*/
|
|
47
|
+
resolveOrganizationId(): Promise<string>;
|
|
48
|
+
/**
|
|
49
|
+
* Translate your own ids to the Opengeni workspace id, creating the
|
|
50
|
+
* workspace on first use (cached per instance):
|
|
51
|
+
* `{ tenant }` is one workspace per tenant, `{ user }` (no tenant) is one
|
|
52
|
+
* workspace per user, and `{ workspaceId }` is returned as is. Opengeni adds
|
|
53
|
+
* a tenant workspace's users on their first request; a per-user workspace
|
|
54
|
+
* gets its one owner from the SDK and admits nobody else.
|
|
55
|
+
*/
|
|
56
|
+
workspaceId(target: ChatTarget | {
|
|
57
|
+
tenant?: string | undefined;
|
|
58
|
+
workspaceId?: string | undefined;
|
|
59
|
+
} | WorkspaceTarget): Promise<string>;
|
|
60
|
+
/**
|
|
61
|
+
* Resolve a tenant workspace or a user's own workspace (user isolation, per
|
|
62
|
+
* tenant when one is given). A user's own workspace is provisioned with that
|
|
63
|
+
* user as its only explicit member.
|
|
64
|
+
*/
|
|
65
|
+
workspaceIdFor(target: WorkspaceIdTarget, options: WorkspaceIdOptions): Promise<string>;
|
|
66
|
+
/** `chats: "isolated"` keeps its tenant-plus-user workspace; a user alone gets their own. */
|
|
67
|
+
private isolatedWorkspaceId;
|
|
68
|
+
/**
|
|
69
|
+
* Address one conversation; the session is created lazily on the first send.
|
|
70
|
+
* Identity selects authority, not the conversation address. The workspace
|
|
71
|
+
* is the tenant's, the user's own (user only), or the explicit id; Opengeni
|
|
72
|
+
* adds the user to it on their first request.
|
|
73
|
+
* Legacy user-namespaced conversations remain accessible by their session ID.
|
|
74
|
+
*/
|
|
75
|
+
chat(options: ChatOptions): Promise<Chat>;
|
|
76
|
+
private createChatSession;
|
|
77
|
+
/**
|
|
78
|
+
* Address an existing session with native API authorization. The same shared
|
|
79
|
+
* session can be opened by different authorized users. Pass null only for an
|
|
80
|
+
* explicitly service-owned operation; the API still enforces service access.
|
|
81
|
+
*/
|
|
82
|
+
chatBySessionId(target: {
|
|
83
|
+
workspaceId: string;
|
|
84
|
+
sessionId: string;
|
|
85
|
+
user: string | null;
|
|
86
|
+
}): Promise<Chat>;
|
|
87
|
+
private findSession;
|
|
88
|
+
private listSessions;
|
|
89
|
+
}
|
|
90
|
+
/** One conversation bound to one deterministic session. */
|
|
91
|
+
export declare class Chat {
|
|
92
|
+
private readonly client;
|
|
93
|
+
readonly workspaceId: string;
|
|
94
|
+
readonly sessionId: string;
|
|
95
|
+
/** The conversation id this chat was opened with; null when addressed by session id. */
|
|
96
|
+
readonly conversation: string | null;
|
|
97
|
+
private session;
|
|
98
|
+
private readonly buildCreate;
|
|
99
|
+
private readonly submitCreate;
|
|
100
|
+
private pendingTurnId;
|
|
101
|
+
constructor(client: OpenGeniClient, init: ChatInit);
|
|
102
|
+
/** True once the session exists on the server. */
|
|
103
|
+
get created(): boolean;
|
|
104
|
+
/** Send a message and wait for the agent's reply text. */
|
|
105
|
+
send(text: string, options?: ChatSendOptions): Promise<ChatReply>;
|
|
106
|
+
/** Send a message and observe the reply as it streams. Ends with a `done` chunk. */
|
|
107
|
+
stream(text: string, options?: ChatSendOptions): AsyncGenerator<ChatChunk, void, void>;
|
|
108
|
+
/** Supersede the current inference with this message and wait for the reply. */
|
|
109
|
+
steer(text: string, options?: Omit<ChatSendOptions, "steer">): Promise<ChatReply>;
|
|
110
|
+
/** Answer a pending approval or human-input request, then wait for the reply. */
|
|
111
|
+
respond(input: ChatRespondInput, options?: Omit<ChatSendOptions, "steer">): Promise<ChatReply>;
|
|
112
|
+
respondStream(input: ChatRespondInput, options?: Omit<ChatSendOptions, "steer">): AsyncGenerator<ChatChunk, void, void>;
|
|
113
|
+
/** User and assistant text in order, from the durable event log. */
|
|
114
|
+
history(): Promise<ChatMessage[]>;
|
|
115
|
+
/** Restore history and pending decisions from the complete ordered timeline. */
|
|
116
|
+
snapshot(): Promise<ChatSnapshot>;
|
|
117
|
+
private submit;
|
|
118
|
+
private submitSteer;
|
|
119
|
+
private submitResponse;
|
|
120
|
+
private streamTurn;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* `modelContext` for imported history: a header line plus one `role: text`
|
|
124
|
+
* line per message, oldest first, trimmed from the oldest end to
|
|
125
|
+
* {@link IMPORTED_HISTORY_MAX_CHARS}. Undefined when nothing usable remains.
|
|
126
|
+
*/
|
|
127
|
+
export declare function formatImportedHistory(messages: ChatImportedMessage[], maxChars?: number): string | undefined;
|
|
128
|
+
/** Current brand spelling; the established SDK export remains compatible. */
|
|
129
|
+
export { OpenGeni as Opengeni };
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import type { FetchLike } from "../client.js";
|
|
2
|
+
import type { Chats } from "../chats.js";
|
|
3
|
+
import type { WorkspaceIdResolverOptions } from "../tenant-workspaces.js";
|
|
4
|
+
import type { CreateSessionRequest, AgentConfigRequest, HumanInputAnswer, LatencyMode, ReasoningEffort, SessionEvent, Session, SessionSkill, ToolRef } from "../types.js";
|
|
5
|
+
/** Which other sessions the agent may reach from this one. */
|
|
6
|
+
export type ChatAgentAccess = "session" | "user" | "workspace";
|
|
7
|
+
/**
|
|
8
|
+
* Compatibility option for personal or workspace Knowledge. `false` initializes
|
|
9
|
+
* Knowledge authoring to Off; authorized retrieval remains available. Omitted
|
|
10
|
+
* follows `chats`: private with a user, or legacy reach-based defaults without one.
|
|
11
|
+
* Task notes cover temporary session-tree data.
|
|
12
|
+
*/
|
|
13
|
+
export type ChatMemory = "user" | "workspace" | false;
|
|
14
|
+
export type OpenGeniOptions = {
|
|
15
|
+
/** Organization API key. Keep it on the server. */
|
|
16
|
+
apiKey: string;
|
|
17
|
+
/**
|
|
18
|
+
* The organization (account) id that owns every workspace. Optional: when
|
|
19
|
+
* omitted it is read once from the API key.
|
|
20
|
+
*/
|
|
21
|
+
organizationId?: string | undefined;
|
|
22
|
+
/** Defaults to `https://app.opengeni.ai`. */
|
|
23
|
+
baseUrl?: string | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* The product identity used as the external-source label for tenant
|
|
26
|
+
* workspaces and end users. Defaults to `"app"`.
|
|
27
|
+
*/
|
|
28
|
+
source?: string | undefined;
|
|
29
|
+
fetch?: FetchLike | undefined;
|
|
30
|
+
/** Display name for a tenant workspace created on first use. Defaults to the tenant id. */
|
|
31
|
+
workspaceName?: ((tenant: string) => string) | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Per-user workspaces only (`{ user }` alone, or `chats: "isolated"`):
|
|
34
|
+
* permissions for the one owner the SDK adds explicitly. Tenant workspaces
|
|
35
|
+
* rely on Opengeni, which adds a user on their first request. Both default
|
|
36
|
+
* to workspace read, session create/read/control (including sending
|
|
37
|
+
* messages), file upload/read, and per-session MCP attachment; no admin
|
|
38
|
+
* permissions. Never updates an existing membership: use
|
|
39
|
+
* `client.updateExternalWorkspaceMember` for that.
|
|
40
|
+
*/
|
|
41
|
+
memberPermissions?: WorkspaceIdResolverOptions["memberPermissions"];
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Which workspace, in your own ids: `tenant` (one workspace per tenant),
|
|
45
|
+
* neither (the `user`'s own workspace), or an explicit `workspaceId`.
|
|
46
|
+
*/
|
|
47
|
+
export type ChatTarget = {
|
|
48
|
+
tenant: string;
|
|
49
|
+
workspaceId?: undefined;
|
|
50
|
+
} | {
|
|
51
|
+
workspaceId: string;
|
|
52
|
+
tenant?: undefined;
|
|
53
|
+
} | {
|
|
54
|
+
user: string;
|
|
55
|
+
tenant?: undefined;
|
|
56
|
+
workspaceId?: undefined;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* A workspace in your own ids, for `og.workspaceId(...)`: `{ tenant }` (one
|
|
60
|
+
* workspace per tenant), `{ user }` (one workspace per user), or
|
|
61
|
+
* `{ workspaceId }`. Precedence: workspaceId, then tenant, then user.
|
|
62
|
+
*/
|
|
63
|
+
export type WorkspaceTarget = {
|
|
64
|
+
tenant?: string | undefined;
|
|
65
|
+
user?: string | undefined;
|
|
66
|
+
workspaceId?: string | undefined;
|
|
67
|
+
};
|
|
68
|
+
export type ChatOptions = ChatTarget & {
|
|
69
|
+
/**
|
|
70
|
+
* Host-authenticated external user; resolved through server-side asUser().
|
|
71
|
+
* Without a tenant or workspaceId, the user gets one workspace of their own.
|
|
72
|
+
*/
|
|
73
|
+
user?: string | undefined;
|
|
74
|
+
/** Stable conversation id; the session id is derived from it deterministically. */
|
|
75
|
+
conversation: string;
|
|
76
|
+
/** Prefer the actual Opengeni session ID for shared or existing conversations.
|
|
77
|
+
* The acting user is independent of the conversation's identity. */
|
|
78
|
+
sessionId?: string | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* Private (default with a user) uses personal Knowledge and session-only reach;
|
|
81
|
+
* shared uses workspace Knowledge/reach, isolated adds a workspace per tenant/user.
|
|
82
|
+
* Without a user, omission keeps workspace visibility, session reach and Knowledge off.
|
|
83
|
+
*/
|
|
84
|
+
chats?: Chats | undefined;
|
|
85
|
+
/** Agent identity, capabilities and instructions; implicit markdown falls back on older servers. */
|
|
86
|
+
agent?: AgentConfigRequest | undefined;
|
|
87
|
+
/** Explicit agent reach overrides the `chats` default. */
|
|
88
|
+
agentAccess?: ChatAgentAccess | undefined;
|
|
89
|
+
memory?: ChatMemory | undefined;
|
|
90
|
+
model?: string | undefined;
|
|
91
|
+
instructions?: string | undefined;
|
|
92
|
+
skills?: SessionSkill[] | undefined;
|
|
93
|
+
tools?: ToolRef[] | undefined;
|
|
94
|
+
/**
|
|
95
|
+
* Raw create-request passthrough (for example `sandboxBackend: "none"` for a
|
|
96
|
+
* pure chat). Explicit values win over facade-derived ones; the message and
|
|
97
|
+
* identity/idempotency fields always come from the facade.
|
|
98
|
+
*/
|
|
99
|
+
create?: Partial<CreateSessionRequest> | undefined;
|
|
100
|
+
};
|
|
101
|
+
/** A turn stopped to wait for a human decision. */
|
|
102
|
+
export type ChatPending = {
|
|
103
|
+
kind: "approval" | "human_input";
|
|
104
|
+
/** The id to pass back through `chat.respond`. */
|
|
105
|
+
requestId: string;
|
|
106
|
+
/** Tool name for an approval; null for structured human input. */
|
|
107
|
+
name: string | null;
|
|
108
|
+
/** The producer's exact payload (approval entry or human-input request). */
|
|
109
|
+
payload: unknown;
|
|
110
|
+
};
|
|
111
|
+
export type ChatReplyStatus = "completed" | "pending" | "cancelled";
|
|
112
|
+
export type ChatReply = {
|
|
113
|
+
text: string;
|
|
114
|
+
sessionId: string;
|
|
115
|
+
workspaceId: string;
|
|
116
|
+
turnId: string | null;
|
|
117
|
+
/** `pending` waits on `chat.respond`; `cancelled` carries the text produced before the cancel. */
|
|
118
|
+
status: ChatReplyStatus;
|
|
119
|
+
/** Set when the turn is waiting on `chat.respond` instead of finished. */
|
|
120
|
+
pending: ChatPending | null;
|
|
121
|
+
/** A non-destructive completion without a model-authored final answer. */
|
|
122
|
+
emptyFinalReply?: true;
|
|
123
|
+
/** Display this informational notice when emptyFinalReply is present. */
|
|
124
|
+
notice?: string;
|
|
125
|
+
/** Every event consumed while folding this turn. */
|
|
126
|
+
events: SessionEvent[];
|
|
127
|
+
toString(): string;
|
|
128
|
+
};
|
|
129
|
+
export type ChatToolStatus = "started" | "completed" | "failed";
|
|
130
|
+
export type ChatChunk = {
|
|
131
|
+
type: "text";
|
|
132
|
+
text: string;
|
|
133
|
+
} | {
|
|
134
|
+
type: "tool";
|
|
135
|
+
name: string;
|
|
136
|
+
status: ChatToolStatus;
|
|
137
|
+
callId?: string | undefined;
|
|
138
|
+
input?: unknown;
|
|
139
|
+
} | {
|
|
140
|
+
type: "pending";
|
|
141
|
+
pending: ChatPending;
|
|
142
|
+
} | {
|
|
143
|
+
type: "done";
|
|
144
|
+
reply: ChatReply;
|
|
145
|
+
};
|
|
146
|
+
export type ChatMessage = {
|
|
147
|
+
role: "user" | "assistant";
|
|
148
|
+
text: string;
|
|
149
|
+
sequence: number;
|
|
150
|
+
};
|
|
151
|
+
/** Durable text and unresolved decisions restored when a chat is reopened. */
|
|
152
|
+
export type ChatSnapshot = {
|
|
153
|
+
messages: ChatMessage[];
|
|
154
|
+
pending: ChatPending[];
|
|
155
|
+
status: Session["status"] | null;
|
|
156
|
+
};
|
|
157
|
+
export type ChatRespondInput = {
|
|
158
|
+
requestId: string;
|
|
159
|
+
decision: "approve" | "reject";
|
|
160
|
+
message?: string | undefined;
|
|
161
|
+
} | {
|
|
162
|
+
requestId: string;
|
|
163
|
+
answers: HumanInputAnswer[];
|
|
164
|
+
} | {
|
|
165
|
+
requestId: string;
|
|
166
|
+
skip: true;
|
|
167
|
+
};
|
|
168
|
+
/** One earlier message from the product's own history, imported as context on the first send. */
|
|
169
|
+
export type ChatImportedMessage = {
|
|
170
|
+
role: "user" | "assistant" | "system";
|
|
171
|
+
text: string;
|
|
172
|
+
};
|
|
173
|
+
export type ChatSendOptions = {
|
|
174
|
+
signal?: AbortSignal | undefined;
|
|
175
|
+
/** Supersede the current inference instead of queueing behind it. */
|
|
176
|
+
steer?: boolean | undefined;
|
|
177
|
+
/**
|
|
178
|
+
* Earlier messages the product already holds, oldest first. Used only when
|
|
179
|
+
* this send creates the session: they become the first message's
|
|
180
|
+
* `modelContext` (skipped when `create.modelContext` was supplied), trimmed
|
|
181
|
+
* from the oldest end to 30,000 characters. Never resent on later turns:
|
|
182
|
+
* after the first message Opengeni owns the history.
|
|
183
|
+
*/
|
|
184
|
+
importedHistory?: ChatImportedMessage[] | undefined;
|
|
185
|
+
/** Model for this message's turn; omitted keeps the session's current policy. */
|
|
186
|
+
model?: string | undefined;
|
|
187
|
+
reasoningEffort?: ReasoningEffort | undefined;
|
|
188
|
+
latencyMode?: LatencyMode | undefined;
|
|
189
|
+
/**
|
|
190
|
+
* Model-visible application context for this one message (for example the
|
|
191
|
+
* page or record the user is looking at). Not shown in the transcript and not
|
|
192
|
+
* secret. On the creating message it is combined with imported history.
|
|
193
|
+
*/
|
|
194
|
+
modelContext?: string | undefined;
|
|
195
|
+
};
|
|
196
|
+
export type ChatSessionListOptions = ChatTarget & {
|
|
197
|
+
user?: string | undefined;
|
|
198
|
+
/** Match the chat's mode; isolated lists that user's separate workspace. */
|
|
199
|
+
chats?: Chats | undefined;
|
|
200
|
+
limit?: number | undefined;
|
|
201
|
+
};
|
|
202
|
+
/** A turn ended without a usable reply, or the facade was misused. */
|
|
203
|
+
export declare class OpenGeniChatError extends Error {
|
|
204
|
+
readonly code: string;
|
|
205
|
+
readonly event: SessionEvent | null;
|
|
206
|
+
constructor(code: string, message: string, event?: SessionEvent | null);
|
|
207
|
+
}
|