@opengeni/contracts 0.27.0 → 0.30.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/{chunk-S4F2GZPD.js → chunk-YWKPXSLB.js} +2578 -2422
- package/dist/chunk-YWKPXSLB.js.map +1 -0
- package/dist/google-drive.js +1 -1
- package/dist/index.d.ts +197 -7
- package/dist/index.js +39 -1
- package/dist/scoped-knowledge.d.ts +233 -0
- package/package.json +1 -1
- package/src/index.ts +182 -8
- package/src/scoped-knowledge.ts +216 -0
- package/dist/chunk-S4F2GZPD.js.map +0 -1
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Tenant scope for normalized knowledge and source provenance. */
|
|
3
|
+
export declare const ScopedKnowledgeScopeKind: z.ZodEnum<{
|
|
4
|
+
organization: "organization";
|
|
5
|
+
personal: "personal";
|
|
6
|
+
workspace: "workspace";
|
|
7
|
+
}>;
|
|
8
|
+
export type ScopedKnowledgeScopeKind = z.infer<typeof ScopedKnowledgeScopeKind>;
|
|
9
|
+
export type ScopedKnowledgeScope = {
|
|
10
|
+
kind: "organization";
|
|
11
|
+
workspaceId: null;
|
|
12
|
+
subjectId: null;
|
|
13
|
+
} | {
|
|
14
|
+
kind: "workspace";
|
|
15
|
+
workspaceId: string;
|
|
16
|
+
subjectId: null;
|
|
17
|
+
} | {
|
|
18
|
+
kind: "personal";
|
|
19
|
+
workspaceId: string | null;
|
|
20
|
+
subjectId: string;
|
|
21
|
+
};
|
|
22
|
+
export declare const ScopedKnowledgeActorKind: z.ZodEnum<{
|
|
23
|
+
human: "human";
|
|
24
|
+
service: "service";
|
|
25
|
+
}>;
|
|
26
|
+
export type ScopedKnowledgeActorKind = z.infer<typeof ScopedKnowledgeActorKind>;
|
|
27
|
+
/**
|
|
28
|
+
* Immutable write provenance. A service actor may retain a causal human, but
|
|
29
|
+
* the service identity never substitutes for that human on personal reads.
|
|
30
|
+
*/
|
|
31
|
+
export type ScopedKnowledgeActor = {
|
|
32
|
+
kind: ScopedKnowledgeActorKind;
|
|
33
|
+
subjectId: string;
|
|
34
|
+
initiatingHumanSubjectId: string | null;
|
|
35
|
+
};
|
|
36
|
+
export declare const KnowledgeLifecycleState: z.ZodEnum<{
|
|
37
|
+
active: "active";
|
|
38
|
+
deleted: "deleted";
|
|
39
|
+
revoked: "revoked";
|
|
40
|
+
}>;
|
|
41
|
+
export type KnowledgeLifecycleState = z.infer<typeof KnowledgeLifecycleState>;
|
|
42
|
+
export declare const KnowledgeLifecycleEventType: z.ZodEnum<{
|
|
43
|
+
acl_changed: "acl_changed";
|
|
44
|
+
deleted: "deleted";
|
|
45
|
+
object_version_added: "object_version_added";
|
|
46
|
+
restored: "restored";
|
|
47
|
+
revoked: "revoked";
|
|
48
|
+
sync_failed: "sync_failed";
|
|
49
|
+
sync_succeeded: "sync_succeeded";
|
|
50
|
+
}>;
|
|
51
|
+
export type KnowledgeLifecycleEventType = z.infer<typeof KnowledgeLifecycleEventType>;
|
|
52
|
+
export declare const KnowledgeSyncRunState: z.ZodEnum<{
|
|
53
|
+
failed: "failed";
|
|
54
|
+
started: "started";
|
|
55
|
+
succeeded: "succeeded";
|
|
56
|
+
}>;
|
|
57
|
+
export type KnowledgeSyncRunState = z.infer<typeof KnowledgeSyncRunState>;
|
|
58
|
+
export declare const KnowledgeClaimOrigin: z.ZodEnum<{
|
|
59
|
+
explicit: "explicit";
|
|
60
|
+
inferred: "inferred";
|
|
61
|
+
}>;
|
|
62
|
+
export type KnowledgeClaimOrigin = z.infer<typeof KnowledgeClaimOrigin>;
|
|
63
|
+
export declare const KnowledgeClaimRelationType: z.ZodEnum<{
|
|
64
|
+
conflicts_with: "conflicts_with";
|
|
65
|
+
supersedes: "supersedes";
|
|
66
|
+
}>;
|
|
67
|
+
export type KnowledgeClaimRelationType = z.infer<typeof KnowledgeClaimRelationType>;
|
|
68
|
+
export declare const KnowledgeClaimEvidencePolarity: z.ZodEnum<{
|
|
69
|
+
contradicts: "contradicts";
|
|
70
|
+
supports: "supports";
|
|
71
|
+
}>;
|
|
72
|
+
export type KnowledgeClaimEvidencePolarity = z.infer<typeof KnowledgeClaimEvidencePolarity>;
|
|
73
|
+
export declare const KnowledgeClaimReviewState: z.ZodEnum<{
|
|
74
|
+
approved: "approved";
|
|
75
|
+
proposed: "proposed";
|
|
76
|
+
rejected: "rejected";
|
|
77
|
+
revoked: "revoked";
|
|
78
|
+
}>;
|
|
79
|
+
export type KnowledgeClaimReviewState = z.infer<typeof KnowledgeClaimReviewState>;
|
|
80
|
+
export declare const KnowledgeFactObjectKind: z.ZodEnum<{
|
|
81
|
+
boolean: "boolean";
|
|
82
|
+
entity: "entity";
|
|
83
|
+
json: "json";
|
|
84
|
+
number: "number";
|
|
85
|
+
text: "text";
|
|
86
|
+
timestamp: "timestamp";
|
|
87
|
+
}>;
|
|
88
|
+
export type KnowledgeFactObjectKind = z.infer<typeof KnowledgeFactObjectKind>;
|
|
89
|
+
export declare const KnowledgeChangeProposalTargetKind: z.ZodEnum<{
|
|
90
|
+
instruction_policy: "instruction_policy";
|
|
91
|
+
preference: "preference";
|
|
92
|
+
}>;
|
|
93
|
+
export type KnowledgeChangeProposalTargetKind = z.infer<typeof KnowledgeChangeProposalTargetKind>;
|
|
94
|
+
export type KnowledgeProviderRecord = {
|
|
95
|
+
id: string;
|
|
96
|
+
accountId: string;
|
|
97
|
+
scope: ScopedKnowledgeScope;
|
|
98
|
+
providerKey: string;
|
|
99
|
+
externalTenantId: string;
|
|
100
|
+
lifecycleState: KnowledgeLifecycleState;
|
|
101
|
+
lifecycleGeneration: number;
|
|
102
|
+
createdAt: string;
|
|
103
|
+
updatedAt: string;
|
|
104
|
+
};
|
|
105
|
+
export type KnowledgeSourceRecord = {
|
|
106
|
+
id: string;
|
|
107
|
+
accountId: string;
|
|
108
|
+
providerId: string;
|
|
109
|
+
scope: ScopedKnowledgeScope;
|
|
110
|
+
externalSourceId: string;
|
|
111
|
+
sourceKind: string;
|
|
112
|
+
sourceUri: string | null;
|
|
113
|
+
currentAclGeneration: number | null;
|
|
114
|
+
syncGeneration: number;
|
|
115
|
+
syncCursor: string | null;
|
|
116
|
+
lifecycleState: KnowledgeLifecycleState;
|
|
117
|
+
lifecycleGeneration: number;
|
|
118
|
+
createdAt: string;
|
|
119
|
+
updatedAt: string;
|
|
120
|
+
};
|
|
121
|
+
export type KnowledgeSourceAclVersionRecord = {
|
|
122
|
+
id: string;
|
|
123
|
+
accountId: string;
|
|
124
|
+
sourceId: string;
|
|
125
|
+
generation: number;
|
|
126
|
+
aclVersion: string | null;
|
|
127
|
+
aclHash: string;
|
|
128
|
+
audience: ScopedKnowledgeScope;
|
|
129
|
+
agentAccess: boolean;
|
|
130
|
+
createdAt: string;
|
|
131
|
+
};
|
|
132
|
+
export type KnowledgeSyncRunRecord = {
|
|
133
|
+
id: string;
|
|
134
|
+
accountId: string;
|
|
135
|
+
sourceId: string;
|
|
136
|
+
operationId: string;
|
|
137
|
+
state: KnowledgeSyncRunState;
|
|
138
|
+
inputSyncGeneration: number;
|
|
139
|
+
inputLifecycleGeneration: number;
|
|
140
|
+
inputCursor: string | null;
|
|
141
|
+
outputCursor: string | null;
|
|
142
|
+
watermark: string | null;
|
|
143
|
+
metadata: Record<string, unknown>;
|
|
144
|
+
errorCode: string | null;
|
|
145
|
+
startedAt: string;
|
|
146
|
+
completedAt: string | null;
|
|
147
|
+
};
|
|
148
|
+
export type KnowledgeSourceObjectRecord = {
|
|
149
|
+
id: string;
|
|
150
|
+
accountId: string;
|
|
151
|
+
sourceId: string;
|
|
152
|
+
scope: ScopedKnowledgeScope;
|
|
153
|
+
externalObjectId: string;
|
|
154
|
+
documentId: string | null;
|
|
155
|
+
lifecycleState: KnowledgeLifecycleState;
|
|
156
|
+
lifecycleGeneration: number;
|
|
157
|
+
versionGeneration: number;
|
|
158
|
+
currentVersionId: string | null;
|
|
159
|
+
createdAt: string;
|
|
160
|
+
updatedAt: string;
|
|
161
|
+
};
|
|
162
|
+
export type KnowledgeDocumentVersionRecord = {
|
|
163
|
+
id: string;
|
|
164
|
+
accountId: string;
|
|
165
|
+
sourceId: string;
|
|
166
|
+
objectId: string;
|
|
167
|
+
scope: ScopedKnowledgeScope;
|
|
168
|
+
versionGeneration: number;
|
|
169
|
+
externalVersionId: string;
|
|
170
|
+
contentSha256: string;
|
|
171
|
+
ingestionKey: string;
|
|
172
|
+
aclVersionId: string;
|
|
173
|
+
aclGeneration: number;
|
|
174
|
+
documentId: string | null;
|
|
175
|
+
fileId: string | null;
|
|
176
|
+
createdAt: string;
|
|
177
|
+
};
|
|
178
|
+
export type KnowledgeEntityRecord = {
|
|
179
|
+
id: string;
|
|
180
|
+
accountId: string;
|
|
181
|
+
scope: ScopedKnowledgeScope;
|
|
182
|
+
entityType: string;
|
|
183
|
+
normalizedKey: string;
|
|
184
|
+
displayName: string;
|
|
185
|
+
createdAt: string;
|
|
186
|
+
};
|
|
187
|
+
export type KnowledgeFactRecord = {
|
|
188
|
+
id: string;
|
|
189
|
+
accountId: string;
|
|
190
|
+
scope: ScopedKnowledgeScope;
|
|
191
|
+
subjectEntityId: string;
|
|
192
|
+
predicateKey: string;
|
|
193
|
+
objectKind: KnowledgeFactObjectKind;
|
|
194
|
+
objectEntityId: string | null;
|
|
195
|
+
objectValue: unknown | null;
|
|
196
|
+
objectHash: string;
|
|
197
|
+
createdAt: string;
|
|
198
|
+
};
|
|
199
|
+
export type KnowledgeClaimRecord = {
|
|
200
|
+
id: string;
|
|
201
|
+
accountId: string;
|
|
202
|
+
scope: ScopedKnowledgeScope;
|
|
203
|
+
factId: string;
|
|
204
|
+
origin: KnowledgeClaimOrigin;
|
|
205
|
+
confidenceBps: number;
|
|
206
|
+
effectiveAt: string;
|
|
207
|
+
expiresAt: string | null;
|
|
208
|
+
extractionMethod: string;
|
|
209
|
+
modelProvider: string | null;
|
|
210
|
+
modelName: string | null;
|
|
211
|
+
modelVersion: string | null;
|
|
212
|
+
createdAt: string;
|
|
213
|
+
};
|
|
214
|
+
export type EligibleKnowledgeClaim = {
|
|
215
|
+
claim: KnowledgeClaimRecord;
|
|
216
|
+
fact: KnowledgeFactRecord;
|
|
217
|
+
reviewState: "approved";
|
|
218
|
+
supportingEvidenceCount: number;
|
|
219
|
+
};
|
|
220
|
+
export type KnowledgeChangeProposalRecord = {
|
|
221
|
+
id: string;
|
|
222
|
+
accountId: string;
|
|
223
|
+
scope: ScopedKnowledgeScope;
|
|
224
|
+
targetKind: KnowledgeChangeProposalTargetKind;
|
|
225
|
+
targetScope: string;
|
|
226
|
+
targetKey: string | null;
|
|
227
|
+
content: string;
|
|
228
|
+
contentHash: string;
|
|
229
|
+
claimId: string;
|
|
230
|
+
evidenceId: string;
|
|
231
|
+
status: "proposed";
|
|
232
|
+
createdAt: string;
|
|
233
|
+
};
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -676,6 +676,10 @@ export const DEFAULT_FIRST_PARTY_MCP_PERMISSIONS = [
|
|
|
676
676
|
"sessions:read",
|
|
677
677
|
"sessions:create",
|
|
678
678
|
"sessions:control",
|
|
679
|
+
// Read-only connection discovery lets the selected first-party connector
|
|
680
|
+
// tools resolve an already-installed workspace principal. Credentials stay
|
|
681
|
+
// inside the broker and remain subject to each tool's own authorization.
|
|
682
|
+
"connections:read",
|
|
679
683
|
"variable-sets:use",
|
|
680
684
|
"variable-sets:manage",
|
|
681
685
|
"rigs:use",
|
|
@@ -732,6 +736,11 @@ export const FIRST_PARTY_MCP_TOOL_NAMES = [
|
|
|
732
736
|
"social_connections_list",
|
|
733
737
|
"social_posts_recent",
|
|
734
738
|
"social_daily_analysis_context",
|
|
739
|
+
"social_search_live",
|
|
740
|
+
"social_mentions_live",
|
|
741
|
+
"social_thread_fetch",
|
|
742
|
+
"social_posts_sync",
|
|
743
|
+
"social_post_reply",
|
|
735
744
|
"scheduled_tasks_list",
|
|
736
745
|
"scheduled_tasks_get",
|
|
737
746
|
"scheduled_tasks_create",
|
|
@@ -760,12 +769,13 @@ export const FirstPartyMcpToolName = z.enum(FIRST_PARTY_MCP_TOOL_NAMES);
|
|
|
760
769
|
export type FirstPartyMcpToolName = z.infer<typeof FirstPartyMcpToolName>;
|
|
761
770
|
|
|
762
771
|
/**
|
|
763
|
-
*
|
|
764
|
-
*
|
|
765
|
-
*
|
|
772
|
+
* Connector-wide tools are explicit-only. Ordinary session omission selects
|
|
773
|
+
* the non-connector catalog, while an explicit session policy may still select
|
|
774
|
+
* any catalogued connector tool and remains independently permission-gated.
|
|
766
775
|
*/
|
|
767
|
-
export const DEFAULT_FIRST_PARTY_MCP_TOOLS =
|
|
768
|
-
|
|
776
|
+
export const DEFAULT_FIRST_PARTY_MCP_TOOLS = FIRST_PARTY_MCP_TOOL_NAMES.filter(
|
|
777
|
+
(name) => !name.startsWith("social_") && !name.startsWith("slack_bot_"),
|
|
778
|
+
) satisfies readonly FirstPartyMcpToolName[];
|
|
769
779
|
|
|
770
780
|
export function prefixedMcpToolName(registryId: string, toolName: string): string {
|
|
771
781
|
return `${registryId}__${toolName}`;
|
|
@@ -2538,6 +2548,46 @@ export const McpServerConnectionRef = z
|
|
|
2538
2548
|
});
|
|
2539
2549
|
export type McpServerConnectionRef = z.infer<typeof McpServerConnectionRef>;
|
|
2540
2550
|
|
|
2551
|
+
/** Internal frozen authority for one personal MCP connection. */
|
|
2552
|
+
export const McpPersonalConnectionDelegation = z
|
|
2553
|
+
.object({
|
|
2554
|
+
serverId: z.string().min(1).max(256),
|
|
2555
|
+
connectionId: z.string().uuid(),
|
|
2556
|
+
ownerSubjectId: z.string().min(1).max(512),
|
|
2557
|
+
providerDomain: z.string().min(1).max(2048),
|
|
2558
|
+
kind: z.enum(["oauth2", "api_key", "app_install", "delegated"]).optional(),
|
|
2559
|
+
})
|
|
2560
|
+
.strict();
|
|
2561
|
+
export type McpPersonalConnectionDelegation = z.infer<typeof McpPersonalConnectionDelegation>;
|
|
2562
|
+
|
|
2563
|
+
/**
|
|
2564
|
+
* Exact personal MCP authority frozen on one causal turn or scheduled task.
|
|
2565
|
+
* One server can have at most one grant; bounded validation keeps corrupt JSON
|
|
2566
|
+
* from becoming executable credential authority at a DB read boundary.
|
|
2567
|
+
*/
|
|
2568
|
+
export const McpPersonalConnectionDelegations = z
|
|
2569
|
+
.array(McpPersonalConnectionDelegation)
|
|
2570
|
+
.max(128)
|
|
2571
|
+
.superRefine((delegations, context) => {
|
|
2572
|
+
const seen = new Set<string>();
|
|
2573
|
+
for (const [index, delegation] of delegations.entries()) {
|
|
2574
|
+
if (seen.has(delegation.serverId)) {
|
|
2575
|
+
context.addIssue({
|
|
2576
|
+
code: "custom",
|
|
2577
|
+
message: "personal MCP delegations must be unique by serverId",
|
|
2578
|
+
path: [index, "serverId"],
|
|
2579
|
+
});
|
|
2580
|
+
}
|
|
2581
|
+
seen.add(delegation.serverId);
|
|
2582
|
+
}
|
|
2583
|
+
});
|
|
2584
|
+
|
|
2585
|
+
export const McpPersonalConnectionSummary = McpPersonalConnectionDelegation.pick({
|
|
2586
|
+
serverId: true,
|
|
2587
|
+
providerDomain: true,
|
|
2588
|
+
});
|
|
2589
|
+
export type McpPersonalConnectionSummary = z.infer<typeof McpPersonalConnectionSummary>;
|
|
2590
|
+
|
|
2541
2591
|
export type McpCredentialsRequest = {
|
|
2542
2592
|
accountId: string;
|
|
2543
2593
|
workspaceId: string;
|
|
@@ -2565,6 +2615,7 @@ export type McpCredentialsRequest = {
|
|
|
2565
2615
|
|
|
2566
2616
|
export type McpCredentialAuthNeededReason =
|
|
2567
2617
|
| CredentialAuthNeededReason
|
|
2618
|
+
| "personal_authority_unavailable"
|
|
2568
2619
|
| "unsupported_auth"
|
|
2569
2620
|
| "resource_scope_unavailable";
|
|
2570
2621
|
|
|
@@ -4011,6 +4062,8 @@ export const SessionTurn = z.object({
|
|
|
4011
4062
|
lineage: z.record(z.string(), z.unknown()),
|
|
4012
4063
|
initiator: TurnInitiator,
|
|
4013
4064
|
initiatorContext: TurnInitiatorContext,
|
|
4065
|
+
/** Secret-safe projection of the exact personal authority frozen on this turn. */
|
|
4066
|
+
personalConnections: z.array(McpPersonalConnectionSummary).default([]),
|
|
4014
4067
|
cancelledBy: z.string().nullable(),
|
|
4015
4068
|
cancelReason: z.string().nullable(),
|
|
4016
4069
|
startedAt: z.string().nullable(),
|
|
@@ -4498,6 +4551,8 @@ export type SessionPendingInputPreview = z.infer<typeof SessionPendingInputPrevi
|
|
|
4498
4551
|
export const SessionQueueSnapshot = z.object({
|
|
4499
4552
|
version: z.number().int().nonnegative(),
|
|
4500
4553
|
effectiveControl: EffectiveSessionControl,
|
|
4554
|
+
/** Secret-safe personal MCP summaries frozen on the exact active turn. */
|
|
4555
|
+
activePersonalConnections: z.array(McpPersonalConnectionSummary).default([]),
|
|
4501
4556
|
/**
|
|
4502
4557
|
* True while the latest attempt is interrupted but has not durably proved
|
|
4503
4558
|
* quiescence: no more inference, user-visible output, or workspace-persistence
|
|
@@ -4865,6 +4920,9 @@ export const ScheduledTask = z.object({
|
|
|
4865
4920
|
runMode: ScheduledTaskRunMode,
|
|
4866
4921
|
overlapPolicy: ScheduledTaskOverlapPolicy,
|
|
4867
4922
|
agentConfig: ScheduledTaskAgentConfig,
|
|
4923
|
+
createdBy: TurnInitiator.default({ kind: "service", subjectId: "unattributed-legacy" }),
|
|
4924
|
+
createdByContext: TurnInitiatorContext.default({}),
|
|
4925
|
+
personalConnections: z.array(McpPersonalConnectionSummary).default([]),
|
|
4868
4926
|
reusableSessionId: z.string().uuid().nullable(),
|
|
4869
4927
|
variableSetId: z.string().uuid().nullable().default(null),
|
|
4870
4928
|
/** @deprecated use variableSetId */
|
|
@@ -5185,6 +5243,7 @@ export type EnablePackRequest = z.infer<typeof EnablePackRequest>;
|
|
|
5185
5243
|
|
|
5186
5244
|
export const SocialProvider = z.enum([
|
|
5187
5245
|
"x",
|
|
5246
|
+
"reddit",
|
|
5188
5247
|
"linkedin",
|
|
5189
5248
|
"instagram",
|
|
5190
5249
|
"facebook",
|
|
@@ -5257,6 +5316,19 @@ export const CreateSocialPostRequest = z.object({
|
|
|
5257
5316
|
});
|
|
5258
5317
|
export type CreateSocialPostRequest = z.infer<typeof CreateSocialPostRequest>;
|
|
5259
5318
|
|
|
5319
|
+
// Social OAuth is first-party (X / Reddit REST APIs), distinct from the MCP
|
|
5320
|
+
// integrations OAuth flow: these providers have no MCP resource metadata, so
|
|
5321
|
+
// endpoints are pinned per provider and tokens live in social_connections.
|
|
5322
|
+
export const SocialOAuthProviderId = z.enum(["x", "reddit"]);
|
|
5323
|
+
export type SocialOAuthProviderId = z.infer<typeof SocialOAuthProviderId>;
|
|
5324
|
+
|
|
5325
|
+
export const SocialOAuthStartRequest = z.object({
|
|
5326
|
+
provider: SocialOAuthProviderId,
|
|
5327
|
+
scopes: z.array(z.string().min(1)).optional(),
|
|
5328
|
+
returnPath: z.string().optional(),
|
|
5329
|
+
});
|
|
5330
|
+
export type SocialOAuthStartRequest = z.infer<typeof SocialOAuthStartRequest>;
|
|
5331
|
+
|
|
5260
5332
|
export const ConnectionKind = z.enum(["oauth2", "api_key", "app_install", "delegated"]);
|
|
5261
5333
|
export type ConnectionKind = z.infer<typeof ConnectionKind>;
|
|
5262
5334
|
|
|
@@ -5306,12 +5378,81 @@ export const ConnectionMetadata = z.object({
|
|
|
5306
5378
|
});
|
|
5307
5379
|
export type ConnectionMetadata = z.infer<typeof ConnectionMetadata>;
|
|
5308
5380
|
|
|
5381
|
+
type PersonalSlackCanonicalConnection = Pick<
|
|
5382
|
+
ConnectionMetadata,
|
|
5383
|
+
"id" | "status" | "createdAt" | "updatedAt"
|
|
5384
|
+
>;
|
|
5385
|
+
|
|
5386
|
+
const PERSONAL_SLACK_CONNECTION_STATUS_RANK = {
|
|
5387
|
+
active: 0,
|
|
5388
|
+
needs_reauth: 1,
|
|
5389
|
+
error: 2,
|
|
5390
|
+
revoked: 3,
|
|
5391
|
+
} as const satisfies Record<ConnectionStatus, number>;
|
|
5392
|
+
|
|
5393
|
+
/**
|
|
5394
|
+
* Canonical ordering for duplicate subject-owned Personal Slack rows.
|
|
5395
|
+
*
|
|
5396
|
+
* PostgreSQL broker lookup mirrors this exact sequence: usable status first,
|
|
5397
|
+
* then newest update, newest creation, and immutable UUID descending.
|
|
5398
|
+
*/
|
|
5399
|
+
export function comparePersonalSlackCanonicalConnections(
|
|
5400
|
+
left: PersonalSlackCanonicalConnection,
|
|
5401
|
+
right: PersonalSlackCanonicalConnection,
|
|
5402
|
+
): number {
|
|
5403
|
+
const statusDelta =
|
|
5404
|
+
PERSONAL_SLACK_CONNECTION_STATUS_RANK[left.status] -
|
|
5405
|
+
PERSONAL_SLACK_CONNECTION_STATUS_RANK[right.status];
|
|
5406
|
+
if (statusDelta !== 0) return statusDelta;
|
|
5407
|
+
|
|
5408
|
+
const updatedAtDelta = compareDescending(
|
|
5409
|
+
canonicalConnectionTimestamp(left.updatedAt),
|
|
5410
|
+
canonicalConnectionTimestamp(right.updatedAt),
|
|
5411
|
+
);
|
|
5412
|
+
if (updatedAtDelta !== 0) return updatedAtDelta;
|
|
5413
|
+
|
|
5414
|
+
const createdAtDelta = compareDescending(
|
|
5415
|
+
canonicalConnectionTimestamp(left.createdAt),
|
|
5416
|
+
canonicalConnectionTimestamp(right.createdAt),
|
|
5417
|
+
);
|
|
5418
|
+
if (createdAtDelta !== 0) return createdAtDelta;
|
|
5419
|
+
|
|
5420
|
+
return compareDescending(left.id, right.id);
|
|
5421
|
+
}
|
|
5422
|
+
|
|
5423
|
+
export function selectCanonicalPersonalSlackConnection<T extends PersonalSlackCanonicalConnection>(
|
|
5424
|
+
connections: readonly T[],
|
|
5425
|
+
): T | null {
|
|
5426
|
+
let selected: T | null = null;
|
|
5427
|
+
for (const connection of connections) {
|
|
5428
|
+
if (!selected || comparePersonalSlackCanonicalConnections(connection, selected) < 0) {
|
|
5429
|
+
selected = connection;
|
|
5430
|
+
}
|
|
5431
|
+
}
|
|
5432
|
+
return selected;
|
|
5433
|
+
}
|
|
5434
|
+
|
|
5435
|
+
function canonicalConnectionTimestamp(value: string): number {
|
|
5436
|
+
const timestamp = Date.parse(value);
|
|
5437
|
+
return Number.isFinite(timestamp) ? timestamp : Number.NEGATIVE_INFINITY;
|
|
5438
|
+
}
|
|
5439
|
+
|
|
5440
|
+
function compareDescending(left: number | string, right: number | string): number {
|
|
5441
|
+
if (left === right) return 0;
|
|
5442
|
+
return left > right ? -1 : 1;
|
|
5443
|
+
}
|
|
5444
|
+
|
|
5309
5445
|
export const ConnectionCredentialBundle = z.record(z.string(), z.unknown());
|
|
5310
5446
|
export type ConnectionCredentialBundle = z.infer<typeof ConnectionCredentialBundle>;
|
|
5311
5447
|
|
|
5448
|
+
export const ConnectionOwnership = z.enum(["workspace", "personal"]);
|
|
5449
|
+
export type ConnectionOwnership = z.infer<typeof ConnectionOwnership>;
|
|
5450
|
+
|
|
5312
5451
|
export const CreateConnectionRequest = z.object({
|
|
5313
5452
|
providerDomain: z.string().min(1),
|
|
5314
5453
|
kind: ConnectionKind,
|
|
5454
|
+
ownership: ConnectionOwnership.optional(),
|
|
5455
|
+
/** @deprecated use ownership */
|
|
5315
5456
|
subjectId: z.string().min(1).nullable().optional(),
|
|
5316
5457
|
credential: ConnectionCredentialBundle,
|
|
5317
5458
|
grantedScopes: z.array(z.string().min(1)).default([]),
|
|
@@ -5361,6 +5502,7 @@ export const OAuthStartRequest = z
|
|
|
5361
5502
|
requestedScopes: z.array(z.string().min(1)).default([]),
|
|
5362
5503
|
returnPath: z.string().min(1).optional(),
|
|
5363
5504
|
connectionId: z.string().uuid().optional(),
|
|
5505
|
+
ownership: ConnectionOwnership.optional(),
|
|
5364
5506
|
oauthClient: z
|
|
5365
5507
|
.object({
|
|
5366
5508
|
clientId: z.string().min(1),
|
|
@@ -5646,8 +5788,8 @@ export const Session = z.object({
|
|
|
5646
5788
|
// Non-default first-party MCP token permissions (manager-style sessions);
|
|
5647
5789
|
// null means the fixed worker default set.
|
|
5648
5790
|
firstPartyMcpPermissions: z.array(Permission).nullable(),
|
|
5649
|
-
// Exact model-visible OpenGeni selection.
|
|
5650
|
-
//
|
|
5791
|
+
// Exact model-visible OpenGeni selection. The default omits connector-wide
|
|
5792
|
+
// tools; [] intentionally selects none.
|
|
5651
5793
|
firstPartyMcpTools: z.array(FirstPartyMcpToolName),
|
|
5652
5794
|
// Per-session third-party MCP servers, metadata only. Credential values are
|
|
5653
5795
|
// write-only and never appear here.
|
|
@@ -6155,6 +6297,7 @@ export const ToolAuthNeededPayload = z.object({
|
|
|
6155
6297
|
"expired",
|
|
6156
6298
|
"insufficient_scope",
|
|
6157
6299
|
"refresh_failed",
|
|
6300
|
+
"personal_authority_unavailable",
|
|
6158
6301
|
"unsupported_auth",
|
|
6159
6302
|
"resource_scope_unavailable",
|
|
6160
6303
|
]),
|
|
@@ -7948,7 +8091,8 @@ export const CreateSessionRequest = withVariableSetIdAlias({
|
|
|
7948
8091
|
// rejected; creation never silently expands a child beyond that set.
|
|
7949
8092
|
firstPartyMcpPermissions: z.array(Permission).optional(),
|
|
7950
8093
|
// Exact model-visible selection from the broad first-party OpenGeni MCP
|
|
7951
|
-
// catalog. Omission selects the
|
|
8094
|
+
// catalog. Omission selects the safe non-connector default; [] intentionally
|
|
8095
|
+
// exposes none.
|
|
7952
8096
|
// This does not grant authority: every registered tool is permission-gated.
|
|
7953
8097
|
firstPartyMcpTools: z.array(FirstPartyMcpToolName).optional(),
|
|
7954
8098
|
// Third-party MCP servers attached only to this session. For an agent-created
|
|
@@ -9326,6 +9470,35 @@ export const ClientConfig = /* @__PURE__ */ defineModelContractSchema(() =>
|
|
|
9326
9470
|
}),
|
|
9327
9471
|
productAccessMode: ProductAccessMode,
|
|
9328
9472
|
auth: ClientAuthConfig.default({ mode: "none" }),
|
|
9473
|
+
analytics: z
|
|
9474
|
+
.object({
|
|
9475
|
+
consentRequired: z.boolean(),
|
|
9476
|
+
providers: z.object({
|
|
9477
|
+
reo: z
|
|
9478
|
+
.object({
|
|
9479
|
+
clientId: z
|
|
9480
|
+
.string()
|
|
9481
|
+
.max(128)
|
|
9482
|
+
.regex(/^[A-Za-z0-9_-]+$/u),
|
|
9483
|
+
})
|
|
9484
|
+
.optional(),
|
|
9485
|
+
posthog: z
|
|
9486
|
+
.object({
|
|
9487
|
+
projectKey: z.string().min(1).max(256),
|
|
9488
|
+
host: z.string().url().max(2_048),
|
|
9489
|
+
})
|
|
9490
|
+
.optional(),
|
|
9491
|
+
ga4: z
|
|
9492
|
+
.object({
|
|
9493
|
+
measurementId: z
|
|
9494
|
+
.string()
|
|
9495
|
+
.max(32)
|
|
9496
|
+
.regex(/^G-[A-Z0-9]+$/u),
|
|
9497
|
+
})
|
|
9498
|
+
.optional(),
|
|
9499
|
+
}),
|
|
9500
|
+
})
|
|
9501
|
+
.default({ consentRequired: true, providers: {} }),
|
|
9329
9502
|
// Server-wide hint: does this deployment support Channel-A structured services
|
|
9330
9503
|
// at all (P4.4). Per-session availability is negotiated on /stream-capabilities
|
|
9331
9504
|
// (it depends on the session's pinned backend); this is the coarse on/off the
|
|
@@ -9421,3 +9594,4 @@ export * from "./secret-redaction";
|
|
|
9421
9594
|
export * from "./workspace-instruction-policies";
|
|
9422
9595
|
export * from "./workspace-state";
|
|
9423
9596
|
export * from "./preference-registry";
|
|
9597
|
+
export * from "./scoped-knowledge";
|