@opengeni/contracts 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeni/contracts",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "description": "Shared zod schemas and wire-contract types for the OpenGeni API.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -32,13 +32,10 @@
32
32
  },
33
33
  "scripts": {
34
34
  "typecheck": "tsc --noEmit",
35
- "build": "tsup"
35
+ "build": "tsup",
36
+ "prepublishOnly": "bash ../../scripts/prepublish-guard"
36
37
  },
37
38
  "dependencies": {
38
39
  "zod": "^4.2.1"
39
- },
40
- "devDependencies": {
41
- "tsup": "^8.5.0",
42
- "typescript": "^6.0.3"
43
40
  }
44
41
  }
package/src/index.ts CHANGED
@@ -470,12 +470,18 @@ export const Permission = z.enum([
470
470
  "github:manage",
471
471
  "github:use",
472
472
  "api_keys:manage",
473
+ "connections:read",
474
+ "connections:write",
473
475
  "environments:manage",
474
476
  "environments:use",
475
477
  // Attach or rotate per-session third-party MCP server credentials. Deliberately
476
478
  // not part of the worker's default first-party MCP permission set: a sandboxed
477
479
  // agent must not be able to hand itself new bearer credentials.
478
480
  "mcp_servers:attach",
481
+ // Programmatic sandbox -> tool access through the first-party MCP gate. This is
482
+ // intentionally narrow and is never part of first-party MCP defaults; callers
483
+ // must receive it through an explicit delegated `ogd_` mint carrying sessionId.
484
+ "toolspace:call",
479
485
  "goals:manage",
480
486
  // Bring-your-own-compute (M5). enrollments:read lists a workspace's machines;
481
487
  // enrollments:manage approves a device-flow enrollment (the LOUD whole-machine
@@ -487,6 +493,10 @@ export const Permission = z.enum([
487
493
  ]);
488
494
  export type Permission = z.infer<typeof Permission>;
489
495
 
496
+ export function prefixedMcpToolName(registryId: string, toolName: string): string {
497
+ return `${registryId}__${toolName}`;
498
+ }
499
+
490
500
  export const ProductAccessMode = z.enum(["local", "configured", "managed"]);
491
501
  export type ProductAccessMode = z.infer<typeof ProductAccessMode>;
492
502
 
@@ -1282,6 +1292,12 @@ export type FileDownloadUrlResponse = z.infer<typeof FileDownloadUrlResponse>;
1282
1292
  export const DocumentStatus = z.enum(["queued", "indexing", "ready", "failed"]);
1283
1293
  export type DocumentStatus = z.infer<typeof DocumentStatus>;
1284
1294
 
1295
+ export const KnowledgeSourceKind = z.enum(["manual_upload", "meeting_transcript", "repository", "email", "chat", "document", "web", "other"]);
1296
+ export type KnowledgeSourceKind = z.infer<typeof KnowledgeSourceKind>;
1297
+
1298
+ export const DocumentSearchMode = z.enum(["hybrid", "vector", "keyword"]);
1299
+ export type DocumentSearchMode = z.infer<typeof DocumentSearchMode>;
1300
+
1285
1301
  export const DocumentBase = z.object({
1286
1302
  id: z.string().uuid(),
1287
1303
  workspaceId: z.string().uuid(),
@@ -1302,6 +1318,15 @@ export const Document = z.object({
1302
1318
  parser: z.string(),
1303
1319
  chunkCount: z.number().int().nonnegative(),
1304
1320
  error: z.string().nullable(),
1321
+ sourceKind: KnowledgeSourceKind,
1322
+ sourceUri: z.string().nullable(),
1323
+ sourceExternalId: z.string().nullable(),
1324
+ sourceTitle: z.string().nullable(),
1325
+ sourceAuthor: z.string().nullable(),
1326
+ sourceCreatedAt: z.string().nullable(),
1327
+ sourceUpdatedAt: z.string().nullable(),
1328
+ sourceVersion: z.string().nullable(),
1329
+ aclTags: z.array(z.string()),
1305
1330
  createdAt: z.string(),
1306
1331
  updatedAt: z.string(),
1307
1332
  });
@@ -1316,8 +1341,20 @@ export const DocumentSearchResult = z.object({
1316
1341
  title: z.string(),
1317
1342
  text: z.string(),
1318
1343
  score: z.number(),
1344
+ matchType: DocumentSearchMode,
1345
+ vectorScore: z.number().nullable(),
1346
+ keywordScore: z.number().nullable(),
1319
1347
  chunkIndex: z.number().int().nonnegative(),
1320
1348
  metadata: z.record(z.string(), z.unknown()),
1349
+ sourceKind: KnowledgeSourceKind,
1350
+ sourceUri: z.string().nullable(),
1351
+ sourceExternalId: z.string().nullable(),
1352
+ sourceTitle: z.string().nullable(),
1353
+ sourceAuthor: z.string().nullable(),
1354
+ sourceCreatedAt: z.string().nullable(),
1355
+ sourceUpdatedAt: z.string().nullable(),
1356
+ sourceVersion: z.string().nullable(),
1357
+ aclTags: z.array(z.string()),
1321
1358
  });
1322
1359
  export type DocumentSearchResult = z.infer<typeof DocumentSearchResult>;
1323
1360
 
@@ -1329,15 +1366,95 @@ export type CreateDocumentBaseRequest = z.infer<typeof CreateDocumentBaseRequest
1329
1366
 
1330
1367
  export const AddDocumentRequest = z.object({
1331
1368
  fileId: z.string().uuid(),
1369
+ title: z.string().min(1).optional(),
1370
+ sourceKind: KnowledgeSourceKind.optional(),
1371
+ sourceUri: z.string().min(1).optional(),
1372
+ sourceExternalId: z.string().min(1).optional(),
1373
+ sourceTitle: z.string().min(1).optional(),
1374
+ sourceAuthor: z.string().min(1).optional(),
1375
+ sourceCreatedAt: z.string().datetime({ offset: true }).optional(),
1376
+ sourceUpdatedAt: z.string().datetime({ offset: true }).optional(),
1377
+ sourceVersion: z.string().min(1).optional(),
1378
+ aclTags: z.array(z.string().min(1)).optional(),
1332
1379
  });
1333
1380
  export type AddDocumentRequest = z.infer<typeof AddDocumentRequest>;
1334
1381
 
1335
1382
  export const DocumentSearchRequest = z.object({
1336
1383
  query: z.string().min(1),
1337
- limit: z.number().int().positive().max(20).default(5),
1384
+ baseIds: z.array(z.string().uuid()).optional(),
1385
+ mode: DocumentSearchMode.optional(),
1386
+ sourceKinds: z.array(KnowledgeSourceKind).optional(),
1387
+ aclTags: z.array(z.string().min(1)).optional(),
1388
+ limit: z.number().int().positive().max(50).default(5),
1338
1389
  });
1339
1390
  export type DocumentSearchRequest = z.infer<typeof DocumentSearchRequest>;
1340
1391
 
1392
+ export const KnowledgeMemoryStatus = z.enum(["proposed", "approved", "rejected"]);
1393
+ export type KnowledgeMemoryStatus = z.infer<typeof KnowledgeMemoryStatus>;
1394
+
1395
+ export const KnowledgeMemoryKind = z.enum(["semantic", "episodic", "procedural", "decision", "preference"]);
1396
+ export type KnowledgeMemoryKind = z.infer<typeof KnowledgeMemoryKind>;
1397
+
1398
+ export const KnowledgeSourceRef = z.object({
1399
+ kind: z.enum(["document_chunk", "document", "session_event", "memory", "external"]),
1400
+ id: z.string().min(1),
1401
+ uri: z.string().min(1).optional(),
1402
+ title: z.string().min(1).optional(),
1403
+ metadata: z.record(z.string(), z.unknown()).default({}),
1404
+ });
1405
+ export type KnowledgeSourceRef = z.infer<typeof KnowledgeSourceRef>;
1406
+
1407
+ export const KnowledgeMemory = z.object({
1408
+ id: z.string().uuid(),
1409
+ workspaceId: z.string().uuid(),
1410
+ status: KnowledgeMemoryStatus,
1411
+ kind: KnowledgeMemoryKind,
1412
+ scope: z.string(),
1413
+ text: z.string(),
1414
+ sourceRefs: z.array(KnowledgeSourceRef),
1415
+ confidence: z.number().min(0).max(1),
1416
+ metadata: z.record(z.string(), z.unknown()),
1417
+ createdBySessionId: z.string().uuid().nullable(),
1418
+ reviewedBy: z.string().nullable(),
1419
+ reviewedAt: z.string().nullable(),
1420
+ createdAt: z.string(),
1421
+ updatedAt: z.string(),
1422
+ });
1423
+ export type KnowledgeMemory = z.infer<typeof KnowledgeMemory>;
1424
+
1425
+ export const CreateKnowledgeMemoryRequest = z.object({
1426
+ status: KnowledgeMemoryStatus.default("proposed"),
1427
+ kind: KnowledgeMemoryKind.default("semantic"),
1428
+ scope: z.string().min(1).default("workspace"),
1429
+ text: z.string().min(1),
1430
+ sourceRefs: z.array(KnowledgeSourceRef).default([]),
1431
+ confidence: z.number().min(0).max(1).default(0.5),
1432
+ metadata: z.record(z.string(), z.unknown()).default({}),
1433
+ createdBySessionId: z.string().uuid().optional(),
1434
+ });
1435
+ export type CreateKnowledgeMemoryRequest = z.infer<typeof CreateKnowledgeMemoryRequest>;
1436
+
1437
+ export const UpdateKnowledgeMemoryRequest = z.object({
1438
+ status: KnowledgeMemoryStatus.optional(),
1439
+ kind: KnowledgeMemoryKind.optional(),
1440
+ scope: z.string().min(1).optional(),
1441
+ text: z.string().min(1).optional(),
1442
+ sourceRefs: z.array(KnowledgeSourceRef).optional(),
1443
+ confidence: z.number().min(0).max(1).optional(),
1444
+ metadata: z.record(z.string(), z.unknown()).optional(),
1445
+ reviewedBy: z.string().min(1).optional(),
1446
+ });
1447
+ export type UpdateKnowledgeMemoryRequest = z.infer<typeof UpdateKnowledgeMemoryRequest>;
1448
+
1449
+ export const KnowledgeMemorySearchRequest = z.object({
1450
+ query: z.string().min(1).optional(),
1451
+ status: KnowledgeMemoryStatus.optional(),
1452
+ kind: KnowledgeMemoryKind.optional(),
1453
+ scope: z.string().min(1).optional(),
1454
+ limit: z.number().int().positive().max(100).default(20),
1455
+ });
1456
+ export type KnowledgeMemorySearchRequest = z.infer<typeof KnowledgeMemorySearchRequest>;
1457
+
1341
1458
  export const ToolRef = z.object({
1342
1459
  kind: z.literal("mcp"),
1343
1460
  id: z.string().min(1),
@@ -1367,6 +1484,12 @@ export const SessionMcpServerInput = z.object({
1367
1484
  allowedTools: z.array(z.string().min(1)).optional(),
1368
1485
  timeoutMs: z.number().int().positive().optional(),
1369
1486
  cacheToolsList: z.boolean().optional(),
1487
+ // Human-approval policy for this server's tools. `true` = every tool of this
1488
+ // server requires approval before it runs (a `session.requiresAction` pause
1489
+ // the caller resolves with `user.approvalDecision`); a string[] = ONLY the
1490
+ // listed UNPREFIXED tool names require approval (e.g. reads auto-run, writes
1491
+ // ask); absent / `false` = auto-run everything (the historical default).
1492
+ requireApproval: z.union([z.boolean(), z.array(z.string().min(1))]).optional(),
1370
1493
  // Write-only credential headers. Values are encrypted at rest and never
1371
1494
  // returned in session responses or events; response metadata exposes names.
1372
1495
  headers: z.record(z.string(), z.string()).optional(),
@@ -2043,6 +2166,110 @@ export const CreateSocialPostRequest = z.object({
2043
2166
  });
2044
2167
  export type CreateSocialPostRequest = z.infer<typeof CreateSocialPostRequest>;
2045
2168
 
2169
+ export const ConnectionKind = z.enum(["oauth2", "api_key", "app_install", "delegated"]);
2170
+ export type ConnectionKind = z.infer<typeof ConnectionKind>;
2171
+
2172
+ export const ConnectionStatus = z.enum(["active", "needs_reauth", "revoked", "error"]);
2173
+ export type ConnectionStatus = z.infer<typeof ConnectionStatus>;
2174
+
2175
+ export const McpServerConnectionRef = z.object({
2176
+ connectionId: z.string().uuid().optional(),
2177
+ providerDomain: z.string().min(1),
2178
+ kind: ConnectionKind.optional(),
2179
+ scopes: z.array(z.string().min(1)).optional(),
2180
+ resource: z.string().min(1).optional(),
2181
+ subjectScope: z.enum(["workspace", "subject"]).optional(),
2182
+ }).strict();
2183
+ export type McpServerConnectionRef = z.infer<typeof McpServerConnectionRef>;
2184
+
2185
+ export const ConnectionMetadata = z.object({
2186
+ id: z.string().uuid(),
2187
+ accountId: z.string().uuid(),
2188
+ workspaceId: z.string().uuid(),
2189
+ subjectId: z.string().nullable(),
2190
+ providerDomain: z.string(),
2191
+ kind: ConnectionKind,
2192
+ status: ConnectionStatus,
2193
+ grantedScopes: z.array(z.string()),
2194
+ expiresAt: z.string().nullable(),
2195
+ lastRefreshAt: z.string().nullable(),
2196
+ lastUsedAt: z.string().nullable(),
2197
+ lastError: z.string().nullable(),
2198
+ version: z.number().int().positive(),
2199
+ metadata: z.record(z.string(), z.unknown()),
2200
+ createdBySubjectId: z.string().nullable(),
2201
+ updatedBySubjectId: z.string().nullable(),
2202
+ createdAt: z.string(),
2203
+ updatedAt: z.string(),
2204
+ });
2205
+ export type ConnectionMetadata = z.infer<typeof ConnectionMetadata>;
2206
+
2207
+ export const ConnectionCredentialBundle = z.record(z.string(), z.unknown());
2208
+ export type ConnectionCredentialBundle = z.infer<typeof ConnectionCredentialBundle>;
2209
+
2210
+ export const CreateConnectionRequest = z.object({
2211
+ providerDomain: z.string().min(1),
2212
+ kind: ConnectionKind,
2213
+ subjectId: z.string().min(1).nullable().optional(),
2214
+ credential: ConnectionCredentialBundle,
2215
+ grantedScopes: z.array(z.string().min(1)).default([]),
2216
+ expiresAt: z.string().datetime({ offset: true }).nullable().optional(),
2217
+ metadata: z.record(z.string(), z.unknown()).default({}),
2218
+ });
2219
+ export type CreateConnectionRequest = z.infer<typeof CreateConnectionRequest>;
2220
+
2221
+ export const UpdateConnectionRequest = z.object({
2222
+ providerDomain: z.string().min(1).optional(),
2223
+ subjectId: z.string().min(1).nullable().optional(),
2224
+ kind: ConnectionKind.optional(),
2225
+ status: ConnectionStatus.optional(),
2226
+ credential: ConnectionCredentialBundle.optional(),
2227
+ grantedScopes: z.array(z.string().min(1)).optional(),
2228
+ expiresAt: z.string().datetime({ offset: true }).nullable().optional(),
2229
+ metadata: z.record(z.string(), z.unknown()).optional(),
2230
+ });
2231
+ export type UpdateConnectionRequest = z.infer<typeof UpdateConnectionRequest>;
2232
+
2233
+ export const ConnectionResponse = z.object({
2234
+ connection: ConnectionMetadata,
2235
+ });
2236
+ export type ConnectionResponse = z.infer<typeof ConnectionResponse>;
2237
+
2238
+ export const ListConnectionsResponse = z.object({
2239
+ connections: z.array(ConnectionMetadata),
2240
+ });
2241
+ export type ListConnectionsResponse = z.infer<typeof ListConnectionsResponse>;
2242
+
2243
+ export const OAuthStartRequest = z.object({
2244
+ providerDomain: z.string().min(1).optional(),
2245
+ mcpUrl: z.string().url().optional(),
2246
+ resource: z.string().url().optional(),
2247
+ requestedScopes: z.array(z.string().min(1)).default([]),
2248
+ returnPath: z.string().min(1).optional(),
2249
+ connectionId: z.string().uuid().optional(),
2250
+ }).refine((value) => Boolean(value.mcpUrl ?? value.resource), {
2251
+ message: "mcpUrl is required",
2252
+ path: ["mcpUrl"],
2253
+ });
2254
+ export type OAuthStartRequest = z.infer<typeof OAuthStartRequest>;
2255
+
2256
+ export const OAuthStartResponse = z.object({
2257
+ state: z.string().min(1),
2258
+ authorizationUrl: z.string().url().nullable(),
2259
+ expiresAt: z.string(),
2260
+ });
2261
+ export type OAuthStartResponse = z.infer<typeof OAuthStartResponse>;
2262
+
2263
+ export const IntegrationClientMetadata = z.object({
2264
+ client_id: z.string().url(),
2265
+ client_name: z.literal("OpenGeni"),
2266
+ redirect_uris: z.array(z.string().url()),
2267
+ token_endpoint_auth_method: z.literal("none"),
2268
+ grant_types: z.array(z.enum(["authorization_code", "refresh_token"])),
2269
+ response_types: z.array(z.literal("code")),
2270
+ });
2271
+ export type IntegrationClientMetadata = z.infer<typeof IntegrationClientMetadata>;
2272
+
2046
2273
  export const MarketingDailyAnalysisTaskRequest = z.object({
2047
2274
  name: z.string().min(1).optional(),
2048
2275
  connectionIds: z.array(z.string().uuid()).default([]),
@@ -2060,12 +2287,18 @@ export type MarketingDailyAnalysisTaskRequest = z.infer<typeof MarketingDailyAna
2060
2287
  export const CapabilityKind = z.enum(["pack", "mcp", "api", "skill", "plugin"]);
2061
2288
  export type CapabilityKind = z.infer<typeof CapabilityKind>;
2062
2289
 
2063
- export const CapabilitySource = z.enum(["built_in", "configured", "public_registry", "manual"]);
2290
+ export const CapabilitySource = z.enum(["built_in", "configured", "public_registry", "registry", "manual"]);
2064
2291
  export type CapabilitySource = z.infer<typeof CapabilitySource>;
2065
2292
 
2066
2293
  export const CapabilityInstallationStatus = z.enum(["active", "disabled"]);
2067
2294
  export type CapabilityInstallationStatus = z.infer<typeof CapabilityInstallationStatus>;
2068
2295
 
2296
+ export const CapabilityCatalogAuthKind = z.enum(["oauth2", "api_key", "none", "unknown"]);
2297
+ export type CapabilityCatalogAuthKind = z.infer<typeof CapabilityCatalogAuthKind>;
2298
+
2299
+ export const CapabilityCatalogTier = z.enum(["verified", "community"]);
2300
+ export type CapabilityCatalogTier = z.infer<typeof CapabilityCatalogTier>;
2301
+
2069
2302
  export const CapabilityRuntime = z.object({
2070
2303
  available: z.boolean().default(false),
2071
2304
  mcpServerId: z.string().min(1).optional(),
@@ -2088,6 +2321,18 @@ export const CapabilityCatalogItem = z.object({
2088
2321
  endpointUrl: z.string().url().nullable().default(null),
2089
2322
  installUrl: z.string().url().nullable().default(null),
2090
2323
  authModel: z.string().min(1).nullable().default(null),
2324
+ providerDomain: z.string().min(1).nullable().default(null),
2325
+ surfaceType: z.string().min(1).nullable().default(null),
2326
+ transport: z.string().min(1).nullable().default(null),
2327
+ mcpUrl: z.string().url().nullable().default(null),
2328
+ authKind: CapabilityCatalogAuthKind.nullable().default(null),
2329
+ credentialFacts: z.array(z.record(z.string(), z.unknown())).default([]),
2330
+ tier: CapabilityCatalogTier.nullable().default(null),
2331
+ provenance: z.string().min(1).nullable().default(null),
2332
+ logoAssetPath: z.string().min(1).nullable().default(null),
2333
+ importBatchId: z.string().uuid().nullable().default(null),
2334
+ stale: z.boolean().default(false),
2335
+ staleAt: z.string().nullable().default(null),
2091
2336
  tools: z.array(ToolRef).default([]),
2092
2337
  runtime: CapabilityRuntime.default({ available: false, notes: null }),
2093
2338
  enabled: z.boolean().default(false),
@@ -2131,6 +2376,7 @@ export type CreateCapabilityCatalogItemRequest = z.infer<typeof CreateCapability
2131
2376
  export const EnableCapabilityRequest = z.object({
2132
2377
  config: z.record(z.string(), z.unknown()).default({}),
2133
2378
  metadata: z.record(z.string(), z.unknown()).default({}),
2379
+ connectionRef: McpServerConnectionRef.optional(),
2134
2380
  /**
2135
2381
  * Credential headers for remote MCP capabilities (for example an
2136
2382
  * Authorization bearer token). Values are encrypted at rest with the
@@ -2246,6 +2492,7 @@ export const SessionEventType = z.enum([
2246
2492
  "agent.reasoning.delta",
2247
2493
  "agent.toolCall.created",
2248
2494
  "agent.toolCall.output",
2495
+ "tool.auth_needed",
2249
2496
  "agent.updated",
2250
2497
  "sandbox.operation.started",
2251
2498
  "sandbox.operation.completed",
@@ -2293,6 +2540,19 @@ export const SessionEventType = z.enum([
2293
2540
  ]);
2294
2541
  export type SessionEventType = z.infer<typeof SessionEventType>;
2295
2542
 
2543
+ export const ToolAuthNeededPayload = z.object({
2544
+ serverId: z.string().min(1),
2545
+ toolName: z.string().min(1).nullable().optional(),
2546
+ providerDomain: z.string().min(1),
2547
+ connectionId: z.string().uuid().nullable().optional(),
2548
+ reason: z.enum(["missing_connection", "expired", "insufficient_scope", "refresh_failed"]),
2549
+ scopes: z.array(z.string().min(1)).optional(),
2550
+ resource: z.string().min(1).optional(),
2551
+ authorizationUrl: z.string().url().optional(),
2552
+ subjectId: z.string().min(1).nullable().optional(),
2553
+ });
2554
+ export type ToolAuthNeededPayload = z.infer<typeof ToolAuthNeededPayload>;
2555
+
2296
2556
  // Channel-B stream-event payloads (07-channel-b §1.2). SessionEvent.payload is
2297
2557
  // z.unknown() (NOT a discriminated union) — these are standalone schemas parsed
2298
2558
  // explicitly at the producer (the API-direct handshake/rotation) and the SDK/
@@ -3227,6 +3487,11 @@ export const EnrollmentSummary = z.object({
3227
3487
  pubkey: z.string(),
3228
3488
  exposure: z.literal("whole-machine"),
3229
3489
  hasDisplay: z.boolean(),
3490
+ // Present (non-null) only when a display EXISTS but capture is blocked (macOS
3491
+ // Screen Recording / TCC not granted): a human, actionable reason so the UI can
3492
+ // show "display: capture not granted" instead of a bare "headless". null == capture
3493
+ // permitted OR genuinely headless.
3494
+ desktopUnavailableReason: z.string().nullish(),
3230
3495
  allowScreenControl: z.boolean(),
3231
3496
  status: z.enum(["active", "revoked"]),
3232
3497
  os: EnrollmentOs,
@@ -3407,6 +3672,10 @@ export const MachineView = z.object({
3407
3672
  os: z.string(),
3408
3673
  arch: z.string(),
3409
3674
  hasDisplay: z.boolean(),
3675
+ // Non-null only when a display exists but capture is blocked (macOS Screen
3676
+ // Recording / TCC not granted) — the UI can surface "display: capture not granted".
3677
+ // null == capture permitted OR headless.
3678
+ desktopUnavailableReason: z.string().nullish(),
3410
3679
  allowScreenControl: z.boolean(),
3411
3680
  sharedSessionCount: z.number().int(),
3412
3681
  lastSeenAt: z.string().nullable(),