@opengeni/contracts 0.39.0 → 0.44.1

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 (130) hide show
  1. package/dist/atlassian.d.ts +278 -0
  2. package/dist/atlassian.js +55 -0
  3. package/dist/atlassian.js.map +1 -0
  4. package/dist/chunk-52SGB2QO.js +688 -0
  5. package/dist/chunk-52SGB2QO.js.map +1 -0
  6. package/dist/{chunk-7JZMI22I.js → chunk-5UDNP7AO.js} +34 -2
  7. package/dist/chunk-5UDNP7AO.js.map +1 -0
  8. package/dist/chunk-BVGIYW7D.js +11 -0
  9. package/dist/chunk-BVGIYW7D.js.map +1 -0
  10. package/dist/chunk-CADSX6UN.js +1145 -0
  11. package/dist/chunk-CADSX6UN.js.map +1 -0
  12. package/dist/chunk-D2HKF2EF.js +1460 -0
  13. package/dist/chunk-D2HKF2EF.js.map +1 -0
  14. package/dist/chunk-FJBG5E4O.js +194 -0
  15. package/dist/chunk-FJBG5E4O.js.map +1 -0
  16. package/dist/chunk-H5BVCZKF.js +382 -0
  17. package/dist/chunk-H5BVCZKF.js.map +1 -0
  18. package/dist/chunk-LSB7GRLG.js +779 -0
  19. package/dist/chunk-LSB7GRLG.js.map +1 -0
  20. package/dist/chunk-MYBZRDTY.js +340 -0
  21. package/dist/chunk-MYBZRDTY.js.map +1 -0
  22. package/dist/chunk-RIY7GYQS.js +1204 -0
  23. package/dist/chunk-RIY7GYQS.js.map +1 -0
  24. package/dist/chunk-TZ6YEYN4.js +386 -0
  25. package/dist/chunk-TZ6YEYN4.js.map +1 -0
  26. package/dist/chunk-VA22KRHS.js +15177 -0
  27. package/dist/chunk-VA22KRHS.js.map +1 -0
  28. package/dist/chunk-Y3MLSLB4.js +392 -0
  29. package/dist/chunk-Y3MLSLB4.js.map +1 -0
  30. package/dist/chunk-YRKRZ6OF.js +134 -0
  31. package/dist/chunk-YRKRZ6OF.js.map +1 -0
  32. package/dist/company-profile.d.ts +629 -0
  33. package/dist/document-artifact-commands.d.ts +282 -0
  34. package/dist/document-artifact-commands.js +54 -0
  35. package/dist/document-artifact-commands.js.map +1 -0
  36. package/dist/document-artifact-query.d.ts +2 -0
  37. package/dist/document-artifact-query.js +54 -0
  38. package/dist/document-artifact-query.js.map +1 -0
  39. package/dist/editable-artifact-binary.d.ts +56 -0
  40. package/dist/editable-artifact-causal-frontier.d.ts +12 -0
  41. package/dist/editable-artifact-causal-frontier.js +18 -0
  42. package/dist/editable-artifact-causal-frontier.js.map +1 -0
  43. package/dist/editable-artifact-codec-registry.d.ts +48 -0
  44. package/dist/editable-artifact-codec-registry.js +20 -0
  45. package/dist/editable-artifact-codec-registry.js.map +1 -0
  46. package/dist/editable-artifact-committed-transaction.d.ts +35 -0
  47. package/dist/editable-artifact-committed-transaction.js +19 -0
  48. package/dist/editable-artifact-committed-transaction.js.map +1 -0
  49. package/dist/editable-artifact-live.d.ts +276 -0
  50. package/dist/editable-artifact-live.js +907 -0
  51. package/dist/editable-artifact-live.js.map +1 -0
  52. package/dist/editable-artifact-serialized-commit.d.ts +53 -0
  53. package/dist/editable-artifact-serialized-commit.js +26 -0
  54. package/dist/editable-artifact-serialized-commit.js.map +1 -0
  55. package/dist/editable-artifact-versions.d.ts +6 -0
  56. package/dist/editable-artifact-versions.js +11 -0
  57. package/dist/editable-artifact-versions.js.map +1 -0
  58. package/dist/editable-artifacts.d.ts +46 -0
  59. package/dist/editable-artifacts.js +236 -0
  60. package/dist/editable-artifacts.js.map +1 -0
  61. package/dist/event-preview.d.ts +7 -7
  62. package/dist/google-drive.d.ts +114 -2
  63. package/dist/google-drive.js +70 -14
  64. package/dist/google-drive.js.map +1 -1
  65. package/dist/image-generation.d.ts +70 -0
  66. package/dist/index.d.ts +5180 -329
  67. package/dist/index.js +1173 -40
  68. package/dist/interaction.d.ts +6895 -0
  69. package/dist/mcp-receipts.d.ts +96 -0
  70. package/dist/memory-slack-delivery.d.ts +397 -0
  71. package/dist/presentation-artifact-commands.d.ts +349 -0
  72. package/dist/presentation-artifact-commands.js +66 -0
  73. package/dist/presentation-artifact-commands.js.map +1 -0
  74. package/dist/presentation-artifact-query.d.ts +2 -0
  75. package/dist/presentation-artifact-query.js +66 -0
  76. package/dist/presentation-artifact-query.js.map +1 -0
  77. package/dist/retained-output.d.ts +83 -6
  78. package/dist/sandbox-snapshots.d.ts +9 -0
  79. package/dist/scoped-knowledge.d.ts +14 -13
  80. package/dist/slack-bot-scopes.d.ts +4 -0
  81. package/dist/slack-bot-scopes.js +3 -1
  82. package/dist/spreadsheet-artifact-commands.d.ts +101 -0
  83. package/dist/spreadsheet-artifact-commands.js +27 -0
  84. package/dist/spreadsheet-artifact-commands.js.map +1 -0
  85. package/dist/spreadsheet-artifact-date.d.ts +4 -0
  86. package/dist/spreadsheet-artifact-query.d.ts +120 -0
  87. package/dist/spreadsheet-artifact-query.js +48 -0
  88. package/dist/spreadsheet-artifact-query.js.map +1 -0
  89. package/dist/tool-catalog.d.ts +576 -0
  90. package/dist/video-generation.d.ts +532 -0
  91. package/dist/video-generation.js +51 -0
  92. package/dist/video-generation.js.map +1 -0
  93. package/dist/workspace-learning-policy.d.ts +208 -0
  94. package/package.json +61 -1
  95. package/src/atlassian.ts +160 -0
  96. package/src/company-profile.ts +306 -0
  97. package/src/document-artifact-commands.ts +1709 -0
  98. package/src/document-artifact-query.ts +2 -0
  99. package/src/editable-artifact-binary.ts +396 -0
  100. package/src/editable-artifact-causal-frontier.ts +154 -0
  101. package/src/editable-artifact-codec-registry.ts +261 -0
  102. package/src/editable-artifact-committed-transaction.ts +478 -0
  103. package/src/editable-artifact-live.ts +1379 -0
  104. package/src/editable-artifact-serialized-commit.ts +494 -0
  105. package/src/editable-artifact-versions.ts +8 -0
  106. package/src/editable-artifacts.ts +473 -0
  107. package/src/event-preview.ts +6 -6
  108. package/src/google-drive.ts +68 -15
  109. package/src/image-generation.ts +106 -0
  110. package/src/index.ts +2535 -282
  111. package/src/interaction.ts +2292 -0
  112. package/src/mcp-receipts.ts +281 -0
  113. package/src/memory-slack-delivery.ts +183 -0
  114. package/src/presentation-artifact-commands.ts +2035 -0
  115. package/src/presentation-artifact-query.ts +2 -0
  116. package/src/retained-output.ts +248 -8
  117. package/src/sandbox-snapshots.ts +28 -1
  118. package/src/scoped-knowledge.ts +18 -4
  119. package/src/slack-bot-scopes.ts +34 -1
  120. package/src/spreadsheet-artifact-commands.ts +999 -0
  121. package/src/spreadsheet-artifact-date.ts +21 -0
  122. package/src/spreadsheet-artifact-query.ts +1411 -0
  123. package/src/tool-catalog.ts +334 -0
  124. package/src/video-generation.ts +394 -0
  125. package/src/workspace-learning-policy.ts +233 -0
  126. package/dist/chunk-7JZMI22I.js.map +0 -1
  127. package/dist/chunk-PCTCJEAF.js +0 -10799
  128. package/dist/chunk-PCTCJEAF.js.map +0 -1
  129. package/dist/secret-redaction.d.ts +0 -40
  130. package/src/secret-redaction.ts +0 -364
@@ -0,0 +1,2 @@
1
+ /** Presentation query/projection ABI lives beside commands so shared scene codecs cannot drift. */
2
+ export * from "./presentation-artifact-commands";
@@ -7,17 +7,36 @@ export const RETAINED_OUTPUT_DEFAULT_PAGE_BYTES = 256 * 1024;
7
7
  /** Receipts are timeline references, never an extensible metadata bag. */
8
8
  export const RETAINED_OUTPUT_RECEIPT_MAX_BYTES = 2 * 1024;
9
9
 
10
+ /** Screenshot bytes are accounted separately from the 10k-token text policy. */
11
+ export const COMPUTER_SCREENSHOT_MAX_BYTES = 32 * 1024 * 1024;
12
+ export const COMPUTER_SCREENSHOT_MAX_DIMENSION = 16_384;
13
+ export const COMPUTER_SCREENSHOT_MAX_PIXELS = 67_108_864;
14
+ /** Canonical ready-object retention window: 30 days from successful settlement. */
15
+ export const COMPUTER_SCREENSHOT_RETENTION_MS = 30 * 24 * 60 * 60 * 1_000;
16
+ /** Hard workspace reservation across pending + ready screenshot artifacts. */
17
+ export const COMPUTER_SCREENSHOT_WORKSPACE_QUOTA_BYTES = 5 * 1024 * 1024 * 1024;
18
+ /** Generated images are permanent workspace files, never inline history blobs. */
19
+ export const GENERATED_IMAGE_MAX_BYTES = 64 * 1024 * 1024;
20
+ /** Generated videos are permanent workspace files and are always streamed. */
21
+ export const GENERATED_VIDEO_MAX_BYTES = 512 * 1024 * 1024;
22
+
10
23
  const encoder = new TextEncoder();
11
24
  const LOWERCASE_UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
12
25
  const LOWERCASE_SHA256 = /^[0-9a-f]{64}$/;
13
26
  const CANONICAL_MEDIA_TYPE = /^[a-z0-9][a-z0-9!#$&^_.+-]{0,62}\/[a-z0-9][a-z0-9!#$&^_.+-]{0,62}$/;
14
- const RETRIEVAL_PATH = /^\/v1\/workspaces\/([0-9a-f-]+)\/artifacts\/([0-9a-f-]+)\/content$/;
27
+ const WORKSPACE_RETRIEVAL_PATH =
28
+ /^\/v1\/workspaces\/([0-9a-f-]+)\/artifacts\/([0-9a-f-]+)\/content$/;
29
+ const SESSION_RETRIEVAL_PATH =
30
+ /^\/v1\/workspaces\/([0-9a-f-]+)\/sessions\/([0-9a-f-]+)\/artifacts\/([0-9a-f-]+)\/content$/;
15
31
 
16
32
  export const RetainedOutputKind = z.enum([
17
33
  "tool_result",
18
34
  "assistant_completion",
19
35
  "internal_update",
20
36
  "event_media",
37
+ "computer_screenshot",
38
+ "generated_image",
39
+ "generated_video",
21
40
  "file",
22
41
  ]);
23
42
  export type RetainedOutputKind = z.infer<typeof RetainedOutputKind>;
@@ -30,6 +49,9 @@ export const RetainedOutputUnavailableReason = z.enum([
30
49
  "deleted",
31
50
  "missing_storage",
32
51
  "storage_write_failed",
52
+ "quota_exceeded",
53
+ "invalid_content",
54
+ "oversized",
33
55
  "unsupported",
34
56
  ]);
35
57
  export type RetainedOutputUnavailableReason = z.infer<typeof RetainedOutputUnavailableReason>;
@@ -50,12 +72,27 @@ export const RetainedArtifactReferenceSchema = z
50
72
  originalBytes: z.number().int().nonnegative().safe(),
51
73
  sha256: z.string().regex(LOWERCASE_SHA256),
52
74
  retainedAt: z.string().datetime({ offset: true }),
53
- retention: z
75
+ dimensions: z
54
76
  .object({
55
- policy: z.literal("workspace_file"),
56
- expiresAt: z.null(),
77
+ width: z.number().int().positive().max(COMPUTER_SCREENSHOT_MAX_DIMENSION),
78
+ height: z.number().int().positive().max(COMPUTER_SCREENSHOT_MAX_DIMENSION),
57
79
  })
58
- .strict(),
80
+ .strict()
81
+ .optional(),
82
+ retention: z.union([
83
+ z
84
+ .object({
85
+ policy: z.literal("workspace_file"),
86
+ expiresAt: z.null(),
87
+ })
88
+ .strict(),
89
+ z
90
+ .object({
91
+ policy: z.literal("session_screenshot"),
92
+ expiresAt: z.string().datetime({ offset: true }),
93
+ })
94
+ .strict(),
95
+ ]),
59
96
  retrieval: z
60
97
  .object({
61
98
  method: z.literal("GET"),
@@ -67,15 +104,99 @@ export const RetainedArtifactReferenceSchema = z
67
104
  })
68
105
  .strict()
69
106
  .superRefine((value, ctx) => {
70
- const match = RETRIEVAL_PATH.exec(value.retrieval.path);
71
- if (!match || !LOWERCASE_UUID.test(match[1] ?? "") || match[2] !== value.artifactId) {
107
+ const workspaceMatch = WORKSPACE_RETRIEVAL_PATH.exec(value.retrieval.path);
108
+ const sessionMatch = SESSION_RETRIEVAL_PATH.exec(value.retrieval.path);
109
+ const workspaceId = workspaceMatch?.[1] ?? sessionMatch?.[1];
110
+ const sessionId = sessionMatch?.[2];
111
+ const artifactId = workspaceMatch?.[2] ?? sessionMatch?.[3];
112
+ if (
113
+ !workspaceId ||
114
+ !LOWERCASE_UUID.test(workspaceId) ||
115
+ (sessionId !== undefined && !LOWERCASE_UUID.test(sessionId)) ||
116
+ artifactId !== value.artifactId
117
+ ) {
72
118
  ctx.addIssue({
73
119
  code: "custom",
74
120
  path: ["retrieval", "path"],
75
- message: "retrieval path must be a workspace API content path for this artifact",
121
+ message: "retrieval path must be a workspace/session API content path for this artifact",
76
122
  });
77
123
  }
78
124
 
125
+ if (
126
+ value.kind === "computer_screenshot" ||
127
+ value.kind === "generated_image" ||
128
+ value.kind === "generated_video"
129
+ ) {
130
+ if (!value.dimensions) {
131
+ ctx.addIssue({
132
+ code: "custom",
133
+ path: ["dimensions"],
134
+ message: `${value.kind} receipts require exact dimensions`,
135
+ });
136
+ } else if (
137
+ value.dimensions.width * value.dimensions.height >
138
+ COMPUTER_SCREENSHOT_MAX_PIXELS
139
+ ) {
140
+ ctx.addIssue({
141
+ code: "custom",
142
+ path: ["dimensions"],
143
+ message: `${value.kind} dimensions exceed the pixel limit`,
144
+ });
145
+ }
146
+ }
147
+
148
+ if (value.kind === "generated_image") {
149
+ if (value.retention.policy !== "workspace_file" || !workspaceMatch || sessionMatch) {
150
+ ctx.addIssue({
151
+ code: "custom",
152
+ path: ["retention"],
153
+ message: "generated images require permanent workspace-file retrieval",
154
+ });
155
+ }
156
+ if (
157
+ !["image/png", "image/jpeg", "image/webp"].includes(value.contentType) ||
158
+ value.originalBytes <= 0 ||
159
+ value.originalBytes > GENERATED_IMAGE_MAX_BYTES
160
+ ) {
161
+ ctx.addIssue({
162
+ code: "custom",
163
+ path: ["contentType"],
164
+ message: "generated image media metadata is invalid",
165
+ });
166
+ }
167
+ }
168
+
169
+ if (value.kind === "generated_video") {
170
+ if (value.retention.policy !== "workspace_file" || !workspaceMatch || sessionMatch) {
171
+ ctx.addIssue({
172
+ code: "custom",
173
+ path: ["retention"],
174
+ message: "generated videos require permanent workspace-file retrieval",
175
+ });
176
+ }
177
+ if (
178
+ value.contentType !== "video/mp4" ||
179
+ value.originalBytes <= 0 ||
180
+ value.originalBytes > GENERATED_VIDEO_MAX_BYTES
181
+ ) {
182
+ ctx.addIssue({
183
+ code: "custom",
184
+ path: ["contentType"],
185
+ message: "generated video media metadata is invalid",
186
+ });
187
+ }
188
+ }
189
+
190
+ if (value.kind === "computer_screenshot") {
191
+ if (value.retention.policy !== "session_screenshot" || !sessionMatch) {
192
+ ctx.addIssue({
193
+ code: "custom",
194
+ path: ["retention"],
195
+ message: "computer screenshots require session-scoped expiring retrieval",
196
+ });
197
+ }
198
+ }
199
+
79
200
  if (encoder.encode(JSON.stringify(value)).byteLength > RETAINED_OUTPUT_RECEIPT_MAX_BYTES) {
80
201
  ctx.addIssue({
81
202
  code: "custom",
@@ -126,6 +247,23 @@ export type RetainedArtifactFileInput = {
126
247
  updatedAt: string;
127
248
  };
128
249
 
250
+ export type RetainedScreenshotArtifactInput = RetainedArtifactFileInput & {
251
+ sessionId: string;
252
+ width: number;
253
+ height: number;
254
+ expiresAt: string;
255
+ };
256
+
257
+ export type RetainedGeneratedImageArtifactInput = RetainedArtifactFileInput & {
258
+ width: number;
259
+ height: number;
260
+ };
261
+
262
+ export type RetainedGeneratedVideoArtifactInput = RetainedArtifactFileInput & {
263
+ width: number;
264
+ height: number;
265
+ };
266
+
129
267
  /**
130
268
  * Convert a ready, integrity-addressed workspace file into the only available
131
269
  * retained-output receipt shape. Invalid, pending, or checksum-less files fail
@@ -159,6 +297,108 @@ export function retainedArtifactReferenceFromFile(
159
297
  return parsed.success ? parsed.data : null;
160
298
  }
161
299
 
300
+ /** Build the closed, session-scoped receipt for one ready screenshot file. */
301
+ export function retainedScreenshotReferenceFromFile(
302
+ file: RetainedScreenshotArtifactInput,
303
+ ): RetainedArtifactReference | null {
304
+ if (file.status !== "ready" || !file.sha256 || file.sizeBytes <= 0) return null;
305
+ const value = {
306
+ available: true as const,
307
+ artifactId: file.id,
308
+ kind: "computer_screenshot" as const,
309
+ contentType: canonicalRetainedContentType(file.contentType),
310
+ originalBytes: file.sizeBytes,
311
+ sha256: file.sha256,
312
+ retainedAt: file.updatedAt,
313
+ dimensions: { width: file.width, height: file.height },
314
+ retention: {
315
+ policy: "session_screenshot" as const,
316
+ expiresAt: file.expiresAt,
317
+ },
318
+ retrieval: {
319
+ method: "GET" as const,
320
+ path: `/v1/workspaces/${file.workspaceId}/sessions/${file.sessionId}/artifacts/${file.id}/content`,
321
+ acceptRanges: "bytes" as const,
322
+ maxRangeBytes: RETAINED_OUTPUT_MAX_PAGE_BYTES,
323
+ },
324
+ };
325
+ const parsed = RetainedArtifactReferenceSchema.safeParse(value);
326
+ return parsed.success ? parsed.data : null;
327
+ }
328
+
329
+ /** Build the permanent workspace receipt for one validated generated image. */
330
+ export function retainedGeneratedImageReferenceFromFile(
331
+ file: RetainedGeneratedImageArtifactInput,
332
+ ): RetainedArtifactReference | null {
333
+ if (
334
+ file.status !== "ready" ||
335
+ !file.sha256 ||
336
+ file.sizeBytes <= 0 ||
337
+ file.sizeBytes > GENERATED_IMAGE_MAX_BYTES
338
+ ) {
339
+ return null;
340
+ }
341
+ const value = {
342
+ available: true as const,
343
+ artifactId: file.id,
344
+ kind: "generated_image" as const,
345
+ contentType: canonicalRetainedContentType(file.contentType),
346
+ originalBytes: file.sizeBytes,
347
+ sha256: file.sha256,
348
+ retainedAt: file.updatedAt,
349
+ dimensions: { width: file.width, height: file.height },
350
+ retention: {
351
+ policy: "workspace_file" as const,
352
+ expiresAt: null,
353
+ },
354
+ retrieval: {
355
+ method: "GET" as const,
356
+ path: `/v1/workspaces/${file.workspaceId}/artifacts/${file.id}/content`,
357
+ acceptRanges: "bytes" as const,
358
+ maxRangeBytes: RETAINED_OUTPUT_MAX_PAGE_BYTES,
359
+ },
360
+ };
361
+ const parsed = RetainedArtifactReferenceSchema.safeParse(value);
362
+ return parsed.success ? parsed.data : null;
363
+ }
364
+
365
+ /** Build the permanent workspace receipt for one validated generated video. */
366
+ export function retainedGeneratedVideoReferenceFromFile(
367
+ file: RetainedGeneratedVideoArtifactInput,
368
+ ): RetainedArtifactReference | null {
369
+ if (
370
+ file.status !== "ready" ||
371
+ file.contentType !== "video/mp4" ||
372
+ !file.sha256 ||
373
+ file.sizeBytes <= 0 ||
374
+ file.sizeBytes > GENERATED_VIDEO_MAX_BYTES
375
+ ) {
376
+ return null;
377
+ }
378
+ const value = {
379
+ available: true as const,
380
+ artifactId: file.id,
381
+ kind: "generated_video" as const,
382
+ contentType: "video/mp4" as const,
383
+ originalBytes: file.sizeBytes,
384
+ sha256: file.sha256,
385
+ retainedAt: file.updatedAt,
386
+ dimensions: { width: file.width, height: file.height },
387
+ retention: {
388
+ policy: "workspace_file" as const,
389
+ expiresAt: null,
390
+ },
391
+ retrieval: {
392
+ method: "GET" as const,
393
+ path: `/v1/workspaces/${file.workspaceId}/artifacts/${file.id}/content`,
394
+ acceptRanges: "bytes" as const,
395
+ maxRangeBytes: RETAINED_OUTPUT_MAX_PAGE_BYTES,
396
+ },
397
+ };
398
+ const parsed = RetainedArtifactReferenceSchema.safeParse(value);
399
+ return parsed.success ? parsed.data : null;
400
+ }
401
+
162
402
  function canonicalRetainedContentType(value: string): string {
163
403
  const mediaType = value.split(";", 1)[0]?.trim().toLowerCase() ?? "";
164
404
  return CANONICAL_MEDIA_TYPE.test(mediaType) ? mediaType : "application/octet-stream";
@@ -6,6 +6,14 @@ export type WorkspaceTreeFingerprint = {
6
6
  entryCount: number;
7
7
  fileCount: number;
8
8
  totalFileBytes: number;
9
+ /**
10
+ * Absent means the original deterministic GNU-tar projection used by remote
11
+ * sandboxes. Host-backed Local/Docker sessions use the Agents SDK's portable
12
+ * archive projection, which intentionally contains directories and regular
13
+ * files only. Keeping the discriminator in the descriptor makes restores
14
+ * stable when a Docker image changes and preserves old descriptor behavior.
15
+ */
16
+ projection?: "sdk_local_archive_v1";
9
17
  };
10
18
 
11
19
  export type TarWorkspaceArchiveDescriptor = {
@@ -114,7 +122,8 @@ export function parseWorkspaceArchiveDescriptor(value: unknown): WorkspaceArchiv
114
122
  !SHA256.test(workspace.sha256) ||
115
123
  !nonnegativeInteger(workspace.entryCount) ||
116
124
  !nonnegativeInteger(workspace.fileCount) ||
117
- !nonnegativeInteger(workspace.totalFileBytes)
125
+ !nonnegativeInteger(workspace.totalFileBytes) ||
126
+ (workspace.projection !== undefined && workspace.projection !== "sdk_local_archive_v1")
118
127
  ) {
119
128
  return null;
120
129
  }
@@ -181,6 +190,24 @@ export function decodeNativeSnapshotRef(bytes: Uint8Array): NativeSnapshotRef |
181
190
  return null;
182
191
  }
183
192
 
193
+ export function encodeNativeSnapshotRef(ref: NativeSnapshotRef): Uint8Array {
194
+ const prefix = NATIVE_SNAPSHOT_PREFIXES.find((entry) => entry.provider === ref.provider)?.prefix;
195
+ if (!prefix || typeof ref.snapshotId !== "string" || ref.snapshotId.length === 0) {
196
+ throw new TypeError("Native snapshot reference requires a supported provider and snapshot id");
197
+ }
198
+ if (ref.workspacePersistence !== undefined && typeof ref.workspacePersistence !== "string") {
199
+ throw new TypeError("Native snapshot workspace persistence must be a string");
200
+ }
201
+ return new TextEncoder().encode(
202
+ `${prefix}${JSON.stringify({
203
+ snapshot_id: ref.snapshotId,
204
+ ...(ref.workspacePersistence === undefined
205
+ ? {}
206
+ : { workspace_persistence: ref.workspacePersistence }),
207
+ })}`,
208
+ );
209
+ }
210
+
184
211
  export function backendForNativeSnapshotProvider(provider: NativeSnapshotProvider): string {
185
212
  return provider === "modal_snapshot_directory" || provider === "modal_snapshot_filesystem"
186
213
  ? "modal"
@@ -4,10 +4,24 @@ import { z } from "zod";
4
4
  export const ScopedKnowledgeScopeKind = z.enum(["organization", "workspace", "personal"]);
5
5
  export type ScopedKnowledgeScopeKind = z.infer<typeof ScopedKnowledgeScopeKind>;
6
6
 
7
- export type ScopedKnowledgeScope =
8
- | { kind: "organization"; workspaceId: null; subjectId: null }
9
- | { kind: "workspace"; workspaceId: string; subjectId: null }
10
- | { kind: "personal"; workspaceId: string | null; subjectId: string };
7
+ export const ScopedKnowledgeScope = z.discriminatedUnion("kind", [
8
+ z.object({
9
+ kind: z.literal("organization"),
10
+ workspaceId: z.null(),
11
+ subjectId: z.null(),
12
+ }),
13
+ z.object({
14
+ kind: z.literal("workspace"),
15
+ workspaceId: z.string().uuid(),
16
+ subjectId: z.null(),
17
+ }),
18
+ z.object({
19
+ kind: z.literal("personal"),
20
+ workspaceId: z.string().uuid().nullable(),
21
+ subjectId: z.string().min(1).max(1024),
22
+ }),
23
+ ]);
24
+ export type ScopedKnowledgeScope = z.infer<typeof ScopedKnowledgeScope>;
11
25
 
12
26
  export const ScopedKnowledgeActorKind = z.enum(["human", "service"]);
13
27
  export type ScopedKnowledgeActorKind = z.infer<typeof ScopedKnowledgeActorKind>;
@@ -41,6 +41,35 @@ export const OPENGENI_SLACK_BOT_EVENTS = [
41
41
  "reaction_added",
42
42
  ] as const;
43
43
 
44
+ /** Full user-token scope set for every tool currently exposed by Slack's hosted MCP server. */
45
+ export const OPENGENI_SLACK_MCP_USER_SCOPES = [
46
+ "search:read.public",
47
+ "search:read.private",
48
+ "search:read.mpim",
49
+ "search:read.im",
50
+ "search:read.files",
51
+ "files:read",
52
+ "emoji:read",
53
+ "search:read.users",
54
+ "chat:write",
55
+ "channels:history",
56
+ "groups:history",
57
+ "mpim:history",
58
+ "im:history",
59
+ "channels:write",
60
+ "groups:write",
61
+ "im:write",
62
+ "mpim:write",
63
+ "reactions:write",
64
+ "canvases:read",
65
+ "canvases:write",
66
+ "users:read",
67
+ "users:read.email",
68
+ "channels:read",
69
+ "groups:read",
70
+ "mpim:read",
71
+ ] as const;
72
+
44
73
  export const OPENGENI_MANAGED_PUBLIC_BASE_URL = "https://app.opengeni.ai" as const;
45
74
 
46
75
  function normalizedSlackManifestBaseUrl(publicBaseUrl: string): string {
@@ -83,7 +112,10 @@ export function buildOpenGeniSlackBotManifest(publicBaseUrl: string) {
83
112
  `${baseUrl}/v1/integrations/oauth/callback`,
84
113
  `${baseUrl}/v1/integrations/slack/callback`,
85
114
  ],
86
- scopes: { bot: [...OPENGENI_SLACK_BOT_REQUESTED_SCOPES] },
115
+ scopes: {
116
+ bot: [...OPENGENI_SLACK_BOT_REQUESTED_SCOPES],
117
+ user: [...OPENGENI_SLACK_MCP_USER_SCOPES],
118
+ },
87
119
  },
88
120
  settings: {
89
121
  event_subscriptions: {
@@ -94,6 +126,7 @@ export function buildOpenGeniSlackBotManifest(publicBaseUrl: string) {
94
126
  is_enabled: true,
95
127
  request_url: `${baseUrl}/v1/integrations/slack/interactions`,
96
128
  },
129
+ is_mcp_enabled: true,
97
130
  org_deploy_enabled: false,
98
131
  socket_mode_enabled: false,
99
132
  token_rotation_enabled: false,