@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.
Files changed (299) hide show
  1. package/README.md +1007 -72
  2. package/dist/adapters/express.d.ts +31 -0
  3. package/dist/adapters/express.js +87 -0
  4. package/dist/adapters/express.js.map +1 -0
  5. package/dist/adapters/hono.d.ts +16 -0
  6. package/dist/adapters/hono.js +8 -0
  7. package/dist/adapters/hono.js.map +1 -0
  8. package/dist/adapters/next.d.ts +29 -0
  9. package/dist/adapters/next.js +22 -0
  10. package/dist/adapters/next.js.map +1 -0
  11. package/dist/allowance-refusal.d.ts +2 -0
  12. package/dist/allowance-refusal.js +50 -0
  13. package/dist/allowance-refusal.js.map +1 -0
  14. package/dist/app-links.d.ts +42 -0
  15. package/dist/app-links.js +66 -0
  16. package/dist/app-links.js.map +1 -0
  17. package/dist/artifact-catalog.d.ts +40 -0
  18. package/dist/artifact-client.d.ts +20 -8
  19. package/dist/artifacts.d.ts +1 -1
  20. package/dist/artifacts.js +8 -6
  21. package/dist/automations.js +8 -2
  22. package/dist/automations.js.map +1 -1
  23. package/dist/azure-live-transport.d.ts +32 -0
  24. package/dist/browser.d.ts +7 -2
  25. package/dist/browser.js +27 -5
  26. package/dist/chat/fold.d.ts +75 -0
  27. package/dist/chat/handler.d.ts +41 -0
  28. package/dist/chat/http.d.ts +67 -0
  29. package/dist/chat/ids.d.ts +34 -0
  30. package/dist/chat/index.d.ts +9 -0
  31. package/dist/chat/index.js +1369 -0
  32. package/dist/chat/index.js.map +1 -0
  33. package/dist/chat/openai.d.ts +30 -0
  34. package/dist/chat/opengeni.d.ts +129 -0
  35. package/dist/chat/types.d.ts +207 -0
  36. package/dist/chat/vercel.d.ts +49 -0
  37. package/dist/chats.d.ts +8 -0
  38. package/dist/chunk-4AHR4KGA.js +301 -0
  39. package/dist/chunk-4AHR4KGA.js.map +1 -0
  40. package/dist/chunk-6GYGMLX4.js +332 -0
  41. package/dist/chunk-6GYGMLX4.js.map +1 -0
  42. package/dist/chunk-7EWT3PV6.js +368 -0
  43. package/dist/chunk-7EWT3PV6.js.map +1 -0
  44. package/dist/chunk-FTWVVPR6.js +1665 -0
  45. package/dist/chunk-FTWVVPR6.js.map +1 -0
  46. package/dist/{chunk-VYCTL62C.js → chunk-GZQSWAKD.js} +1 -1
  47. package/dist/chunk-GZQSWAKD.js.map +1 -0
  48. package/dist/chunk-KGEABAID.js +71 -0
  49. package/dist/chunk-KGEABAID.js.map +1 -0
  50. package/dist/{chunk-YKZME56C.js → chunk-KWADQ227.js} +3 -3
  51. package/dist/{chunk-YKZME56C.js.map → chunk-KWADQ227.js.map} +1 -1
  52. package/dist/{chunk-JUS2UYRP.js → chunk-NCU5OAN7.js} +27 -2
  53. package/dist/chunk-NCU5OAN7.js.map +1 -0
  54. package/dist/{chunk-YXQX7RQT.js → chunk-OI5YLASH.js} +73 -2
  55. package/dist/chunk-OI5YLASH.js.map +1 -0
  56. package/dist/chunk-OV3POE62.js +359 -0
  57. package/dist/chunk-OV3POE62.js.map +1 -0
  58. package/dist/chunk-P7UWKORG.js +561 -0
  59. package/dist/chunk-P7UWKORG.js.map +1 -0
  60. package/dist/chunk-QGEIL4TR.js +195 -0
  61. package/dist/chunk-QGEIL4TR.js.map +1 -0
  62. package/dist/{chunk-TRNI7KEO.js → chunk-S2NLS3ES.js} +3669 -1281
  63. package/dist/chunk-S2NLS3ES.js.map +1 -0
  64. package/dist/chunk-UM4ZXXJR.js +9 -0
  65. package/dist/chunk-UM4ZXXJR.js.map +1 -0
  66. package/dist/{chunk-QT3KFVDP.js → chunk-UME3X7CP.js} +28 -32
  67. package/dist/chunk-UME3X7CP.js.map +1 -0
  68. package/dist/chunk-VT4YM4XQ.js +210 -0
  69. package/dist/chunk-VT4YM4XQ.js.map +1 -0
  70. package/dist/chunk-WSYYXONG.js +1602 -0
  71. package/dist/chunk-WSYYXONG.js.map +1 -0
  72. package/dist/{chunk-C2H7HBNP.js → chunk-WVCJRSGJ.js} +119 -14
  73. package/dist/chunk-WVCJRSGJ.js.map +1 -0
  74. package/dist/chunk-X5ITQVXE.js +15 -0
  75. package/dist/chunk-X5ITQVXE.js.map +1 -0
  76. package/dist/chunk-XA7HVIHI.js +126 -0
  77. package/dist/chunk-XA7HVIHI.js.map +1 -0
  78. package/dist/{chunk-KKRO2VCP.js → chunk-YJCHB7R3.js} +60 -12
  79. package/dist/chunk-YJCHB7R3.js.map +1 -0
  80. package/dist/chunk-YKIHNLWD.js +153 -0
  81. package/dist/chunk-YKIHNLWD.js.map +1 -0
  82. package/dist/chunk-ZDUBPV33.js +277 -0
  83. package/dist/chunk-ZDUBPV33.js.map +1 -0
  84. package/dist/client.d.ts +1068 -118
  85. package/dist/codex-realtime-controller.d.ts +13 -0
  86. package/dist/codex-realtime-controller.js +4 -2
  87. package/dist/codex-realtime-v3-wire.d.ts +3 -2
  88. package/dist/codex-realtime.d.ts +5 -1
  89. package/dist/company-brain.d.ts +1 -11
  90. package/dist/core.d.ts +7 -2
  91. package/dist/core.js +25 -6
  92. package/dist/deprecation.d.ts +47 -0
  93. package/dist/document-authority-client.d.ts +24 -2
  94. package/dist/document-authority.js +7 -5
  95. package/dist/editable-artifacts/index.d.ts +1 -1
  96. package/dist/editable-artifacts/types.d.ts +12 -2
  97. package/dist/editable-artifacts.js +19 -3
  98. package/dist/editable-artifacts.js.map +1 -1
  99. package/dist/embedding-client.d.ts +129 -0
  100. package/dist/errors.d.ts +76 -1
  101. package/dist/external-vault-receiver.d.ts +203 -0
  102. package/dist/external-vault-receiver.js +564 -0
  103. package/dist/external-vault-receiver.js.map +1 -0
  104. package/dist/feedback.d.ts +23 -0
  105. package/dist/gateway-realtime-transport.js +1 -1
  106. package/dist/github-repositories.d.ts +10 -0
  107. package/dist/github-repositories.js +36 -0
  108. package/dist/github-repositories.js.map +1 -0
  109. package/dist/index.d.ts +62 -11
  110. package/dist/index.js +557 -338
  111. package/dist/index.js.map +1 -1
  112. package/dist/insights-usage.d.ts +33 -0
  113. package/dist/insights-usage.js +7 -0
  114. package/dist/insights-usage.js.map +1 -0
  115. package/dist/interaction.d.ts +165 -71
  116. package/dist/interaction.js +2 -2
  117. package/dist/knowledge.d.ts +7 -0
  118. package/dist/knowledge.js +20 -0
  119. package/dist/knowledge.js.map +1 -0
  120. package/dist/known-tools.d.ts +4 -0
  121. package/dist/message-links.d.ts +68 -0
  122. package/dist/model-context.d.ts +68 -0
  123. package/dist/model-display.d.ts +2 -0
  124. package/dist/model-display.js +17 -0
  125. package/dist/model-display.js.map +1 -0
  126. package/dist/model-picker-order.d.ts +1 -0
  127. package/dist/model-picker-order.js +10 -0
  128. package/dist/model-picker-order.js.map +1 -0
  129. package/dist/organization-integration-policy.d.ts +26 -0
  130. package/dist/organization-integration-policy.js +26 -0
  131. package/dist/organization-integration-policy.js.map +1 -0
  132. package/dist/pr-review-client.d.ts +1 -1
  133. package/dist/pr-review.d.ts +1 -1
  134. package/dist/pr-review.js.map +1 -1
  135. package/dist/preference-registry.d.ts +1 -1
  136. package/dist/prepared-mcp-setup.d.ts +5 -0
  137. package/dist/proxy.d.ts +13 -11
  138. package/dist/realtime.d.ts +1 -1
  139. package/dist/realtime.js +253 -7
  140. package/dist/realtime.js.map +1 -1
  141. package/dist/session-history-import.d.ts +22 -0
  142. package/dist/session-history-import.js +36 -0
  143. package/dist/session-history-import.js.map +1 -0
  144. package/dist/session-list-entries.d.ts +1 -0
  145. package/dist/session-list-entries.js +7 -0
  146. package/dist/session-list-entries.js.map +1 -0
  147. package/dist/session-message-search.d.ts +53 -0
  148. package/dist/session-proxy-client.d.ts +28 -0
  149. package/dist/session-proxy.d.ts +334 -0
  150. package/dist/session-proxy.js +24 -0
  151. package/dist/session-proxy.js.map +1 -0
  152. package/dist/session-titles.d.ts +2 -28
  153. package/dist/session-usage-limits.d.ts +10 -0
  154. package/dist/session-usage-limits.js +43 -0
  155. package/dist/session-usage-limits.js.map +1 -0
  156. package/dist/shared-catalog-loader.d.ts +34 -0
  157. package/dist/site-ai.d.ts +35 -0
  158. package/dist/site-bridge-host.d.ts +112 -0
  159. package/dist/site-bridge-host.js +286 -0
  160. package/dist/site-bridge-host.js.map +1 -0
  161. package/dist/site-browser-entry.d.ts +1 -0
  162. package/dist/site-browser-runtime.gen.d.ts +1 -0
  163. package/dist/site-data.d.ts +178 -0
  164. package/dist/site-document.d.ts +5 -0
  165. package/dist/site-document.js +20 -0
  166. package/dist/site-document.js.map +1 -0
  167. package/dist/site-document.test.d.ts +1 -0
  168. package/dist/site-http.d.ts +17 -0
  169. package/dist/site-sql.d.ts +31 -0
  170. package/dist/site-tool-bridge.d.ts +57 -0
  171. package/dist/site.d.ts +186 -0
  172. package/dist/site.js +63 -0
  173. package/dist/site.js.map +1 -0
  174. package/dist/skills.d.ts +75 -0
  175. package/dist/sse.d.ts +1 -1
  176. package/dist/stream.d.ts +2 -0
  177. package/dist/tenant-workspaces.d.ts +47 -0
  178. package/dist/tenant-workspaces.js +8 -0
  179. package/dist/tenant-workspaces.js.map +1 -0
  180. package/dist/tool-auth.d.ts +87 -0
  181. package/dist/tool-auth.js +23 -0
  182. package/dist/tool-auth.js.map +1 -0
  183. package/dist/tool-display-metadata.d.ts +3 -0
  184. package/dist/tools-37DCTCNZ.js +12 -0
  185. package/dist/tools-37DCTCNZ.js.map +1 -0
  186. package/dist/tools.d.ts +81 -0
  187. package/dist/transcription.d.ts +1 -1
  188. package/dist/types.d.ts +2807 -583
  189. package/dist/usage-allowances.d.ts +36 -0
  190. package/dist/usage-allowances.js +80 -0
  191. package/dist/usage-allowances.js.map +1 -0
  192. package/dist/vault-types.d.ts +324 -0
  193. package/dist/vaults-api.d.ts +65 -0
  194. package/dist/workspace-artifacts.d.ts +47 -5
  195. package/dist/workspace-instruction-policies.d.ts +2 -2
  196. package/dist/workspace-integrations.d.ts +74 -0
  197. package/dist/workspace-integrations.js +67 -0
  198. package/dist/workspace-integrations.js.map +1 -0
  199. package/dist/workspace-state.d.ts +8 -71
  200. package/package.json +103 -5
  201. package/src/adapters/express.ts +136 -0
  202. package/src/adapters/hono.ts +18 -0
  203. package/src/adapters/next.ts +42 -0
  204. package/src/allowance-refusal.ts +5 -0
  205. package/src/app-links.ts +117 -0
  206. package/src/artifact-catalog.ts +51 -0
  207. package/src/artifact-client.ts +40 -49
  208. package/src/artifacts.ts +1 -0
  209. package/src/automations-client.ts +8 -2
  210. package/src/azure-live-transport.ts +286 -0
  211. package/src/browser.ts +37 -0
  212. package/src/chat/fold.ts +431 -0
  213. package/src/chat/handler.ts +240 -0
  214. package/src/chat/http.ts +257 -0
  215. package/src/chat/ids.ts +85 -0
  216. package/src/chat/index.ts +88 -0
  217. package/src/chat/openai.ts +439 -0
  218. package/src/chat/opengeni.ts +737 -0
  219. package/src/chat/types.ts +219 -0
  220. package/src/chat/vercel.ts +204 -0
  221. package/src/chats.ts +16 -0
  222. package/src/client.ts +5697 -1833
  223. package/src/codex-realtime-controller.ts +163 -8
  224. package/src/codex-realtime-v3-wire.ts +4 -3
  225. package/src/codex-realtime-v3.ts +12 -3
  226. package/src/codex-realtime.ts +11 -3
  227. package/src/company-brain.ts +0 -40
  228. package/src/core.ts +20 -0
  229. package/src/deprecation.ts +149 -0
  230. package/src/document-authority-client.ts +104 -1
  231. package/src/editable-artifacts/controller.ts +36 -2
  232. package/src/editable-artifacts/index.ts +1 -0
  233. package/src/editable-artifacts/types.ts +29 -16
  234. package/src/embedding-client.ts +519 -0
  235. package/src/errors.ts +303 -4
  236. package/src/external-vault-receiver.ts +914 -0
  237. package/src/feedback.ts +20 -0
  238. package/src/gateway-realtime-transport.ts +3 -3
  239. package/src/github-repositories.ts +60 -0
  240. package/src/index.ts +603 -65
  241. package/src/insights-usage.ts +64 -0
  242. package/src/interaction.ts +315 -93
  243. package/src/knowledge.ts +72 -0
  244. package/src/known-tools.ts +279 -0
  245. package/src/message-links.ts +178 -0
  246. package/src/model-context.ts +113 -0
  247. package/src/model-display.ts +11 -0
  248. package/src/model-picker-order.ts +6 -0
  249. package/src/organization-integration-policy.ts +54 -0
  250. package/src/pr-review-client.ts +1 -1
  251. package/src/pr-review.ts +1 -1
  252. package/src/preference-registry.ts +2 -0
  253. package/src/prepared-mcp-setup.ts +123 -0
  254. package/src/proxy.ts +23 -12
  255. package/src/realtime.ts +15 -6
  256. package/src/session-history-import.ts +84 -0
  257. package/src/session-list-entries.ts +1 -0
  258. package/src/session-message-search.ts +47 -0
  259. package/src/session-proxy-client.ts +68 -0
  260. package/src/session-proxy.ts +2098 -0
  261. package/src/session-titles.ts +8 -82
  262. package/src/session-usage-limits.ts +71 -0
  263. package/src/shared-catalog-loader.ts +169 -0
  264. package/src/site-ai.ts +284 -0
  265. package/src/site-bridge-host.ts +422 -0
  266. package/src/site-browser-entry.ts +6 -0
  267. package/src/site-browser-runtime.gen.ts +2 -0
  268. package/src/site-data.ts +372 -0
  269. package/src/site-document.test.ts +64 -0
  270. package/src/site-document.ts +18 -0
  271. package/src/site-http.ts +171 -0
  272. package/src/site-sql.ts +153 -0
  273. package/src/site-tool-bridge.ts +401 -0
  274. package/src/site.ts +878 -0
  275. package/src/skills.ts +69 -0
  276. package/src/sse.ts +9 -3
  277. package/src/stream.ts +33 -10
  278. package/src/tenant-workspaces.ts +148 -0
  279. package/src/tool-auth.ts +301 -0
  280. package/src/tool-display-metadata.ts +27 -0
  281. package/src/tools.ts +452 -0
  282. package/src/transcription.ts +3 -0
  283. package/src/types.ts +3170 -582
  284. package/src/usage-allowances.ts +189 -0
  285. package/src/vault-types.ts +379 -0
  286. package/src/vaults-api.ts +339 -0
  287. package/src/workspace-artifacts.ts +55 -6
  288. package/src/workspace-instruction-policies.ts +2 -1
  289. package/src/workspace-integrations.ts +402 -0
  290. package/src/workspace-state.ts +8 -82
  291. package/dist/chunk-C2H7HBNP.js.map +0 -1
  292. package/dist/chunk-C4DJPZRU.js +0 -119
  293. package/dist/chunk-C4DJPZRU.js.map +0 -1
  294. package/dist/chunk-JUS2UYRP.js.map +0 -1
  295. package/dist/chunk-KKRO2VCP.js.map +0 -1
  296. package/dist/chunk-QT3KFVDP.js.map +0 -1
  297. package/dist/chunk-TRNI7KEO.js.map +0 -1
  298. package/dist/chunk-VYCTL62C.js.map +0 -1
  299. package/dist/chunk-YXQX7RQT.js.map +0 -1
@@ -1,9 +1,80 @@
1
1
  import {
2
2
  OpenGeniClient
3
- } from "./chunk-TRNI7KEO.js";
3
+ } from "./chunk-S2NLS3ES.js";
4
4
 
5
5
  // src/document-authority-client.ts
6
6
  var OpenGeniDocumentAuthorityClient = class extends OpenGeniClient {
7
+ /** Read organization-key metadata and policy; never returns the secret token. */
8
+ async getOrganizationApiKey(organizationId, apiKeyId) {
9
+ return await this.requestJson(
10
+ "GET",
11
+ `/v1/organizations/${organizationId}/api-keys/${apiKeyId}`
12
+ );
13
+ }
14
+ /** Update metadata or replace the policy. Policy narrowing applies on the next request. */
15
+ async updateOrganizationApiKey(organizationId, apiKeyId, request) {
16
+ return await this.requestJson(
17
+ "PATCH",
18
+ `/v1/organizations/${organizationId}/api-keys/${apiKeyId}`,
19
+ request
20
+ );
21
+ }
22
+ /** Issue an exact-session or standing personal-resource grant. */
23
+ async issueUserResourceGrant(workspaceId, authorityId, request) {
24
+ return await this.requestJson(
25
+ "POST",
26
+ `/v1/workspaces/${workspaceId}/user-resource-authorities/${authorityId}/grants`,
27
+ request
28
+ );
29
+ }
30
+ async listDocumentBases(workspaceId) {
31
+ return await this.requestJson(
32
+ "GET",
33
+ `/v1/workspaces/${workspaceId}/document-bases`
34
+ );
35
+ }
36
+ /**
37
+ * List every Document the current human can manage from this workspace,
38
+ * including portable personal and organization-scoped Documents whose
39
+ * immutable ingestion workspace is different.
40
+ */
41
+ async listAccessibleDocuments(workspaceId) {
42
+ return await this.requestJson("GET", `/v1/workspaces/${workspaceId}/documents`);
43
+ }
44
+ /** Mint a source-file URL through the Document's effective authority. */
45
+ async createDocumentOriginalFileDownloadUrl(workspaceId, documentId) {
46
+ return await this.requestJson(
47
+ "POST",
48
+ `/v1/workspaces/${workspaceId}/documents/${documentId}/original-file/download-url`
49
+ );
50
+ }
51
+ /** Retry indexing for a failed document. */
52
+ async reindexDocument(workspaceId, baseId, documentId) {
53
+ return await this.requestJson(
54
+ "POST",
55
+ `/v1/workspaces/${workspaceId}/document-bases/${baseId}/documents/${documentId}/reindex`
56
+ );
57
+ }
58
+ /** Permission-filtered Company Brain package with authorized guidance bodies. */
59
+ getCompanyBrain(workspaceId) {
60
+ return this.requestJson(
61
+ "GET",
62
+ `/v1/workspaces/${workspaceId}/company-brain`
63
+ );
64
+ }
65
+ /** Download the deterministic Markdown/YAML Company Brain package. */
66
+ async exportCompanyBrainOkf(workspaceId) {
67
+ const response = await this.requestResponse(
68
+ "GET",
69
+ `/v1/workspaces/${workspaceId}/company-brain/export`
70
+ );
71
+ const headers = response.headers;
72
+ return {
73
+ content: await response.text(),
74
+ contentType: headers.get("content-type") ?? "text/markdown",
75
+ filename: headers.get("content-disposition")?.split('"')[1] ?? "company-brain.okf.md"
76
+ };
77
+ }
7
78
  /**
8
79
  * Atomically reclassify a Document's authority and every indexed chunk.
9
80
  * The operation is replay-safe and rejects a stale expected authority tuple.
@@ -76,4 +147,4 @@ var OpenGeniDocumentAuthorityClient = class extends OpenGeniClient {
76
147
  export {
77
148
  OpenGeniDocumentAuthorityClient
78
149
  };
79
- //# sourceMappingURL=chunk-YXQX7RQT.js.map
150
+ //# sourceMappingURL=chunk-OI5YLASH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/document-authority-client.ts"],"sourcesContent":["import type { CompanyBrainOkfDownload, CompanyBrainOkfPackage } from \"./company-brain\";\nimport { OpenGeniClient as OpenGeniCoreClient } from \"./client\";\nimport type {\n ApiKey,\n UpdateOrganizationApiKeyRequest,\n Document,\n IssueUserResourceGrantRequest,\n UserResourceGrantMutationResponse,\n DocumentBase,\n FileDownloadUrlResponse,\n DocumentAuthorityReclassification,\n DocumentDefaultCollectionBackfill,\n DocumentDefaultCollectionBackfillAudit,\n GetDocumentDefaultCollectionBackfillAuditOptions,\n ListDocumentAuthorityReclassificationsOptions,\n ListDocumentAuthorityReclassificationsResponse,\n ListDocumentDefaultCollectionBackfillRunsResponse,\n ListOrganizationDocumentAuthorityReclassificationsResponse,\n ReclassifyDocumentAuthorityRequest,\n RunDocumentDefaultCollectionBackfillRequest,\n} from \"./types\";\n\n/**\n * Operator-only authority administration and Document tenancy-backfill surface.\n *\n * The public root and legacy `core` clients extend this class for compatibility.\n * Browser consoles that import `@opengeni/sdk/browser` do not retain these\n * methods or their routes.\n */\nexport class OpenGeniDocumentAuthorityClient extends OpenGeniCoreClient {\n /** Read organization-key metadata and policy; never returns the secret token. */\n async getOrganizationApiKey(organizationId: string, apiKeyId: string): Promise<ApiKey> {\n return await this.requestJson<ApiKey>(\n \"GET\",\n `/v1/organizations/${organizationId}/api-keys/${apiKeyId}`,\n );\n }\n\n /** Update metadata or replace the policy. Policy narrowing applies on the next request. */\n async updateOrganizationApiKey(\n organizationId: string,\n apiKeyId: string,\n request: UpdateOrganizationApiKeyRequest,\n ): Promise<ApiKey> {\n return await this.requestJson<ApiKey>(\n \"PATCH\",\n `/v1/organizations/${organizationId}/api-keys/${apiKeyId}`,\n request,\n );\n }\n\n /** Issue an exact-session or standing personal-resource grant. */\n async issueUserResourceGrant(\n workspaceId: string,\n authorityId: string,\n request: IssueUserResourceGrantRequest,\n ): Promise<UserResourceGrantMutationResponse> {\n return await this.requestJson<UserResourceGrantMutationResponse>(\n \"POST\",\n `/v1/workspaces/${workspaceId}/user-resource-authorities/${authorityId}/grants`,\n request,\n );\n }\n\n async listDocumentBases(workspaceId: string): Promise<DocumentBase[]> {\n return await this.requestJson<DocumentBase[]>(\n \"GET\",\n `/v1/workspaces/${workspaceId}/document-bases`,\n );\n }\n\n /**\n * List every Document the current human can manage from this workspace,\n * including portable personal and organization-scoped Documents whose\n * immutable ingestion workspace is different.\n */\n async listAccessibleDocuments(workspaceId: string): Promise<Document[]> {\n return await this.requestJson<Document[]>(\"GET\", `/v1/workspaces/${workspaceId}/documents`);\n }\n\n /** Mint a source-file URL through the Document's effective authority. */\n async createDocumentOriginalFileDownloadUrl(\n workspaceId: string,\n documentId: string,\n ): Promise<FileDownloadUrlResponse> {\n return await this.requestJson<FileDownloadUrlResponse>(\n \"POST\",\n `/v1/workspaces/${workspaceId}/documents/${documentId}/original-file/download-url`,\n );\n }\n\n /** Retry indexing for a failed document. */\n async reindexDocument(\n workspaceId: string,\n baseId: string,\n documentId: string,\n ): Promise<Document> {\n return await this.requestJson<Document>(\n \"POST\",\n `/v1/workspaces/${workspaceId}/document-bases/${baseId}/documents/${documentId}/reindex`,\n );\n }\n\n /** Permission-filtered Company Brain package with authorized guidance bodies. */\n getCompanyBrain(workspaceId: string): Promise<CompanyBrainOkfPackage> {\n return this.requestJson<CompanyBrainOkfPackage>(\n \"GET\",\n `/v1/workspaces/${workspaceId}/company-brain`,\n );\n }\n\n /** Download the deterministic Markdown/YAML Company Brain package. */\n async exportCompanyBrainOkf(workspaceId: string): Promise<CompanyBrainOkfDownload> {\n const response = await this.requestResponse(\n \"GET\",\n `/v1/workspaces/${workspaceId}/company-brain/export`,\n );\n const headers = response.headers;\n return {\n content: await response.text(),\n contentType: headers.get(\"content-type\") ?? \"text/markdown\",\n filename: headers.get(\"content-disposition\")?.split('\"')[1] ?? \"company-brain.okf.md\",\n };\n }\n\n /**\n * Atomically reclassify a Document's authority and every indexed chunk.\n * The operation is replay-safe and rejects a stale expected authority tuple.\n */\n async reclassifyDocumentAuthority(\n workspaceId: string,\n documentId: string,\n request: ReclassifyDocumentAuthorityRequest,\n ): Promise<DocumentAuthorityReclassification> {\n return await this.requestJson<DocumentAuthorityReclassification>(\n \"POST\",\n `/v1/workspaces/${workspaceId}/documents/${documentId}/authority-reclassifications`,\n request,\n );\n }\n\n /** List the current actor's durable authority-reclassification receipts. */\n async listDocumentAuthorityReclassifications(\n workspaceId: string,\n documentId: string,\n options: ListDocumentAuthorityReclassificationsOptions = {},\n ): Promise<ListDocumentAuthorityReclassificationsResponse> {\n const params = new URLSearchParams();\n if (options.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options.cursor) params.set(\"cursor\", options.cursor);\n const query = params.size > 0 ? `?${params.toString()}` : \"\";\n return await this.requestJson<ListDocumentAuthorityReclassificationsResponse>(\n \"GET\",\n `/v1/workspaces/${workspaceId}/documents/${documentId}/authority-reclassifications${query}`,\n );\n }\n\n /**\n * Advance one resumable, organization-scoped Default collection backfill.\n * Reusing an operation ID is idempotent; keep the run ID across batches.\n */\n async runDocumentDefaultCollectionBackfill(\n workspaceId: string,\n request: RunDocumentDefaultCollectionBackfillRequest,\n ): Promise<DocumentDefaultCollectionBackfill> {\n return await this.requestJson<DocumentDefaultCollectionBackfill>(\n \"POST\",\n `/v1/workspaces/${workspaceId}/document-default-collection-backfills`,\n request,\n );\n }\n\n /** List organization-scoped Default collection backfill runs (organization admin only). */\n async listDocumentDefaultCollectionBackfillRuns(\n workspaceId: string,\n options: ListDocumentAuthorityReclassificationsOptions = {},\n ): Promise<ListDocumentDefaultCollectionBackfillRunsResponse> {\n const params = new URLSearchParams();\n if (options.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options.cursor) params.set(\"cursor\", options.cursor);\n const query = params.size > 0 ? `?${params.toString()}` : \"\";\n return await this.requestJson<ListDocumentDefaultCollectionBackfillRunsResponse>(\n \"GET\",\n `/v1/workspaces/${workspaceId}/document-default-collection-backfills${query}`,\n );\n }\n\n /** Read bounded operation and workspace receipts for one Default-collection backfill run. */\n async getDocumentDefaultCollectionBackfillAudit(\n workspaceId: string,\n runId: string,\n options: GetDocumentDefaultCollectionBackfillAuditOptions = {},\n ): Promise<DocumentDefaultCollectionBackfillAudit> {\n const params = new URLSearchParams();\n if (options.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options.operationCursor) params.set(\"operationCursor\", options.operationCursor);\n if (options.receiptCursor) params.set(\"receiptCursor\", options.receiptCursor);\n const query = params.size > 0 ? `?${params.toString()}` : \"\";\n return await this.requestJson<DocumentDefaultCollectionBackfillAudit>(\n \"GET\",\n `/v1/workspaces/${workspaceId}/document-default-collection-backfills/${runId}${query}`,\n );\n }\n\n /** List organization-wide Document authority changes (organization admin only). */\n async listOrganizationDocumentAuthorityReclassifications(\n workspaceId: string,\n options: ListDocumentAuthorityReclassificationsOptions = {},\n ): Promise<ListOrganizationDocumentAuthorityReclassificationsResponse> {\n const params = new URLSearchParams();\n if (options.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options.cursor) params.set(\"cursor\", options.cursor);\n const query = params.size > 0 ? `?${params.toString()}` : \"\";\n return await this.requestJson<ListOrganizationDocumentAuthorityReclassificationsResponse>(\n \"GET\",\n `/v1/workspaces/${workspaceId}/document-authority-reclassifications${query}`,\n );\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,359 @@
1
+ // ../contracts/src/session-final-reply.ts
2
+ var EMPTY_FINAL_REPLY_NOTICE = "The model returned no final reply after a reply reminder. Completed work is preserved; the goal and later updates are unaffected.";
3
+ function turnCompletedWithEmptyFinalReply(payload) {
4
+ return payload !== null && typeof payload === "object" && !Array.isArray(payload) && payload.emptyFinalReply === true;
5
+ }
6
+
7
+ // src/chat/types.ts
8
+ var OpenGeniChatError = class extends Error {
9
+ code;
10
+ event;
11
+ constructor(code, message, event = null) {
12
+ super(message);
13
+ this.name = "OpenGeniChatError";
14
+ this.code = code;
15
+ this.event = event;
16
+ }
17
+ };
18
+
19
+ // src/chat/fold.ts
20
+ var ChatPendingFold = class {
21
+ requests = /* @__PURE__ */ new Map();
22
+ push(event) {
23
+ const payload = asRecord(event.payload);
24
+ if (event.type === "session.requiresAction") {
25
+ for (const [key, request] of this.requests) {
26
+ if (request.pending.kind === "approval") this.requests.delete(key);
27
+ }
28
+ for (const approval of Array.isArray(payload.approvals) ? payload.approvals : []) {
29
+ const pending = approvalPending({ approvals: [approval] });
30
+ if (pending) this.put(pending, event.turnId ?? null);
31
+ }
32
+ } else if (event.type === "session.humanInput.requested") {
33
+ const pending = humanInputPending(payload);
34
+ if (pending) this.put(pending, event.turnId ?? null);
35
+ } else if (event.type === "user.approvalDecision") {
36
+ this.requests.delete(`approval:${payload.approvalId}`);
37
+ } else if (event.type === "user.humanInputResponse") {
38
+ this.requests.delete(`human_input:${payload.requestId}`);
39
+ } else if (["turn.completed", "turn.failed", "turn.cancelled"].includes(event.type)) {
40
+ for (const [key, request] of this.requests) {
41
+ if (request.turnId === null || event.turnId == null || request.turnId === event.turnId) {
42
+ this.requests.delete(key);
43
+ }
44
+ }
45
+ }
46
+ }
47
+ pending(now = Date.now()) {
48
+ return [...this.requests.values()].map((request) => request.pending).filter((pending) => {
49
+ if (pending.kind !== "human_input") return true;
50
+ const expiresAt = asRecord(pending.payload).expiresAt;
51
+ return expiresAt == null || typeof expiresAt === "string" && Date.parse(expiresAt) > now;
52
+ });
53
+ }
54
+ put(pending, turnId) {
55
+ this.requests.set(`${pending.kind}:${pending.requestId}`, { pending, turnId });
56
+ }
57
+ };
58
+ function noStep() {
59
+ return { chunks: [], terminal: null };
60
+ }
61
+ var ChatTurnFold = class {
62
+ constructor(workspaceId, sessionId, expectedTurnId) {
63
+ this.workspaceId = workspaceId;
64
+ this.sessionId = sessionId;
65
+ this.turnId = expectedTurnId;
66
+ }
67
+ events = [];
68
+ turnId;
69
+ pending = null;
70
+ failure = null;
71
+ emptyFinalReply = false;
72
+ segments = [];
73
+ openTools = /* @__PURE__ */ new Map();
74
+ get text() {
75
+ return this.segments.filter((segment) => !segment.commentary).map((segment) => segment.text).filter((text) => text.length > 0).join("\n\n");
76
+ }
77
+ push(event) {
78
+ const eventTurnId = typeof event.turnId === "string" ? event.turnId : null;
79
+ if (this.turnId && eventTurnId && eventTurnId !== this.turnId) {
80
+ return { chunks: [], terminal: null };
81
+ }
82
+ if (!this.turnId && eventTurnId && isTurnScopedType(event.type)) {
83
+ this.turnId = eventTurnId;
84
+ }
85
+ this.events.push(event);
86
+ const payload = asRecord(event.payload);
87
+ switch (event.type) {
88
+ case "agent.message.delta": {
89
+ const text = stringValue(payload.text);
90
+ if (!text) return noStep();
91
+ const messageId = stringValue(payload.messageId) || null;
92
+ if (messageId) return this.messageDelta(messageId, text, isCommentary(payload));
93
+ const open = this.segments.at(-1);
94
+ if (isCommentary(payload)) {
95
+ if (open?.open && open.commentary) {
96
+ open.text += text;
97
+ } else {
98
+ this.closeSegments();
99
+ this.segments.push({ text, open: true, commentary: true, messageId: null });
100
+ }
101
+ return noStep();
102
+ }
103
+ if (open?.open && !open.commentary) {
104
+ open.text += text;
105
+ } else {
106
+ this.closeSegments();
107
+ return { chunks: [this.startSegment(text, true, null)], terminal: null };
108
+ }
109
+ return { chunks: [{ type: "text", text }], terminal: null };
110
+ }
111
+ case "agent.message.completed": {
112
+ const text = stringValue(payload.text) ?? "";
113
+ const messageId = stringValue(payload.messageId) || null;
114
+ if (messageId) return this.messageCompleted(messageId, text, isCommentary(payload));
115
+ const last = this.segments.at(-1);
116
+ if (isCommentary(payload)) {
117
+ if (last?.commentary && (last.open || text.startsWith(last.text))) {
118
+ last.open = false;
119
+ if (text) last.text = text;
120
+ return noStep();
121
+ }
122
+ const streamed = last && !last.commentary && last.open && text.startsWith(last.text);
123
+ if (!streamed) {
124
+ if (text) {
125
+ this.closeSegments();
126
+ this.segments.push({ text, open: false, commentary: true, messageId: null });
127
+ }
128
+ return noStep();
129
+ }
130
+ }
131
+ const target = last?.commentary ? void 0 : last;
132
+ if (!target || !target.open && target.text && !text.startsWith(target.text)) {
133
+ if (!text) return noStep();
134
+ if (payload.phase === void 0 && this.latestAnswer()?.text === text) return noStep();
135
+ this.closeSegments();
136
+ return { chunks: [this.startSegment(text, false, null)], terminal: null };
137
+ }
138
+ target.open = false;
139
+ return { chunks: this.extendAnswer(target, text), terminal: null };
140
+ }
141
+ case "agent.toolCall.created": {
142
+ this.closeSegments();
143
+ const name = stringValue(payload.name) ?? "tool";
144
+ const callId = stringValue(payload.id);
145
+ if (callId) this.openTools.set(callId, name);
146
+ return {
147
+ chunks: [
148
+ {
149
+ type: "tool",
150
+ name,
151
+ status: "started",
152
+ ...callId ? { callId } : {},
153
+ ..."arguments" in payload ? { input: payload.arguments } : {}
154
+ }
155
+ ],
156
+ terminal: null
157
+ };
158
+ }
159
+ case "agent.toolCall.output": {
160
+ const callId = stringValue(payload.id);
161
+ const name = (callId ? this.openTools.get(callId) : void 0) ?? "tool";
162
+ if (callId) this.openTools.delete(callId);
163
+ return {
164
+ chunks: [
165
+ {
166
+ type: "tool",
167
+ name,
168
+ status: isErrorOutput(payload) ? "failed" : "completed",
169
+ ...callId ? { callId } : {}
170
+ }
171
+ ],
172
+ terminal: null
173
+ };
174
+ }
175
+ case "session.requiresAction": {
176
+ const pending = approvalPending(payload);
177
+ if (!pending) return { chunks: [], terminal: null };
178
+ this.pending = pending;
179
+ return {
180
+ chunks: [...this.settleSegments(), { type: "pending", pending }],
181
+ terminal: "pending"
182
+ };
183
+ }
184
+ case "session.humanInput.requested": {
185
+ const pending = humanInputPending(payload);
186
+ if (!pending) return { chunks: [], terminal: null };
187
+ this.pending = pending;
188
+ return {
189
+ chunks: [...this.settleSegments(), { type: "pending", pending }],
190
+ terminal: "pending"
191
+ };
192
+ }
193
+ case "turn.completed":
194
+ this.emptyFinalReply = turnCompletedWithEmptyFinalReply(payload);
195
+ return { chunks: this.settleSegments(), terminal: "completed" };
196
+ case "turn.failed":
197
+ this.failure = event;
198
+ return { chunks: this.settleSegments(), terminal: "failed" };
199
+ case "turn.cancelled":
200
+ return { chunks: this.settleSegments(), terminal: "cancelled" };
201
+ default:
202
+ return { chunks: [], terminal: null };
203
+ }
204
+ }
205
+ reply(terminal) {
206
+ const text = this.text;
207
+ return {
208
+ text,
209
+ sessionId: this.sessionId,
210
+ workspaceId: this.workspaceId,
211
+ turnId: this.turnId,
212
+ status: terminal === "pending" ? "pending" : terminal === "cancelled" ? "cancelled" : "completed",
213
+ pending: this.pending,
214
+ ...this.emptyFinalReply ? { emptyFinalReply: true, notice: EMPTY_FINAL_REPLY_NOTICE } : {},
215
+ events: [...this.events],
216
+ toString: () => text
217
+ };
218
+ }
219
+ /** The error to throw for a `turn.failed` settlement. */
220
+ failureError() {
221
+ const payload = asRecord(this.failure?.payload);
222
+ const code = stringValue(payload.code) ?? "turn_failed";
223
+ const message = stringValue(payload.error) ?? stringValue(payload.message) ?? "The turn failed.";
224
+ return new OpenGeniChatError(code, message, this.failure);
225
+ }
226
+ messageDelta(messageId, text, commentary) {
227
+ const segment = this.segmentOf(messageId);
228
+ if (segment?.open) {
229
+ segment.text += text;
230
+ return segment.commentary ? noStep() : { chunks: [{ type: "text", text }], terminal: null };
231
+ }
232
+ this.closeSegments();
233
+ if (commentary) {
234
+ this.segments.push({ text, open: true, commentary: true, messageId });
235
+ return noStep();
236
+ }
237
+ return { chunks: [this.startSegment(text, true, messageId)], terminal: null };
238
+ }
239
+ messageCompleted(messageId, text, commentary) {
240
+ const segment = this.segmentOf(messageId) ?? this.unidentifiedStreamingSegment(text);
241
+ if (segment) {
242
+ segment.messageId = messageId;
243
+ segment.open = false;
244
+ if (segment.commentary) {
245
+ if (text) segment.text = text;
246
+ return noStep();
247
+ }
248
+ return { chunks: this.extendAnswer(segment, text), terminal: null };
249
+ }
250
+ if (!text) return noStep();
251
+ if (commentary) {
252
+ this.segments.push({ text, open: false, commentary: true, messageId });
253
+ return noStep();
254
+ }
255
+ return { chunks: [this.startSegment(text, false, messageId)], terminal: null };
256
+ }
257
+ segmentOf(messageId) {
258
+ return this.findLastSegment((segment) => segment.messageId === messageId);
259
+ }
260
+ /** Deltas that carried no identity, still streaming the text this completion names. */
261
+ unidentifiedStreamingSegment(text) {
262
+ const last = this.segments.at(-1);
263
+ return last?.open && last.messageId === null && text.startsWith(last.text) ? last : void 0;
264
+ }
265
+ latestAnswer() {
266
+ return this.findLastSegment((segment) => !segment.commentary);
267
+ }
268
+ findLastSegment(predicate) {
269
+ for (let index = this.segments.length - 1; index >= 0; index -= 1) {
270
+ const segment = this.segments[index];
271
+ if (predicate(segment)) return segment;
272
+ }
273
+ return void 0;
274
+ }
275
+ /**
276
+ * Complete an answer segment. Only the newest answer can grow: a remainder
277
+ * for an earlier one would land after later text for append-only consumers.
278
+ */
279
+ extendAnswer(segment, text) {
280
+ if (text.length <= segment.text.length || !text.startsWith(segment.text)) return [];
281
+ if (segment !== this.latestAnswer()) return [];
282
+ const remainder = text.slice(segment.text.length);
283
+ segment.text = text;
284
+ return [{ type: "text", text: remainder }];
285
+ }
286
+ closeSegments() {
287
+ for (const segment of this.segments) segment.open = false;
288
+ }
289
+ /**
290
+ * Close the turn's text. A turn that produced commentary but no answer text
291
+ * (for example one that ends waiting for a worker) replies with its latest
292
+ * commentary rather than nothing.
293
+ */
294
+ settleSegments() {
295
+ this.closeSegments();
296
+ if (this.emptyFinalReply) return [];
297
+ if (this.segments.some((segment) => !segment.commentary)) return [];
298
+ const latest = [...this.segments].reverse().find((segment) => segment.commentary && segment.text);
299
+ if (!latest) return [];
300
+ latest.commentary = false;
301
+ return [{ type: "text", text: latest.text }];
302
+ }
303
+ startSegment(text, open, messageId) {
304
+ const separator = this.segments.some((segment) => !segment.commentary) ? "\n\n" : "";
305
+ this.segments.push({ text, open, commentary: false, messageId });
306
+ return { type: "text", text: separator + text };
307
+ }
308
+ };
309
+ function isCommentary(payload) {
310
+ return payload.phase === "commentary";
311
+ }
312
+ function isTurnScopedType(type) {
313
+ return type.startsWith("turn.") || type.startsWith("agent.") || type === "user.message";
314
+ }
315
+ function approvalPending(payload) {
316
+ const approvals = Array.isArray(payload.approvals) ? payload.approvals : [];
317
+ const first = approvals[0];
318
+ if (!first) return null;
319
+ const raw = asRecord(first);
320
+ const rawItem = asRecord(raw.rawItem);
321
+ const requestId = stringValue(rawItem.callId) ?? stringValue(rawItem.id) ?? stringValue(raw.id) ?? stringValue(raw.callId);
322
+ if (!requestId) return null;
323
+ return {
324
+ kind: "approval",
325
+ requestId,
326
+ name: stringValue(raw.name) ?? stringValue(raw.toolName) ?? stringValue(rawItem.name) ?? null,
327
+ payload: first
328
+ };
329
+ }
330
+ function humanInputPending(payload) {
331
+ const request = asRecord(payload.request);
332
+ const requestId = stringValue(request.id);
333
+ if (!requestId || !Array.isArray(request.questions)) return null;
334
+ return { kind: "human_input", requestId, name: null, payload: payload.request };
335
+ }
336
+ function asRecord(value) {
337
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
338
+ }
339
+ function stringValue(value) {
340
+ return typeof value === "string" ? value : void 0;
341
+ }
342
+ function isErrorOutput(payload) {
343
+ if (payload.error === true || payload.failed === true) return true;
344
+ const output = payload.output;
345
+ return !!output && typeof output === "object" && output.isError === true;
346
+ }
347
+
348
+ export {
349
+ EMPTY_FINAL_REPLY_NOTICE,
350
+ turnCompletedWithEmptyFinalReply,
351
+ OpenGeniChatError,
352
+ ChatPendingFold,
353
+ ChatTurnFold,
354
+ approvalPending,
355
+ humanInputPending,
356
+ asRecord,
357
+ stringValue
358
+ };
359
+ //# sourceMappingURL=chunk-OV3POE62.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../contracts/src/session-final-reply.ts","../src/chat/types.ts","../src/chat/fold.ts"],"sourcesContent":["/** A response-quality notice, not a failed turn or a completed deliverable. */\nexport const EMPTY_FINAL_REPLY_NOTICE =\n \"The model returned no final reply after a reply reminder. Completed work is preserved; the goal and later updates are unaffected.\";\n\nexport type EmptyFinalReplyCompletion = {\n emptyFinalReply: true;\n};\n\nexport function turnCompletedWithEmptyFinalReply(payload: unknown): boolean {\n return (\n payload !== null &&\n typeof payload === \"object\" &&\n !Array.isArray(payload) &&\n (payload as { emptyFinalReply?: unknown }).emptyFinalReply === true\n );\n}\n","import type { FetchLike } from \"../client\";\nimport type { Chats } from \"../chats\";\nimport type { WorkspaceIdResolverOptions } from \"../tenant-workspaces\";\nimport type {\n CreateSessionRequest,\n AgentConfigRequest,\n HumanInputAnswer,\n LatencyMode,\n ReasoningEffort,\n SessionEvent,\n Session,\n SessionSkill,\n ToolRef,\n} from \"../types\";\n\n/** Which other sessions the agent may reach from this one. */\nexport type ChatAgentAccess = \"session\" | \"user\" | \"workspace\";\n\n/**\n * Compatibility option for personal or workspace Knowledge. `false` initializes\n * Knowledge authoring to Off; authorized retrieval remains available. Omitted\n * follows `chats`: private with a user, or legacy reach-based defaults without one.\n * Task notes cover temporary session-tree data.\n */\nexport type ChatMemory = \"user\" | \"workspace\" | false;\n\nexport type OpenGeniOptions = {\n /** Organization API key. Keep it on the server. */\n apiKey: string;\n /**\n * The organization (account) id that owns every workspace. Optional: when\n * omitted it is read once from the API key.\n */\n organizationId?: string | undefined;\n /** Defaults to `https://app.opengeni.ai`. */\n baseUrl?: string | undefined;\n /**\n * The product identity used as the external-source label for tenant\n * workspaces and end users. Defaults to `\"app\"`.\n */\n source?: string | undefined;\n fetch?: FetchLike | undefined;\n /** Display name for a tenant workspace created on first use. Defaults to the tenant id. */\n workspaceName?: ((tenant: string) => string) | undefined;\n /**\n * Per-user workspaces only (`{ user }` alone, or `chats: \"isolated\"`):\n * permissions for the one owner the SDK adds explicitly. Tenant workspaces\n * rely on Opengeni, which adds a user on their first request. Both default\n * to workspace read, session create/read/control (including sending\n * messages), file upload/read, and per-session MCP attachment; no admin\n * permissions. Never updates an existing membership: use\n * `client.updateExternalWorkspaceMember` for that.\n */\n memberPermissions?: WorkspaceIdResolverOptions[\"memberPermissions\"];\n};\n\n/**\n * Which workspace, in your own ids: `tenant` (one workspace per tenant),\n * neither (the `user`'s own workspace), or an explicit `workspaceId`.\n */\nexport type ChatTarget =\n | { tenant: string; workspaceId?: undefined }\n | { workspaceId: string; tenant?: undefined }\n | { user: string; tenant?: undefined; workspaceId?: undefined };\n\n/**\n * A workspace in your own ids, for `og.workspaceId(...)`: `{ tenant }` (one\n * workspace per tenant), `{ user }` (one workspace per user), or\n * `{ workspaceId }`. Precedence: workspaceId, then tenant, then user.\n */\nexport type WorkspaceTarget = {\n tenant?: string | undefined;\n user?: string | undefined;\n workspaceId?: string | undefined;\n};\n\nexport type ChatOptions = ChatTarget & {\n /**\n * Host-authenticated external user; resolved through server-side asUser().\n * Without a tenant or workspaceId, the user gets one workspace of their own.\n */\n user?: string | undefined;\n /** Stable conversation id; the session id is derived from it deterministically. */\n conversation: string;\n /** Prefer the actual Opengeni session ID for shared or existing conversations.\n * The acting user is independent of the conversation's identity. */\n sessionId?: string | undefined;\n /**\n * Private (default with a user) uses personal Knowledge and session-only reach;\n * shared uses workspace Knowledge/reach, isolated adds a workspace per tenant/user.\n * Without a user, omission keeps workspace visibility, session reach and Knowledge off.\n */\n chats?: Chats | undefined;\n /** Agent identity, capabilities and instructions; implicit markdown falls back on older servers. */\n agent?: AgentConfigRequest | undefined;\n /** Explicit agent reach overrides the `chats` default. */\n agentAccess?: ChatAgentAccess | undefined;\n memory?: ChatMemory | undefined;\n model?: string | undefined;\n instructions?: string | undefined;\n skills?: SessionSkill[] | undefined;\n tools?: ToolRef[] | undefined;\n /**\n * Raw create-request passthrough (for example `sandboxBackend: \"none\"` for a\n * pure chat). Explicit values win over facade-derived ones; the message and\n * identity/idempotency fields always come from the facade.\n */\n create?: Partial<CreateSessionRequest> | undefined;\n};\n\n/** A turn stopped to wait for a human decision. */\nexport type ChatPending = {\n kind: \"approval\" | \"human_input\";\n /** The id to pass back through `chat.respond`. */\n requestId: string;\n /** Tool name for an approval; null for structured human input. */\n name: string | null;\n /** The producer's exact payload (approval entry or human-input request). */\n payload: unknown;\n};\n\nexport type ChatReplyStatus = \"completed\" | \"pending\" | \"cancelled\";\n\nexport type ChatReply = {\n text: string;\n sessionId: string;\n workspaceId: string;\n turnId: string | null;\n /** `pending` waits on `chat.respond`; `cancelled` carries the text produced before the cancel. */\n status: ChatReplyStatus;\n /** Set when the turn is waiting on `chat.respond` instead of finished. */\n pending: ChatPending | null;\n /** A non-destructive completion without a model-authored final answer. */\n emptyFinalReply?: true;\n /** Display this informational notice when emptyFinalReply is present. */\n notice?: string;\n /** Every event consumed while folding this turn. */\n events: SessionEvent[];\n toString(): string;\n};\n\nexport type ChatToolStatus = \"started\" | \"completed\" | \"failed\";\n\nexport type ChatChunk =\n | { type: \"text\"; text: string }\n | {\n type: \"tool\";\n name: string;\n status: ChatToolStatus;\n callId?: string | undefined;\n input?: unknown;\n }\n | { type: \"pending\"; pending: ChatPending }\n | { type: \"done\"; reply: ChatReply };\n\nexport type ChatMessage = {\n role: \"user\" | \"assistant\";\n text: string;\n sequence: number;\n};\n\n/** Durable text and unresolved decisions restored when a chat is reopened. */\nexport type ChatSnapshot = {\n messages: ChatMessage[];\n pending: ChatPending[];\n status: Session[\"status\"] | null;\n};\n\nexport type ChatRespondInput =\n | { requestId: string; decision: \"approve\" | \"reject\"; message?: string | undefined }\n | { requestId: string; answers: HumanInputAnswer[] }\n | { requestId: string; skip: true };\n\n/** One earlier message from the product's own history, imported as context on the first send. */\nexport type ChatImportedMessage = { role: \"user\" | \"assistant\" | \"system\"; text: string };\n\nexport type ChatSendOptions = {\n signal?: AbortSignal | undefined;\n /** Supersede the current inference instead of queueing behind it. */\n steer?: boolean | undefined;\n /**\n * Earlier messages the product already holds, oldest first. Used only when\n * this send creates the session: they become the first message's\n * `modelContext` (skipped when `create.modelContext` was supplied), trimmed\n * from the oldest end to 30,000 characters. Never resent on later turns:\n * after the first message Opengeni owns the history.\n */\n importedHistory?: ChatImportedMessage[] | undefined;\n /** Model for this message's turn; omitted keeps the session's current policy. */\n model?: string | undefined;\n reasoningEffort?: ReasoningEffort | undefined;\n latencyMode?: LatencyMode | undefined;\n /**\n * Model-visible application context for this one message (for example the\n * page or record the user is looking at). Not shown in the transcript and not\n * secret. On the creating message it is combined with imported history.\n */\n modelContext?: string | undefined;\n};\n\nexport type ChatSessionListOptions = ChatTarget & {\n user?: string | undefined;\n /** Match the chat's mode; isolated lists that user's separate workspace. */\n chats?: Chats | undefined;\n limit?: number | undefined;\n};\n\n/** A turn ended without a usable reply, or the facade was misused. */\nexport class OpenGeniChatError extends Error {\n readonly code: string;\n readonly event: SessionEvent | null;\n\n constructor(code: string, message: string, event: SessionEvent | null = null) {\n super(message);\n this.name = \"OpenGeniChatError\";\n this.code = code;\n this.event = event;\n }\n}\n","import type { SessionEvent } from \"../types\";\nimport {\n EMPTY_FINAL_REPLY_NOTICE,\n turnCompletedWithEmptyFinalReply,\n} from \"@opengeni/contracts/session-final-reply\";\nimport { OpenGeniChatError, type ChatChunk, type ChatPending, type ChatReply } from \"./types\";\n\n/**\n * Event folding shared by `send`, `stream`, and every protocol adapter.\n *\n * One fold covers one logical turn: text deltas accumulate into message\n * segments (a tool call closes the current segment, the completed event\n * reconciles it), tool call/output pairs become tool chunks, and the turn\n * settles on a terminal event or a human wait. Events that carry a different\n * turn id than the expected one are ignored so a queued follow-up never ends\n * early on the previous turn's settlement.\n *\n * A segment belongs to one provider message when events carry `messageId`: a\n * delta for another message starts a new segment, and a completion reconciles\n * only the segment of its own message. Completions may arrive after later\n * messages already streamed, so matching by position would let one message's\n * completion close another's segment and repeat its text.\n *\n * Commentary (`phase: \"commentary\"`) narrates the work, like a tool chunk, so\n * it is held back from the reply text. Only a turn that settles without any\n * answer text falls back to its latest commentary, emitted at settlement.\n */\n\nexport type ChatTurnTerminal = \"completed\" | \"failed\" | \"cancelled\" | \"pending\";\n\nexport type ChatFoldStep = {\n chunks: ChatChunk[];\n terminal: ChatTurnTerminal | null;\n};\n\n/** Incremental replay of unresolved requests, without retaining the event log. */\nexport class ChatPendingFold {\n private readonly requests = new Map<string, { pending: ChatPending; turnId: string | null }>();\n\n push(event: SessionEvent): void {\n const payload = asRecord(event.payload);\n if (event.type === \"session.requiresAction\") {\n for (const [key, request] of this.requests) {\n if (request.pending.kind === \"approval\") this.requests.delete(key);\n }\n for (const approval of Array.isArray(payload.approvals) ? payload.approvals : []) {\n const pending = approvalPending({ approvals: [approval] });\n if (pending) this.put(pending, event.turnId ?? null);\n }\n } else if (event.type === \"session.humanInput.requested\") {\n const pending = humanInputPending(payload);\n if (pending) this.put(pending, event.turnId ?? null);\n } else if (event.type === \"user.approvalDecision\") {\n this.requests.delete(`approval:${payload.approvalId}`);\n } else if (event.type === \"user.humanInputResponse\") {\n this.requests.delete(`human_input:${payload.requestId}`);\n } else if ([\"turn.completed\", \"turn.failed\", \"turn.cancelled\"].includes(event.type)) {\n for (const [key, request] of this.requests) {\n if (request.turnId === null || event.turnId == null || request.turnId === event.turnId) {\n this.requests.delete(key);\n }\n }\n }\n }\n\n pending(now = Date.now()): ChatPending[] {\n return [...this.requests.values()]\n .map((request) => request.pending)\n .filter((pending) => {\n if (pending.kind !== \"human_input\") return true;\n const expiresAt = asRecord(pending.payload).expiresAt;\n return expiresAt == null || (typeof expiresAt === \"string\" && Date.parse(expiresAt) > now);\n });\n }\n\n private put(pending: ChatPending, turnId: string | null): void {\n this.requests.set(`${pending.kind}:${pending.requestId}`, { pending, turnId });\n }\n}\n\ntype Segment = {\n text: string;\n open: boolean;\n commentary: boolean;\n /** Provider message identity; `null` for events that carry none. */\n messageId: string | null;\n};\n\nfunction noStep(): ChatFoldStep {\n return { chunks: [], terminal: null };\n}\n\nexport class ChatTurnFold {\n readonly events: SessionEvent[] = [];\n turnId: string | null;\n pending: ChatPending | null = null;\n failure: SessionEvent | null = null;\n private emptyFinalReply = false;\n private readonly segments: Segment[] = [];\n private readonly openTools = new Map<string, string>();\n\n constructor(\n private readonly workspaceId: string,\n private readonly sessionId: string,\n expectedTurnId: string | null,\n ) {\n this.turnId = expectedTurnId;\n }\n\n get text(): string {\n return this.segments\n .filter((segment) => !segment.commentary)\n .map((segment) => segment.text)\n .filter((text) => text.length > 0)\n .join(\"\\n\\n\");\n }\n\n push(event: SessionEvent): ChatFoldStep {\n const eventTurnId = typeof event.turnId === \"string\" ? event.turnId : null;\n if (this.turnId && eventTurnId && eventTurnId !== this.turnId) {\n return { chunks: [], terminal: null };\n }\n if (!this.turnId && eventTurnId && isTurnScopedType(event.type)) {\n this.turnId = eventTurnId;\n }\n this.events.push(event);\n const payload = asRecord(event.payload);\n switch (event.type) {\n case \"agent.message.delta\": {\n const text = stringValue(payload.text);\n if (!text) return noStep();\n const messageId = stringValue(payload.messageId) || null;\n if (messageId) return this.messageDelta(messageId, text, isCommentary(payload));\n const open = this.segments.at(-1);\n if (isCommentary(payload)) {\n if (open?.open && open.commentary) {\n open.text += text;\n } else {\n this.closeSegments();\n this.segments.push({ text, open: true, commentary: true, messageId: null });\n }\n return noStep();\n }\n if (open?.open && !open.commentary) {\n open.text += text;\n } else {\n this.closeSegments();\n return { chunks: [this.startSegment(text, true, null)], terminal: null };\n }\n return { chunks: [{ type: \"text\", text }], terminal: null };\n }\n case \"agent.message.completed\": {\n const text = stringValue(payload.text) ?? \"\";\n const messageId = stringValue(payload.messageId) || null;\n if (messageId) return this.messageCompleted(messageId, text, isCommentary(payload));\n const last = this.segments.at(-1);\n if (isCommentary(payload)) {\n if (last?.commentary && (last.open || text.startsWith(last.text))) {\n last.open = false;\n if (text) last.text = text;\n return noStep();\n }\n // Undeclared deltas that the completion reveals as commentary were\n // already streamed as reply text; keep the reply equal to the stream.\n const streamed = last && !last.commentary && last.open && text.startsWith(last.text);\n if (!streamed) {\n if (text) {\n this.closeSegments();\n this.segments.push({ text, open: false, commentary: true, messageId: null });\n }\n return noStep();\n }\n }\n const target = last?.commentary ? undefined : last;\n if (!target || (!target.open && target.text && !text.startsWith(target.text))) {\n if (!text) return noStep();\n // The phase-less settlement copy of an answer this turn already\n // completed message by message.\n if (payload.phase === undefined && this.latestAnswer()?.text === text) return noStep();\n this.closeSegments();\n return { chunks: [this.startSegment(text, false, null)], terminal: null };\n }\n target.open = false;\n return { chunks: this.extendAnswer(target, text), terminal: null };\n }\n case \"agent.toolCall.created\": {\n this.closeSegments();\n const name = stringValue(payload.name) ?? \"tool\";\n const callId = stringValue(payload.id);\n if (callId) this.openTools.set(callId, name);\n return {\n chunks: [\n {\n type: \"tool\",\n name,\n status: \"started\",\n ...(callId ? { callId } : {}),\n ...(\"arguments\" in payload ? { input: payload.arguments } : {}),\n },\n ],\n terminal: null,\n };\n }\n case \"agent.toolCall.output\": {\n const callId = stringValue(payload.id);\n const name = (callId ? this.openTools.get(callId) : undefined) ?? \"tool\";\n if (callId) this.openTools.delete(callId);\n return {\n chunks: [\n {\n type: \"tool\",\n name,\n status: isErrorOutput(payload) ? \"failed\" : \"completed\",\n ...(callId ? { callId } : {}),\n },\n ],\n terminal: null,\n };\n }\n case \"session.requiresAction\": {\n const pending = approvalPending(payload);\n if (!pending) return { chunks: [], terminal: null };\n this.pending = pending;\n return {\n chunks: [...this.settleSegments(), { type: \"pending\", pending }],\n terminal: \"pending\",\n };\n }\n case \"session.humanInput.requested\": {\n const pending = humanInputPending(payload);\n if (!pending) return { chunks: [], terminal: null };\n this.pending = pending;\n return {\n chunks: [...this.settleSegments(), { type: \"pending\", pending }],\n terminal: \"pending\",\n };\n }\n case \"turn.completed\":\n this.emptyFinalReply = turnCompletedWithEmptyFinalReply(payload);\n return { chunks: this.settleSegments(), terminal: \"completed\" };\n case \"turn.failed\":\n this.failure = event;\n return { chunks: this.settleSegments(), terminal: \"failed\" };\n case \"turn.cancelled\":\n return { chunks: this.settleSegments(), terminal: \"cancelled\" };\n default:\n return { chunks: [], terminal: null };\n }\n }\n\n reply(terminal: ChatTurnTerminal): ChatReply {\n const text = this.text;\n return {\n text,\n sessionId: this.sessionId,\n workspaceId: this.workspaceId,\n turnId: this.turnId,\n status:\n terminal === \"pending\" ? \"pending\" : terminal === \"cancelled\" ? \"cancelled\" : \"completed\",\n pending: this.pending,\n ...(this.emptyFinalReply\n ? { emptyFinalReply: true as const, notice: EMPTY_FINAL_REPLY_NOTICE }\n : {}),\n events: [...this.events],\n toString: () => text,\n };\n }\n\n /** The error to throw for a `turn.failed` settlement. */\n failureError(): OpenGeniChatError {\n const payload = asRecord(this.failure?.payload);\n const code = stringValue(payload.code) ?? \"turn_failed\";\n const message =\n stringValue(payload.error) ?? stringValue(payload.message) ?? \"The turn failed.\";\n return new OpenGeniChatError(code, message, this.failure);\n }\n\n private messageDelta(messageId: string, text: string, commentary: boolean): ChatFoldStep {\n const segment = this.segmentOf(messageId);\n if (segment?.open) {\n segment.text += text;\n return segment.commentary ? noStep() : { chunks: [{ type: \"text\", text }], terminal: null };\n }\n // Providers stream messages one after another: every earlier one is done.\n this.closeSegments();\n if (commentary) {\n this.segments.push({ text, open: true, commentary: true, messageId });\n return noStep();\n }\n return { chunks: [this.startSegment(text, true, messageId)], terminal: null };\n }\n\n private messageCompleted(messageId: string, text: string, commentary: boolean): ChatFoldStep {\n const segment = this.segmentOf(messageId) ?? this.unidentifiedStreamingSegment(text);\n if (segment) {\n segment.messageId = messageId;\n segment.open = false;\n if (segment.commentary) {\n if (text) segment.text = text;\n return noStep();\n }\n // Streamed as reply text, even when the completion reveals commentary:\n // the reply stays equal to what append-only consumers already have.\n return { chunks: this.extendAnswer(segment, text), terminal: null };\n }\n if (!text) return noStep();\n if (commentary) {\n this.segments.push({ text, open: false, commentary: true, messageId });\n return noStep();\n }\n return { chunks: [this.startSegment(text, false, messageId)], terminal: null };\n }\n\n private segmentOf(messageId: string): Segment | undefined {\n return this.findLastSegment((segment) => segment.messageId === messageId);\n }\n\n /** Deltas that carried no identity, still streaming the text this completion names. */\n private unidentifiedStreamingSegment(text: string): Segment | undefined {\n const last = this.segments.at(-1);\n return last?.open && last.messageId === null && text.startsWith(last.text) ? last : undefined;\n }\n\n private latestAnswer(): Segment | undefined {\n return this.findLastSegment((segment) => !segment.commentary);\n }\n\n private findLastSegment(predicate: (segment: Segment) => boolean): Segment | undefined {\n for (let index = this.segments.length - 1; index >= 0; index -= 1) {\n const segment = this.segments[index]!;\n if (predicate(segment)) return segment;\n }\n return undefined;\n }\n\n /**\n * Complete an answer segment. Only the newest answer can grow: a remainder\n * for an earlier one would land after later text for append-only consumers.\n */\n private extendAnswer(segment: Segment, text: string): ChatChunk[] {\n if (text.length <= segment.text.length || !text.startsWith(segment.text)) return [];\n if (segment !== this.latestAnswer()) return [];\n const remainder = text.slice(segment.text.length);\n segment.text = text;\n return [{ type: \"text\", text: remainder }];\n }\n\n private closeSegments(): void {\n for (const segment of this.segments) segment.open = false;\n }\n\n /**\n * Close the turn's text. A turn that produced commentary but no answer text\n * (for example one that ends waiting for a worker) replies with its latest\n * commentary rather than nothing.\n */\n private settleSegments(): ChatChunk[] {\n this.closeSegments();\n // A typed missing-final notice must not turn progress commentary into\n // the missing answer. Ordinary waits retain their historical fallback.\n if (this.emptyFinalReply) return [];\n if (this.segments.some((segment) => !segment.commentary)) return [];\n const latest = [...this.segments]\n .reverse()\n .find((segment) => segment.commentary && segment.text);\n if (!latest) return [];\n latest.commentary = false;\n return [{ type: \"text\", text: latest.text }];\n }\n\n private startSegment(text: string, open: boolean, messageId: string | null): ChatChunk {\n // Match the separator used by `text` before exposing the next segment to\n // append-only consumers (React and both protocol adapters).\n const separator = this.segments.some((segment) => !segment.commentary) ? \"\\n\\n\" : \"\";\n this.segments.push({ text, open, commentary: false, messageId });\n return { type: \"text\", text: separator + text };\n }\n}\n\nfunction isCommentary(payload: Record<string, unknown>): boolean {\n return payload.phase === \"commentary\";\n}\n\nfunction isTurnScopedType(type: string): boolean {\n return type.startsWith(\"turn.\") || type.startsWith(\"agent.\") || type === \"user.message\";\n}\n\nexport function approvalPending(payload: Record<string, unknown>): ChatPending | null {\n const approvals = Array.isArray(payload.approvals) ? payload.approvals : [];\n const first = approvals[0];\n if (!first) return null;\n const raw = asRecord(first);\n const rawItem = asRecord(raw.rawItem);\n const requestId =\n stringValue(rawItem.callId) ??\n stringValue(rawItem.id) ??\n stringValue(raw.id) ??\n stringValue(raw.callId);\n if (!requestId) return null;\n return {\n kind: \"approval\",\n requestId,\n name: stringValue(raw.name) ?? stringValue(raw.toolName) ?? stringValue(rawItem.name) ?? null,\n payload: first,\n };\n}\n\nexport function humanInputPending(payload: Record<string, unknown>): ChatPending | null {\n const request = asRecord(payload.request);\n const requestId = stringValue(request.id);\n if (!requestId || !Array.isArray(request.questions)) return null;\n return { kind: \"human_input\", requestId, name: null, payload: payload.request };\n}\n\nexport function asRecord(value: unknown): Record<string, unknown> {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n}\n\nexport function stringValue(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction isErrorOutput(payload: Record<string, unknown>): boolean {\n if (payload.error === true || payload.failed === true) return true;\n const output = payload.output;\n return (\n !!output && typeof output === \"object\" && (output as { isError?: unknown }).isError === true\n );\n}\n"],"mappings":"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","names":[]}