@opengeni/db 0.31.1 → 0.36.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/dist/browser-auth.d.ts +209 -1
- package/dist/browser-downloads.d.ts +51 -0
- package/dist/browser-identities.d.ts +11 -2
- package/dist/browser-sessions.d.ts +83 -1
- package/dist/browser-state-artifacts.d.ts +75 -1
- package/dist/canonical-human-identities.d.ts +48 -0
- package/dist/canonical-human-identities.js +28 -0
- package/dist/canonical-human-identities.js.map +1 -0
- package/dist/capability-integrations.d.ts +8 -6
- package/dist/{chunk-MWDVXQOL.js → chunk-5KTIEDX7.js} +5773 -4212
- package/dist/chunk-5KTIEDX7.js.map +1 -0
- package/dist/{chunk-NBE6CHRI.js → chunk-CQZ4QSP5.js} +49 -9
- package/dist/chunk-CQZ4QSP5.js.map +1 -0
- package/dist/chunk-F32YT7MP.js +117 -0
- package/dist/chunk-F32YT7MP.js.map +1 -0
- package/dist/{chunk-ISI2TIUG.js → chunk-JC5QPLUM.js} +30 -3
- package/dist/chunk-JC5QPLUM.js.map +1 -0
- package/dist/{chunk-F5FT7BEZ.js → chunk-P3RE4D2B.js} +2 -2
- package/dist/chunk-TAUTWOS5.js +259 -0
- package/dist/chunk-TAUTWOS5.js.map +1 -0
- package/dist/{chunk-YHZXQ7HP.js → chunk-VKLB2ZGI.js} +446 -19
- package/dist/chunk-VKLB2ZGI.js.map +1 -0
- package/dist/database.d.ts +5 -0
- package/dist/editable-artifact-durable-export.js +2 -2
- package/dist/editable-artifacts.js +3 -3
- package/dist/index.d.ts +438 -29
- package/dist/index.js +35640 -28969
- package/dist/index.js.map +1 -1
- package/dist/insights.d.ts +23 -7
- package/dist/integration-bindings.d.ts +24 -24
- package/dist/integration-facets.d.ts +99 -0
- package/dist/interaction-revisions.d.ts +11 -0
- package/dist/interaction-schema.d.ts +698 -34
- package/dist/provision-roles.js +1 -1
- package/dist/runtime-posture.d.ts +8 -7
- package/dist/schema.d.ts +9464 -5412
- package/dist/schema.js +51 -9
- package/dist/session-control.d.ts +29 -3
- package/dist/session-tenancy.d.ts +44 -0
- package/dist/session-tenancy.js +16 -0
- package/dist/session-tenancy.js.map +1 -0
- package/dist/slack-task-policy-schema.d.ts +847 -0
- package/dist/slack-task-policy.d.ts +65 -0
- package/dist/task-notes-schema.d.ts +924 -0
- package/dist/task-notes.d.ts +85 -0
- package/dist/video-generation.d.ts +9 -0
- package/dist/video-generation.js +5 -3
- package/dist/xai-subscription.d.ts +326 -0
- package/drizzle/0212_browser_state_transfer_hardening.sql +560 -0
- package/drizzle/0213_browser_interaction_authority.sql +67 -0
- package/drizzle/0214_browser_download_saves.sql +34 -0
- package/drizzle/0215_browser_controller_host.sql +385 -0
- package/drizzle/0216_browser_auth_health_evidence.sql +137 -0
- package/drizzle/0217_external_browser_auth_operations.sql +22 -0
- package/drizzle/0218_organization_tenancy_foundation.sql +299 -0
- package/drizzle/0219_organization_tenancy_managed_human_provisioning.sql +317 -0
- package/drizzle/0219_site_auth_maintenance_sessions.sql +234 -0
- package/drizzle/0220_memory_slack_append_only_cascade.sql +38 -0
- package/drizzle/0220_session_channels.sql +54 -0
- package/drizzle/0221_sessions_channel_index.sql +5 -0
- package/drizzle/0222_session_visibility_authority_epochs.sql +158 -0
- package/drizzle/0222_sessions_channel_fk.sql +89 -0
- package/drizzle/0223_pending_tool_event_output.sql +55 -0
- package/drizzle/0223_sessions_channel_fk_validate.sql +118 -0
- package/drizzle/0224_slack_post_outcome_reconciliation.sql +123 -0
- package/drizzle/0225_session_visibility_fork_activation.sql +1363 -0
- package/drizzle/0226_personal_codex_authority_foundation.sql +365 -0
- package/drizzle/0227_slack_native_actions.sql +145 -0
- package/drizzle/0228_interaction_controller_data_plane.sql +14 -0
- package/drizzle/0228_slack_task_policy.sql +400 -0
- package/drizzle/0229_slack_inbox_file_fact.sql +10 -0
- package/drizzle/0230_user_scoped_variable_sets_rigs.sql +84 -0
- package/drizzle/0231_integration_definition_identity_cutover.sql +271 -0
- package/drizzle/0232_integration_facet_authority_cutover.sql +610 -0
- package/drizzle/0233_skill_and_integration_authority_cutover.sql +1162 -0
- package/drizzle/0234_xai_subscription_authority.sql +1139 -0
- package/drizzle/0235_canonical_human_login_bindings.sql +920 -0
- package/drizzle/0236_browser_identity_lifecycle.sql +39 -0
- package/drizzle/0236_session_visibility_slack_policy.sql +72 -0
- package/drizzle/0237_interaction_transition_reaper.sql +263 -0
- package/drizzle/0238_goal_persistence_policy.sql +471 -0
- package/drizzle/0238_supergrok_realtime_model.sql +29 -0
- package/drizzle/0239_supergrok_video_funding.sql +50 -0
- package/drizzle/0239_task_tree_notes.sql +990 -0
- package/package.json +13 -5
- package/src/browser-auth.ts +2600 -123
- package/src/browser-downloads.ts +517 -0
- package/src/browser-identities.ts +220 -3
- package/src/browser-sessions.ts +334 -45
- package/src/browser-state-artifacts.ts +402 -12
- package/src/canonical-human-identities.ts +317 -0
- package/src/capability-integrations.ts +121 -213
- package/src/database.ts +41 -1
- package/src/index.ts +4157 -394
- package/src/insights.ts +109 -28
- package/src/integration-bindings.ts +101 -101
- package/src/{integration-features.ts → integration-facets.ts} +187 -184
- package/src/interaction-revisions.ts +33 -3
- package/src/interaction-schema.ts +311 -8
- package/src/pack-components.ts +43 -43
- package/src/pack-installations.ts +0 -43
- package/src/plugin-packages.ts +9 -9
- package/src/provision-roles.ts +232 -0
- package/src/runtime-posture.ts +227 -14
- package/src/schema.ts +1188 -75
- package/src/session-control.ts +122 -37
- package/src/session-queue-commands.ts +78 -1
- package/src/session-tenancy.ts +188 -0
- package/src/session-tool-call-settlement.ts +9 -3
- package/src/slack-task-policy-schema.ts +130 -0
- package/src/slack-task-policy.ts +341 -0
- package/src/task-notes-schema.ts +135 -0
- package/src/task-notes.ts +178 -0
- package/src/video-generation.ts +90 -12
- package/src/workspace-artifacts.ts +1 -1
- package/src/xai-subscription.ts +1887 -0
- package/dist/chunk-ISI2TIUG.js.map +0 -1
- package/dist/chunk-MWDVXQOL.js.map +0 -1
- package/dist/chunk-NBE6CHRI.js.map +0 -1
- package/dist/chunk-YHZXQ7HP.js.map +0 -1
- package/dist/integration-features.d.ts +0 -99
- /package/dist/{chunk-F5FT7BEZ.js.map → chunk-P3RE4D2B.js.map} +0 -0
|
@@ -16,14 +16,14 @@ import {
|
|
|
16
16
|
type Database,
|
|
17
17
|
} from "./database";
|
|
18
18
|
import {
|
|
19
|
-
|
|
19
|
+
ensureIntegrationFacetDefinition,
|
|
20
20
|
integrationBindingKey,
|
|
21
21
|
integrationDefinitionHasBindingOwner,
|
|
22
22
|
integrationRuntimeKey,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
type
|
|
23
|
+
listIntegrationFacetBindingOwners,
|
|
24
|
+
removeIntegrationFacetBindingOwner,
|
|
25
|
+
upsertIntegrationFacetBinding,
|
|
26
|
+
type IntegrationFacetBindingOwner,
|
|
27
27
|
} from "./integration-bindings";
|
|
28
28
|
import * as schema from "./schema";
|
|
29
29
|
|
|
@@ -31,8 +31,8 @@ export type ApiIntegrationProtocol = "openapi" | "graphql";
|
|
|
31
31
|
export type ApiIntegrationToolSafety = "read" | "write" | "destructive";
|
|
32
32
|
export type ApiIntegrationApprovalMode = "never" | "ask";
|
|
33
33
|
|
|
34
|
-
export type
|
|
35
|
-
readonly
|
|
34
|
+
export type ApiIntegrationFacetDefinition = {
|
|
35
|
+
readonly facetKey: string;
|
|
36
36
|
readonly kind: "knowledge_source" | "inbound_trigger" | "delivery_destination" | "identity_link";
|
|
37
37
|
readonly configSchema: Readonly<Record<string, unknown>>;
|
|
38
38
|
readonly capabilities: Readonly<Record<string, unknown>>;
|
|
@@ -52,7 +52,7 @@ export type ApiIntegrationToolDefinition = {
|
|
|
52
52
|
|
|
53
53
|
type StoredApiIntegrationRevisionBase = {
|
|
54
54
|
readonly id: string;
|
|
55
|
-
readonly
|
|
55
|
+
readonly definitionId: string;
|
|
56
56
|
readonly contentSha256: string;
|
|
57
57
|
readonly source: {
|
|
58
58
|
readonly url?: string;
|
|
@@ -116,7 +116,8 @@ export type InstallApiIntegrationInput = {
|
|
|
116
116
|
description?: string | null;
|
|
117
117
|
category?: string;
|
|
118
118
|
tags?: string[];
|
|
119
|
-
|
|
119
|
+
definitionId: string;
|
|
120
|
+
definitionProvenance: "curated" | "workspace";
|
|
120
121
|
provider?: string;
|
|
121
122
|
providerDomain: string;
|
|
122
123
|
protocol: ApiIntegrationProtocol;
|
|
@@ -130,7 +131,7 @@ export type InstallApiIntegrationInput = {
|
|
|
130
131
|
requiredScopes?: string[];
|
|
131
132
|
ownership?: "workspace" | "subject" | "either";
|
|
132
133
|
allowedTools?: string[];
|
|
133
|
-
|
|
134
|
+
facetDefinitions?: readonly ApiIntegrationFacetDefinition[];
|
|
134
135
|
revision: StoredApiIntegrationRevision;
|
|
135
136
|
owner?: ApiIntegrationOwner;
|
|
136
137
|
};
|
|
@@ -167,7 +168,8 @@ export type ApiIntegrationRuntime = {
|
|
|
167
168
|
name: string;
|
|
168
169
|
description: string | null;
|
|
169
170
|
protocol: ApiIntegrationProtocol;
|
|
170
|
-
|
|
171
|
+
definitionId: string;
|
|
172
|
+
definitionProvenance: "curated" | "workspace";
|
|
171
173
|
baseUrl: string;
|
|
172
174
|
sourceUrl: string | null;
|
|
173
175
|
providerDomain: string;
|
|
@@ -291,7 +293,8 @@ export async function installApiIntegration(
|
|
|
291
293
|
capabilityId: input.capabilityId,
|
|
292
294
|
serverId: input.serverId,
|
|
293
295
|
protocol: input.protocol,
|
|
294
|
-
|
|
296
|
+
definitionId: input.definitionId,
|
|
297
|
+
definitionProvenance: input.definitionProvenance,
|
|
295
298
|
provider: input.provider ?? null,
|
|
296
299
|
providerDomain: input.providerDomain,
|
|
297
300
|
baseUrl: input.baseUrl,
|
|
@@ -391,7 +394,7 @@ export async function installApiIntegration(
|
|
|
391
394
|
)
|
|
392
395
|
.onConflictDoNothing();
|
|
393
396
|
|
|
394
|
-
const owner:
|
|
397
|
+
const owner: IntegrationFacetBindingOwner = input.owner ?? {
|
|
395
398
|
kind: "direct",
|
|
396
399
|
id: input.capabilityId,
|
|
397
400
|
removable: true,
|
|
@@ -401,9 +404,9 @@ export async function installApiIntegration(
|
|
|
401
404
|
const displayName =
|
|
402
405
|
input.displayName?.trim() ||
|
|
403
406
|
(instanceKey === "default" ? input.name : `${input.name} — connected account`);
|
|
404
|
-
const
|
|
407
|
+
const toolsFacet = await ensureIntegrationFacetDefinition(tx as unknown as Database, {
|
|
405
408
|
integrationFacetId: integrationFacet.id,
|
|
406
|
-
|
|
409
|
+
facetKey: "tools",
|
|
407
410
|
kind: "tools",
|
|
408
411
|
configSchema: {
|
|
409
412
|
type: "object",
|
|
@@ -415,18 +418,19 @@ export async function installApiIntegration(
|
|
|
415
418
|
},
|
|
416
419
|
capabilities: { protocol: input.protocol, runtime: "mcp" },
|
|
417
420
|
});
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
421
|
+
const facetDefinitions = new Map<
|
|
422
|
+
string,
|
|
423
|
+
typeof schema.integrationFacetDefinitions.$inferSelect
|
|
424
|
+
>([[toolsFacet.facetKey, toolsFacet]]);
|
|
425
|
+
for (const definition of input.facetDefinitions ?? []) {
|
|
426
|
+
const facet = await ensureIntegrationFacetDefinition(tx as unknown as Database, {
|
|
423
427
|
integrationFacetId: integrationFacet.id,
|
|
424
|
-
|
|
425
|
-
kind:
|
|
426
|
-
configSchema: { ...
|
|
427
|
-
capabilities: { ...
|
|
428
|
+
facetKey: definition.facetKey,
|
|
429
|
+
kind: definition.kind,
|
|
430
|
+
configSchema: { ...definition.configSchema },
|
|
431
|
+
capabilities: { ...definition.capabilities },
|
|
428
432
|
});
|
|
429
|
-
|
|
433
|
+
facetDefinitions.set(facet.facetKey, facet);
|
|
430
434
|
}
|
|
431
435
|
|
|
432
436
|
let [pluginInstallation] = await tx
|
|
@@ -521,7 +525,7 @@ export async function installApiIntegration(
|
|
|
521
525
|
oldFacetInstallations,
|
|
522
526
|
integrationFacetInstallationId: integrationFacetInstallation.id,
|
|
523
527
|
apiFacetInstallationId: apiFacetInstallation.id,
|
|
524
|
-
|
|
528
|
+
facetDefinitions,
|
|
525
529
|
excludedRuntimeKey: runtimeServerId,
|
|
526
530
|
revision: input.revision,
|
|
527
531
|
});
|
|
@@ -529,11 +533,11 @@ export async function installApiIntegration(
|
|
|
529
533
|
const approvalRequiredTools = input.revision.tools
|
|
530
534
|
.filter((tool) => selectedTools.includes(tool.id) && tool.approvalMode === "ask")
|
|
531
535
|
.map((tool) => tool.id);
|
|
532
|
-
const bindingResult = await
|
|
536
|
+
const bindingResult = await upsertIntegrationFacetBinding(tx as unknown as Database, {
|
|
533
537
|
accountId: input.accountId,
|
|
534
538
|
workspaceId: input.workspaceId,
|
|
535
539
|
integrationFacetInstallationId: integrationFacetInstallation.id,
|
|
536
|
-
|
|
540
|
+
facetDefinitionId: toolsFacet.id,
|
|
537
541
|
bindingKey: instanceKey,
|
|
538
542
|
displayName,
|
|
539
543
|
runtimeKey: runtimeServerId,
|
|
@@ -592,101 +596,6 @@ export async function installApiIntegration(
|
|
|
592
596
|
);
|
|
593
597
|
}
|
|
594
598
|
|
|
595
|
-
const compatibilityMetadata = {
|
|
596
|
-
platformVersion: 2,
|
|
597
|
-
protocol: input.protocol,
|
|
598
|
-
provider: input.provider ?? null,
|
|
599
|
-
providerDomain: input.providerDomain,
|
|
600
|
-
pluginId: plugin.id,
|
|
601
|
-
pluginVersionId: pluginVersion.id,
|
|
602
|
-
integrationFacetId: integrationFacet.id,
|
|
603
|
-
apiFacetId: apiFacet.id,
|
|
604
|
-
revisionId: input.revision.id,
|
|
605
|
-
contentSha256: input.revision.contentSha256,
|
|
606
|
-
baseServerId: input.serverId,
|
|
607
|
-
multiInstance: true,
|
|
608
|
-
provenance: "workspace_import",
|
|
609
|
-
};
|
|
610
|
-
await tx
|
|
611
|
-
.insert(schema.capabilityCatalogItems)
|
|
612
|
-
.values({
|
|
613
|
-
id: input.capabilityId,
|
|
614
|
-
accountId: input.accountId,
|
|
615
|
-
workspaceId: input.workspaceId,
|
|
616
|
-
kind: "api",
|
|
617
|
-
source: "manual",
|
|
618
|
-
name: input.name,
|
|
619
|
-
description: input.description ?? null,
|
|
620
|
-
category: input.category ?? "integrations",
|
|
621
|
-
tags: normalizedStrings(input.tags ?? ["integration", input.protocol], 64),
|
|
622
|
-
homepageUrl: input.sourceUrl ?? input.baseUrl,
|
|
623
|
-
endpointUrl: input.baseUrl,
|
|
624
|
-
authModel: objectValue(input.authScheme ?? {}).kind
|
|
625
|
-
? String(objectValue(input.authScheme ?? {}).kind)
|
|
626
|
-
: null,
|
|
627
|
-
providerDomain: input.providerDomain,
|
|
628
|
-
surfaceType: "api",
|
|
629
|
-
authKind: connection ? connection.kind : "none",
|
|
630
|
-
provenance: "workspace_import",
|
|
631
|
-
tier: "community",
|
|
632
|
-
metadata: compatibilityMetadata,
|
|
633
|
-
updatedAt: now,
|
|
634
|
-
})
|
|
635
|
-
.onConflictDoUpdate({
|
|
636
|
-
target: [schema.capabilityCatalogItems.workspaceId, schema.capabilityCatalogItems.id],
|
|
637
|
-
set: {
|
|
638
|
-
name: input.name,
|
|
639
|
-
description: input.description ?? null,
|
|
640
|
-
tags: normalizedStrings(input.tags ?? ["integration", input.protocol], 64),
|
|
641
|
-
homepageUrl: input.sourceUrl ?? input.baseUrl,
|
|
642
|
-
endpointUrl: input.baseUrl,
|
|
643
|
-
authModel: objectValue(input.authScheme ?? {}).kind
|
|
644
|
-
? String(objectValue(input.authScheme ?? {}).kind)
|
|
645
|
-
: null,
|
|
646
|
-
providerDomain: input.providerDomain,
|
|
647
|
-
surfaceType: "api",
|
|
648
|
-
authKind: connection ? connection.kind : "none",
|
|
649
|
-
metadata: compatibilityMetadata,
|
|
650
|
-
updatedAt: now,
|
|
651
|
-
},
|
|
652
|
-
});
|
|
653
|
-
await tx
|
|
654
|
-
.insert(schema.capabilityInstallations)
|
|
655
|
-
.values({
|
|
656
|
-
accountId: input.accountId,
|
|
657
|
-
workspaceId: input.workspaceId,
|
|
658
|
-
capabilityId: input.capabilityId,
|
|
659
|
-
kind: "api",
|
|
660
|
-
status: "active",
|
|
661
|
-
config: { baseServerId: input.serverId, multiInstance: true },
|
|
662
|
-
metadata: {
|
|
663
|
-
...compatibilityMetadata,
|
|
664
|
-
pluginInstallationId: pluginInstallation.id,
|
|
665
|
-
integrationFacetInstallationId: integrationFacetInstallation.id,
|
|
666
|
-
apiFacetInstallationId: apiFacetInstallation.id,
|
|
667
|
-
},
|
|
668
|
-
enabledAt: now,
|
|
669
|
-
updatedAt: now,
|
|
670
|
-
})
|
|
671
|
-
.onConflictDoUpdate({
|
|
672
|
-
target: [
|
|
673
|
-
schema.capabilityInstallations.workspaceId,
|
|
674
|
-
schema.capabilityInstallations.capabilityId,
|
|
675
|
-
],
|
|
676
|
-
set: {
|
|
677
|
-
status: "active",
|
|
678
|
-
config: { baseServerId: input.serverId, multiInstance: true },
|
|
679
|
-
metadata: {
|
|
680
|
-
...compatibilityMetadata,
|
|
681
|
-
pluginInstallationId: pluginInstallation.id,
|
|
682
|
-
integrationFacetInstallationId: integrationFacetInstallation.id,
|
|
683
|
-
apiFacetInstallationId: apiFacetInstallation.id,
|
|
684
|
-
},
|
|
685
|
-
enabledAt: now,
|
|
686
|
-
updatedAt: now,
|
|
687
|
-
},
|
|
688
|
-
});
|
|
689
|
-
|
|
690
599
|
return {
|
|
691
600
|
capabilityId: input.capabilityId,
|
|
692
601
|
pluginId: plugin.id,
|
|
@@ -756,32 +665,32 @@ export async function listInstalledApiIntegrationsInRlsContext(
|
|
|
756
665
|
authScheme: schema.capabilityApiFacets.authScheme,
|
|
757
666
|
providerDomain: schema.capabilityIntegrationFacets.providerDomain,
|
|
758
667
|
requiredScopes: schema.capabilityIntegrationFacets.requiredScopes,
|
|
759
|
-
instanceId: schema.
|
|
760
|
-
instanceKey: schema.
|
|
761
|
-
displayName: schema.
|
|
762
|
-
instanceVersion: schema.
|
|
763
|
-
runtimeKey: schema.
|
|
764
|
-
bindingConfig: schema.
|
|
765
|
-
connectionId: schema.
|
|
668
|
+
instanceId: schema.integrationFacetBindings.id,
|
|
669
|
+
instanceKey: schema.integrationFacetBindings.bindingKey,
|
|
670
|
+
displayName: schema.integrationFacetBindings.displayName,
|
|
671
|
+
instanceVersion: schema.integrationFacetBindings.version,
|
|
672
|
+
runtimeKey: schema.integrationFacetBindings.runtimeKey,
|
|
673
|
+
bindingConfig: schema.integrationFacetBindings.config,
|
|
674
|
+
connectionId: schema.integrationFacetBindings.connectionId,
|
|
766
675
|
revision: schema.integrationSpecRevisions.spec,
|
|
767
676
|
})
|
|
768
|
-
.from(schema.
|
|
677
|
+
.from(schema.integrationFacetBindings)
|
|
769
678
|
.innerJoin(
|
|
770
|
-
schema.
|
|
771
|
-
eq(schema.
|
|
679
|
+
schema.integrationFacetDefinitions,
|
|
680
|
+
eq(schema.integrationFacetDefinitions.id, schema.integrationFacetBindings.facetDefinitionId),
|
|
772
681
|
)
|
|
773
682
|
.innerJoin(
|
|
774
683
|
schema.capabilityIntegrationFacets,
|
|
775
684
|
eq(
|
|
776
685
|
schema.capabilityIntegrationFacets.facetId,
|
|
777
|
-
schema.
|
|
686
|
+
schema.integrationFacetDefinitions.integrationFacetId,
|
|
778
687
|
),
|
|
779
688
|
)
|
|
780
689
|
.innerJoin(
|
|
781
690
|
schema.capabilityFacetInstallations,
|
|
782
691
|
eq(
|
|
783
692
|
schema.capabilityFacetInstallations.id,
|
|
784
|
-
schema.
|
|
693
|
+
schema.integrationFacetBindings.integrationFacetInstallationId,
|
|
785
694
|
),
|
|
786
695
|
)
|
|
787
696
|
.innerJoin(
|
|
@@ -815,17 +724,17 @@ export async function listInstalledApiIntegrationsInRlsContext(
|
|
|
815
724
|
eq(schema.capabilityPluginInstallations.workspaceId, workspaceId),
|
|
816
725
|
eq(schema.capabilityPluginInstallations.status, "active"),
|
|
817
726
|
eq(schema.capabilityFacetInstallations.status, "active"),
|
|
818
|
-
eq(schema.
|
|
819
|
-
eq(schema.
|
|
820
|
-
sql`${schema.
|
|
727
|
+
eq(schema.integrationFacetDefinitions.kind, "tools"),
|
|
728
|
+
eq(schema.integrationFacetBindings.status, "active"),
|
|
729
|
+
sql`${schema.integrationFacetBindings.runtimeKey} is not null`,
|
|
821
730
|
sql`exists (
|
|
822
731
|
select 1 from ${schema.capabilityComponentOwners} owner
|
|
823
732
|
where owner.facet_installation_id = ${schema.capabilityFacetInstallations.id}
|
|
824
733
|
and ${effectiveCapabilityOwnerSql(sql`owner.owner_kind`, sql`owner.owner_id`)}
|
|
825
734
|
)`,
|
|
826
735
|
sql`exists (
|
|
827
|
-
select 1 from ${schema.
|
|
828
|
-
where owner.binding_id = ${schema.
|
|
736
|
+
select 1 from ${schema.integrationFacetBindingOwners} owner
|
|
737
|
+
where owner.binding_id = ${schema.integrationFacetBindings.id}
|
|
829
738
|
and ${effectiveCapabilityOwnerSql(sql`owner.owner_kind`, sql`owner.owner_id`)}
|
|
830
739
|
)`,
|
|
831
740
|
sql`exists (
|
|
@@ -836,18 +745,18 @@ export async function listInstalledApiIntegrationsInRlsContext(
|
|
|
836
745
|
)`,
|
|
837
746
|
subjectId
|
|
838
747
|
? sql`(
|
|
839
|
-
${schema.
|
|
748
|
+
${schema.integrationFacetBindings.connectionId} is null
|
|
840
749
|
or exists (
|
|
841
750
|
select 1 from ${schema.connections} connection
|
|
842
|
-
where connection.id = ${schema.
|
|
751
|
+
where connection.id = ${schema.integrationFacetBindings.connectionId}
|
|
843
752
|
and (connection.subject_id is null or connection.subject_id = ${subjectId})
|
|
844
753
|
)
|
|
845
754
|
)`
|
|
846
755
|
: sql`(
|
|
847
|
-
${schema.
|
|
756
|
+
${schema.integrationFacetBindings.connectionId} is null
|
|
848
757
|
or exists (
|
|
849
758
|
select 1 from ${schema.connections} connection
|
|
850
|
-
where connection.id = ${schema.
|
|
759
|
+
where connection.id = ${schema.integrationFacetBindings.connectionId}
|
|
851
760
|
and connection.subject_id is null
|
|
852
761
|
)
|
|
853
762
|
)`,
|
|
@@ -855,8 +764,8 @@ export async function listInstalledApiIntegrationsInRlsContext(
|
|
|
855
764
|
)
|
|
856
765
|
.orderBy(
|
|
857
766
|
asc(schema.capabilityPlugins.name),
|
|
858
|
-
asc(schema.
|
|
859
|
-
asc(schema.
|
|
767
|
+
asc(schema.integrationFacetBindings.displayName),
|
|
768
|
+
asc(schema.integrationFacetBindings.bindingKey),
|
|
860
769
|
);
|
|
861
770
|
|
|
862
771
|
return rows.flatMap((row): ApiIntegrationRuntime[] => {
|
|
@@ -864,9 +773,16 @@ export async function listInstalledApiIntegrationsInRlsContext(
|
|
|
864
773
|
const config = objectValue(row.bindingConfig);
|
|
865
774
|
const manifest = objectValue(row.manifest);
|
|
866
775
|
const capabilityId = stringValue(manifest.capabilityId);
|
|
867
|
-
const
|
|
776
|
+
const definitionId = stringValue(manifest.definitionId);
|
|
777
|
+
const definitionProvenance = stringValue(manifest.definitionProvenance);
|
|
868
778
|
const serverId = row.runtimeKey;
|
|
869
|
-
if (
|
|
779
|
+
if (
|
|
780
|
+
!capabilityId ||
|
|
781
|
+
!definitionId ||
|
|
782
|
+
(definitionProvenance !== "curated" && definitionProvenance !== "workspace") ||
|
|
783
|
+
!serverId ||
|
|
784
|
+
row.protocol !== revision.protocol
|
|
785
|
+
) {
|
|
870
786
|
throw new Error(`Installed API Integration ${row.pluginKey} has invalid immutable metadata`);
|
|
871
787
|
}
|
|
872
788
|
const allowedTools = stringArray(config.allowedTools) ?? revision.tools.map((tool) => tool.id);
|
|
@@ -904,7 +820,8 @@ export async function listInstalledApiIntegrationsInRlsContext(
|
|
|
904
820
|
name: row.displayName,
|
|
905
821
|
description: row.pluginDescription,
|
|
906
822
|
protocol: revision.protocol,
|
|
907
|
-
|
|
823
|
+
definitionId,
|
|
824
|
+
definitionProvenance,
|
|
908
825
|
baseUrl: row.baseUrl,
|
|
909
826
|
sourceUrl: row.sourceUrl,
|
|
910
827
|
providerDomain: row.providerDomain,
|
|
@@ -947,7 +864,7 @@ export async function getApiIntegrationUninstallPreview(
|
|
|
947
864
|
removesDefinition: false,
|
|
948
865
|
};
|
|
949
866
|
}
|
|
950
|
-
const owners = await
|
|
867
|
+
const owners = await listIntegrationFacetBindingOwners(scopedDb, context.instanceId);
|
|
951
868
|
const directOwner = owners.find(
|
|
952
869
|
(owner) => owner.kind === "direct" && owner.id === capabilityId,
|
|
953
870
|
);
|
|
@@ -1024,7 +941,7 @@ export async function uninstallApiIntegration(
|
|
|
1024
941
|
context.installationVersion,
|
|
1025
942
|
);
|
|
1026
943
|
}
|
|
1027
|
-
const bindingOwners = await
|
|
944
|
+
const bindingOwners = await listIntegrationFacetBindingOwners(
|
|
1028
945
|
tx as unknown as Database,
|
|
1029
946
|
context.instanceId,
|
|
1030
947
|
);
|
|
@@ -1039,7 +956,7 @@ export async function uninstallApiIntegration(
|
|
|
1039
956
|
definitionStatus: "retained",
|
|
1040
957
|
};
|
|
1041
958
|
}
|
|
1042
|
-
const removed = await
|
|
959
|
+
const removed = await removeIntegrationFacetBindingOwner(tx as unknown as Database, {
|
|
1043
960
|
workspaceId: input.workspaceId,
|
|
1044
961
|
bindingId: context.instanceId,
|
|
1045
962
|
owner: { kind: "direct", id: input.capabilityId },
|
|
@@ -1100,15 +1017,6 @@ export async function uninstallApiIntegration(
|
|
|
1100
1017
|
updatedAt: now,
|
|
1101
1018
|
})
|
|
1102
1019
|
.where(eq(schema.capabilityPluginInstallations.id, context.pluginInstallationId));
|
|
1103
|
-
await tx
|
|
1104
|
-
.update(schema.capabilityInstallations)
|
|
1105
|
-
.set({ status: "disabled", updatedAt: now })
|
|
1106
|
-
.where(
|
|
1107
|
-
and(
|
|
1108
|
-
eq(schema.capabilityInstallations.workspaceId, input.workspaceId),
|
|
1109
|
-
eq(schema.capabilityInstallations.capabilityId, input.capabilityId),
|
|
1110
|
-
),
|
|
1111
|
-
);
|
|
1112
1020
|
return {
|
|
1113
1021
|
capabilityId: input.capabilityId,
|
|
1114
1022
|
instanceKey: input.instanceKey,
|
|
@@ -1150,7 +1058,7 @@ async function migrateApiIntegrationFacetInstallations(
|
|
|
1150
1058
|
oldFacetInstallations: InstalledFacetRow[];
|
|
1151
1059
|
integrationFacetInstallationId: string;
|
|
1152
1060
|
apiFacetInstallationId: string;
|
|
1153
|
-
|
|
1061
|
+
facetDefinitions: ReadonlyMap<string, typeof schema.integrationFacetDefinitions.$inferSelect>;
|
|
1154
1062
|
excludedRuntimeKey: string;
|
|
1155
1063
|
revision: StoredApiIntegrationRevision;
|
|
1156
1064
|
},
|
|
@@ -1192,22 +1100,22 @@ async function migrateApiIntegrationFacetInstallations(
|
|
|
1192
1100
|
if (!oldIntegration) return;
|
|
1193
1101
|
const bindings = await db
|
|
1194
1102
|
.select({
|
|
1195
|
-
binding: schema.
|
|
1196
|
-
|
|
1197
|
-
|
|
1103
|
+
binding: schema.integrationFacetBindings,
|
|
1104
|
+
facetKey: schema.integrationFacetDefinitions.facetKey,
|
|
1105
|
+
facetKind: schema.integrationFacetDefinitions.kind,
|
|
1198
1106
|
})
|
|
1199
|
-
.from(schema.
|
|
1107
|
+
.from(schema.integrationFacetBindings)
|
|
1200
1108
|
.innerJoin(
|
|
1201
|
-
schema.
|
|
1202
|
-
eq(schema.
|
|
1109
|
+
schema.integrationFacetDefinitions,
|
|
1110
|
+
eq(schema.integrationFacetDefinitions.id, schema.integrationFacetBindings.facetDefinitionId),
|
|
1203
1111
|
)
|
|
1204
1112
|
.where(
|
|
1205
1113
|
and(
|
|
1206
|
-
eq(schema.
|
|
1207
|
-
eq(schema.
|
|
1114
|
+
eq(schema.integrationFacetBindings.workspaceId, input.workspaceId),
|
|
1115
|
+
eq(schema.integrationFacetBindings.integrationFacetInstallationId, oldIntegration.id),
|
|
1208
1116
|
or(
|
|
1209
|
-
sql`${schema.
|
|
1210
|
-
ne(schema.
|
|
1117
|
+
sql`${schema.integrationFacetBindings.runtimeKey} is null`,
|
|
1118
|
+
ne(schema.integrationFacetBindings.runtimeKey, input.excludedRuntimeKey),
|
|
1211
1119
|
),
|
|
1212
1120
|
),
|
|
1213
1121
|
)
|
|
@@ -1215,12 +1123,12 @@ async function migrateApiIntegrationFacetInstallations(
|
|
|
1215
1123
|
const available = new Set(input.revision.tools.map((tool) => tool.id));
|
|
1216
1124
|
for (const row of bindings) {
|
|
1217
1125
|
const binding = row.binding;
|
|
1218
|
-
const
|
|
1219
|
-
if (!
|
|
1220
|
-
throw new Error(`API Integration update would remove configured
|
|
1126
|
+
const targetFacet = input.facetDefinitions.get(row.facetKey);
|
|
1127
|
+
if (!targetFacet || targetFacet.kind !== row.facetKind) {
|
|
1128
|
+
throw new Error(`API Integration update would remove configured facet ${row.facetKey}`);
|
|
1221
1129
|
}
|
|
1222
1130
|
const config = objectValue(binding.config);
|
|
1223
|
-
const toolsConfig = row.
|
|
1131
|
+
const toolsConfig = row.facetKind === "tools";
|
|
1224
1132
|
const selected = toolsConfig
|
|
1225
1133
|
? (stringArray(config.allowedTools) ?? []).filter((tool) => available.has(tool))
|
|
1226
1134
|
: [];
|
|
@@ -1230,10 +1138,10 @@ async function migrateApiIntegrationFacetInstallations(
|
|
|
1230
1138
|
.map((tool) => tool.id)
|
|
1231
1139
|
: [];
|
|
1232
1140
|
await db
|
|
1233
|
-
.update(schema.
|
|
1141
|
+
.update(schema.integrationFacetBindings)
|
|
1234
1142
|
.set({
|
|
1235
1143
|
integrationFacetInstallationId: input.integrationFacetInstallationId,
|
|
1236
|
-
|
|
1144
|
+
facetDefinitionId: targetFacet.id,
|
|
1237
1145
|
config: toolsConfig ? { ...config, allowedTools: selected, requireApproval } : config,
|
|
1238
1146
|
status: toolsConfig && selected.length === 0 ? "needs_attention" : binding.status,
|
|
1239
1147
|
lastErrorCode:
|
|
@@ -1241,7 +1149,7 @@ async function migrateApiIntegrationFacetInstallations(
|
|
|
1241
1149
|
version: binding.version + 1,
|
|
1242
1150
|
updatedAt: new Date(),
|
|
1243
1151
|
})
|
|
1244
|
-
.where(eq(schema.
|
|
1152
|
+
.where(eq(schema.integrationFacetBindings.id, binding.id));
|
|
1245
1153
|
}
|
|
1246
1154
|
}
|
|
1247
1155
|
|
|
@@ -1414,22 +1322,22 @@ async function integrationInstanceContext(
|
|
|
1414
1322
|
): Promise<IntegrationInstanceContext | null> {
|
|
1415
1323
|
let query = db
|
|
1416
1324
|
.select({
|
|
1417
|
-
instanceId: schema.
|
|
1418
|
-
instanceVersion: schema.
|
|
1419
|
-
displayName: schema.
|
|
1325
|
+
instanceId: schema.integrationFacetBindings.id,
|
|
1326
|
+
instanceVersion: schema.integrationFacetBindings.version,
|
|
1327
|
+
displayName: schema.integrationFacetBindings.displayName,
|
|
1420
1328
|
pluginInstallationId: schema.capabilityPluginInstallations.id,
|
|
1421
1329
|
installationVersion: schema.capabilityPluginInstallations.version,
|
|
1422
1330
|
})
|
|
1423
|
-
.from(schema.
|
|
1331
|
+
.from(schema.integrationFacetBindings)
|
|
1424
1332
|
.innerJoin(
|
|
1425
|
-
schema.
|
|
1426
|
-
eq(schema.
|
|
1333
|
+
schema.integrationFacetDefinitions,
|
|
1334
|
+
eq(schema.integrationFacetDefinitions.id, schema.integrationFacetBindings.facetDefinitionId),
|
|
1427
1335
|
)
|
|
1428
1336
|
.innerJoin(
|
|
1429
1337
|
schema.capabilityFacetInstallations,
|
|
1430
1338
|
eq(
|
|
1431
1339
|
schema.capabilityFacetInstallations.id,
|
|
1432
|
-
schema.
|
|
1340
|
+
schema.integrationFacetBindings.integrationFacetInstallationId,
|
|
1433
1341
|
),
|
|
1434
1342
|
)
|
|
1435
1343
|
.innerJoin(
|
|
@@ -1445,15 +1353,15 @@ async function integrationInstanceContext(
|
|
|
1445
1353
|
)
|
|
1446
1354
|
.where(
|
|
1447
1355
|
and(
|
|
1448
|
-
eq(schema.
|
|
1449
|
-
eq(schema.
|
|
1450
|
-
eq(schema.
|
|
1356
|
+
eq(schema.integrationFacetBindings.workspaceId, workspaceId),
|
|
1357
|
+
eq(schema.integrationFacetBindings.bindingKey, instanceKey),
|
|
1358
|
+
eq(schema.integrationFacetDefinitions.kind, "tools"),
|
|
1451
1359
|
sql`${schema.capabilityPluginVersions.manifest} ->> 'capabilityId' = ${capabilityId}`,
|
|
1452
1360
|
sql`(
|
|
1453
|
-
${schema.
|
|
1361
|
+
${schema.integrationFacetBindings.connectionId} is null
|
|
1454
1362
|
or exists (
|
|
1455
1363
|
select 1 from ${schema.connections} connection
|
|
1456
|
-
where connection.id = ${schema.
|
|
1364
|
+
where connection.id = ${schema.integrationFacetBindings.connectionId}
|
|
1457
1365
|
and (connection.subject_id is null or connection.subject_id = ${subjectId})
|
|
1458
1366
|
)
|
|
1459
1367
|
)`,
|
|
@@ -1473,34 +1381,34 @@ async function integrationDefinitionHasOtherBindingOwner(
|
|
|
1473
1381
|
workspaceId: string;
|
|
1474
1382
|
pluginInstallationId: string;
|
|
1475
1383
|
excludedBindingId: string;
|
|
1476
|
-
owner: Pick<
|
|
1384
|
+
owner: Pick<IntegrationFacetBindingOwner, "kind" | "id">;
|
|
1477
1385
|
},
|
|
1478
1386
|
): Promise<boolean> {
|
|
1479
1387
|
const [row] = await db
|
|
1480
|
-
.select({ id: schema.
|
|
1481
|
-
.from(schema.
|
|
1388
|
+
.select({ id: schema.integrationFacetBindingOwners.id })
|
|
1389
|
+
.from(schema.integrationFacetBindingOwners)
|
|
1482
1390
|
.innerJoin(
|
|
1483
|
-
schema.
|
|
1484
|
-
eq(schema.
|
|
1391
|
+
schema.integrationFacetBindings,
|
|
1392
|
+
eq(schema.integrationFacetBindings.id, schema.integrationFacetBindingOwners.bindingId),
|
|
1485
1393
|
)
|
|
1486
1394
|
.innerJoin(
|
|
1487
1395
|
schema.capabilityFacetInstallations,
|
|
1488
1396
|
eq(
|
|
1489
1397
|
schema.capabilityFacetInstallations.id,
|
|
1490
|
-
schema.
|
|
1398
|
+
schema.integrationFacetBindings.integrationFacetInstallationId,
|
|
1491
1399
|
),
|
|
1492
1400
|
)
|
|
1493
1401
|
.where(
|
|
1494
1402
|
and(
|
|
1495
|
-
eq(schema.
|
|
1496
|
-
eq(schema.
|
|
1497
|
-
eq(schema.
|
|
1498
|
-
ne(schema.
|
|
1403
|
+
eq(schema.integrationFacetBindingOwners.workspaceId, input.workspaceId),
|
|
1404
|
+
eq(schema.integrationFacetBindingOwners.ownerKind, input.owner.kind),
|
|
1405
|
+
eq(schema.integrationFacetBindingOwners.ownerId, input.owner.id),
|
|
1406
|
+
ne(schema.integrationFacetBindingOwners.bindingId, input.excludedBindingId),
|
|
1499
1407
|
eq(schema.capabilityFacetInstallations.pluginInstallationId, input.pluginInstallationId),
|
|
1500
1408
|
or(
|
|
1501
|
-
eq(schema.
|
|
1502
|
-
eq(schema.
|
|
1503
|
-
eq(schema.
|
|
1409
|
+
eq(schema.integrationFacetBindings.status, "active"),
|
|
1410
|
+
eq(schema.integrationFacetBindings.status, "needs_attention"),
|
|
1411
|
+
eq(schema.integrationFacetBindings.status, "paused"),
|
|
1504
1412
|
),
|
|
1505
1413
|
),
|
|
1506
1414
|
)
|
|
@@ -1563,6 +1471,9 @@ async function integrationOwners(
|
|
|
1563
1471
|
function assertInstallInput(input: InstallApiIntegrationInput): void {
|
|
1564
1472
|
if (input.revision.protocol !== input.protocol)
|
|
1565
1473
|
throw new Error("API Integration protocol mismatch");
|
|
1474
|
+
if (!input.definitionId.trim() || input.revision.definitionId !== input.definitionId) {
|
|
1475
|
+
throw new Error("API Integration Definition identity mismatch");
|
|
1476
|
+
}
|
|
1566
1477
|
if (
|
|
1567
1478
|
input.revision.contentSha256.length !== 64 ||
|
|
1568
1479
|
!/^[0-9a-f]+$/.test(input.revision.contentSha256)
|
|
@@ -1575,15 +1486,12 @@ function assertInstallInput(input: InstallApiIntegrationInput): void {
|
|
|
1575
1486
|
if (new Set(input.revision.tools.map((tool) => tool.id)).size !== input.revision.tools.length) {
|
|
1576
1487
|
throw new Error("API Integration revision has duplicate tool ids");
|
|
1577
1488
|
}
|
|
1578
|
-
const
|
|
1579
|
-
if (
|
|
1580
|
-
throw new Error("API Integration exposes too many
|
|
1489
|
+
const facetDefinitions = input.facetDefinitions ?? [];
|
|
1490
|
+
if (facetDefinitions.length > 128) {
|
|
1491
|
+
throw new Error("API Integration exposes too many facet definitions");
|
|
1581
1492
|
}
|
|
1582
|
-
if (
|
|
1583
|
-
new
|
|
1584
|
-
featureDefinitions.length
|
|
1585
|
-
) {
|
|
1586
|
-
throw new Error("API Integration has duplicate feature keys");
|
|
1493
|
+
if (new Set(facetDefinitions.map((facet) => facet.facetKey)).size !== facetDefinitions.length) {
|
|
1494
|
+
throw new Error("API Integration has duplicate facet keys");
|
|
1587
1495
|
}
|
|
1588
1496
|
const base = new URL(input.baseUrl);
|
|
1589
1497
|
if (base.protocol !== "https:" || base.username || base.password || base.hash) {
|
|
@@ -1620,7 +1528,7 @@ function storedRevision(value: Record<string, unknown>): StoredApiIntegrationRev
|
|
|
1620
1528
|
if (
|
|
1621
1529
|
(protocol !== "openapi" && protocol !== "graphql") ||
|
|
1622
1530
|
typeof value.id !== "string" ||
|
|
1623
|
-
typeof value.
|
|
1531
|
+
typeof value.definitionId !== "string" ||
|
|
1624
1532
|
typeof value.contentSha256 !== "string" ||
|
|
1625
1533
|
typeof value.title !== "string" ||
|
|
1626
1534
|
!Array.isArray(tools) ||
|