@tangle-network/agent-interface 3.2.0 → 5.0.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/README.md +11 -2
- package/dist/environment-provider.d.ts +1 -0
- package/dist/environment-provider.js +1 -0
- package/dist/environment-requests.d.ts +72 -0
- package/dist/environment-requests.js +16 -0
- package/dist/environment-runtime.d.ts +789 -39
- package/dist/environment-runtime.js +11 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/portable-context-commitments.d.ts +47 -0
- package/dist/portable-context-commitments.js +48 -0
- package/dist/portable-context-plan-request.d.ts +2 -1
- package/dist/portable-context-plan-wire.d.ts +103 -0
- package/dist/portable-context-plan-wire.js +127 -0
- package/dist/portable-context-plan.d.ts +6 -13
- package/dist/portable-context-plan.js +12 -14
- package/dist/portable-context-transfer.d.ts +344 -37
- package/dist/portable-context-transfer.js +40 -3
- package/dist/portable-context.d.ts +1 -0
- package/dist/portable-context.js +1 -0
- package/dist/provider-adapter.d.ts +9 -3
- package/dist/provider-config.d.ts +5 -0
- package/dist/workspace-snapshot.d.ts +79 -0
- package/dist/workspace-snapshot.js +31 -0
- package/package.json +1 -1
|
@@ -198,6 +198,7 @@ export const AgentEnvironmentCapabilitiesSchema = z
|
|
|
198
198
|
freshSession: z.boolean(),
|
|
199
199
|
requestIdempotency: z.boolean(),
|
|
200
200
|
lookup: z.boolean(),
|
|
201
|
+
attach: z.boolean().optional(),
|
|
201
202
|
})
|
|
202
203
|
.optional(),
|
|
203
204
|
interactions: InteractionCapabilitiesSchema.optional(),
|
|
@@ -241,9 +242,11 @@ export const AgentEnvironmentCapabilitiesSchema = z
|
|
|
241
242
|
.min(1)
|
|
242
243
|
.max(CONTRACT_MAX_ARRAY_LENGTH)
|
|
243
244
|
.optional(),
|
|
245
|
+
durableIdempotency: z.boolean().optional(),
|
|
244
246
|
billingOwner: z.boolean().optional(),
|
|
245
247
|
runtimeAttachments: z.strictObject({ mcp: z.literal(true) }).optional(),
|
|
246
248
|
workspaceCheckpoint: z.boolean().optional(),
|
|
249
|
+
workspaceSnapshot: z.boolean().optional(),
|
|
247
250
|
})
|
|
248
251
|
.optional(),
|
|
249
252
|
observation: z
|
|
@@ -350,10 +353,12 @@ export const AgentEnvironmentCapabilitiesSchema = z
|
|
|
350
353
|
}
|
|
351
354
|
const create = capabilities.create;
|
|
352
355
|
if (create !== undefined) {
|
|
353
|
-
if (create.
|
|
356
|
+
if (create.durableIdempotency === undefined &&
|
|
357
|
+
create.egress === undefined &&
|
|
354
358
|
create.billingOwner === undefined &&
|
|
355
359
|
create.runtimeAttachments === undefined &&
|
|
356
|
-
create.workspaceCheckpoint === undefined
|
|
360
|
+
create.workspaceCheckpoint === undefined &&
|
|
361
|
+
create.workspaceSnapshot === undefined) {
|
|
357
362
|
refinement.addIssue({
|
|
358
363
|
code: "custom",
|
|
359
364
|
path: ["create"],
|
|
@@ -515,3 +520,7 @@ export async function createAgentEnvironmentWithIdempotency(records, input, crea
|
|
|
515
520
|
throw error;
|
|
516
521
|
}
|
|
517
522
|
}
|
|
523
|
+
export const AgentEnvironmentGetOptionsSchema = z.strictObject({
|
|
524
|
+
signal: z.custom().optional(),
|
|
525
|
+
contextTransfer: ContextTransferRequestSchema.optional(),
|
|
526
|
+
});
|
package/dist/index.d.ts
CHANGED
|
@@ -9,11 +9,12 @@ export * from "./host-services.js";
|
|
|
9
9
|
export * from "./mcp.js";
|
|
10
10
|
export * from "./provider-adapter.js";
|
|
11
11
|
export type * from "./environment-provider.js";
|
|
12
|
-
export { AgentEnvironmentCapabilitiesSchema, AgentRuntimeAttachmentsSchema, AgentNativeContextContinuationAdmissionSchema, AgentNativeContextContinuationResultSchema, AgentTurnInputSchema, AgentTurnResultSchema, agentEnvironmentCreateInputDigest, agentNativeContextContinuationAdmissionMatchesRequest, agentNativeContextContinuationResultMatchesRequest, AccountUsageSchema, AgentEnvironmentObservationSchema, AgentEnvironmentStatusSchema, ComputeBillingSchema, EnvironmentLifecycleSchema, ModelUsageSchema, ObservationProvenanceSchema, PlacementDescriptorSchema, ProviderIdentitySchema, ResourceProfileSchema, ResourceUseSampleSchema, SafeEndpointSchema, agentEnvironmentObservationIdentityMatches, observationContainsCredential, observationOf, AgentInteractiveSessionAttachSchema, AgentInteractiveSessionControlClaimAcknowledgementSchema, AgentInteractiveSessionControlClaimRequestSchema, AgentInteractiveSessionControlClaimSchema, AgentInteractiveSessionPromptAcknowledgementSchema, AgentInteractiveSessionPromptCommandSchema, AgentInteractiveSessionRefSchema, AgentInteractiveSessionStartSchema, AgentInteractiveSessionStopAcknowledgementSchema, AgentInteractiveSessionStopCommandSchema, AgentInteractiveSessionStatusSchema, agentInteractiveSessionControlClaimAcknowledgementMatchesRequest, agentInteractiveSessionControlClaimRequestDigest, agentInteractiveSessionControlClaimMatchesRef, agentInteractiveSessionControlClaimIsNewer, agentInteractiveSessionPromptAcknowledgementMatchesCommand, agentInteractiveSessionPromptRequestDigest, agentInteractiveSessionStopAcknowledgementMatchesCommand, agentInteractiveSessionStopRequestDigest, agentInteractiveSessionRefMatchesStart, agentInteractiveSessionRunRef, agentInteractiveSessionStatusMatchesRef, exactAgentInteractiveSessionStart, createAgentEnvironmentWithIdempotency, canonicalWorkspaceCwd, MAX_WORKSPACE_CWD_LENGTH, workspaceCwdSchema, workspaceCwdPathForBase, WorkspaceRequestSchema, TerminalAttachRequestSchema, TerminalAttachResultSchema, TerminalDetachAckSchema, TerminalInputSchema, TerminalOutputEventSchema, TerminalReplayWindowSchema, TerminalResizeSchema, TerminalSessionRefSchema, terminalAttachResultMatchesRequest, terminalSessionUsable, } from "./environment-provider.js";
|
|
12
|
+
export { AgentEnvironmentCapabilitiesSchema, AgentRuntimeAttachmentsSchema, AgentNativeContextContinuationAdmissionSchema, AgentNativeContextContinuationResultSchema, AgentTurnInputSchema, AgentTurnResultSchema, agentEnvironmentCreateInputDigest, agentNativeContextContinuationAdmissionMatchesRequest, agentNativeContextContinuationResultMatchesRequest, AccountUsageSchema, AgentEnvironmentObservationSchema, AgentEnvironmentStatusSchema, ComputeBillingSchema, EnvironmentLifecycleSchema, ModelUsageSchema, ObservationProvenanceSchema, PlacementDescriptorSchema, ProviderIdentitySchema, ResourceProfileSchema, ResourceUseSampleSchema, SafeEndpointSchema, agentEnvironmentObservationIdentityMatches, observationContainsCredential, observationOf, AgentInteractiveSessionAttachSchema, AgentInteractiveSessionControlClaimAcknowledgementSchema, AgentInteractiveSessionControlClaimRequestSchema, AgentInteractiveSessionControlClaimSchema, AgentInteractiveSessionPromptAcknowledgementSchema, AgentInteractiveSessionPromptCommandSchema, AgentInteractiveSessionRefSchema, AgentInteractiveSessionStartSchema, AgentInteractiveSessionStopAcknowledgementSchema, AgentInteractiveSessionStopCommandSchema, AgentInteractiveSessionStatusSchema, agentInteractiveSessionControlClaimAcknowledgementMatchesRequest, agentInteractiveSessionControlClaimRequestDigest, agentInteractiveSessionControlClaimMatchesRef, agentInteractiveSessionControlClaimIsNewer, agentInteractiveSessionPromptAcknowledgementMatchesCommand, agentInteractiveSessionPromptRequestDigest, agentInteractiveSessionStopAcknowledgementMatchesCommand, agentInteractiveSessionStopRequestDigest, agentInteractiveSessionRefMatchesStart, agentInteractiveSessionRunRef, agentInteractiveSessionStatusMatchesRef, exactAgentInteractiveSessionStart, createAgentEnvironmentWithIdempotency, canonicalWorkspaceCwd, MAX_WORKSPACE_CWD_LENGTH, workspaceCwdSchema, workspaceCwdPathForBase, WorkspaceRequestSchema, ResourceRequestSchema, TerminalAttachRequestSchema, TerminalAttachResultSchema, TerminalDetachAckSchema, TerminalInputSchema, TerminalOutputEventSchema, TerminalReplayWindowSchema, TerminalResizeSchema, TerminalSessionRefSchema, terminalAttachResultMatchesRequest, terminalSessionUsable, } from "./environment-provider.js";
|
|
13
13
|
export * from "./plan.js";
|
|
14
14
|
export * from "./runtime-control.js";
|
|
15
15
|
export * from "./portable-context.js";
|
|
16
16
|
export * from "./workspace-branching.js";
|
|
17
|
+
export * from "./workspace-snapshot.js";
|
|
17
18
|
export * from "./interaction.js";
|
|
18
19
|
export * from "./agent-candidate.js";
|
|
19
20
|
export * from "./agent-candidate-schema.js";
|
package/dist/index.js
CHANGED
|
@@ -8,11 +8,12 @@ export * from "./provider-config.js";
|
|
|
8
8
|
export * from "./host-services.js";
|
|
9
9
|
export * from "./mcp.js";
|
|
10
10
|
export * from "./provider-adapter.js";
|
|
11
|
-
export { AgentEnvironmentCapabilitiesSchema, AgentRuntimeAttachmentsSchema, AgentNativeContextContinuationAdmissionSchema, AgentNativeContextContinuationResultSchema, AgentTurnInputSchema, AgentTurnResultSchema, agentEnvironmentCreateInputDigest, agentNativeContextContinuationAdmissionMatchesRequest, agentNativeContextContinuationResultMatchesRequest, AccountUsageSchema, AgentEnvironmentObservationSchema, AgentEnvironmentStatusSchema, ComputeBillingSchema, EnvironmentLifecycleSchema, ModelUsageSchema, ObservationProvenanceSchema, PlacementDescriptorSchema, ProviderIdentitySchema, ResourceProfileSchema, ResourceUseSampleSchema, SafeEndpointSchema, agentEnvironmentObservationIdentityMatches, observationContainsCredential, observationOf, AgentInteractiveSessionAttachSchema, AgentInteractiveSessionControlClaimAcknowledgementSchema, AgentInteractiveSessionControlClaimRequestSchema, AgentInteractiveSessionControlClaimSchema, AgentInteractiveSessionPromptAcknowledgementSchema, AgentInteractiveSessionPromptCommandSchema, AgentInteractiveSessionRefSchema, AgentInteractiveSessionStartSchema, AgentInteractiveSessionStopAcknowledgementSchema, AgentInteractiveSessionStopCommandSchema, AgentInteractiveSessionStatusSchema, agentInteractiveSessionControlClaimAcknowledgementMatchesRequest, agentInteractiveSessionControlClaimRequestDigest, agentInteractiveSessionControlClaimMatchesRef, agentInteractiveSessionControlClaimIsNewer, agentInteractiveSessionPromptAcknowledgementMatchesCommand, agentInteractiveSessionPromptRequestDigest, agentInteractiveSessionStopAcknowledgementMatchesCommand, agentInteractiveSessionStopRequestDigest, agentInteractiveSessionRefMatchesStart, agentInteractiveSessionRunRef, agentInteractiveSessionStatusMatchesRef, exactAgentInteractiveSessionStart, createAgentEnvironmentWithIdempotency, canonicalWorkspaceCwd, MAX_WORKSPACE_CWD_LENGTH, workspaceCwdSchema, workspaceCwdPathForBase, WorkspaceRequestSchema, TerminalAttachRequestSchema, TerminalAttachResultSchema, TerminalDetachAckSchema, TerminalInputSchema, TerminalOutputEventSchema, TerminalReplayWindowSchema, TerminalResizeSchema, TerminalSessionRefSchema, terminalAttachResultMatchesRequest, terminalSessionUsable, } from "./environment-provider.js";
|
|
11
|
+
export { AgentEnvironmentCapabilitiesSchema, AgentRuntimeAttachmentsSchema, AgentNativeContextContinuationAdmissionSchema, AgentNativeContextContinuationResultSchema, AgentTurnInputSchema, AgentTurnResultSchema, agentEnvironmentCreateInputDigest, agentNativeContextContinuationAdmissionMatchesRequest, agentNativeContextContinuationResultMatchesRequest, AccountUsageSchema, AgentEnvironmentObservationSchema, AgentEnvironmentStatusSchema, ComputeBillingSchema, EnvironmentLifecycleSchema, ModelUsageSchema, ObservationProvenanceSchema, PlacementDescriptorSchema, ProviderIdentitySchema, ResourceProfileSchema, ResourceUseSampleSchema, SafeEndpointSchema, agentEnvironmentObservationIdentityMatches, observationContainsCredential, observationOf, AgentInteractiveSessionAttachSchema, AgentInteractiveSessionControlClaimAcknowledgementSchema, AgentInteractiveSessionControlClaimRequestSchema, AgentInteractiveSessionControlClaimSchema, AgentInteractiveSessionPromptAcknowledgementSchema, AgentInteractiveSessionPromptCommandSchema, AgentInteractiveSessionRefSchema, AgentInteractiveSessionStartSchema, AgentInteractiveSessionStopAcknowledgementSchema, AgentInteractiveSessionStopCommandSchema, AgentInteractiveSessionStatusSchema, agentInteractiveSessionControlClaimAcknowledgementMatchesRequest, agentInteractiveSessionControlClaimRequestDigest, agentInteractiveSessionControlClaimMatchesRef, agentInteractiveSessionControlClaimIsNewer, agentInteractiveSessionPromptAcknowledgementMatchesCommand, agentInteractiveSessionPromptRequestDigest, agentInteractiveSessionStopAcknowledgementMatchesCommand, agentInteractiveSessionStopRequestDigest, agentInteractiveSessionRefMatchesStart, agentInteractiveSessionRunRef, agentInteractiveSessionStatusMatchesRef, exactAgentInteractiveSessionStart, createAgentEnvironmentWithIdempotency, canonicalWorkspaceCwd, MAX_WORKSPACE_CWD_LENGTH, workspaceCwdSchema, workspaceCwdPathForBase, WorkspaceRequestSchema, ResourceRequestSchema, TerminalAttachRequestSchema, TerminalAttachResultSchema, TerminalDetachAckSchema, TerminalInputSchema, TerminalOutputEventSchema, TerminalReplayWindowSchema, TerminalResizeSchema, TerminalSessionRefSchema, terminalAttachResultMatchesRequest, terminalSessionUsable, } from "./environment-provider.js";
|
|
12
12
|
export * from "./plan.js";
|
|
13
13
|
export * from "./runtime-control.js";
|
|
14
14
|
export * from "./portable-context.js";
|
|
15
15
|
export * from "./workspace-branching.js";
|
|
16
|
+
export * from "./workspace-snapshot.js";
|
|
16
17
|
export * from "./interaction.js";
|
|
17
18
|
export * from "./agent-candidate.js";
|
|
18
19
|
export * from "./agent-candidate-schema.js";
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { BackendMessage } from "./backend-message.js";
|
|
2
|
+
import type { PortableContextPlanMaterial } from "./portable-context-plan.js";
|
|
3
|
+
export declare function portableContextMessageMetadataDigest(message: BackendMessage): `sha256:${string}`;
|
|
4
|
+
/** Bind the full local source and decisions without sending omitted bytes or explanation text. */
|
|
5
|
+
export declare function portableContextPlanCommitmentMaterial(plan: PortableContextPlanMaterial): {
|
|
6
|
+
kind: "portable-context-transfer-plan";
|
|
7
|
+
planId: string;
|
|
8
|
+
reviewDigest: `sha256:${string}`;
|
|
9
|
+
source: {
|
|
10
|
+
source: import("./portable-context-base.js").PortableContextSourceBoundary;
|
|
11
|
+
digest: `sha256:${string}`;
|
|
12
|
+
completeness: "complete" | "partial";
|
|
13
|
+
messages: {
|
|
14
|
+
messageId: string;
|
|
15
|
+
metadataDigest?: `sha256:${string}` | undefined;
|
|
16
|
+
parts: (`sha256:${string}` | null)[];
|
|
17
|
+
}[];
|
|
18
|
+
attachments: {
|
|
19
|
+
messageId: string;
|
|
20
|
+
partIndex: number;
|
|
21
|
+
digest: `sha256:${string}`;
|
|
22
|
+
}[];
|
|
23
|
+
};
|
|
24
|
+
destination: {
|
|
25
|
+
runner: string;
|
|
26
|
+
provider: string;
|
|
27
|
+
environmentId?: string | undefined;
|
|
28
|
+
sessionId: string;
|
|
29
|
+
runId: string;
|
|
30
|
+
executionId: string;
|
|
31
|
+
model?: string | undefined;
|
|
32
|
+
profileDigest: `sha256:${string}`;
|
|
33
|
+
workspaceSnapshotDigest?: `sha256:${string}` | undefined;
|
|
34
|
+
};
|
|
35
|
+
messages: {
|
|
36
|
+
messageId: string;
|
|
37
|
+
action: "include" | "omit";
|
|
38
|
+
parts: {
|
|
39
|
+
partIndex: number;
|
|
40
|
+
action: "include" | "omit" | "transform";
|
|
41
|
+
outputDigest?: `sha256:${string}` | undefined;
|
|
42
|
+
}[];
|
|
43
|
+
}[];
|
|
44
|
+
context: import("./portable-context-base.js").PortableConversationContext;
|
|
45
|
+
estimatedTokens?: number | undefined;
|
|
46
|
+
requiresAcceptance: boolean;
|
|
47
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { wireDigest } from "./portable-context-shared.js";
|
|
2
|
+
export function portableContextMessageMetadataDigest(message) {
|
|
3
|
+
const { parts: _parts, ...metadata } = message;
|
|
4
|
+
return wireDigest(metadata);
|
|
5
|
+
}
|
|
6
|
+
/** Bind the full local source and decisions without sending omitted bytes or explanation text. */
|
|
7
|
+
export function portableContextPlanCommitmentMaterial(plan) {
|
|
8
|
+
return {
|
|
9
|
+
kind: "portable-context-transfer-plan",
|
|
10
|
+
planId: plan.planId,
|
|
11
|
+
reviewDigest: wireDigest({ source: plan.source, messages: plan.messages }),
|
|
12
|
+
source: {
|
|
13
|
+
source: plan.source.source,
|
|
14
|
+
digest: plan.source.digest,
|
|
15
|
+
completeness: plan.source.completeness,
|
|
16
|
+
messages: plan.source.messages.map((message) => {
|
|
17
|
+
const decision = plan.messages.find((item) => item.messageId === message.id);
|
|
18
|
+
return {
|
|
19
|
+
messageId: message.id,
|
|
20
|
+
...(decision?.action === "include" ? { metadataDigest: portableContextMessageMetadataDigest(message) } : {}),
|
|
21
|
+
parts: message.parts.map((part, partIndex) => decision?.action === "include" &&
|
|
22
|
+
decision.parts.find((item) => item.partIndex === partIndex)?.action === "include" ? wireDigest(part) : null),
|
|
23
|
+
};
|
|
24
|
+
}),
|
|
25
|
+
attachments: plan.source.attachments.filter((attachment) => {
|
|
26
|
+
const decision = plan.messages.find((item) => item.messageId === attachment.messageId);
|
|
27
|
+
return decision?.action === "include" && decision.parts.find((part) => part.partIndex === attachment.partIndex)?.action === "include";
|
|
28
|
+
}).map((attachment) => ({
|
|
29
|
+
messageId: attachment.messageId,
|
|
30
|
+
partIndex: attachment.partIndex,
|
|
31
|
+
digest: wireDigest(attachment),
|
|
32
|
+
})),
|
|
33
|
+
},
|
|
34
|
+
destination: plan.destination,
|
|
35
|
+
messages: plan.messages.map((message) => ({
|
|
36
|
+
messageId: message.messageId,
|
|
37
|
+
action: message.action,
|
|
38
|
+
parts: message.parts.map((part) => ({
|
|
39
|
+
partIndex: part.partIndex,
|
|
40
|
+
action: part.action,
|
|
41
|
+
...(part.output === undefined ? {} : { outputDigest: wireDigest(part.output) }),
|
|
42
|
+
})),
|
|
43
|
+
})),
|
|
44
|
+
context: plan.context,
|
|
45
|
+
...(plan.estimatedTokens === undefined ? {} : { estimatedTokens: plan.estimatedTokens }),
|
|
46
|
+
requiresAcceptance: plan.requiresAcceptance,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -54,12 +54,13 @@ export declare const PortableContextPlanRequestSchema: z.ZodObject<{
|
|
|
54
54
|
destination: z.ZodObject<{
|
|
55
55
|
runner: z.ZodString;
|
|
56
56
|
provider: z.ZodString;
|
|
57
|
-
environmentId: z.ZodString
|
|
57
|
+
environmentId: z.ZodOptional<z.ZodString>;
|
|
58
58
|
sessionId: z.ZodString;
|
|
59
59
|
runId: z.ZodString;
|
|
60
60
|
executionId: z.ZodString;
|
|
61
61
|
model: z.ZodOptional<z.ZodString>;
|
|
62
62
|
profileDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
|
|
63
|
+
workspaceSnapshotDigest: z.ZodOptional<z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>>;
|
|
63
64
|
}, z.core.$strict>;
|
|
64
65
|
maxInputTokens: z.ZodOptional<z.ZodNumber>;
|
|
65
66
|
}, z.core.$strict>;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type PortableContextPlan } from "./portable-context-plan.js";
|
|
3
|
+
/** Destination wire plan. The complete source and human explanations remain at the caller. */
|
|
4
|
+
export declare const PortableContextTransferPlanSchema: z.ZodObject<{
|
|
5
|
+
kind: z.ZodLiteral<"portable-context-transfer-plan">;
|
|
6
|
+
planId: z.ZodString;
|
|
7
|
+
reviewDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
|
|
8
|
+
source: z.ZodObject<{
|
|
9
|
+
source: z.ZodObject<{
|
|
10
|
+
runId: z.ZodString;
|
|
11
|
+
messageId: z.ZodString;
|
|
12
|
+
provider: z.ZodString;
|
|
13
|
+
environmentId: z.ZodString;
|
|
14
|
+
sessionId: z.ZodString;
|
|
15
|
+
executionId: z.ZodString;
|
|
16
|
+
requestDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
|
|
17
|
+
branchId: z.ZodOptional<z.ZodString>;
|
|
18
|
+
}, z.core.$strict>;
|
|
19
|
+
digest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
|
|
20
|
+
completeness: z.ZodEnum<{
|
|
21
|
+
complete: "complete";
|
|
22
|
+
partial: "partial";
|
|
23
|
+
}>;
|
|
24
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
25
|
+
messageId: z.ZodString;
|
|
26
|
+
metadataDigest: z.ZodOptional<z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>>;
|
|
27
|
+
parts: z.ZodArray<z.ZodNullable<z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>>>;
|
|
28
|
+
}, z.core.$strict>>;
|
|
29
|
+
attachments: z.ZodArray<z.ZodObject<{
|
|
30
|
+
messageId: z.ZodString;
|
|
31
|
+
partIndex: z.ZodNumber;
|
|
32
|
+
digest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
|
|
33
|
+
}, z.core.$strict>>;
|
|
34
|
+
}, z.core.$strict>;
|
|
35
|
+
destination: z.ZodObject<{
|
|
36
|
+
runner: z.ZodString;
|
|
37
|
+
provider: z.ZodString;
|
|
38
|
+
environmentId: z.ZodOptional<z.ZodString>;
|
|
39
|
+
sessionId: z.ZodString;
|
|
40
|
+
runId: z.ZodString;
|
|
41
|
+
executionId: z.ZodString;
|
|
42
|
+
model: z.ZodOptional<z.ZodString>;
|
|
43
|
+
profileDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
|
|
44
|
+
workspaceSnapshotDigest: z.ZodOptional<z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>>;
|
|
45
|
+
}, z.core.$strict>;
|
|
46
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
47
|
+
messageId: z.ZodString;
|
|
48
|
+
action: z.ZodEnum<{
|
|
49
|
+
include: "include";
|
|
50
|
+
omit: "omit";
|
|
51
|
+
}>;
|
|
52
|
+
parts: z.ZodArray<z.ZodObject<{
|
|
53
|
+
partIndex: z.ZodNumber;
|
|
54
|
+
action: z.ZodEnum<{
|
|
55
|
+
include: "include";
|
|
56
|
+
omit: "omit";
|
|
57
|
+
transform: "transform";
|
|
58
|
+
}>;
|
|
59
|
+
outputDigest: z.ZodOptional<z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>>;
|
|
60
|
+
}, z.core.$strict>>;
|
|
61
|
+
}, z.core.$strict>>;
|
|
62
|
+
context: z.ZodObject<{
|
|
63
|
+
source: z.ZodObject<{
|
|
64
|
+
runId: z.ZodString;
|
|
65
|
+
messageId: z.ZodString;
|
|
66
|
+
provider: z.ZodString;
|
|
67
|
+
environmentId: z.ZodString;
|
|
68
|
+
sessionId: z.ZodString;
|
|
69
|
+
executionId: z.ZodString;
|
|
70
|
+
requestDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
|
|
71
|
+
branchId: z.ZodOptional<z.ZodString>;
|
|
72
|
+
}, z.core.$strict>;
|
|
73
|
+
completeness: z.ZodEnum<{
|
|
74
|
+
complete: "complete";
|
|
75
|
+
partial: "partial";
|
|
76
|
+
}>;
|
|
77
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
78
|
+
id: z.ZodString;
|
|
79
|
+
role: z.ZodEnum<{
|
|
80
|
+
assistant: "assistant";
|
|
81
|
+
system: "system";
|
|
82
|
+
user: "user";
|
|
83
|
+
}>;
|
|
84
|
+
parts: z.ZodArray<z.ZodCustom<unknown, unknown>>;
|
|
85
|
+
timestamp: z.ZodISODateTime;
|
|
86
|
+
metadata: z.ZodOptional<z.ZodCustom<Record<string, unknown>, Record<string, unknown>>>;
|
|
87
|
+
}, z.core.$strict>>;
|
|
88
|
+
attachments: z.ZodArray<z.ZodObject<{
|
|
89
|
+
messageId: z.ZodString;
|
|
90
|
+
partIndex: z.ZodNumber;
|
|
91
|
+
digest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
|
|
92
|
+
name: z.ZodOptional<z.ZodString>;
|
|
93
|
+
mediaType: z.ZodOptional<z.ZodString>;
|
|
94
|
+
}, z.core.$strict>>;
|
|
95
|
+
digest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
|
|
96
|
+
}, z.core.$strict>;
|
|
97
|
+
estimatedTokens: z.ZodOptional<z.ZodNumber>;
|
|
98
|
+
requiresAcceptance: z.ZodBoolean;
|
|
99
|
+
digest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
|
|
100
|
+
}, z.core.$strict>;
|
|
101
|
+
export type PortableContextTransferPlan = z.infer<typeof PortableContextTransferPlanSchema>;
|
|
102
|
+
export declare function portableContextTransferPlanDigest(material: Omit<PortableContextTransferPlan, "digest">): `sha256:${string}`;
|
|
103
|
+
export declare function projectPortableContextPlan(plan: PortableContextPlan): PortableContextTransferPlan;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { CONTRACT_MAX_ARRAY_LENGTH } from "./contract-limits.js";
|
|
3
|
+
import { PortableContextSourceBoundarySchema, PortableConversationContextSchema } from "./portable-context-base.js";
|
|
4
|
+
import { portableContextMessageMetadataDigest, portableContextPlanCommitmentMaterial } from "./portable-context-commitments.js";
|
|
5
|
+
import { PortableContextDestinationSchema, PortableContextPlanSchema } from "./portable-context-plan.js";
|
|
6
|
+
import { idSchema, InputPartSchema, sameStringSet, sha256DigestSchema, wireDigest } from "./portable-context-shared.js";
|
|
7
|
+
const partDecisionSchema = z.strictObject({
|
|
8
|
+
partIndex: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
|
|
9
|
+
action: z.enum(["include", "transform", "omit"]),
|
|
10
|
+
outputDigest: sha256DigestSchema.optional(),
|
|
11
|
+
}).superRefine((part, refinement) => {
|
|
12
|
+
if ((part.action === "transform") !== (part.outputDigest !== undefined)) {
|
|
13
|
+
refinement.addIssue({ code: "custom", message: "only transformed parts require an output commitment" });
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
const messageDecisionSchema = z.strictObject({
|
|
17
|
+
messageId: idSchema,
|
|
18
|
+
action: z.enum(["include", "omit"]),
|
|
19
|
+
parts: z.array(partDecisionSchema).max(CONTRACT_MAX_ARRAY_LENGTH),
|
|
20
|
+
}).superRefine((message, refinement) => {
|
|
21
|
+
if (message.action === "omit" && message.parts.some((part) => part.action !== "omit")) {
|
|
22
|
+
refinement.addIssue({ code: "custom", message: "omitted messages must omit every part" });
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
/** Destination wire plan. The complete source and human explanations remain at the caller. */
|
|
26
|
+
export const PortableContextTransferPlanSchema = z.strictObject({
|
|
27
|
+
kind: z.literal("portable-context-transfer-plan"),
|
|
28
|
+
planId: idSchema,
|
|
29
|
+
reviewDigest: sha256DigestSchema,
|
|
30
|
+
source: z.strictObject({
|
|
31
|
+
source: PortableContextSourceBoundarySchema,
|
|
32
|
+
digest: sha256DigestSchema,
|
|
33
|
+
completeness: z.enum(["complete", "partial"]),
|
|
34
|
+
messages: z.array(z.strictObject({
|
|
35
|
+
messageId: idSchema,
|
|
36
|
+
metadataDigest: sha256DigestSchema.optional(),
|
|
37
|
+
parts: z.array(sha256DigestSchema.nullable()).max(CONTRACT_MAX_ARRAY_LENGTH),
|
|
38
|
+
})).max(CONTRACT_MAX_ARRAY_LENGTH),
|
|
39
|
+
attachments: z.array(z.strictObject({
|
|
40
|
+
messageId: idSchema,
|
|
41
|
+
partIndex: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
|
|
42
|
+
digest: sha256DigestSchema,
|
|
43
|
+
})).max(CONTRACT_MAX_ARRAY_LENGTH),
|
|
44
|
+
}),
|
|
45
|
+
destination: PortableContextDestinationSchema,
|
|
46
|
+
messages: z.array(messageDecisionSchema).max(CONTRACT_MAX_ARRAY_LENGTH),
|
|
47
|
+
context: PortableConversationContextSchema,
|
|
48
|
+
estimatedTokens: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).optional(),
|
|
49
|
+
requiresAcceptance: z.boolean(),
|
|
50
|
+
digest: sha256DigestSchema,
|
|
51
|
+
}).superRefine((plan, refinement) => {
|
|
52
|
+
const invalid = (message) => refinement.addIssue({ code: "custom", message });
|
|
53
|
+
const sourceIds = plan.source.messages.map((message) => message.messageId);
|
|
54
|
+
const decisionIds = plan.messages.map((message) => message.messageId);
|
|
55
|
+
if (new Set(sourceIds).size !== sourceIds.length || new Set(decisionIds).size !== decisionIds.length || !sameStringSet(sourceIds, decisionIds)) {
|
|
56
|
+
invalid("a transfer plan must decide every source message exactly once");
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (wireDigest(plan.source.source) !== wireDigest(plan.context.source))
|
|
60
|
+
invalid("output context source must match the immutable source");
|
|
61
|
+
const outputIds = [];
|
|
62
|
+
const expectedAttachments = [];
|
|
63
|
+
for (const source of plan.source.messages) {
|
|
64
|
+
const decision = plan.messages.find((message) => message.messageId === source.messageId);
|
|
65
|
+
const ordered = [...decision.parts].sort((left, right) => left.partIndex - right.partIndex);
|
|
66
|
+
if (ordered.length !== source.parts.length || ordered.some((part, index) => part.partIndex !== index)) {
|
|
67
|
+
invalid("each source part requires exactly one transfer decision");
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if ((decision.action === "include") !== (source.metadataDigest !== undefined) ||
|
|
71
|
+
ordered.some((part) => (decision.action === "include" && part.action === "include") !== (source.parts[part.partIndex] !== null))) {
|
|
72
|
+
invalid("only selected source parts and metadata may carry individual commitments");
|
|
73
|
+
}
|
|
74
|
+
if (decision.action === "omit")
|
|
75
|
+
continue;
|
|
76
|
+
outputIds.push(source.messageId);
|
|
77
|
+
const output = plan.context.messages.find((message) => message.id === source.messageId);
|
|
78
|
+
const retained = ordered.filter((part) => part.action !== "omit");
|
|
79
|
+
if (!output || portableContextMessageMetadataDigest(output) !== source.metadataDigest || retained.length === 0 || output.parts.length !== retained.length) {
|
|
80
|
+
invalid("selected message metadata and part count must match the source commitments");
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
for (const [outputIndex, part] of retained.entries()) {
|
|
84
|
+
const value = output.parts[outputIndex];
|
|
85
|
+
if (!InputPartSchema.safeParse(value).success || wireDigest(value) !== (part.action === "transform" ? part.outputDigest : source.parts[part.partIndex])) {
|
|
86
|
+
invalid("selected part bytes must match the accepted source or transform commitment");
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (JSON.stringify(outputIds) !== JSON.stringify(plan.context.messages.map((message) => message.id)))
|
|
91
|
+
invalid("selected messages must retain source order");
|
|
92
|
+
for (const attachment of plan.source.attachments) {
|
|
93
|
+
const message = plan.source.messages.find((item) => item.messageId === attachment.messageId);
|
|
94
|
+
if (message === undefined || attachment.partIndex >= message.parts.length) {
|
|
95
|
+
invalid("attachment commitment must reference a source part");
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const decision = plan.messages.find((item) => item.messageId === attachment.messageId);
|
|
99
|
+
const retained = [...decision.parts].sort((a, b) => a.partIndex - b.partIndex).filter((part) => part.action !== "omit");
|
|
100
|
+
const outputIndex = retained.findIndex((part) => part.partIndex === attachment.partIndex);
|
|
101
|
+
if (decision.action !== "include" || retained[outputIndex]?.action !== "include") {
|
|
102
|
+
invalid("only selected source attachments may carry individual commitments");
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
const selected = plan.context.attachments.find((item) => item.messageId === attachment.messageId && item.partIndex === outputIndex && wireDigest({ ...item, partIndex: attachment.partIndex }) === attachment.digest);
|
|
106
|
+
if (selected === undefined)
|
|
107
|
+
invalid("selected attachment must match its source commitment");
|
|
108
|
+
else
|
|
109
|
+
expectedAttachments.push(selected);
|
|
110
|
+
}
|
|
111
|
+
if (wireDigest(expectedAttachments) !== wireDigest(plan.context.attachments))
|
|
112
|
+
invalid("output attachments must exactly match the selected source parts");
|
|
113
|
+
const changes = plan.messages.some((message) => message.action === "omit" || message.parts.some((part) => part.action !== "include"));
|
|
114
|
+
const partial = changes || plan.source.completeness === "partial";
|
|
115
|
+
if (plan.context.completeness !== (partial ? "partial" : "complete") || plan.requiresAcceptance !== partial)
|
|
116
|
+
invalid("changed or partial context requires explicit acceptance");
|
|
117
|
+
const { digest, ...material } = plan;
|
|
118
|
+
if (digest !== wireDigest(material))
|
|
119
|
+
invalid("portable transfer plan digest does not match its commitments");
|
|
120
|
+
});
|
|
121
|
+
export function portableContextTransferPlanDigest(material) {
|
|
122
|
+
return wireDigest(material);
|
|
123
|
+
}
|
|
124
|
+
export function projectPortableContextPlan(plan) {
|
|
125
|
+
const exact = PortableContextPlanSchema.parse(plan);
|
|
126
|
+
return PortableContextTransferPlanSchema.parse({ ...portableContextPlanCommitmentMaterial(exact), digest: exact.digest });
|
|
127
|
+
}
|
|
@@ -2,26 +2,18 @@ import { z } from "zod";
|
|
|
2
2
|
import type { Sha256Digest } from "./agent-candidate.js";
|
|
3
3
|
import type { InputPart } from "./parts.js";
|
|
4
4
|
import { type PortableConversationContext } from "./portable-context-base.js";
|
|
5
|
-
export interface PortableContextDestination {
|
|
6
|
-
runner: string;
|
|
7
|
-
provider: string;
|
|
8
|
-
environmentId: string;
|
|
9
|
-
sessionId: string;
|
|
10
|
-
runId: string;
|
|
11
|
-
executionId: string;
|
|
12
|
-
model?: string;
|
|
13
|
-
profileDigest: Sha256Digest;
|
|
14
|
-
}
|
|
15
5
|
export declare const PortableContextDestinationSchema: z.ZodObject<{
|
|
16
6
|
runner: z.ZodString;
|
|
17
7
|
provider: z.ZodString;
|
|
18
|
-
environmentId: z.ZodString
|
|
8
|
+
environmentId: z.ZodOptional<z.ZodString>;
|
|
19
9
|
sessionId: z.ZodString;
|
|
20
10
|
runId: z.ZodString;
|
|
21
11
|
executionId: z.ZodString;
|
|
22
12
|
model: z.ZodOptional<z.ZodString>;
|
|
23
13
|
profileDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
|
|
14
|
+
workspaceSnapshotDigest: z.ZodOptional<z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>>;
|
|
24
15
|
}, z.core.$strict>;
|
|
16
|
+
export type PortableContextDestination = z.infer<typeof PortableContextDestinationSchema>;
|
|
25
17
|
export interface PortableContextPartPlan {
|
|
26
18
|
partIndex: number;
|
|
27
19
|
action: "include" | "transform" | "omit";
|
|
@@ -96,7 +88,7 @@ export declare const PortableContextMessagePlanSchema: z.ZodObject<{
|
|
|
96
88
|
}, z.core.$strict>;
|
|
97
89
|
export interface PortableContextPlan {
|
|
98
90
|
planId: string;
|
|
99
|
-
/** Full immutable source
|
|
91
|
+
/** Full immutable local source for accepting decisions. Never serialize this plan to a destination. */
|
|
100
92
|
source: PortableConversationContext;
|
|
101
93
|
destination: PortableContextDestination;
|
|
102
94
|
messages: PortableContextMessagePlan[];
|
|
@@ -147,12 +139,13 @@ export declare const PortableContextPlanSchema: z.ZodObject<{
|
|
|
147
139
|
destination: z.ZodObject<{
|
|
148
140
|
runner: z.ZodString;
|
|
149
141
|
provider: z.ZodString;
|
|
150
|
-
environmentId: z.ZodString
|
|
142
|
+
environmentId: z.ZodOptional<z.ZodString>;
|
|
151
143
|
sessionId: z.ZodString;
|
|
152
144
|
runId: z.ZodString;
|
|
153
145
|
executionId: z.ZodString;
|
|
154
146
|
model: z.ZodOptional<z.ZodString>;
|
|
155
147
|
profileDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
|
|
148
|
+
workspaceSnapshotDigest: z.ZodOptional<z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>>;
|
|
156
149
|
}, z.core.$strict>;
|
|
157
150
|
messages: z.ZodArray<z.ZodObject<{
|
|
158
151
|
messageId: z.ZodString;
|
|
@@ -2,15 +2,19 @@ import { z } from "zod";
|
|
|
2
2
|
import { idSchema, InputPartSchema, sha256DigestSchema, sameStringSet, wireDigest, } from "./portable-context-shared.js";
|
|
3
3
|
import { boundedStringSchema, CONTRACT_MAX_ARRAY_LENGTH } from "./contract-limits.js";
|
|
4
4
|
import { PortableConversationContextSchema } from "./portable-context-base.js";
|
|
5
|
+
import { portableContextPlanCommitmentMaterial } from "./portable-context-commitments.js";
|
|
5
6
|
export const PortableContextDestinationSchema = z.strictObject({
|
|
6
7
|
runner: idSchema,
|
|
7
8
|
provider: idSchema,
|
|
8
|
-
|
|
9
|
+
/** Omitted when the provider allocates the environment after acceptance. */
|
|
10
|
+
environmentId: idSchema.optional(),
|
|
9
11
|
sessionId: idSchema,
|
|
10
12
|
runId: idSchema,
|
|
11
13
|
executionId: idSchema,
|
|
12
14
|
model: idSchema.optional(),
|
|
13
15
|
profileDigest: sha256DigestSchema,
|
|
16
|
+
/** Complete portable workspace reference approved with this destination. */
|
|
17
|
+
workspaceSnapshotDigest: sha256DigestSchema.optional(),
|
|
14
18
|
});
|
|
15
19
|
export const PortableContextPartPlanSchema = z
|
|
16
20
|
.strictObject({
|
|
@@ -86,17 +90,7 @@ const PortableContextPlanMaterialSchema = z.strictObject({
|
|
|
86
90
|
});
|
|
87
91
|
export function portableContextPlanDigest(plan) {
|
|
88
92
|
const parsed = PortableContextPlanMaterialSchema.parse(plan);
|
|
89
|
-
return wireDigest(
|
|
90
|
-
planId: parsed.planId,
|
|
91
|
-
source: parsed.source,
|
|
92
|
-
destination: parsed.destination,
|
|
93
|
-
messages: parsed.messages,
|
|
94
|
-
context: parsed.context,
|
|
95
|
-
...(parsed.estimatedTokens === undefined
|
|
96
|
-
? {}
|
|
97
|
-
: { estimatedTokens: parsed.estimatedTokens }),
|
|
98
|
-
requiresAcceptance: parsed.requiresAcceptance,
|
|
99
|
-
});
|
|
93
|
+
return wireDigest(portableContextPlanCommitmentMaterial(parsed));
|
|
100
94
|
}
|
|
101
95
|
export const PortableContextPlanSchema = z
|
|
102
96
|
.strictObject({
|
|
@@ -188,10 +182,14 @@ export const PortableContextPlanSchema = z
|
|
|
188
182
|
message: "output messages do not exactly match the source decisions",
|
|
189
183
|
});
|
|
190
184
|
}
|
|
191
|
-
const expectedAttachments = plan.source.attachments.
|
|
185
|
+
const expectedAttachments = plan.source.attachments.flatMap((attachment) => {
|
|
192
186
|
const message = plan.messages.find((candidate) => candidate.messageId === attachment.messageId);
|
|
193
187
|
const part = message?.parts.find((candidate) => candidate.partIndex === attachment.partIndex);
|
|
194
|
-
|
|
188
|
+
if (message?.action !== "include" || part?.action !== "include")
|
|
189
|
+
return [];
|
|
190
|
+
const retained = [...message.parts].sort((left, right) => left.partIndex - right.partIndex)
|
|
191
|
+
.filter((item) => item.action !== "omit");
|
|
192
|
+
return [{ ...attachment, partIndex: retained.findIndex((item) => item.partIndex === attachment.partIndex) }];
|
|
195
193
|
});
|
|
196
194
|
if (wireDigest(expectedAttachments) !== wireDigest(plan.context.attachments)) {
|
|
197
195
|
refinement.addIssue({
|