@tangle-network/agent-provider-tangle 0.6.2 → 0.7.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.
@@ -1,6 +1,48 @@
1
+ import { CanonicalStreamEventSchema, } from "@tangle-network/agent-interface";
1
2
  import { assertBoundedJson } from "./tangle-contract-safety.js";
2
3
  import { optionalNonEmptyString } from "./tangle-environment-values.js";
3
4
  import { tokenUsageFromData } from "./tangle-result-values.js";
5
+ /** The sidecar sends this envelope when an SSE connection is ready. */
6
+ export function isSandboxConnectionMarker(event) {
7
+ if (!event || typeof event !== "object")
8
+ return false;
9
+ const record = event;
10
+ if (record.type === "connection.established")
11
+ return true;
12
+ const data = record.data;
13
+ return (data !== null &&
14
+ typeof data === "object" &&
15
+ !Array.isArray(data) &&
16
+ data.type === "connection.established");
17
+ }
18
+ /** Read identity from both run frames and /agents/events session envelopes. */
19
+ export function sandboxEventIdentity(event) {
20
+ const record = event;
21
+ const data = record.data;
22
+ if (!data || typeof data !== "object" || Array.isArray(data)) {
23
+ return {};
24
+ }
25
+ const dataRecord = data;
26
+ const properties = dataRecord.properties &&
27
+ typeof dataRecord.properties === "object" &&
28
+ !Array.isArray(dataRecord.properties)
29
+ ? dataRecord.properties
30
+ : undefined;
31
+ const info = properties?.info &&
32
+ typeof properties.info === "object" &&
33
+ !Array.isArray(properties.info)
34
+ ? properties.info
35
+ : undefined;
36
+ return {
37
+ executionId: optionalNonEmptyString(dataRecord.executionId ?? properties?.executionId ?? info?.executionId, "Tangle Sandbox event executionId"),
38
+ sessionId: optionalNonEmptyString(dataRecord.sessionId ??
39
+ dataRecord.sessionID ??
40
+ properties?.sessionId ??
41
+ properties?.sessionID ??
42
+ info?.sessionId ??
43
+ info?.sessionID, "Tangle Sandbox event sessionId"),
44
+ };
45
+ }
4
46
  export function environmentEventFromSandboxEvent(event, expected = {}) {
5
47
  if (!event || typeof event !== "object") {
6
48
  throw new Error("Tangle Sandbox emitted a non-object event");
@@ -30,27 +72,145 @@ export function environmentEventFromSandboxEvent(event, expected = {}) {
30
72
  if (Object.prototype.hasOwnProperty.call(data, "contextTransferReceipt")) {
31
73
  throw new Error("Tangle Sandbox emitted an unsolicited context transfer receipt");
32
74
  }
33
- const eventExecutionId = optionalNonEmptyString(data.executionId, "Tangle Sandbox event executionId");
34
- const eventSessionId = optionalNonEmptyString(data.sessionId, "Tangle Sandbox event sessionId");
75
+ const { executionId: eventExecutionId, sessionId: eventSessionId } = sandboxEventIdentity(event);
35
76
  if (expected.executionId !== undefined &&
36
- (eventExecutionId === undefined || eventExecutionId !== expected.executionId)) {
77
+ ((eventExecutionId === undefined && expected.streamBound !== true) ||
78
+ (eventExecutionId !== undefined && eventExecutionId !== expected.executionId))) {
37
79
  throw new Error("Tangle exact session event identified a different executionId");
38
80
  }
39
81
  if (expected.sessionId !== undefined &&
40
- (eventSessionId === undefined || eventSessionId !== expected.sessionId)) {
82
+ ((eventSessionId === undefined && expected.streamBound !== true) ||
83
+ (eventSessionId !== undefined && eventSessionId !== expected.sessionId))) {
41
84
  throw new Error("Tangle exact session event identified a different sessionId");
42
85
  }
43
86
  const usage = tokenUsageFromData(data);
87
+ const normalized = normalizeSandboxEvent(record.type, data);
44
88
  return {
45
89
  type: record.type,
46
90
  data,
47
91
  ...(typeof record.id === "string" ? { id: record.id } : {}),
92
+ ...(normalized ? { normalized } : {}),
48
93
  // Absent rather than zeroed: an event that reported no usage must not
49
94
  // contribute a total to whatever sums these events.
50
95
  ...(usage ? { usage } : {}),
51
96
  providerEvent: event,
52
97
  };
53
98
  }
99
+ function normalizeSandboxEvent(type, data) {
100
+ const supplied = data.normalized;
101
+ if (supplied !== undefined) {
102
+ const parsed = CanonicalStreamEventSchema.safeParse(supplied);
103
+ if (!parsed.success) {
104
+ throw new Error("Tangle Sandbox emitted an invalid normalized event");
105
+ }
106
+ if (parsed.data.type !== type) {
107
+ throw new Error(`Tangle Sandbox normalized event type "${parsed.data.type}" does not match transport type "${type}"`);
108
+ }
109
+ return parsed.data;
110
+ }
111
+ switch (type) {
112
+ case "status": {
113
+ const status = statusFromSandboxValue(data.status);
114
+ if (!status)
115
+ return undefined;
116
+ return {
117
+ type: "status",
118
+ status,
119
+ ...detailFromSandboxData(data),
120
+ };
121
+ }
122
+ case "message.part.updated": {
123
+ const candidate = {
124
+ type,
125
+ ...(data.part !== undefined ? { part: data.part } : {}),
126
+ ...(typeof data.delta === "string" ? { delta: data.delta } : {}),
127
+ };
128
+ const parsed = CanonicalStreamEventSchema.safeParse(candidate);
129
+ return parsed.success ? parsed.data : undefined;
130
+ }
131
+ case "tool-heartbeat":
132
+ return parseCanonical({
133
+ type,
134
+ toolName: data.toolName,
135
+ partId: data.partId,
136
+ elapsedMs: data.elapsedMs,
137
+ });
138
+ case "tool-slow":
139
+ return parseCanonical({
140
+ type,
141
+ toolName: data.toolName,
142
+ partId: data.partId,
143
+ elapsedMs: data.elapsedMs,
144
+ thresholdMs: data.thresholdMs,
145
+ });
146
+ case "model-processing":
147
+ return parseCanonical({
148
+ type,
149
+ phase: data.phase,
150
+ ...(typeof data.toolName === "string" ? { toolName: data.toolName } : {}),
151
+ ...(typeof data.elapsedMs === "number" ? { elapsedMs: data.elapsedMs } : {}),
152
+ });
153
+ case "warning":
154
+ return parseCanonical({
155
+ type,
156
+ code: data.code,
157
+ message: data.message,
158
+ });
159
+ case "session.updated":
160
+ return parseCanonical({
161
+ type,
162
+ sessionId: data.sessionId ?? data.sessionID,
163
+ ...(typeof data.title === "string" ? { title: data.title } : {}),
164
+ ...(data.time !== undefined ? { time: data.time } : {}),
165
+ });
166
+ case "interaction":
167
+ return parseCanonical({ type, request: data.request });
168
+ case "interaction.cancel":
169
+ return parseCanonical({
170
+ type,
171
+ id: data.id,
172
+ ...(typeof data.reason === "string" ? { reason: data.reason } : {}),
173
+ });
174
+ case "plan.submitted":
175
+ return parseCanonical({ type, plan: data.plan });
176
+ case "result":
177
+ case "done":
178
+ default:
179
+ // These transport frames carry terminal/result data, but they are not
180
+ // members of the provider-neutral canonical event union. The exact
181
+ // result endpoint remains the authoritative result surface.
182
+ return undefined;
183
+ }
184
+ }
185
+ function parseCanonical(value) {
186
+ const parsed = CanonicalStreamEventSchema.safeParse(value);
187
+ return parsed.success ? parsed.data : undefined;
188
+ }
189
+ function statusFromSandboxValue(value) {
190
+ if (typeof value !== "string")
191
+ return undefined;
192
+ switch (value) {
193
+ case "started":
194
+ case "queued":
195
+ return "started";
196
+ case "processing":
197
+ case "running":
198
+ return "processing";
199
+ case "completed":
200
+ case "success":
201
+ return "completed";
202
+ case "failed":
203
+ case "error":
204
+ case "cancelled":
205
+ return "failed";
206
+ default:
207
+ return undefined;
208
+ }
209
+ }
210
+ function detailFromSandboxData(data) {
211
+ const detail = [data.detail, data.error, data.message].find((value) => typeof value === "string" && value.length > 0);
212
+ return detail === undefined ? {} : { detail };
213
+ }
54
214
  function assertBoundedRecord(value) {
55
215
  if (Object.keys(value).length > 256) {
56
216
  throw new Error("Tangle Sandbox event data has too many fields");
@@ -1,6 +1,6 @@
1
1
  import type { PromptOptions, PromptResult } from "@tangle-network/sandbox";
2
2
  import type { AgentTurnInput, AgentTurnResult } from "@tangle-network/agent-interface/environment-provider";
3
- import type { InputPart } from "@tangle-network/agent-interface";
3
+ import type { AgentExactRunControlRef, InputPart } from "@tangle-network/agent-interface";
4
4
  export declare function promptFromTurnInput(input: AgentTurnInput): string | InputPart[];
5
5
  export declare function executionIdFromTurnInput(input: AgentTurnInput): string | undefined;
6
6
  export declare function promptOptionsFromTurnInput(input: AgentTurnInput, target: {
@@ -20,5 +20,6 @@ export declare function agentTurnResultFromPromptRecord(record: ValidatedSandbox
20
20
  contextTransferRequested?: boolean;
21
21
  contextTransferRequest?: import("@tangle-network/agent-interface").ContextTransferRequest;
22
22
  sessionId?: string;
23
+ controlRef?: AgentExactRunControlRef;
23
24
  }): AgentTurnResult;
24
25
  export {};
@@ -31,9 +31,6 @@ export function promptOptionsFromTurnInput(input, target) {
31
31
  if (controlRef.sessionId === undefined || controlRef.executionId === undefined) {
32
32
  throw new Error("Tangle control reference requires exact sessionId and executionId");
33
33
  }
34
- if (controlRef.runId !== controlRef.executionId) {
35
- throw new Error("Tangle control reference requires runId to equal executionId");
36
- }
37
34
  if (input.sessionId !== undefined &&
38
35
  input.sessionId !== controlRef.sessionId) {
39
36
  throw new Error("Tangle sessionId conflicts with the control reference");
@@ -55,6 +52,7 @@ export function promptOptionsFromTurnInput(input, target) {
55
52
  ...(input.context ? { context: input.context } : {}),
56
53
  ...(input.signal ? { signal: input.signal } : {}),
57
54
  ...(executionId ? { executionId } : {}),
55
+ ...(controlRef ? { runControlRef: controlRef } : {}),
58
56
  ...(input.lastEventId ? { lastEventId: input.lastEventId } : {}),
59
57
  ...(input.turnId ? { turnId: input.turnId } : {}),
60
58
  ...(input.detach !== undefined ? { detach: input.detach } : {}),
@@ -118,6 +116,18 @@ const AWAITING_STATUSES = new Set([
118
116
  "awaiting_plan_decision",
119
117
  ]);
120
118
  export function agentTurnResultFromPromptRecord(record, options = {}) {
119
+ const controlRef = options.controlRef
120
+ ? AgentExactRunControlRefSchema.parse(options.controlRef)
121
+ : undefined;
122
+ if (controlRef !== undefined &&
123
+ options.sessionId !== undefined &&
124
+ controlRef.sessionId !== options.sessionId) {
125
+ throw new Error("Tangle prompt result sessionId conflicts with its control reference");
126
+ }
127
+ if (controlRef !== undefined &&
128
+ record.executionId !== controlRef.executionId) {
129
+ throw new Error("Tangle prompt result did not confirm its exact executionId");
130
+ }
121
131
  const text = typeof record.response === "string"
122
132
  ? record.response
123
133
  : typeof record.text === "string"
@@ -155,6 +165,13 @@ export function agentTurnResultFromPromptRecord(record, options = {}) {
155
165
  // "the agent is asking you something" indistinguishable from "the turn
156
166
  // failed", while the sandbox stayed alive waiting for an answer.
157
167
  metadata: {
168
+ ...(controlRef
169
+ ? {
170
+ runId: controlRef.runId,
171
+ executionId: controlRef.executionId,
172
+ requestDigest: controlRef.requestDigest,
173
+ }
174
+ : {}),
158
175
  status: record.status,
159
176
  awaitingInteraction: awaiting,
160
177
  terminal: !awaiting,
@@ -15,7 +15,7 @@ export function createTangleProvider(options) {
15
15
  providerName,
16
16
  })
17
17
  : undefined;
18
- const resolveCapabilities = async () => {
18
+ const resolveDeclaredCapabilities = async () => {
19
19
  const configured = options.capabilities
20
20
  ? typeof options.capabilities === "function"
21
21
  ? await options.capabilities()
@@ -24,14 +24,17 @@ export function createTangleProvider(options) {
24
24
  if (!exactProcess && configured.exactProcess) {
25
25
  throw new Error("Tangle capabilities cannot advertise exactProcess without exactProcess configuration");
26
26
  }
27
- const withExactProcess = exactProcess
27
+ return exactProcess
28
28
  ? {
29
29
  ...configured,
30
30
  exactProcess: { egress: ["blocked", "strict"] },
31
31
  }
32
32
  : configured;
33
- return AgentEnvironmentCapabilitiesSchema.parse(capabilitiesForClient(withExactProcess, options.client));
34
33
  };
34
+ // Provider-boundary document: client-stage facts only. It also validates
35
+ // the configured document, so create() and get() call it before any effect.
36
+ const narrowedProviderCapabilities = (declared) => AgentEnvironmentCapabilitiesSchema.parse(capabilitiesForClient(declared, options.client));
37
+ const resolveCapabilities = async () => narrowedProviderCapabilities(await resolveDeclaredCapabilities());
35
38
  return {
36
39
  name: providerName,
37
40
  ...(exactProcess ? { exactProcess } : {}),
@@ -44,7 +47,11 @@ export function createTangleProvider(options) {
44
47
  if (input.providerOptions && Object.keys(input.providerOptions).length > 0) {
45
48
  throw new Error("Tangle create providerOptions are not supported");
46
49
  }
47
- const capabilities = await resolveCapabilities();
50
+ // The sandbox stage narrows from the declared document, not the
51
+ // provider-boundary one: the client stage cannot observe box-scoped
52
+ // facts, so measured instance facts must decide them per sandbox.
53
+ const declaredCapabilities = await resolveDeclaredCapabilities();
54
+ narrowedProviderCapabilities(declaredCapabilities);
48
55
  const createOptions = options.mapCreateInput?.(input) ??
49
56
  sandboxOptionsFromCreateInput(input, options.defaultBackend ?? "opencode");
50
57
  assertMappedCreateOptions(createOptions);
@@ -76,7 +83,7 @@ export function createTangleProvider(options) {
76
83
  }
77
84
  try {
78
85
  input.signal?.throwIfAborted();
79
- const environment = sandboxInstanceAsEnvironment(box, providerName, options.client, capabilities);
86
+ const environment = sandboxInstanceAsEnvironment(box, providerName, options.client, declaredCapabilities);
80
87
  input.signal?.throwIfAborted();
81
88
  return environment;
82
89
  }
@@ -101,14 +108,14 @@ export function createTangleProvider(options) {
101
108
  async get(id, operation) {
102
109
  assertProviderOperationOptions(operation, "Tangle get");
103
110
  boundedIdentifier(id, "Tangle environment id");
111
+ const declaredCapabilities = await resolveDeclaredCapabilities();
112
+ narrowedProviderCapabilities(declaredCapabilities);
104
113
  operation?.signal?.throwIfAborted();
105
114
  const box = await awaitWithSignal(options.client.get?.(id, operation), operation?.signal);
106
115
  operation?.signal?.throwIfAborted();
107
116
  if (!box || boundedIdentifier(box.id, "Tangle environment id") !== id)
108
117
  return null;
109
- return box
110
- ? sandboxInstanceAsEnvironment(box, providerName, options.client, await resolveCapabilities())
111
- : null;
118
+ return sandboxInstanceAsEnvironment(box, providerName, options.client, declaredCapabilities);
112
119
  },
113
120
  }
114
121
  : {}),
@@ -1,7 +1,8 @@
1
- import type { AgentRunControlRef } from "@tangle-network/agent-interface";
1
+ import type { AgentExactRunControlRef, AgentRunControlRef } from "@tangle-network/agent-interface";
2
2
  import type { AgentSessionRef } from "@tangle-network/agent-interface/environment-provider";
3
- export declare function sessionRefFromSandboxDispatch(dispatched: unknown, providerName: string, environmentId: string, expectedExecutionId: string | undefined, requestDigest?: `sha256:${string}` | undefined, expectedSessionId?: string | undefined): AgentSessionRef;
4
- export declare function retainedSessionControlRef(sessionId: string, executionId: string, provider: string, environmentId: string, requestDigest?: `sha256:${string}`): AgentRunControlRef;
5
- export declare function sessionPromptExecutionId(provider: string, environmentId: string, sessionId: string, turnId: string | undefined): string;
3
+ export declare function sessionRefFromSandboxDispatch(dispatched: unknown, providerName: string, environmentId: string, expectedExecutionId: string | undefined, requestDigest?: `sha256:${string}` | undefined, expectedSessionId?: string | undefined, callerControlRef?: AgentExactRunControlRef | undefined): AgentSessionRef;
4
+ export declare function retainedSessionControlRef(sessionId: string, executionId: string, provider: string, environmentId: string, requestDigest?: `sha256:${string}`, runId?: string): AgentExactRunControlRef;
5
+ export declare function sessionPromptExecutionId(requestDigest: `sha256:${string}`): string;
6
+ export declare function sessionPromptSessionId(provider: string, environmentId: string, turnId: string | undefined): string | undefined;
6
7
  export declare function sameRunControlRef(left: AgentRunControlRef, right: AgentRunControlRef): boolean;
7
- export declare function resolveRetainedSessionControlRef(candidate: AgentRunControlRef | undefined, sessionId: string, provider: string, environmentId: string): AgentRunControlRef | undefined;
8
+ export declare function resolveRetainedSessionControlRef(candidate: AgentRunControlRef | undefined, sessionId: string, provider: string, environmentId: string): AgentExactRunControlRef | undefined;
@@ -1,8 +1,8 @@
1
- import { createHash, randomUUID } from "node:crypto";
1
+ import { createHash } from "node:crypto";
2
2
  import { AgentExactRunControlRefSchema, canonicalCandidateDigest, } from "@tangle-network/agent-interface";
3
3
  import { nonEmptyString } from "./tangle-environment-values.js";
4
4
  import { assertBoundedJson, boundedIdentifier, } from "./tangle-contract-safety.js";
5
- export function sessionRefFromSandboxDispatch(dispatched, providerName, environmentId, expectedExecutionId, requestDigest = undefined, expectedSessionId = undefined) {
5
+ export function sessionRefFromSandboxDispatch(dispatched, providerName, environmentId, expectedExecutionId, requestDigest = undefined, expectedSessionId = undefined, callerControlRef = undefined) {
6
6
  const record = dispatched && typeof dispatched === "object" && !Array.isArray(dispatched)
7
7
  ? dispatched
8
8
  : undefined;
@@ -34,11 +34,26 @@ export function sessionRefFromSandboxDispatch(dispatched, providerName, environm
34
34
  if (record.dispatched !== undefined && typeof record.dispatched !== "boolean") {
35
35
  throw new Error("sandbox dispatch returned an invalid dispatched flag");
36
36
  }
37
+ const accepted = record.runControlRef === undefined
38
+ ? callerControlRef === undefined
39
+ ? undefined
40
+ : AgentExactRunControlRefSchema.safeParse(callerControlRef)
41
+ : AgentExactRunControlRefSchema.safeParse(record.runControlRef);
42
+ if (accepted === undefined || !accepted.success) {
43
+ throw new Error("sandbox dispatch did not return the exact run control reference");
44
+ }
45
+ if (accepted.data.provider !== providerName ||
46
+ accepted.data.environmentId !== environmentId ||
47
+ accepted.data.sessionId !== id ||
48
+ accepted.data.executionId !== executionId ||
49
+ (requestDigest !== undefined && accepted.data.requestDigest !== requestDigest)) {
50
+ throw new Error("sandbox dispatch returned an exact control reference for another run");
51
+ }
52
+ const controlRef = Object.freeze(accepted.data);
37
53
  return {
38
54
  id,
39
55
  provider: providerName,
40
- controlRef: retainedSessionControlRef(id, executionId, providerName, environmentId, requestDigest ??
41
- canonicalCandidateDigest({ provider: providerName, environmentId, id, executionId })),
56
+ controlRef,
42
57
  metadata: {
43
58
  ...(record.status ? { status: record.status } : {}),
44
59
  ...(record.alreadyExisted !== undefined ? { alreadyExisted: record.alreadyExisted } : {}),
@@ -46,24 +61,27 @@ export function sessionRefFromSandboxDispatch(dispatched, providerName, environm
46
61
  },
47
62
  };
48
63
  }
49
- export function retainedSessionControlRef(sessionId, executionId, provider, environmentId, requestDigest) {
50
- return AgentExactRunControlRefSchema.parse({
51
- runId: executionId,
64
+ export function retainedSessionControlRef(sessionId, executionId, provider, environmentId, requestDigest, runId = executionId) {
65
+ return Object.freeze(AgentExactRunControlRefSchema.parse({
66
+ runId,
52
67
  provider,
53
68
  environmentId,
54
69
  sessionId,
55
70
  executionId,
56
71
  requestDigest: requestDigest ??
57
72
  canonicalCandidateDigest({ provider, environmentId, sessionId, executionId }),
58
- });
73
+ }));
74
+ }
75
+ export function sessionPromptExecutionId(requestDigest) {
76
+ return `session-turn-${requestDigest.slice("sha256:".length)}`;
59
77
  }
60
- export function sessionPromptExecutionId(provider, environmentId, sessionId, turnId) {
78
+ export function sessionPromptSessionId(provider, environmentId, turnId) {
61
79
  if (turnId === undefined)
62
- return randomUUID();
80
+ return undefined;
63
81
  const digest = createHash("sha256")
64
- .update(`${provider}\0${environmentId}\0${sessionId}\0${turnId}`)
82
+ .update(`${provider}\0${environmentId}\0${turnId}`)
65
83
  .digest("hex");
66
- return `session-turn-${digest}`;
84
+ return `session-${digest}`;
67
85
  }
68
86
  export function sameRunControlRef(left, right) {
69
87
  return (left.runId === right.runId &&
@@ -82,8 +100,5 @@ export function resolveRetainedSessionControlRef(candidate, sessionId, provider,
82
100
  controlRef.sessionId !== sessionId) {
83
101
  throw new Error("Tangle control reference does not match this session");
84
102
  }
85
- if (controlRef.runId !== controlRef.executionId) {
86
- throw new Error("Tangle session control reference requires runId to equal executionId");
87
- }
88
- return controlRef;
103
+ return retainedSessionControlRef(sessionId, controlRef.executionId, provider, environmentId, controlRef.requestDigest, controlRef.runId);
89
104
  }
@@ -1,5 +1,5 @@
1
1
  import type { BackendType, CreateSandboxOptions, ExecResult as SandboxExecResult, PromptOptions, PromptResult, SandboxEvent } from "@tangle-network/sandbox";
2
- import type { InputPart } from "@tangle-network/agent-interface";
2
+ import type { AgentRunCancellationAcknowledgement, AgentRunCancellationRequest, InputPart } from "@tangle-network/agent-interface";
3
3
  import type { AgentEnvironmentCapabilities, AgentEnvironmentProvider, CreateAgentEnvironmentInput } from "@tangle-network/agent-interface/environment-provider";
4
4
  export interface TangleExactProcessOptions {
5
5
  teamId?: string;
@@ -9,6 +9,17 @@ export interface SandboxClientLike {
9
9
  signal?: AbortSignal;
10
10
  timeoutMs?: number;
11
11
  }): Promise<SandboxInstanceLike>;
12
+ /**
13
+ * SDK HttpClient transport, present on `Sandbox` and `TangleSandboxClient`.
14
+ * Retained control requires it: the provider mints a lazy probe instance
15
+ * over this surface to read the linked SDK's method surface before any
16
+ * sandbox exists. An object-spread wrapper (`{ ...client }`) drops class
17
+ * prototype methods including this one, so such a wrapper never claims
18
+ * retained control; pass the SDK client itself or delegate its methods.
19
+ */
20
+ fetch?(path: string, options?: RequestInit, fetchOptions?: {
21
+ timeoutMs?: number;
22
+ }): Promise<Response>;
12
23
  get?(id: string, requestOptions?: {
13
24
  signal?: AbortSignal;
14
25
  }): Promise<SandboxInstanceLike | null>;
@@ -95,12 +106,6 @@ export interface SandboxInstanceLike {
95
106
  }): Promise<unknown>;
96
107
  };
97
108
  process?: SandboxProcessManagerLike;
98
- checkpoint?(options?: {
99
- signal?: AbortSignal;
100
- } & Record<string, unknown>): Promise<unknown>;
101
- fork?(checkpointId: string, options?: {
102
- signal?: AbortSignal;
103
- } & Record<string, unknown>): Promise<SandboxInstanceLike>;
104
109
  refresh?(options?: {
105
110
  signal?: AbortSignal;
106
111
  }): Promise<void>;
@@ -129,6 +134,9 @@ export interface SandboxSessionLike {
129
134
  }): Promise<{
130
135
  cancelled: boolean;
131
136
  }>;
137
+ cancelRun?(request: AgentRunCancellationRequest, options?: {
138
+ signal?: AbortSignal;
139
+ }): Promise<AgentRunCancellationAcknowledgement>;
132
140
  }
133
141
  export interface TangleProviderOptions {
134
142
  client: SandboxClientLike;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-provider-tangle",
3
- "version": "0.6.2",
3
+ "version": "0.7.0",
4
4
  "description": "AgentEnvironmentProvider adapter for Tangle sandboxes",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -70,7 +70,7 @@
70
70
  "@tangle-network/agent-interface": "0.47.0"
71
71
  },
72
72
  "peerDependencies": {
73
- "@tangle-network/sandbox": ">=0.17.0 <1.0.0"
73
+ "@tangle-network/sandbox": ">=0.19.6 <1.0.0"
74
74
  },
75
75
  "peerDependenciesMeta": {
76
76
  "@tangle-network/sandbox": {
@@ -78,7 +78,9 @@
78
78
  }
79
79
  },
80
80
  "devDependencies": {
81
- "@tangle-network/sandbox": "0.17.0",
81
+ "@tangle-network/agent-eval": "0.145.3",
82
+ "@tangle-network/agent-runtime": "0.132.13",
83
+ "@tangle-network/sandbox": "0.21.1",
82
84
  "@types/node": "25.6.0",
83
85
  "typescript": "^6.0.3",
84
86
  "vitest": "^4.1.5",