@opengeni/sdk 3.3.2-canary.1 → 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 (295) 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 +6 -2
  25. package/dist/browser.js +25 -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-E5BNEG2D.js → chunk-NCU5OAN7.js} +27 -2
  53. package/dist/chunk-NCU5OAN7.js.map +1 -0
  54. package/dist/{chunk-BESZFWMU.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-GY6RQPCG.js → chunk-S2NLS3ES.js} +3598 -1278
  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-TFCLHRZK.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-6NEPJ7NC.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-QTBAMHEF.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 +1056 -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 +6 -2
  91. package/dist/core.js +23 -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 +64 -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 +61 -11
  110. package/dist/index.js +555 -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/organization-integration-policy.d.ts +26 -0
  127. package/dist/organization-integration-policy.js +26 -0
  128. package/dist/organization-integration-policy.js.map +1 -0
  129. package/dist/pr-review-client.d.ts +1 -1
  130. package/dist/pr-review.d.ts +1 -1
  131. package/dist/pr-review.js.map +1 -1
  132. package/dist/preference-registry.d.ts +1 -1
  133. package/dist/prepared-mcp-setup.d.ts +5 -0
  134. package/dist/proxy.d.ts +13 -11
  135. package/dist/realtime.d.ts +1 -1
  136. package/dist/realtime.js +253 -7
  137. package/dist/realtime.js.map +1 -1
  138. package/dist/session-history-import.d.ts +22 -0
  139. package/dist/session-history-import.js +36 -0
  140. package/dist/session-history-import.js.map +1 -0
  141. package/dist/session-list-entries.d.ts +1 -0
  142. package/dist/session-list-entries.js +7 -0
  143. package/dist/session-list-entries.js.map +1 -0
  144. package/dist/session-message-search.d.ts +53 -0
  145. package/dist/session-proxy-client.d.ts +28 -0
  146. package/dist/session-proxy.d.ts +334 -0
  147. package/dist/session-proxy.js +24 -0
  148. package/dist/session-proxy.js.map +1 -0
  149. package/dist/session-titles.d.ts +2 -28
  150. package/dist/session-usage-limits.d.ts +10 -0
  151. package/dist/session-usage-limits.js +43 -0
  152. package/dist/session-usage-limits.js.map +1 -0
  153. package/dist/shared-catalog-loader.d.ts +34 -0
  154. package/dist/site-ai.d.ts +35 -0
  155. package/dist/site-bridge-host.d.ts +112 -0
  156. package/dist/site-bridge-host.js +286 -0
  157. package/dist/site-bridge-host.js.map +1 -0
  158. package/dist/site-browser-entry.d.ts +1 -0
  159. package/dist/site-browser-runtime.gen.d.ts +1 -0
  160. package/dist/site-data.d.ts +178 -0
  161. package/dist/site-document.d.ts +5 -0
  162. package/dist/site-document.js +20 -0
  163. package/dist/site-document.js.map +1 -0
  164. package/dist/site-document.test.d.ts +1 -0
  165. package/dist/site-http.d.ts +17 -0
  166. package/dist/site-sql.d.ts +31 -0
  167. package/dist/site-tool-bridge.d.ts +57 -0
  168. package/dist/site.d.ts +186 -0
  169. package/dist/site.js +63 -0
  170. package/dist/site.js.map +1 -0
  171. package/dist/skills.d.ts +75 -0
  172. package/dist/sse.d.ts +1 -1
  173. package/dist/stream.d.ts +2 -0
  174. package/dist/tenant-workspaces.d.ts +47 -0
  175. package/dist/tenant-workspaces.js +8 -0
  176. package/dist/tenant-workspaces.js.map +1 -0
  177. package/dist/tool-auth.d.ts +87 -0
  178. package/dist/tool-auth.js +23 -0
  179. package/dist/tool-auth.js.map +1 -0
  180. package/dist/tool-display-metadata.d.ts +3 -0
  181. package/dist/tools-37DCTCNZ.js +12 -0
  182. package/dist/tools-37DCTCNZ.js.map +1 -0
  183. package/dist/tools.d.ts +81 -0
  184. package/dist/transcription.d.ts +1 -1
  185. package/dist/types.d.ts +2785 -592
  186. package/dist/usage-allowances.d.ts +36 -0
  187. package/dist/usage-allowances.js +80 -0
  188. package/dist/usage-allowances.js.map +1 -0
  189. package/dist/vault-types.d.ts +324 -0
  190. package/dist/vaults-api.d.ts +65 -0
  191. package/dist/workspace-artifacts.d.ts +47 -5
  192. package/dist/workspace-instruction-policies.d.ts +2 -2
  193. package/dist/workspace-integrations.d.ts +74 -0
  194. package/dist/workspace-integrations.js +67 -0
  195. package/dist/workspace-integrations.js.map +1 -0
  196. package/dist/workspace-state.d.ts +8 -71
  197. package/package.json +99 -5
  198. package/src/adapters/express.ts +136 -0
  199. package/src/adapters/hono.ts +18 -0
  200. package/src/adapters/next.ts +42 -0
  201. package/src/allowance-refusal.ts +5 -0
  202. package/src/app-links.ts +117 -0
  203. package/src/artifact-catalog.ts +51 -0
  204. package/src/artifact-client.ts +40 -49
  205. package/src/artifacts.ts +1 -0
  206. package/src/automations-client.ts +8 -2
  207. package/src/azure-live-transport.ts +286 -0
  208. package/src/browser.ts +35 -0
  209. package/src/chat/fold.ts +431 -0
  210. package/src/chat/handler.ts +240 -0
  211. package/src/chat/http.ts +257 -0
  212. package/src/chat/ids.ts +85 -0
  213. package/src/chat/index.ts +88 -0
  214. package/src/chat/openai.ts +439 -0
  215. package/src/chat/opengeni.ts +737 -0
  216. package/src/chat/types.ts +219 -0
  217. package/src/chat/vercel.ts +204 -0
  218. package/src/chats.ts +16 -0
  219. package/src/client.ts +5595 -1847
  220. package/src/codex-realtime-controller.ts +163 -8
  221. package/src/codex-realtime-v3-wire.ts +4 -3
  222. package/src/codex-realtime-v3.ts +12 -3
  223. package/src/codex-realtime.ts +11 -3
  224. package/src/company-brain.ts +0 -40
  225. package/src/core.ts +18 -0
  226. package/src/deprecation.ts +149 -0
  227. package/src/document-authority-client.ts +104 -1
  228. package/src/editable-artifacts/controller.ts +36 -2
  229. package/src/editable-artifacts/index.ts +1 -0
  230. package/src/editable-artifacts/types.ts +29 -16
  231. package/src/embedding-client.ts +519 -0
  232. package/src/errors.ts +281 -5
  233. package/src/external-vault-receiver.ts +914 -0
  234. package/src/feedback.ts +20 -0
  235. package/src/gateway-realtime-transport.ts +3 -3
  236. package/src/github-repositories.ts +60 -0
  237. package/src/index.ts +592 -65
  238. package/src/insights-usage.ts +64 -0
  239. package/src/interaction.ts +315 -93
  240. package/src/knowledge.ts +72 -0
  241. package/src/known-tools.ts +279 -0
  242. package/src/message-links.ts +178 -0
  243. package/src/model-context.ts +113 -0
  244. package/src/model-display.ts +11 -0
  245. package/src/organization-integration-policy.ts +54 -0
  246. package/src/pr-review-client.ts +1 -1
  247. package/src/pr-review.ts +1 -1
  248. package/src/preference-registry.ts +2 -0
  249. package/src/prepared-mcp-setup.ts +123 -0
  250. package/src/proxy.ts +23 -12
  251. package/src/realtime.ts +15 -6
  252. package/src/session-history-import.ts +84 -0
  253. package/src/session-list-entries.ts +1 -0
  254. package/src/session-message-search.ts +47 -0
  255. package/src/session-proxy-client.ts +68 -0
  256. package/src/session-proxy.ts +2098 -0
  257. package/src/session-titles.ts +8 -82
  258. package/src/session-usage-limits.ts +71 -0
  259. package/src/shared-catalog-loader.ts +169 -0
  260. package/src/site-ai.ts +284 -0
  261. package/src/site-bridge-host.ts +422 -0
  262. package/src/site-browser-entry.ts +6 -0
  263. package/src/site-browser-runtime.gen.ts +2 -0
  264. package/src/site-data.ts +372 -0
  265. package/src/site-document.test.ts +64 -0
  266. package/src/site-document.ts +18 -0
  267. package/src/site-http.ts +171 -0
  268. package/src/site-sql.ts +153 -0
  269. package/src/site-tool-bridge.ts +401 -0
  270. package/src/site.ts +878 -0
  271. package/src/skills.ts +69 -0
  272. package/src/sse.ts +9 -3
  273. package/src/stream.ts +33 -10
  274. package/src/tenant-workspaces.ts +148 -0
  275. package/src/tool-auth.ts +301 -0
  276. package/src/tool-display-metadata.ts +27 -0
  277. package/src/tools.ts +452 -0
  278. package/src/transcription.ts +3 -0
  279. package/src/types.ts +3142 -594
  280. package/src/usage-allowances.ts +189 -0
  281. package/src/vault-types.ts +379 -0
  282. package/src/vaults-api.ts +339 -0
  283. package/src/workspace-artifacts.ts +55 -6
  284. package/src/workspace-instruction-policies.ts +2 -1
  285. package/src/workspace-integrations.ts +402 -0
  286. package/src/workspace-state.ts +8 -82
  287. package/dist/chunk-6NEPJ7NC.js.map +0 -1
  288. package/dist/chunk-BESZFWMU.js.map +0 -1
  289. package/dist/chunk-E5BNEG2D.js.map +0 -1
  290. package/dist/chunk-GY6RQPCG.js.map +0 -1
  291. package/dist/chunk-OO5LPTO7.js +0 -132
  292. package/dist/chunk-OO5LPTO7.js.map +0 -1
  293. package/dist/chunk-QTBAMHEF.js.map +0 -1
  294. package/dist/chunk-TFCLHRZK.js.map +0 -1
  295. package/dist/chunk-VYCTL62C.js.map +0 -1
@@ -0,0 +1,72 @@
1
+ export type {
2
+ AgentLearningMode,
3
+ AgentLearningCategory,
4
+ AgentLearningDefaults,
5
+ AgentLearningOverrides,
6
+ AgentLearningContext,
7
+ AgentLearningOverridePatch,
8
+ AgentLearningSettingsRecord,
9
+ AgentLearningOverrideRecord,
10
+ SaveAgentLearningSettingsRequest,
11
+ KnowledgeFilePreparationResult,
12
+ KnowledgeSavePreparationRequest,
13
+ KnowledgeSavePreparationResponse,
14
+ KnowledgeOriginalFileDownload,
15
+ KnowledgeEntryKind,
16
+ KnowledgeEntryScope,
17
+ KnowledgeIndexStatus,
18
+ KnowledgeEntryContent,
19
+ KnowledgeEntrySource,
20
+ KnowledgeEntryEvidence,
21
+ KnowledgeEntryRelationship,
22
+ KnowledgeEntryRecord,
23
+ KnowledgeEntrySummary,
24
+ KnowledgeEntrySaveRequest,
25
+ KnowledgeEntryReviewRequest,
26
+ KnowledgeEntryBatchReviewRequest,
27
+ KnowledgeEntryRestoreRequest,
28
+ KnowledgeEntryWriteReceipt,
29
+ KnowledgeEntryListRequest,
30
+ KnowledgeEntryListResponse,
31
+ KnowledgeReviewBatch,
32
+ KnowledgeReviewBatchListRequest,
33
+ KnowledgeReviewBatchListResponse,
34
+ AgentInstructionReviewRequest,
35
+ AgentInstructionReceipt,
36
+ AgentInstructionReviewItem,
37
+ AgentInstructionReviewListResponse,
38
+ } from "@opengeni/contracts";
39
+
40
+ import type { OpenGeniClient } from "./client";
41
+ import type {
42
+ KnowledgeSavePreparationRequest,
43
+ KnowledgeSavePreparationResponse,
44
+ KnowledgeFilePreparationResult,
45
+ } from "@opengeni/contracts";
46
+
47
+ /** Agent-only source preparation is a focused transport surface, outside the browser client. */
48
+ export async function prepareKnowledgeFile(
49
+ client: Pick<OpenGeniClient, "requestJson">,
50
+ workspaceId: string,
51
+ fileId: string,
52
+ purpose?: "evidence" | "reference",
53
+ ): Promise<KnowledgeFilePreparationResult> {
54
+ return client.requestJson(
55
+ "POST",
56
+ `/v1/workspaces/${encodeURIComponent(workspaceId)}/knowledge/files/${encodeURIComponent(fileId)}/prepare`,
57
+ purpose ? { purpose } : undefined,
58
+ );
59
+ }
60
+
61
+ /** Read-only collection/duplicate discovery for a live selected agent or human Knowledge reviewer. */
62
+ export async function prepareKnowledgeSave(
63
+ client: Pick<OpenGeniClient, "requestJson">,
64
+ workspaceId: string,
65
+ request: KnowledgeSavePreparationRequest,
66
+ ): Promise<KnowledgeSavePreparationResponse> {
67
+ return client.requestJson(
68
+ "POST",
69
+ `/v1/workspaces/${encodeURIComponent(workspaceId)}/knowledge/entries/prepare-save`,
70
+ request,
71
+ );
72
+ }
@@ -0,0 +1,279 @@
1
+ import { OpenGeniApiError } from "./errors";
2
+ import { createSharedCatalogLoader, type SharedCatalogLoader } from "./shared-catalog-loader";
3
+ import {
4
+ OpenGeniToolCallError,
5
+ OpenGeniToolReapprovalRequiredError,
6
+ type OpenGeniToolTransport,
7
+ type OpenGeniWorkspaceTools,
8
+ type OpenGeniToolCallOptions,
9
+ } from "./tools";
10
+ import type {
11
+ ToolGatewayTarget,
12
+ ToolGatewayResolvedTool,
13
+ ToolGatewayInvokeRequest,
14
+ ToolGatewayInvokeResponse,
15
+ ToolGatewayTargetApprovalResponse,
16
+ ToolGatewayManifestRequest,
17
+ ToolGatewayManifestResponse,
18
+ ToolGatewayIdentity,
19
+ } from "./types";
20
+
21
+ type Snapshot = ToolGatewayResolvedTool & { digest: string };
22
+ const targetKey = (target: ToolGatewayTarget) =>
23
+ "identity" in target
24
+ ? JSON.stringify(["identity", target.identity.serverId, target.identity.toolName])
25
+ : JSON.stringify(["path", ...target.path]);
26
+ export const isToolDefinitionStale = (error: unknown) => {
27
+ if (typeof error !== "object" || error === null) return false;
28
+ if (
29
+ ("outcomeUnknown" in error && error.outcomeUnknown === true) ||
30
+ ("retryable" in error && error.retryable === false)
31
+ )
32
+ return false;
33
+ return error instanceof OpenGeniApiError
34
+ ? error.status === 409 && error.details?.code === "tool_definition_stale"
35
+ : typeof error === "object" &&
36
+ error !== null &&
37
+ "code" in error &&
38
+ error.code === "tool_definition_stale";
39
+ };
40
+
41
+ /** Per-facade metadata only. Never coalesce invocations or retain credentials. */
42
+ export function createKnownWorkspaceTools(
43
+ transport: OpenGeniToolTransport,
44
+ workspaceId: string,
45
+ createLegacy: () => OpenGeniWorkspaceTools,
46
+ ): OpenGeniWorkspaceTools {
47
+ const base = `/v1/workspaces/${encodeURIComponent(workspaceId)}/tools`;
48
+ let legacy: OpenGeniWorkspaceTools | undefined;
49
+ const old = () => (legacy ??= createLegacy());
50
+ const legacyTokens = new Set<string>();
51
+ const loaders = new Map<string, SharedCatalogLoader<Snapshot>>();
52
+ const snapshots = new Map<string, ToolGatewayResolvedTool>();
53
+ const revisions = new Map<string, number>();
54
+ let revisionSequence = 0;
55
+ const advance = (key: string) => {
56
+ if (!revisions.has(key) && revisions.size >= 256)
57
+ revisions.delete(revisions.keys().next().value!);
58
+ const revision = ++revisionSequence;
59
+ revisions.set(key, revision);
60
+ return revision;
61
+ };
62
+ const approvals = new Map<string, ToolGatewayTargetApprovalResponse>();
63
+ const loader = (target: ToolGatewayTarget) => {
64
+ const key = targetKey(target);
65
+ let value = loaders.get(key);
66
+ if (!value) {
67
+ value = createSharedCatalogLoader(async (_refresh, signal) => {
68
+ const result = await transport.requestJson<ToolGatewayResolvedTool>(
69
+ "POST",
70
+ `${base}/resolve`,
71
+ { target },
72
+ {},
73
+ { signal },
74
+ );
75
+ return { ...result, digest: result.definitionDigest };
76
+ });
77
+ if (loaders.size >= 256) loaders.delete(loaders.keys().next().value!);
78
+ loaders.set(key, value);
79
+ }
80
+ return value;
81
+ };
82
+ const remember = (target: ToolGatewayTarget, tool: ToolGatewayResolvedTool, revision: number) => {
83
+ const key = targetKey(target);
84
+ if (revisions.get(key) !== revision) return;
85
+ if (snapshots.size >= 256) snapshots.delete(snapshots.keys().next().value!);
86
+ snapshots.set(key, tool);
87
+ };
88
+ const resolve = async (
89
+ target: ToolGatewayTarget,
90
+ options: {
91
+ refresh?: boolean;
92
+ signal?: AbortSignal;
93
+ siteArtifactId?: string;
94
+ siteVersionId?: string;
95
+ } = {},
96
+ ) => {
97
+ if (options.siteArtifactId || options.siteVersionId)
98
+ return await transport.requestJson<ToolGatewayResolvedTool>(
99
+ "POST",
100
+ `${base}/resolve`,
101
+ { target, siteArtifactId: options.siteArtifactId, siteVersionId: options.siteVersionId },
102
+ {},
103
+ options.signal ? { signal: options.signal } : {},
104
+ );
105
+ const key = targetKey(target);
106
+ const revision = advance(key);
107
+ if (options.refresh) snapshots.delete(key);
108
+ const result = await loader(target).load(options);
109
+ remember(target, result, revision);
110
+ return result;
111
+ };
112
+ const invoke = (request: ToolGatewayInvokeRequest, options: { signal?: AbortSignal } = {}) =>
113
+ transport.requestJson<ToolGatewayInvokeResponse>(
114
+ "POST",
115
+ `${base}/invoke`,
116
+ request,
117
+ {},
118
+ options,
119
+ );
120
+ const call = async (
121
+ target: ToolGatewayTarget,
122
+ args: Record<string, unknown> = {},
123
+ options: OpenGeniToolCallOptions = {},
124
+ ) => {
125
+ if (
126
+ options.approvalToken &&
127
+ (options.approvalBinding === "catalog" || legacyTokens.has(options.approvalToken))
128
+ ) {
129
+ if ("identity" in target) return await old().$call(target.identity, args, options);
130
+ let node: unknown = old();
131
+ for (const part of target.path) node = (node as Record<string, unknown>)[part];
132
+ return await (
133
+ node as (
134
+ args: Record<string, unknown>,
135
+ options: OpenGeniToolCallOptions,
136
+ ) => Promise<unknown>
137
+ )(args, options);
138
+ }
139
+ if (options.approvalToken && !options.operationId)
140
+ throw new TypeError("operationId is required when using an approval token");
141
+ options.signal?.throwIfAborted();
142
+ const operationId = options.operationId ?? crypto.randomUUID();
143
+ const key = targetKey(target);
144
+ const revision = advance(key);
145
+ if (options.refreshCatalog) snapshots.delete(key);
146
+ let tool = options.refreshCatalog
147
+ ? await loader(target).load({
148
+ refresh: true,
149
+ ...(options.signal ? { signal: options.signal } : {}),
150
+ })
151
+ : snapshots.get(key);
152
+ const approved = options.approvalToken ? approvals.get(options.approvalToken) : undefined;
153
+ const expected =
154
+ options.expectedDefinitionDigest !== undefined
155
+ ? options.expectedDefinitionDigest
156
+ : options.approvalToken
157
+ ? undefined
158
+ : tool?.definitionDigest;
159
+ if (
160
+ approved &&
161
+ (approved.operationId !== operationId ||
162
+ ("identity" in target && targetKey({ identity: approved.tool.entry.identity }) !== key))
163
+ )
164
+ throw new OpenGeniToolReapprovalRequiredError(
165
+ operationId,
166
+ approved.tool.definitionDigest,
167
+ expected ?? "",
168
+ approved.tool.entry.identity,
169
+ );
170
+ const send = (digest: string | undefined) =>
171
+ invoke(
172
+ {
173
+ operationId,
174
+ target,
175
+ arguments: args,
176
+ ...(digest === undefined ? {} : { expectedDefinitionDigest: digest }),
177
+ ...(options.approvalToken ? { approvalToken: options.approvalToken } : {}),
178
+ },
179
+ options.signal ? { signal: options.signal } : {},
180
+ );
181
+ let response: ToolGatewayInvokeResponse;
182
+ try {
183
+ response = await send(expected);
184
+ } catch (error) {
185
+ if (!isToolDefinitionStale(error) || expected === undefined) throw error;
186
+ if (revisions.get(key) === revision) snapshots.delete(key);
187
+ if (options.expectedDefinitionDigest !== undefined && !options.approvalToken) throw error;
188
+ tool = await loader(target).reloadAfterStale(expected, options.signal);
189
+ remember(target, tool, revision);
190
+ if (options.approvalToken || options.expectedDefinitionDigest !== undefined)
191
+ throw new OpenGeniToolReapprovalRequiredError(
192
+ operationId,
193
+ expected,
194
+ tool.definitionDigest,
195
+ tool.entry.identity,
196
+ );
197
+ response = await send(tool.definitionDigest);
198
+ }
199
+ if (options.approvalToken) approvals.delete(options.approvalToken);
200
+ remember(target, response.tool, revision);
201
+ if (response.result.isError) throw new OpenGeniToolCallError(response.result);
202
+ return response.tool.entry.outputSchema && response.result.structuredContent !== undefined
203
+ ? response.result.structuredContent
204
+ : response.result;
205
+ };
206
+ const approveTarget = async (
207
+ identity: ToolGatewayIdentity,
208
+ args: Record<string, unknown> = {},
209
+ options: OpenGeniToolCallOptions = {},
210
+ ) => {
211
+ const tool = await resolve(
212
+ { identity },
213
+ { ...(options.signal ? { signal: options.signal } : {}) },
214
+ );
215
+ const response = await transport.requestJson<ToolGatewayTargetApprovalResponse>(
216
+ "POST",
217
+ `${base}/target-approvals`,
218
+ {
219
+ identity,
220
+ arguments: args,
221
+ operationId: options.operationId ?? crypto.randomUUID(),
222
+ expectedDefinitionDigest:
223
+ options.expectedDefinitionDigest === undefined
224
+ ? tool.definitionDigest
225
+ : options.expectedDefinitionDigest,
226
+ },
227
+ {},
228
+ options.signal ? { signal: options.signal } : {},
229
+ );
230
+ if (approvals.size >= 256) approvals.delete(approvals.keys().next().value!);
231
+ approvals.set(response.approvalToken, response);
232
+ return response;
233
+ };
234
+ const node = (path: string[]): unknown =>
235
+ new Proxy(
236
+ async (args: Record<string, unknown> = {}, options: OpenGeniToolCallOptions = {}) =>
237
+ call({ path }, args, options),
238
+ {
239
+ get: (_target, property) =>
240
+ property === "then" || typeof property !== "string"
241
+ ? undefined
242
+ : node([...path, property]),
243
+ },
244
+ );
245
+ return new Proxy(Object.create(null) as OpenGeniWorkspaceTools, {
246
+ get: (_target, property) => {
247
+ if (property === "then" || typeof property !== "string") return undefined;
248
+ if (property === "$targetProtocol") return 1;
249
+ if (property === "$resolve") return resolve;
250
+ if (property === "$invoke") return invoke;
251
+ if (property === "$manifest")
252
+ return (request: ToolGatewayManifestRequest, options: { signal?: AbortSignal } = {}) =>
253
+ transport.requestJson<ToolGatewayManifestResponse>(
254
+ "POST",
255
+ `${base}/manifest`,
256
+ request,
257
+ {},
258
+ options,
259
+ );
260
+ if (property === "$call")
261
+ return (
262
+ identity: ToolGatewayIdentity,
263
+ args?: Record<string, unknown>,
264
+ options?: OpenGeniToolCallOptions,
265
+ ) => call({ identity }, args, options);
266
+ if (property === "$approveTarget") return approveTarget;
267
+ if (property === "$approve")
268
+ return async (...args: Parameters<OpenGeniWorkspaceTools["$approve"]>) => {
269
+ const response = await old().$approve(...args);
270
+ if (legacyTokens.size >= 256) legacyTokens.delete(legacyTokens.values().next().value!);
271
+ legacyTokens.add(response.approvalToken);
272
+ return response;
273
+ };
274
+ if (property === "$catalog") return old().$catalog;
275
+ if (property === "$declarations") return old().$declarations;
276
+ return node([property]);
277
+ },
278
+ });
279
+ }
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Links an agent writes into chat Markdown that point at Opengeni-owned objects.
3
+ *
4
+ * Agents write these forms (tool receipts and bundled Skills teach them):
5
+ *
6
+ * - `artifact:<file uuid>` — a retained workspace file (exports, published files, images).
7
+ * - `sandbox:<path>[:<line>]` — a file in the session's sandbox or Connected Machine.
8
+ * - `/workspaces/<ws>/artifacts/editable/<32-hex id>` — a live editable document,
9
+ * workbook, or presentation.
10
+ * - `/workspaces/<ws>/artifacts/<uuid>` — a saved Site / published HTML artifact.
11
+ * - `/workspaces/<ws>/artifacts/files/<uuid>` — a retained file (console path form).
12
+ *
13
+ * None of them is a URL a browser can navigate on its own: the `/workspaces/...`
14
+ * forms are Opengeni console routes, so inside another product they resolve
15
+ * against that product's origin and 404. Parse them with {@link parseOpenGeniLink}
16
+ * and route each target to the host's own UI (download, panel, page).
17
+ */
18
+ export type OpenGeniLinkTarget =
19
+ | { kind: "file"; fileId: string; workspaceId: string | null; fromSession?: string }
20
+ | { kind: "editable-artifact"; artifactId: string; workspaceId: string; fromSession?: string }
21
+ | { kind: "site"; artifactId: string; workspaceId: string; fromSession?: string }
22
+ | { kind: "sandbox-file"; path: string; line: number | null };
23
+
24
+ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu;
25
+ const EDITABLE_ID = /^[0-9a-f]{32}$/iu;
26
+ const WORKSPACE_SEGMENT = /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/u;
27
+ const SANDBOX_SCHEME = "sandbox:";
28
+ const LEGACY_WORKSPACE_PREFIX = "/workspace/";
29
+ const TRAILING_LINE = /:([0-9]+)$/u;
30
+ const TRAILING_INVALID_LINE = /:-(?:[0-9]+)$|:[0-9]+-[0-9]+$/u;
31
+ const CONTROL_CHARACTER = /[\u0000-\u001f\u007f]/u;
32
+
33
+ /** Application scheme names are case-insensitive, unlike their payloads. */
34
+ export function openGeniLinkScheme(href: string | undefined): "artifact" | "sandbox" | null {
35
+ const scheme = /^([a-z]+):/iu.exec(href ?? "")?.[1]?.toLowerCase();
36
+ return scheme === "artifact" || scheme === "sandbox" ? scheme : null;
37
+ }
38
+
39
+ /** Reserved references must never fall back to navigation on a host origin. */
40
+ export function isReservedOpenGeniLink(href: string | undefined): boolean {
41
+ if (!href) return false;
42
+ if (openGeniLinkScheme(href) || href.startsWith(LEGACY_WORKSPACE_PREFIX)) return true;
43
+ // Decoding is for reservation only: encoded variants are not valid targets.
44
+ try {
45
+ return /^\/workspaces\/[^/]+\/artifacts(?:\/|[?#]|$)/u.test(decodeURIComponent(href));
46
+ } catch {
47
+ return /^\/workspaces\/[^/]+\/artifacts/u.test(href);
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Parse an Opengeni `sandbox:` href (plus the historical bare `/workspace/...`
53
+ * form). The decoded path is intentionally opaque: target selection, path
54
+ * policy, and filesystem authority belong to the session-aware host.
55
+ */
56
+ export function parseSandboxLink(
57
+ href: string | undefined,
58
+ ): { path: string; line: number | null } | null {
59
+ if (!href) return null;
60
+ const encodedLocation =
61
+ openGeniLinkScheme(href) === "sandbox"
62
+ ? href.slice(SANDBOX_SCHEME.length)
63
+ : href.startsWith(LEGACY_WORKSPACE_PREFIX)
64
+ ? href
65
+ : null;
66
+ if (!encodedLocation || encodedLocation.includes("?") || encodedLocation.includes("#")) {
67
+ return null;
68
+ }
69
+ if (TRAILING_INVALID_LINE.test(encodedLocation)) return null;
70
+ const lineMatch = TRAILING_LINE.exec(encodedLocation);
71
+ const encodedPath = lineMatch ? encodedLocation.slice(0, -lineMatch[0].length) : encodedLocation;
72
+ const line = lineMatch?.[1] ? Number(lineMatch[1]) : null;
73
+ if (line !== null && (!Number.isSafeInteger(line) || line < 1)) return null;
74
+ if (!encodedPath) return null;
75
+ try {
76
+ const path = decodeURIComponent(encodedPath);
77
+ return path && !CONTROL_CHARACTER.test(path) ? { path, line } : null;
78
+ } catch {
79
+ return null;
80
+ }
81
+ }
82
+
83
+ /** Return the retained-file id of an exact `artifact:<uuid>` reference. */
84
+ export function parseRetainedFileReference(href: string | undefined): string | null {
85
+ if (openGeniLinkScheme(href) !== "artifact") return null;
86
+ if (!href) return null;
87
+ const id = href.slice("artifact:".length);
88
+ return UUID.test(id) ? id.toLowerCase() : null;
89
+ }
90
+
91
+ /**
92
+ * Classify an agent-authored Markdown href. Returns `null` for ordinary links
93
+ * (`https://…`, `mailto:`, relative host links), which render as-is.
94
+ *
95
+ * Only root-relative console paths are recognized; an absolute URL is always an
96
+ * ordinary link, so a host's own `https://` routes are never reinterpreted.
97
+ * A validated `?fromSession=<uuid>` return hint is preserved.
98
+ */
99
+ export function parseOpenGeniLink(href: string | undefined): OpenGeniLinkTarget | null {
100
+ if (!href) return null;
101
+ const fileId = parseRetainedFileReference(href);
102
+ if (fileId) return { kind: "file", fileId, workspaceId: null };
103
+ if (openGeniLinkScheme(href) === "sandbox" || href.startsWith(LEGACY_WORKSPACE_PREFIX)) {
104
+ const location = parseSandboxLink(href);
105
+ return location ? { kind: "sandbox-file", ...location } : null;
106
+ }
107
+ if (!href.startsWith("/workspaces/") || href.includes("#")) return null;
108
+ const separator = href.indexOf("?");
109
+ const pathname = separator < 0 ? href : href.slice(0, separator);
110
+ const search = separator < 0 ? undefined : href.slice(separator + 1);
111
+ let fromSession: string | undefined;
112
+ if (search !== undefined) {
113
+ const params = new URLSearchParams(search);
114
+ const keys = [...params.keys()];
115
+ if (keys.some((key) => key !== "fromSession") || keys.length > 1) return null;
116
+ if (!UUID.test(params.get("fromSession") ?? "")) return null;
117
+ fromSession = params.get("fromSession")!.toLowerCase();
118
+ }
119
+ const parts = pathname.split("/");
120
+ const workspaceId = parts[2] ?? "";
121
+ if (parts[1] !== "workspaces" || parts[3] !== "artifacts" || !WORKSPACE_SEGMENT.test(workspaceId))
122
+ return null;
123
+ if (parts.length === 6 && parts[4] === "editable" && EDITABLE_ID.test(parts[5] ?? "")) {
124
+ return {
125
+ kind: "editable-artifact",
126
+ artifactId: parts[5]!.toLowerCase(),
127
+ workspaceId,
128
+ ...(fromSession ? { fromSession } : {}),
129
+ };
130
+ }
131
+ if (parts.length === 6 && parts[4] === "files" && UUID.test(parts[5] ?? "")) {
132
+ return {
133
+ kind: "file",
134
+ fileId: parts[5]!.toLowerCase(),
135
+ workspaceId,
136
+ ...(fromSession ? { fromSession } : {}),
137
+ };
138
+ }
139
+ if (parts.length === 5 && UUID.test(parts[4] ?? "")) {
140
+ return {
141
+ kind: "site",
142
+ artifactId: parts[4]!.toLowerCase(),
143
+ workspaceId,
144
+ ...(fromSession ? { fromSession } : {}),
145
+ };
146
+ }
147
+ return null;
148
+ }
149
+
150
+ /** The Opengeni console route for a target (the form agents write). */
151
+ export function openGeniConsolePath(
152
+ target: OpenGeniLinkTarget,
153
+ workspaceId: string,
154
+ ): string | null {
155
+ const workspace = encodeURIComponent(
156
+ target.kind === "sandbox-file" ? workspaceId : (target.workspaceId ?? workspaceId),
157
+ );
158
+ const search =
159
+ target.kind !== "sandbox-file" && target.fromSession && UUID.test(target.fromSession)
160
+ ? `?fromSession=${encodeURIComponent(target.fromSession)}`
161
+ : "";
162
+ switch (target.kind) {
163
+ case "file":
164
+ return `/workspaces/${workspace}/artifacts/files/${target.fileId}${search}`;
165
+ case "editable-artifact":
166
+ return `/workspaces/${workspace}/artifacts/editable/${target.artifactId}${search}`;
167
+ case "site":
168
+ return `/workspaces/${workspace}/artifacts/${target.artifactId}${search}`;
169
+ case "sandbox-file":
170
+ return null;
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Request header naming the session an embedded artifact read belongs to.
176
+ * `createSessionProxyHandler` only serves artifacts Opengeni lists for it.
177
+ */
178
+ export const SESSION_SCOPE_HEADER = "x-opengeni-session-id";
@@ -0,0 +1,113 @@
1
+ export type ModelContextInstructionLayerId =
2
+ | "operational_contract"
3
+ | "persona_and_core"
4
+ | "workspace_governance"
5
+ | "session_instructions"
6
+ | "workspace_memory"
7
+ | "skill_catalog"
8
+ | "codemode"
9
+ | "code_search"
10
+ | "git_bindings"
11
+ | "builtin_skills"
12
+ | "genesis_title"
13
+ | "sdk_capability_instructions"
14
+ | "sandbox_preamble"
15
+ | "sandbox_filesystem"
16
+ | "sent_system_instructions"
17
+ | "identity";
18
+
19
+ /** Sections of a modular operational contract, in composition order. */
20
+ export type AgentPromptModuleId =
21
+ | "base_behavior"
22
+ | "runtime_mechanics"
23
+ | "renderer_markdown"
24
+ | "sandbox"
25
+ | "connected_machine"
26
+ | "repositories"
27
+ | "workspace_environment"
28
+ | "rig"
29
+ | "artifacts"
30
+ | "media"
31
+ | "goals"
32
+ | "subagents"
33
+ | "knowledge"
34
+ | "skills"
35
+ | "secrets"
36
+ | "admin"
37
+ | "attachments";
38
+
39
+ export type ModelContextInstructionModule = {
40
+ id: AgentPromptModuleId;
41
+ chars: number;
42
+ };
43
+
44
+ export type ModelContextInstructionLayer = {
45
+ id: ModelContextInstructionLayerId;
46
+ title: string;
47
+ content: string;
48
+ utf8Bytes: number;
49
+ estimatedTokens: number;
50
+ /** Present on the operational contract of sessions with an agent configuration. */
51
+ modules?: ModelContextInstructionModule[] | undefined;
52
+ };
53
+
54
+ export type ModelContextToolVisibility = "eager" | "searchable";
55
+
56
+ export type ModelContextTool = {
57
+ name: string;
58
+ type: string;
59
+ visibility: ModelContextToolVisibility;
60
+ description?: string | undefined;
61
+ namespace?: string | undefined;
62
+ schema?: unknown | undefined;
63
+ utf8Bytes: number;
64
+ estimatedTokens: number;
65
+ };
66
+
67
+ export type ModelContextSkillKind = "preference_descriptor" | "runtime_skill" | "native_tool_skill";
68
+
69
+ export type ModelContextSkill = {
70
+ kind: ModelContextSkillKind;
71
+ name: string;
72
+ description: string;
73
+ source?: string | undefined;
74
+ path?: string | undefined;
75
+ };
76
+
77
+ export type ModelContextTokenCounts = {
78
+ instructions: number;
79
+ tools: number;
80
+ prefix: number;
81
+ };
82
+
83
+ export type ModelContextSnapshot = {
84
+ providerRequest?:
85
+ | {
86
+ provider: string;
87
+ body: string | null;
88
+ unavailableReason?: string | undefined;
89
+ parts: {
90
+ key: string;
91
+ estimatedTokens: number | null;
92
+ utf8Bytes: number;
93
+ itemEstimatedTokens?: (number | null)[] | undefined;
94
+ }[];
95
+ }
96
+ | undefined;
97
+ version: 1;
98
+ capturedAt: string;
99
+ source: "model_request";
100
+ requestIndex: number;
101
+ instructions: string;
102
+ layers: ModelContextInstructionLayer[];
103
+ tools: ModelContextTool[];
104
+ skills: ModelContextSkill[];
105
+ tokens: ModelContextTokenCounts;
106
+ };
107
+
108
+ export type SessionModelContextResponse = {
109
+ sessionId: string;
110
+ attemptId: string | null;
111
+ turnId: string | null;
112
+ snapshot: ModelContextSnapshot | null;
113
+ };
@@ -0,0 +1,11 @@
1
+ /** One clean model name and maker for every surface outside model settings. */
2
+ export {
3
+ humanizeModelSlug,
4
+ isRawModelLabel,
5
+ modelDisplayName,
6
+ modelLogoUrl,
7
+ modelSlug,
8
+ modelVendor,
9
+ type ModelDisplayInput,
10
+ type ModelVendor,
11
+ } from "@opengeni/contracts/model-display";