@opengeni/contracts 2.15.2 → 3.0.1-canary.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/atlassian.js +10 -9
- package/dist/{chunk-NPYLOZAP.js → chunk-5LYFSZ7O.js} +12 -12
- package/dist/{chunk-QP3BIGSC.js → chunk-FBXZZSXA.js} +7668 -7654
- package/dist/chunk-FBXZZSXA.js.map +1 -0
- package/dist/chunk-FY5DZL7T.js +348 -0
- package/dist/chunk-FY5DZL7T.js.map +1 -0
- package/dist/{chunk-6TCVR53X.js → chunk-O5LEQHDM.js} +2 -2
- package/dist/chunk-P3HLDT77.js +59 -0
- package/dist/chunk-P3HLDT77.js.map +1 -0
- package/dist/chunk-TEMFILR7.js +143 -0
- package/dist/chunk-TEMFILR7.js.map +1 -0
- package/dist/connect.d.ts +325 -0
- package/dist/connect.js +182 -0
- package/dist/connect.js.map +1 -0
- package/dist/connection-authority.js +28 -334
- package/dist/connection-authority.js.map +1 -1
- package/dist/editable-artifact-codec-registry.js +2 -2
- package/dist/editable-artifact-live.js +2 -2
- package/dist/editable-artifact-serialized-commit.js +3 -3
- package/dist/editable-artifacts.js +24 -24
- package/dist/external-identities.d.ts +620 -0
- package/dist/external-identities.js +34 -0
- package/dist/external-identities.js.map +1 -0
- package/dist/google-drive.js +12 -11
- package/dist/google-drive.js.map +1 -1
- package/dist/host-mcp-bindings.d.ts +297 -0
- package/dist/host-mcp-bindings.js +195 -0
- package/dist/host-mcp-bindings.js.map +1 -0
- package/dist/index.d.ts +150 -72
- package/dist/index.js +89 -81
- package/dist/personal-github.js +10 -9
- package/dist/personal-github.js.map +1 -1
- package/dist/sandbox-snapshots.d.ts +18 -0
- package/package.json +13 -1
- package/src/connect.ts +202 -0
- package/src/external-identities.ts +213 -0
- package/src/host-mcp-bindings.ts +226 -0
- package/src/index.ts +165 -69
- package/src/sandbox-snapshots.ts +67 -3
- package/dist/chunk-QP3BIGSC.js.map +0 -1
- /package/dist/{chunk-NPYLOZAP.js.map → chunk-5LYFSZ7O.js.map} +0 -0
- /package/dist/{chunk-6TCVR53X.js.map → chunk-O5LEQHDM.js.map} +0 -0
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SkillReviewReference } from "./skills";
|
|
1
|
+
import { SkillReviewReference, skillReviewHumanInput } from "./skills";
|
|
2
2
|
export * from "./skills";
|
|
3
3
|
export * from "./bundled-skills";
|
|
4
4
|
import { BundledSkillSelection } from "./bundled-skills";
|
|
@@ -8,6 +8,25 @@ import { isSafeSkillRelativePath, validateSkillTextFiles } from "./skill-files";
|
|
|
8
8
|
export * from "./model-connection-access";
|
|
9
9
|
export * from "./sandbox-provider-command";
|
|
10
10
|
import { z } from "zod";
|
|
11
|
+
export const HostMcpCreateSelections = z
|
|
12
|
+
.array(
|
|
13
|
+
z
|
|
14
|
+
.object({
|
|
15
|
+
serverId: z.string().min(1).max(256),
|
|
16
|
+
delegationId: z
|
|
17
|
+
.string()
|
|
18
|
+
.uuid()
|
|
19
|
+
.transform((value) => value.toLowerCase()),
|
|
20
|
+
generation: z.number().int().positive().safe(),
|
|
21
|
+
})
|
|
22
|
+
.strict(),
|
|
23
|
+
)
|
|
24
|
+
.max(128)
|
|
25
|
+
.superRefine((values, ctx) => {
|
|
26
|
+
if (new Set(values.map((value) => value.serverId)).size !== values.length)
|
|
27
|
+
ctx.addIssue({ code: "custom", message: "Duplicate host server selection" });
|
|
28
|
+
});
|
|
29
|
+
export type HostMcpCreateSelection = z.input<typeof HostMcpCreateSelections>[number];
|
|
11
30
|
import { Permission } from "./permissions";
|
|
12
31
|
import { ScopedKnowledgeScope } from "./scoped-knowledge";
|
|
13
32
|
export { siteSessionPath, SiteSessionPathError } from "./site-session-http";
|
|
@@ -161,7 +180,9 @@ export {
|
|
|
161
180
|
encodeNativeSnapshotRef,
|
|
162
181
|
omitInlineWorkspaceArchiveWhenObjectRefPresent,
|
|
163
182
|
parseWorkspaceArchiveDescriptor,
|
|
183
|
+
parseWorkspaceArchiveObjectKey,
|
|
164
184
|
parseWorkspaceArchiveObjectRef,
|
|
185
|
+
validateWorkspaceArchiveObjectRef,
|
|
165
186
|
workspaceArchiveObjectKey,
|
|
166
187
|
workspaceArchivePayloadPresent,
|
|
167
188
|
type NativeSnapshotDescriptor,
|
|
@@ -170,6 +191,7 @@ export {
|
|
|
170
191
|
type TarWorkspaceArchiveDescriptor,
|
|
171
192
|
type WorkspaceArchiveDescriptor,
|
|
172
193
|
type WorkspaceArchiveObjectRef,
|
|
194
|
+
type WorkspaceArchiveObjectKey,
|
|
173
195
|
type WorkspaceTreeFingerprint,
|
|
174
196
|
} from "./sandbox-snapshots";
|
|
175
197
|
|
|
@@ -4093,6 +4115,11 @@ export const McpServerConnectionRef = z
|
|
|
4093
4115
|
connectionId: z.string().min(1).optional(),
|
|
4094
4116
|
/** Host-owned credential authority; omission keeps OpenGeni's native connection authority. */
|
|
4095
4117
|
authoritySource: z.literal("host").optional(),
|
|
4118
|
+
/** Opt-in durable reference. A live execution validator is mandatory. */
|
|
4119
|
+
hostBinding: z
|
|
4120
|
+
.object({ bindingId: z.string().uuid(), generation: z.number().int().positive().safe() })
|
|
4121
|
+
.strict()
|
|
4122
|
+
.optional(),
|
|
4096
4123
|
/** Stable provider family (for example github, gitlab, or azure_devops). */
|
|
4097
4124
|
provider: z.string().min(1).max(128).optional(),
|
|
4098
4125
|
/** Provider host or tenant domain. */
|
|
@@ -4114,6 +4141,12 @@ export const McpServerConnectionRef = z
|
|
|
4114
4141
|
path: ["connectionId"],
|
|
4115
4142
|
});
|
|
4116
4143
|
}
|
|
4144
|
+
if (reference.hostBinding && reference.authoritySource !== "host")
|
|
4145
|
+
context.addIssue({
|
|
4146
|
+
code: "custom",
|
|
4147
|
+
path: ["hostBinding"],
|
|
4148
|
+
message: "Durable binding requires host authority",
|
|
4149
|
+
});
|
|
4117
4150
|
if (!reference.selectedResources) return;
|
|
4118
4151
|
if (!reference.connectionId) {
|
|
4119
4152
|
context.addIssue({
|
|
@@ -4407,7 +4440,39 @@ export type McpCredentialResolution =
|
|
|
4407
4440
|
authorizationUrl?: string;
|
|
4408
4441
|
};
|
|
4409
4442
|
|
|
4443
|
+
/** Non-turn authority captured by the authenticated API gateway, never by caller JSON. */
|
|
4444
|
+
export type McpGatewayCredentialAuthority = {
|
|
4445
|
+
kind: "external_user" | "organization_service";
|
|
4446
|
+
subjectId: string;
|
|
4447
|
+
permissions: AccessGrant["permissions"];
|
|
4448
|
+
};
|
|
4449
|
+
|
|
4450
|
+
export type McpGatewayCredentialsRequest = Pick<
|
|
4451
|
+
McpCredentialsRequest,
|
|
4452
|
+
| "accountId"
|
|
4453
|
+
| "workspaceId"
|
|
4454
|
+
| "destinationUrl"
|
|
4455
|
+
| "credentialTarget"
|
|
4456
|
+
| "serverId"
|
|
4457
|
+
| "toolName"
|
|
4458
|
+
| "connectionRef"
|
|
4459
|
+
| "forceRefresh"
|
|
4460
|
+
> & {
|
|
4461
|
+
surface: "workspace_gateway";
|
|
4462
|
+
requestId: string;
|
|
4463
|
+
authority: McpGatewayCredentialAuthority;
|
|
4464
|
+
};
|
|
4465
|
+
|
|
4466
|
+
export type McpGatewayCredentialResolution =
|
|
4467
|
+
| (Omit<Extract<McpCredentialResolution, { status: "ok" }>, "sessionId"> & { requestId: string })
|
|
4468
|
+
| (Omit<Extract<McpCredentialResolution, { status: "auth_needed" }>, "sessionId"> & {
|
|
4469
|
+
requestId: string;
|
|
4470
|
+
});
|
|
4471
|
+
|
|
4410
4472
|
export type ConnectionCredentialsPort = {
|
|
4473
|
+
/** Restrict an optional remote adapter to explicit host refs. Omission keeps
|
|
4474
|
+
* existing in-process host override and legacy-reference behavior. */
|
|
4475
|
+
mcpAuthoritySource?: "host";
|
|
4411
4476
|
// Every leg is optional: a host may drive only the credential classes it
|
|
4412
4477
|
// owns. An unset leg falls through to today's standalone implementation for
|
|
4413
4478
|
// that leg only.
|
|
@@ -4426,6 +4491,11 @@ export type ConnectionCredentialsPort = {
|
|
|
4426
4491
|
* used by model-visible MCP tools and the exact-attempt Codemode projection.
|
|
4427
4492
|
*/
|
|
4428
4493
|
mcpCredentials?(input: McpCredentialsRequest): Promise<McpCredentialResolution>;
|
|
4494
|
+
/** Explicit opt-in for authenticated pre-session discovery and invocation.
|
|
4495
|
+
* Does not call the turn-based mcpCredentials fallback or grant durable use. */
|
|
4496
|
+
mcpGatewayCredentials?(
|
|
4497
|
+
input: McpGatewayCredentialsRequest,
|
|
4498
|
+
): Promise<McpGatewayCredentialResolution>;
|
|
4429
4499
|
};
|
|
4430
4500
|
|
|
4431
4501
|
// ============ connection-credential provider — GitHub App API port (BYO-App, §7.6 / GitHub credential prototype remainder) ===
|
|
@@ -6736,7 +6806,10 @@ export const SessionAuthorizationActor = z.discriminatedUnion("kind", [
|
|
|
6736
6806
|
/** Frozen authority that admitted the calling turn. */
|
|
6737
6807
|
initiator: TurnInitiator,
|
|
6738
6808
|
initiatorContext: TurnInitiatorContext,
|
|
6739
|
-
/**
|
|
6809
|
+
/**
|
|
6810
|
+
* Durable causal-human selector for named human-bound capabilities. It never
|
|
6811
|
+
* authorizes by itself and is null for pure service work.
|
|
6812
|
+
*/
|
|
6740
6813
|
initiatingHumanSubjectId: z.string().min(1).max(1024).nullable(),
|
|
6741
6814
|
}),
|
|
6742
6815
|
]);
|
|
@@ -6789,57 +6862,46 @@ export const SESSION_AUTHORIZATION_LIST_SCOPE_MAX_IDS = 10_000;
|
|
|
6789
6862
|
|
|
6790
6863
|
/**
|
|
6791
6864
|
* How far a live agent attempt on a session may reach across the workspace,
|
|
6792
|
-
*
|
|
6793
|
-
*
|
|
6794
|
-
*
|
|
6795
|
-
*
|
|
6865
|
+
* under ordinary resource authorization. `workspace` is the platform default.
|
|
6866
|
+
* `user` limits outgoing reach to the same canonical {@link SessionScopeSubjectId};
|
|
6867
|
+
* `session` limits it to the own root tree. Target task scope does not restrict
|
|
6868
|
+
* incoming access; private ownership remains enforced. Humans and API keys
|
|
6796
6869
|
* are unaffected: this is an agent-to-agent fence enforced only in the core
|
|
6797
6870
|
* session-authorization seam.
|
|
6798
6871
|
*/
|
|
6799
6872
|
export const SessionAgentAccess = z.enum(["session", "user", "workspace"]);
|
|
6800
6873
|
export type SessionAgentAccess = z.infer<typeof SessionAgentAccess>;
|
|
6801
6874
|
|
|
6802
|
-
export const SESSION_END_USER_SOURCE_MAX_CHARS = 200;
|
|
6803
|
-
export const SESSION_END_USER_ID_MAX_CHARS = 1_024;
|
|
6804
|
-
|
|
6805
|
-
const NUL_CHARACTER = String.fromCharCode(0);
|
|
6806
|
-
const UNPAIRED_SURROGATE_PATTERN =
|
|
6807
|
-
/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/u;
|
|
6808
|
-
|
|
6809
|
-
function opaqueEndUserSegment(maxChars: number) {
|
|
6810
|
-
return z
|
|
6811
|
-
.string()
|
|
6812
|
-
.min(1)
|
|
6813
|
-
.max(maxChars)
|
|
6814
|
-
.refine((value) => !value.includes(NUL_CHARACTER), "must not contain NUL")
|
|
6815
|
-
.refine((value) => !UNPAIRED_SURROGATE_PATTERN.test(value), "must be well-formed UTF-16");
|
|
6816
|
-
}
|
|
6817
|
-
|
|
6818
6875
|
/**
|
|
6819
|
-
*
|
|
6820
|
-
*
|
|
6821
|
-
*
|
|
6822
|
-
* scopes `agentAccess: "user"` reach, `memoryScope: "user"` Memory rows, and
|
|
6823
|
-
* the session-list `endUserSource`/`endUserId` filter.
|
|
6876
|
+
* Server-derived canonical user for the session's agent-reach boundary.
|
|
6877
|
+
* This is an output/filter value, never caller-supplied creation authority.
|
|
6878
|
+
* Human visibility remains an independent resource authorization check.
|
|
6824
6879
|
*/
|
|
6825
|
-
export const
|
|
6826
|
-
.
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
|
|
6830
|
-
|
|
6831
|
-
export type SessionEndUser = z.infer<typeof SessionEndUser>;
|
|
6880
|
+
export const SessionScopeSubjectId = z
|
|
6881
|
+
.string()
|
|
6882
|
+
.min(1)
|
|
6883
|
+
.max(1024)
|
|
6884
|
+
.regex(/^(?:user:|external_user:).+/);
|
|
6885
|
+
export type SessionScopeSubjectId = z.infer<typeof SessionScopeSubjectId>;
|
|
6832
6886
|
|
|
6833
6887
|
/**
|
|
6834
6888
|
* The typed Workspace Memory selector an agent reads and writes. `workspace`
|
|
6835
|
-
* is
|
|
6889
|
+
* is shared memory; `user` adds a private layer
|
|
6836
6890
|
* (the agent still reads workspace facts and saves to its narrowest scope);
|
|
6837
6891
|
* `off` registers no Memory tools for the session. `user` requires an
|
|
6838
|
-
*
|
|
6892
|
+
* authenticated canonical user on the active turn. Use task notes for task-local data.
|
|
6839
6893
|
*/
|
|
6840
|
-
export const SessionMemoryScope = z.enum(["workspace", "user", "
|
|
6894
|
+
export const SessionMemoryScope = z.enum(["workspace", "user", "off"]);
|
|
6841
6895
|
export type SessionMemoryScope = z.infer<typeof SessionMemoryScope>;
|
|
6842
6896
|
|
|
6897
|
+
/** Read old persisted selectors without promoting task-local data or authority.
|
|
6898
|
+
* New requests must use SessionMemoryScope directly and reject `session`.
|
|
6899
|
+
* Historical Memory rows remain retained; task notes own new task-local facts. */
|
|
6900
|
+
export function storedSessionMemoryScope(value: unknown): SessionMemoryScope {
|
|
6901
|
+
if (value === "session") return "off";
|
|
6902
|
+
return SessionMemoryScope.parse(value ?? "workspace");
|
|
6903
|
+
}
|
|
6904
|
+
|
|
6843
6905
|
/**
|
|
6844
6906
|
* The calling agent attempt's own access scope, resolved by OpenGeni from the
|
|
6845
6907
|
* caller session row (never from the request) and applied as one SQL
|
|
@@ -6849,7 +6911,7 @@ export const SessionAgentAccessViewer = z
|
|
|
6849
6911
|
.object({
|
|
6850
6912
|
callerRootSessionId: z.string().uuid(),
|
|
6851
6913
|
agentAccess: SessionAgentAccess,
|
|
6852
|
-
|
|
6914
|
+
scopeSubjectId: SessionScopeSubjectId.nullable(),
|
|
6853
6915
|
})
|
|
6854
6916
|
.strict();
|
|
6855
6917
|
export type SessionAgentAccessViewer = z.infer<typeof SessionAgentAccessViewer>;
|
|
@@ -9403,6 +9465,7 @@ const CreateAgentScheduledTaskRequest = /* @__PURE__ */ withVariableSetIdAlias({
|
|
|
9403
9465
|
overlapPolicy: ScheduledTaskOverlapPolicy.default("allow_concurrent"),
|
|
9404
9466
|
targetSessionId: z.string().uuid().nullable().optional(),
|
|
9405
9467
|
connectionAuthorities: McpConnectionAuthoritySelections.default([]),
|
|
9468
|
+
selectedHostMcpDelegations: HostMcpCreateSelections.optional(),
|
|
9406
9469
|
agentConfig: ScheduledTaskAgentConfigInput,
|
|
9407
9470
|
status: ScheduledTaskStatus.default("active"),
|
|
9408
9471
|
variableSetId: z.string().uuid().nullable().optional(),
|
|
@@ -9482,6 +9545,7 @@ export const UpdateScheduledTaskRequest =
|
|
|
9482
9545
|
action: ScheduledTaskAction.optional(),
|
|
9483
9546
|
targetSessionId: z.string().uuid().nullable().optional(),
|
|
9484
9547
|
connectionAuthorities: McpConnectionAuthoritySelections.optional(),
|
|
9548
|
+
selectedHostMcpDelegations: HostMcpCreateSelections.optional(),
|
|
9485
9549
|
agentConfig: ScheduledTaskAgentConfigInput.optional(),
|
|
9486
9550
|
status: ScheduledTaskStatus.optional(),
|
|
9487
9551
|
variableSetId: z.string().uuid().nullable().optional(),
|
|
@@ -10714,6 +10778,8 @@ export type ConnectionOwnership = z.infer<typeof ConnectionOwnership>;
|
|
|
10714
10778
|
|
|
10715
10779
|
export const SocialConnection = z.object({
|
|
10716
10780
|
id: z.string().uuid(),
|
|
10781
|
+
/** Present on version-aware deployments; required for observed reconnect. */
|
|
10782
|
+
version: z.number().int().positive().optional(),
|
|
10717
10783
|
accountId: z.string().uuid(),
|
|
10718
10784
|
workspaceId: z.string().uuid(),
|
|
10719
10785
|
provider: SocialProvider,
|
|
@@ -10845,6 +10911,8 @@ export const FikenInstallRequest = z.object({
|
|
|
10845
10911
|
export type FikenInstallRequest = z.infer<typeof FikenInstallRequest>;
|
|
10846
10912
|
|
|
10847
10913
|
export const FikenOAuthStartRequest = z.object({
|
|
10914
|
+
/** Same-origin product route to return to after provider consent. */
|
|
10915
|
+
returnPath: z.string().min(1).max(2048).optional(),
|
|
10848
10916
|
/** Existing Fiken connection to re-authorize in place (reconnect). */
|
|
10849
10917
|
connectionId: z.string().uuid().optional(),
|
|
10850
10918
|
});
|
|
@@ -11046,6 +11114,7 @@ export const OAuthStartRequest = z
|
|
|
11046
11114
|
resource: z.string().url().optional(),
|
|
11047
11115
|
requestedScopes: z.array(z.string().min(1)).default([]),
|
|
11048
11116
|
returnPath: z.string().min(1).optional(),
|
|
11117
|
+
returnUrl: z.string().min(1).max(4096).optional(),
|
|
11049
11118
|
connectionId: z.string().uuid().optional(),
|
|
11050
11119
|
ownership: ConnectionOwnership.optional(),
|
|
11051
11120
|
oauthClient: z
|
|
@@ -12270,8 +12339,8 @@ export const Session = /* @__PURE__ */ defineSkillContractSchema(() =>
|
|
|
12270
12339
|
policyRole: WorkspaceInstructionPolicyRoleKeyInput.nullable().default(null),
|
|
12271
12340
|
/** Agent-to-agent reach declared at create; see {@link SessionAgentAccess}. */
|
|
12272
12341
|
agentAccess: SessionAgentAccess.default("workspace"),
|
|
12273
|
-
/**
|
|
12274
|
-
|
|
12342
|
+
/** Canonical native/asUser scope identity; null for unscoped service work. */
|
|
12343
|
+
scopeSubjectId: SessionScopeSubjectId.nullable().default(null),
|
|
12275
12344
|
/** Typed Memory selector frozen at create; see {@link SessionMemoryScope}. */
|
|
12276
12345
|
memoryScope: SessionMemoryScope.default("workspace"),
|
|
12277
12346
|
resources: z.array(ResourceRef),
|
|
@@ -12487,27 +12556,17 @@ export const SessionListResponse = /* @__PURE__ */ defineSkillContractSchema(()
|
|
|
12487
12556
|
export type SessionListResponse = z.infer<typeof SessionListResponse>;
|
|
12488
12557
|
|
|
12489
12558
|
/**
|
|
12490
|
-
*
|
|
12491
|
-
*
|
|
12492
|
-
* exact lifecycle state.
|
|
12559
|
+
* Organization session queries may filter a canonical scope subject and lifecycle
|
|
12560
|
+
* state. Legacy end-user label filters are rejected.
|
|
12493
12561
|
*/
|
|
12494
|
-
export const ListOrganizationSessionsQuery = z
|
|
12495
|
-
.
|
|
12496
|
-
|
|
12497
|
-
|
|
12498
|
-
|
|
12499
|
-
|
|
12500
|
-
|
|
12501
|
-
|
|
12502
|
-
.superRefine((value, context) => {
|
|
12503
|
-
if ((value.endUserSource === undefined) !== (value.endUserId === undefined)) {
|
|
12504
|
-
context.addIssue({
|
|
12505
|
-
code: z.ZodIssueCode.custom,
|
|
12506
|
-
message: "endUserSource and endUserId must be supplied together",
|
|
12507
|
-
path: ["endUserId"],
|
|
12508
|
-
});
|
|
12509
|
-
}
|
|
12510
|
-
});
|
|
12562
|
+
export const ListOrganizationSessionsQuery = z.object({
|
|
12563
|
+
limit: z.coerce.number().int().min(1).max(200).default(50),
|
|
12564
|
+
cursor: z.string().min(1).optional(),
|
|
12565
|
+
scopeSubjectId: SessionScopeSubjectId.optional(),
|
|
12566
|
+
endUserSource: z.never().optional(),
|
|
12567
|
+
endUserId: z.never().optional(),
|
|
12568
|
+
status: SessionStatus.optional(),
|
|
12569
|
+
});
|
|
12511
12570
|
export type ListOrganizationSessionsQuery = z.infer<typeof ListOrganizationSessionsQuery>;
|
|
12512
12571
|
|
|
12513
12572
|
/**
|
|
@@ -14838,6 +14897,8 @@ export const CreateSessionRequest = /* @__PURE__ */ defineSkillContractSchema(()
|
|
|
14838
14897
|
* identity or authorization from the UUID.
|
|
14839
14898
|
*/
|
|
14840
14899
|
requestedSessionId: z.string().uuid().optional(),
|
|
14900
|
+
/** Explicit external-owner grants for the direct initial turn only. */
|
|
14901
|
+
selectedHostMcpDelegations: HostMcpCreateSelections.optional(),
|
|
14841
14902
|
/** Top-level omission is workspace-visible. Agent-child omission inherits
|
|
14842
14903
|
* the exact parent visibility; cross-visibility child creation is rejected.
|
|
14843
14904
|
* Top-level private creation is an activated managed-cookie owning-human
|
|
@@ -14849,12 +14910,11 @@ export const CreateSessionRequest = /* @__PURE__ */ defineSkillContractSchema(()
|
|
|
14849
14910
|
* omission and may only narrow it (workspace > user > session); a wider
|
|
14850
14911
|
* explicit child value is rejected. Never widens human or API-key access. */
|
|
14851
14912
|
agentAccess: SessionAgentAccess.default("workspace"),
|
|
14852
|
-
/**
|
|
14853
|
-
|
|
14854
|
-
endUser:
|
|
14855
|
-
/** Typed Memory selector. `user` requires
|
|
14856
|
-
*
|
|
14857
|
-
* omission and may only narrow it (workspace > user > session > off). */
|
|
14913
|
+
/** Identity comes from verified native/asUser authority, never request fields. */
|
|
14914
|
+
scopeSubjectId: z.never().optional(),
|
|
14915
|
+
endUser: z.never().optional(),
|
|
14916
|
+
/** Typed Memory selector. `user` requires canonical user authority. Children
|
|
14917
|
+
* inherit omission and may only narrow (workspace > user > off). */
|
|
14858
14918
|
memoryScope: SessionMemoryScope.default("workspace"),
|
|
14859
14919
|
initialMessage: z.string().min(1).optional(),
|
|
14860
14920
|
// Creates the durable session shell without fabricating a user message or
|
|
@@ -15051,9 +15111,8 @@ export const CreateSessionRequest = /* @__PURE__ */ defineSkillContractSchema(()
|
|
|
15051
15111
|
message: "new-session attachment authority epoch is derived by the server",
|
|
15052
15112
|
});
|
|
15053
15113
|
}
|
|
15054
|
-
//
|
|
15055
|
-
//
|
|
15056
|
-
// core create resolver (422) after inheritance rather than at parse time.
|
|
15114
|
+
// Canonical user authority and child inheritance are resolved by the core
|
|
15115
|
+
// create resolver, which rejects user Memory without that authority.
|
|
15057
15116
|
}),
|
|
15058
15117
|
);
|
|
15059
15118
|
export type CreateSessionRequest = z.infer<typeof CreateSessionRequest>;
|
|
@@ -15149,6 +15208,41 @@ export const HumanInputQuestion = z
|
|
|
15149
15208
|
});
|
|
15150
15209
|
export type HumanInputQuestion = z.infer<typeof HumanInputQuestion>;
|
|
15151
15210
|
|
|
15211
|
+
/** Only known presentation wire differences are equivalent. This is not
|
|
15212
|
+
* authorization: response admission still binds the immutable source receipt.
|
|
15213
|
+
* Compare original keys as well as parsed values so unknown fields cannot be
|
|
15214
|
+
* hidden by Zod's ordinary object projection during a pending-card re-freeze. */
|
|
15215
|
+
export function canonicalSkillReviewQuestion(
|
|
15216
|
+
question: HumanInputQuestion,
|
|
15217
|
+
): HumanInputQuestion | null {
|
|
15218
|
+
if (
|
|
15219
|
+
!HumanInputQuestion.safeParse(question).success ||
|
|
15220
|
+
!SkillReviewReference.strict().safeParse(question.skillReview).success
|
|
15221
|
+
)
|
|
15222
|
+
return null;
|
|
15223
|
+
const canonical = skillReviewHumanInput(question.skillReview!).questions[0]!;
|
|
15224
|
+
const normalized = {
|
|
15225
|
+
...question,
|
|
15226
|
+
allowOther: false,
|
|
15227
|
+
options: question.options.map((option) => {
|
|
15228
|
+
if (option.description != null) return option;
|
|
15229
|
+
const { description: _description, ...rest } = option;
|
|
15230
|
+
return rest;
|
|
15231
|
+
}),
|
|
15232
|
+
};
|
|
15233
|
+
if (
|
|
15234
|
+
normalized.validation == null ||
|
|
15235
|
+
(Object.keys(normalized.validation).every((key) =>
|
|
15236
|
+
["minSelections", "maxSelections"].includes(key),
|
|
15237
|
+
) &&
|
|
15238
|
+
normalized.validation.minSelections == null &&
|
|
15239
|
+
normalized.validation.maxSelections == null)
|
|
15240
|
+
) {
|
|
15241
|
+
delete normalized.validation;
|
|
15242
|
+
}
|
|
15243
|
+
return stableJson(normalized) === stableJson(canonical) ? canonical : null;
|
|
15244
|
+
}
|
|
15245
|
+
|
|
15152
15246
|
export const HumanInputRequestStatus = z.enum([
|
|
15153
15247
|
"pending",
|
|
15154
15248
|
"answered",
|
|
@@ -15266,6 +15360,7 @@ export const SessionUserMessagePayload = z
|
|
|
15266
15360
|
mcpCredentialUpdates: z.array(SessionMcpCredentialUpdateInput).optional(),
|
|
15267
15361
|
/** Explicit personal-connection grants for this exact logical turn. */
|
|
15268
15362
|
connectionAuthorities: McpConnectionAuthoritySelections.default([]),
|
|
15363
|
+
selectedHostMcpDelegations: HostMcpCreateSelections.optional(),
|
|
15269
15364
|
personalResourceAttachment: PersonalResourceAttachmentIntent.optional(),
|
|
15270
15365
|
})
|
|
15271
15366
|
.strict()
|
|
@@ -15315,6 +15410,7 @@ export const SteerSessionMessageRequest = z
|
|
|
15315
15410
|
mcpCredentialUpdates: z.array(SessionMcpCredentialUpdateInput).optional(),
|
|
15316
15411
|
/** Explicit personal-connection grants for this exact steered turn. */
|
|
15317
15412
|
connectionAuthorities: McpConnectionAuthoritySelections.default([]),
|
|
15413
|
+
selectedHostMcpDelegations: HostMcpCreateSelections.optional(),
|
|
15318
15414
|
personalResourceAttachment: PersonalResourceAttachmentIntent.optional(),
|
|
15319
15415
|
})
|
|
15320
15416
|
.strict()
|
package/src/sandbox-snapshots.ts
CHANGED
|
@@ -64,8 +64,35 @@ export type WorkspaceArchiveObjectRef = {
|
|
|
64
64
|
backend: string;
|
|
65
65
|
};
|
|
66
66
|
|
|
67
|
+
// Keep legacy scope/key spelling readable. New physical upload identities must
|
|
68
|
+
// be a complete RFC UUID (including version and variant), never arbitrary text.
|
|
69
|
+
const UPLOAD_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
67
70
|
const OBJECT_KEY =
|
|
68
|
-
/^sandbox-archives\/v1\/[0-9a-f-]{36}\/[0-9a-f-]{36}\/[0-9a-f-]{36}\/wa1:[0-9]{13}:[0-9a-f]{64}
|
|
71
|
+
/^sandbox-archives\/v1\/([0-9a-f-]{36})\/([0-9a-f-]{36})\/([0-9a-f-]{36})\/(wa1:[0-9]{13}:[0-9a-f]{64})(?:\.([0-9a-f-]+))?\.tar$/i;
|
|
72
|
+
|
|
73
|
+
export type WorkspaceArchiveObjectKey = {
|
|
74
|
+
accountId: string;
|
|
75
|
+
workspaceId: string;
|
|
76
|
+
sandboxGroupId: string;
|
|
77
|
+
revision: string;
|
|
78
|
+
uploadId: string | null;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export function parseWorkspaceArchiveObjectKey(value: unknown): WorkspaceArchiveObjectKey | null {
|
|
82
|
+
if (typeof value !== "string") return null;
|
|
83
|
+
const match = OBJECT_KEY.exec(value);
|
|
84
|
+
// JS $ may match before a final newline; a locator must match in full.
|
|
85
|
+
if (!match || match[0] !== value || (match[5] !== undefined && !UPLOAD_ID.test(match[5]))) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
accountId: match[1]!,
|
|
90
|
+
workspaceId: match[2]!,
|
|
91
|
+
sandboxGroupId: match[3]!,
|
|
92
|
+
revision: match[4]!,
|
|
93
|
+
uploadId: match[5] ?? null,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
69
96
|
|
|
70
97
|
export function parseWorkspaceArchiveObjectRef(value: unknown): WorkspaceArchiveObjectRef | null {
|
|
71
98
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
@@ -73,7 +100,7 @@ export function parseWorkspaceArchiveObjectRef(value: unknown): WorkspaceArchive
|
|
|
73
100
|
if (
|
|
74
101
|
candidate.schema !== WORKSPACE_ARCHIVE_OBJECT_REF_SCHEMA ||
|
|
75
102
|
typeof candidate.key !== "string" ||
|
|
76
|
-
!
|
|
103
|
+
!parseWorkspaceArchiveObjectKey(candidate.key) ||
|
|
77
104
|
typeof candidate.sha256 !== "string" ||
|
|
78
105
|
!SHA256.test(candidate.sha256) ||
|
|
79
106
|
!nonnegativeInteger(candidate.bytes) ||
|
|
@@ -98,8 +125,45 @@ export function workspaceArchiveObjectKey(input: {
|
|
|
98
125
|
workspaceId: string;
|
|
99
126
|
sandboxGroupId: string;
|
|
100
127
|
revision: string;
|
|
128
|
+
/** New upload invocations supply a fresh randomUUID; omission is legacy-only. */
|
|
129
|
+
uploadId?: string;
|
|
101
130
|
}): string {
|
|
102
|
-
|
|
131
|
+
if (
|
|
132
|
+
input.uploadId !== undefined &&
|
|
133
|
+
(!UPLOAD_ID.test(input.uploadId) || input.uploadId.length !== 36)
|
|
134
|
+
) {
|
|
135
|
+
throw new Error("Invalid workspace archive upload UUID");
|
|
136
|
+
}
|
|
137
|
+
return `sandbox-archives/v1/${input.accountId}/${input.workspaceId}/${input.sandboxGroupId}/${input.revision}${input.uploadId === undefined ? "" : `.${input.uploadId}`}.tar`;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Bind a stored locator to its publication/restore scope and verified tar
|
|
141
|
+
* descriptor. A logical revision never substitutes for the exact physical key. */
|
|
142
|
+
export function validateWorkspaceArchiveObjectRef(
|
|
143
|
+
value: unknown,
|
|
144
|
+
input: {
|
|
145
|
+
accountId: string;
|
|
146
|
+
workspaceId: string;
|
|
147
|
+
sandboxGroupId: string;
|
|
148
|
+
descriptor: WorkspaceArchiveDescriptor;
|
|
149
|
+
},
|
|
150
|
+
): WorkspaceArchiveObjectRef | null {
|
|
151
|
+
const ref = parseWorkspaceArchiveObjectRef(value);
|
|
152
|
+
const key = ref && parseWorkspaceArchiveObjectKey(ref.key);
|
|
153
|
+
const descriptor = parseWorkspaceArchiveDescriptor(input.descriptor);
|
|
154
|
+
if (
|
|
155
|
+
!ref ||
|
|
156
|
+
!key ||
|
|
157
|
+
descriptor?.version !== 1 ||
|
|
158
|
+
key.accountId.toLowerCase() !== input.accountId.toLowerCase() ||
|
|
159
|
+
key.workspaceId.toLowerCase() !== input.workspaceId.toLowerCase() ||
|
|
160
|
+
key.sandboxGroupId.toLowerCase() !== input.sandboxGroupId.toLowerCase() ||
|
|
161
|
+
key.revision !== descriptor.revision ||
|
|
162
|
+
ref.sha256 !== descriptor.archiveSha256 ||
|
|
163
|
+
ref.bytes !== descriptor.archiveBytes
|
|
164
|
+
)
|
|
165
|
+
return null;
|
|
166
|
+
return ref;
|
|
103
167
|
}
|
|
104
168
|
|
|
105
169
|
export function workspaceArchivePayloadPresent(
|