@tangle-network/agent-provider-tangle 0.7.2 → 0.8.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 CHANGED
@@ -1,7 +1,8 @@
1
1
  # @tangle-network/agent-provider-tangle
2
2
 
3
3
  Wraps `@tangle-network/sandbox` as an `AgentEnvironmentProvider`.
4
- The peer range is `>=0.19.6 <1.0.0`; retained-run cancellation (`session.cancelRun`) first shipped in 0.19.6, and this package is developed and tested against 0.21.1.
4
+ The peer range is `>=0.19.6 <1.0.0`; retained-run cancellation (`session.cancelRun`) first shipped in 0.19.6, and this package is developed and tested against 0.22.0.
5
+ The floor stays at 0.19.6 although deployment capability discovery (`box.capabilities()`) needs 0.22.0: the adapter feature-detects that method, so a consumer on an older SDK keeps working and claims no retained control instead of failing to load.
5
6
 
6
7
  ```ts
7
8
  import { Sandbox } from '@tangle-network/sandbox'
@@ -18,11 +19,49 @@ Reconstruct an exact session with `environment.session(reference.id, { controlRe
18
19
  Result, replay, and cancel operations select that exact execution instead of whichever execution most recently changed the shared session.
19
20
  Session status with an exact control reference reports a state only when the payload names that execution; a payload bound to a different or unnamed execution reports `unknown`.
20
21
 
21
- The provider claims `retainedControl` only from probed facts.
22
+ ## Two capability documents
23
+
24
+ Capabilities are derived in two stages, and the two stages answer different questions.
25
+
26
+ `provider.capabilities()` answers "what can this provider do against a deployment that backs it".
27
+ It runs before any sandbox exists, so it measures the adapter surface alone and states the adapter's ceiling for everything a deployment decides.
22
28
  A lazy instance handle minted from the linked Sandbox SDK over the client's `fetch` transport must prove `dispatchPrompt`, `session`, and `cancelRun`, and the client must expose `get` for reconstruction; the probe sends no request and creates no resource.
23
- The probe measures the linked SDK's method surface, not the connected service; service-side truth needs the sidecar capability endpoint and is a follow-up.
24
- A client that cannot prove those facts gets no claim, so the runtime rejects retained dispatch before any sandbox is created.
25
- Each concrete sandbox narrows the declared document independently against its own measured method surface, so a capable sandbox keeps retained control even when the provider-level claim failed closed.
29
+ That handle measures the linked SDK's method surface, never the connected service.
30
+ A client that cannot prove those facts gets no retained-control claim, so the runtime rejects retained dispatch before any sandbox is created.
31
+
32
+ `environment.capabilities` answers "what can this environment do", and it is the document to read before offering an operation.
33
+ Composing an environment calls `box.capabilities()` once and derives every deployment-decided claim from that document.
34
+ The operations an environment exposes match its own document exactly: a claim the document does not carry has no method behind it.
35
+ One provider reaches deployments of different ages, which is why the environment carries its own document rather than inheriting the provider's.
36
+
37
+ Each deployment flag this adapter reads gates the claims it backs, and no flag is read that gates nothing:
38
+
39
+ | Deployment flag | Claims it gates |
40
+ | --- | --- |
41
+ | `dispatch.runControlRef` | `streaming.detach`, `streaming.turnIdempotency`, `sessions.continue`, `retainedControl`, `session.cancelRun` |
42
+ | `dispatch.executionIdOnAdmission` | `streaming.detach`, `streaming.turnIdempotency`, `sessions.continue`, `retainedControl`, `session.cancelRun` |
43
+ | `cancel.canonicalRunCancellation` | `sessions.continue`, `retainedControl`, `session.cancelRun` |
44
+ | `cancel.digestBound` | `sessions.continue`, `retainedControl`, `session.cancelRun` |
45
+ | `cancel.idempotent` | `sessions.continue`, `retainedControl`, `session.cancelRun` |
46
+ | `runs.eventReplay` | `streaming.replay`, `sessions.continue`, `retainedControl`, `session.cancelRun` |
47
+ | `runs.executionScopedStatus` | `sessions.continue`, `retainedControl`, `session.cancelRun` |
48
+
49
+ Detached dispatch carries the caller's exact reference and refuses a receipt that does not name the execution back, so it needs both `dispatch` flags and a session handle to reach the run through.
50
+ `sessions.continue`, `retainedControl`, and `session.cancelRun` need every flag in the table, because the capability schema refuses a partial retained-control block and each identity rests on its own flag.
51
+ A claim takes its operation with it: `streaming.detach` gates `dispatch()`, and `session()` stands while any of `streaming.detach`, `streaming.replay`, or `sessions.continue` stands.
52
+ A missing flag means unknown, and unknown is never a claim.
53
+
54
+ Four inputs claim nothing at all: a Sandbox SDK older than 0.22.0, a sandbox that is not running, a `null` document (a deployment predating capability discovery, or one serving a newer schema this SDK cannot read), and a capability read that fails.
55
+ In each case the environment omits `dispatch` and `session`, so a caller never selects an action the deployment will reject.
56
+ A document that leaves a flag unset is not one of them.
57
+ It drops the claims that flag gates and keeps every claim its remaining flags back.
58
+ A document without `cancel.digestBound` still carries `streaming.detach` and `streaming.replay`, and its environment still exposes `dispatch` and `session`.
59
+ A failed read claims nothing rather than failing `create()`: discovery runs against a sandbox a cold provision has already paid for, and a transport failure is not evidence about the deployment.
60
+ The failure is reported on the warning channel.
61
+
62
+ The document is measured once, when the environment is composed.
63
+ A sandbox that is not yet running cannot answer, so an environment composed during provisioning claims nothing and keeps claiming nothing — the exposed operations and the document are composed together, and a caller may already hold either one.
64
+ Compose the environment again through `provider.get(id)` once the sandbox is running.
26
65
 
27
66
  Pass the SDK client itself when retained control matters.
28
67
  An object-spread wrapper (`{ ...client }`) drops class prototype methods, including `fetch`, so the provider treats the wrapper as a non-SDK client and claims no retained control.
@@ -1,19 +1,22 @@
1
1
  import type { AgentEnvironmentCapabilities, HarnessType } from "@tangle-network/agent-interface";
2
2
  import type { SandboxClientLike, SandboxInstanceLike } from "./tangle-types.js";
3
+ import type { DeploymentCapabilitySupport } from "./tangle-deployment-capabilities.js";
3
4
  /**
4
5
  * The full capability document this adapter supports when the Sandbox client
5
6
  * implements every optional method.
6
7
  *
7
- * This is an upper bound, not a claim. `capabilitiesForClient()` and
8
- * `capabilitiesForSandbox()` narrow it to what the deployment actually
9
- * exposes, because a capability the client cannot back becomes an action the
10
- * caller selects and finds missing.
8
+ * This is an upper bound, not a claim. `capabilitiesForClient()` narrows it
9
+ * to the adapter surface, and `capabilitiesForSandbox()` narrows it again to
10
+ * what the deployment behind one sandbox reports, because a capability
11
+ * nothing backs becomes an action the caller selects and finds missing.
11
12
  */
12
13
  export declare function defaultTangleSandboxCapabilities(harness?: HarnessType): AgentEnvironmentCapabilities;
13
14
  /**
14
- * Deployment facts that gate declared capabilities. Every fact defaults to
15
- * false when it cannot be established; a false fact clears the matching
16
- * declared capability.
15
+ * Adapter-surface facts that gate declared capabilities: which methods this
16
+ * process can actually call. Every fact defaults to false when it cannot be
17
+ * established; a false fact clears the matching declared capability. These
18
+ * facts bound the claim from above — what the connected deployment honors is
19
+ * a separate fact, carried by `DeploymentCapabilitySupport`.
17
20
  */
18
21
  export interface SandboxCapabilitySupport {
19
22
  /** The provider can rebuild an environment by id (`client.get`). */
@@ -29,29 +32,64 @@ export interface SandboxCapabilitySupport {
29
32
  }
30
33
  export declare function sandboxCapabilitySupport(box: SandboxInstanceLike, client: SandboxClientLike): SandboxCapabilitySupport;
31
34
  /**
32
- * Establish client-stage facts before any sandbox exists. Two sources:
33
- * the client's own members (get, describePlacement) and, for an SDK-backed
34
- * client, the linked SDK surface via `linkedSdkProbeInstance`. Retained
35
- * control fails closed: without a probe handle nothing proves `cancelRun`,
36
- * so the provider must not claim it. Box-scoped workspace and streaming
37
- * facts stay at the declared upper bound when no handle can be minted
38
- * each concrete sandbox re-narrows them in `capabilitiesForSandbox`.
35
+ * Establish client-stage facts before any sandbox exists. Two sources: the
36
+ * client's own members (get, describePlacement) and, for an SDK-backed client,
37
+ * the linked SDK surface via `linkedSdkProbeInstance`. These facts bound what
38
+ * the adapter can execute; the deployment that decides whether an execution is
39
+ * honored is unreachable at this stage. Box-scoped workspace facts stay at the
40
+ * declared upper bound when no handle can be minted, and each concrete sandbox
41
+ * re-measures them in `capabilitiesForSandbox`.
39
42
  */
40
43
  export declare function clientCapabilitySupport(client: SandboxClientLike): SandboxCapabilitySupport;
44
+ /**
45
+ * Decide whether retained control may be claimed.
46
+ *
47
+ * Two independent fact sets must agree. The adapter surface must be able to
48
+ * execute it: exact dispatch, a session handle, canonical cancellation, and
49
+ * environment reconstruction by id. The connected deployment must honor it:
50
+ * exact dispatch, canonical cancellation, event replay, and execution-scoped
51
+ * status together. A deployment that leaves any of the four unreported refuses
52
+ * the claim even when every local method exists, because a method this process
53
+ * can call is not a run the service retains.
54
+ */
55
+ export declare function tangleRetainedControlSupported(declared: AgentEnvironmentCapabilities, support: SandboxCapabilitySupport, deployment: DeploymentCapabilitySupport): boolean;
41
56
  /**
42
57
  * Narrow a declared capability document to established facts.
43
58
  *
44
59
  * Braid derives product actions from these flags, so an over-claimed flag is
45
- * an offered action that throws at the moment the user selects it. Retained
46
- * control requires the complete fact set: exact dispatch, a session handle,
47
- * canonical cancellation, and environment reconstruction by id.
60
+ * an offered action that throws at the moment the user selects it. Each flag
61
+ * takes the narrowest fact set it rests on. Detached dispatch carries the
62
+ * caller's exact `runControlRef` and refuses a receipt that does not echo the
63
+ * execution back, and it is only reachable through a session handle, so
64
+ * `streaming.detach` needs exact dispatch from the deployment plus both local
65
+ * methods. Cursor replay needs the deployment's own event replay, and turn
66
+ * idempotency needs the deployment to honor the exact reference that
67
+ * identifies a repeated turn.
48
68
  */
49
- export declare function narrowedTangleCapabilities(declared: AgentEnvironmentCapabilities, support: SandboxCapabilitySupport): AgentEnvironmentCapabilities;
69
+ export declare function narrowedTangleCapabilities(declared: AgentEnvironmentCapabilities, support: SandboxCapabilitySupport, deployment: DeploymentCapabilitySupport): AgentEnvironmentCapabilities;
50
70
  /**
51
71
  * Narrow provider-level claims to facts the client can prove before any
52
- * sandbox exists. `clientCapabilitySupport` documents which facts stay at
53
- * the declared upper bound when the client offers no probe surface.
72
+ * sandbox exists.
73
+ *
74
+ * This document answers "what can this provider do against a deployment that
75
+ * backs it", which is the question a caller selects a provider on. No sandbox
76
+ * exists here, so the deployment input is the adapter's ceiling and this
77
+ * document is a bound, never a statement about one environment. Each concrete
78
+ * sandbox reads its own deployment in `capabilitiesForSandbox` and publishes
79
+ * the answer as `AgentEnvironment.capabilities`, which is the document a
80
+ * caller reads to decide which operation to offer against that environment.
54
81
  */
55
82
  export declare function capabilitiesForClient(declared: AgentEnvironmentCapabilities, client: SandboxClientLike): AgentEnvironmentCapabilities;
56
- /** Narrow a declared capability document to what this Sandbox instance backs. */
57
- export declare function capabilitiesForSandbox(declared: AgentEnvironmentCapabilities, support: SandboxCapabilitySupport): AgentEnvironmentCapabilities;
83
+ /**
84
+ * Freeze a capability document before an environment publishes it.
85
+ *
86
+ * The document and the operations an environment exposes are decided together
87
+ * and must stay equal, so the copy a caller holds cannot be writable: a
88
+ * mutated flag would describe a surface this environment does not have.
89
+ */
90
+ export declare function frozenCapabilityDocument<T>(document: T): T;
91
+ /**
92
+ * Narrow a declared capability document to what this Sandbox instance backs
93
+ * and what the deployment behind it reports.
94
+ */
95
+ export declare function capabilitiesForSandbox(declared: AgentEnvironmentCapabilities, support: SandboxCapabilitySupport, deployment: DeploymentCapabilitySupport): AgentEnvironmentCapabilities;
@@ -1,13 +1,14 @@
1
1
  import { harnessSystemPromptIntents } from "@tangle-network/agent-interface";
2
2
  import { SandboxInstance } from "@tangle-network/sandbox";
3
+ import { ADAPTER_CEILING_DEPLOYMENT, deploymentBacksRetainedControl, } from "./tangle-deployment-capabilities.js";
3
4
  /**
4
5
  * The full capability document this adapter supports when the Sandbox client
5
6
  * implements every optional method.
6
7
  *
7
- * This is an upper bound, not a claim. `capabilitiesForClient()` and
8
- * `capabilitiesForSandbox()` narrow it to what the deployment actually
9
- * exposes, because a capability the client cannot back becomes an action the
10
- * caller selects and finds missing.
8
+ * This is an upper bound, not a claim. `capabilitiesForClient()` narrows it
9
+ * to the adapter surface, and `capabilitiesForSandbox()` narrows it again to
10
+ * what the deployment behind one sandbox reports, because a capability
11
+ * nothing backs becomes an action the caller selects and finds missing.
11
12
  */
12
13
  export function defaultTangleSandboxCapabilities(harness) {
13
14
  return {
@@ -35,10 +36,11 @@ export function defaultTangleSandboxCapabilities(harness) {
35
36
  streaming: { live: true, replay: true, detach: true, turnIdempotency: true },
36
37
  // Retained control is declared as intent here and stripped by narrowing
37
38
  // wherever the facts cannot prove dispatchPrompt, session, cancelRun,
38
- // and environment reconstruction by id. The four sub-flags are
39
- // all-or-nothing by design: this adapter implements the identities
39
+ // and environment reconstruction by id, or wherever the deployment does
40
+ // not report the run-control and cancellation flags. The four sub-flags
41
+ // are all-or-nothing by design: this adapter implements the identities
40
42
  // together over one Sandbox surface, and the capability schema refuses
41
- // a partial block, so they stand or fall on the same probed fact set.
43
+ // a partial block, so they stand or fall on the same fact set.
42
44
  sessions: { continue: true, list: false, messages: false },
43
45
  retainedControl: {
44
46
  exactRunIdentity: true,
@@ -86,13 +88,14 @@ export function sandboxCapabilitySupport(box, client) {
86
88
  /**
87
89
  * Mint a lazy instance handle from the sandbox SDK linked into this process.
88
90
  * The handle measures the LINKED SDK's instance and session method surface —
89
- * an adapter-capability fact, not deployment truth. It is valid exactly when
90
- * the client is SDK-backed (carries the SDK `fetch` transport), because the
91
+ * an adapter-surface fact and therefore an upper bound, never a claim that
92
+ * the connected service honors those methods. It is valid exactly when the
93
+ * client is SDK-backed (carries the SDK `fetch` transport), because the
91
94
  * sandboxes such a client returns are instances of these same classes.
92
- * Deployment truth (what the connected service honors) needs the sidecar
93
- * capability endpoint and is a follow-up. The handle and its probe session
94
- * never leave the process: construction and `session(id)` are lazy in the
95
- * SDK, so no request is sent and no billable resource is created.
95
+ * Deployment truth arrives per-sandbox, from `box.capabilities()`, and can
96
+ * only narrow this bound. The handle and its probe session never leave the
97
+ * process: construction and `session(id)` are lazy in the SDK, so no request
98
+ * is sent and no billable resource is created.
96
99
  */
97
100
  function linkedSdkProbeInstance(client) {
98
101
  if (typeof client.fetch !== "function")
@@ -109,13 +112,13 @@ function linkedSdkProbeInstance(client) {
109
112
  }
110
113
  }
111
114
  /**
112
- * Establish client-stage facts before any sandbox exists. Two sources:
113
- * the client's own members (get, describePlacement) and, for an SDK-backed
114
- * client, the linked SDK surface via `linkedSdkProbeInstance`. Retained
115
- * control fails closed: without a probe handle nothing proves `cancelRun`,
116
- * so the provider must not claim it. Box-scoped workspace and streaming
117
- * facts stay at the declared upper bound when no handle can be minted
118
- * each concrete sandbox re-narrows them in `capabilitiesForSandbox`.
115
+ * Establish client-stage facts before any sandbox exists. Two sources: the
116
+ * client's own members (get, describePlacement) and, for an SDK-backed client,
117
+ * the linked SDK surface via `linkedSdkProbeInstance`. These facts bound what
118
+ * the adapter can execute; the deployment that decides whether an execution is
119
+ * honored is unreachable at this stage. Box-scoped workspace facts stay at the
120
+ * declared upper bound when no handle can be minted, and each concrete sandbox
121
+ * re-measures them in `capabilitiesForSandbox`.
119
122
  */
120
123
  export function clientCapabilitySupport(client) {
121
124
  const probe = linkedSdkProbeInstance(client);
@@ -134,22 +137,43 @@ export function clientCapabilitySupport(client) {
134
137
  };
135
138
  }
136
139
  /**
137
- * Narrow a declared capability document to established facts.
140
+ * Decide whether retained control may be claimed.
138
141
  *
139
- * Braid derives product actions from these flags, so an over-claimed flag is
140
- * an offered action that throws at the moment the user selects it. Retained
141
- * control requires the complete fact set: exact dispatch, a session handle,
142
- * canonical cancellation, and environment reconstruction by id.
142
+ * Two independent fact sets must agree. The adapter surface must be able to
143
+ * execute it: exact dispatch, a session handle, canonical cancellation, and
144
+ * environment reconstruction by id. The connected deployment must honor it:
145
+ * exact dispatch, canonical cancellation, event replay, and execution-scoped
146
+ * status together. A deployment that leaves any of the four unreported refuses
147
+ * the claim even when every local method exists, because a method this process
148
+ * can call is not a run the service retains.
143
149
  */
144
- export function narrowedTangleCapabilities(declared, support) {
145
- const supportsRetainedControl = declared.sessions.continue === true &&
150
+ export function tangleRetainedControlSupported(declared, support, deployment) {
151
+ return (deploymentBacksRetainedControl(deployment) &&
152
+ declared.sessions.continue === true &&
146
153
  declared.streaming.detach === true &&
147
154
  declared.streaming.replay === true &&
148
155
  declared.streaming.turnIdempotency === true &&
149
156
  support.reconstruct &&
150
157
  support.dispatchPrompt &&
151
158
  support.session &&
152
- support.cancelRun;
159
+ support.cancelRun);
160
+ }
161
+ /**
162
+ * Narrow a declared capability document to established facts.
163
+ *
164
+ * Braid derives product actions from these flags, so an over-claimed flag is
165
+ * an offered action that throws at the moment the user selects it. Each flag
166
+ * takes the narrowest fact set it rests on. Detached dispatch carries the
167
+ * caller's exact `runControlRef` and refuses a receipt that does not echo the
168
+ * execution back, and it is only reachable through a session handle, so
169
+ * `streaming.detach` needs exact dispatch from the deployment plus both local
170
+ * methods. Cursor replay needs the deployment's own event replay, and turn
171
+ * idempotency needs the deployment to honor the exact reference that
172
+ * identifies a repeated turn.
173
+ */
174
+ export function narrowedTangleCapabilities(declared, support, deployment) {
175
+ const supportsRetainedControl = tangleRetainedControlSupported(declared, support, deployment);
176
+ const supportsDetach = support.dispatchPrompt && support.session && deployment.exactDispatch;
153
177
  // A cleared fact forces false; a held fact passes the declared value
154
178
  // through unchanged, so a malformed declaration still reaches the schema
155
179
  // at the provider boundary instead of being laundered into a boolean.
@@ -157,9 +181,11 @@ export function narrowedTangleCapabilities(declared, support) {
157
181
  ...declared,
158
182
  streaming: {
159
183
  ...declared.streaming,
160
- detach: support.dispatchPrompt ? declared.streaming.detach : false,
161
- replay: support.session ? declared.streaming.replay : false,
162
- turnIdempotency: support.session
184
+ detach: supportsDetach ? declared.streaming.detach : false,
185
+ replay: support.session && deployment.eventReplay
186
+ ? declared.streaming.replay
187
+ : false,
188
+ turnIdempotency: deployment.exactDispatch
163
189
  ? declared.streaming.turnIdempotency
164
190
  : false,
165
191
  },
@@ -197,13 +223,37 @@ export function narrowedTangleCapabilities(declared, support) {
197
223
  }
198
224
  /**
199
225
  * Narrow provider-level claims to facts the client can prove before any
200
- * sandbox exists. `clientCapabilitySupport` documents which facts stay at
201
- * the declared upper bound when the client offers no probe surface.
226
+ * sandbox exists.
227
+ *
228
+ * This document answers "what can this provider do against a deployment that
229
+ * backs it", which is the question a caller selects a provider on. No sandbox
230
+ * exists here, so the deployment input is the adapter's ceiling and this
231
+ * document is a bound, never a statement about one environment. Each concrete
232
+ * sandbox reads its own deployment in `capabilitiesForSandbox` and publishes
233
+ * the answer as `AgentEnvironment.capabilities`, which is the document a
234
+ * caller reads to decide which operation to offer against that environment.
202
235
  */
203
236
  export function capabilitiesForClient(declared, client) {
204
- return narrowedTangleCapabilities(declared, clientCapabilitySupport(client));
237
+ return narrowedTangleCapabilities(declared, clientCapabilitySupport(client), ADAPTER_CEILING_DEPLOYMENT);
238
+ }
239
+ /**
240
+ * Freeze a capability document before an environment publishes it.
241
+ *
242
+ * The document and the operations an environment exposes are decided together
243
+ * and must stay equal, so the copy a caller holds cannot be writable: a
244
+ * mutated flag would describe a surface this environment does not have.
245
+ */
246
+ export function frozenCapabilityDocument(document) {
247
+ if (document === null || typeof document !== "object")
248
+ return document;
249
+ for (const value of Object.values(document))
250
+ frozenCapabilityDocument(value);
251
+ return Object.freeze(document);
205
252
  }
206
- /** Narrow a declared capability document to what this Sandbox instance backs. */
207
- export function capabilitiesForSandbox(declared, support) {
208
- return narrowedTangleCapabilities(declared, support);
253
+ /**
254
+ * Narrow a declared capability document to what this Sandbox instance backs
255
+ * and what the deployment behind it reports.
256
+ */
257
+ export function capabilitiesForSandbox(declared, support, deployment) {
258
+ return narrowedTangleCapabilities(declared, support, deployment);
209
259
  }
@@ -0,0 +1,83 @@
1
+ import type { SandboxInstanceLike, SandboxRuntimeCapabilityDocument } from "./tangle-types.js";
2
+ /**
3
+ * What the connected deployment reports about the run operations this adapter
4
+ * builds on top of a sandbox.
5
+ *
6
+ * Each fact is the conjunction of every document flag its operation needs, so
7
+ * a document that reports part of an operation reports none of it. A flag the
8
+ * document leaves unset is unknown, and unknown is never a claim: an absent,
9
+ * unreadable, or partial document leaves every fact false.
10
+ */
11
+ export interface DeploymentCapabilitySupport {
12
+ /**
13
+ * Run requests carry the caller's exact `runControlRef`, and admission
14
+ * echoes the executionId. Detached dispatch needs both: it sends the
15
+ * reference and refuses a receipt that does not name the execution back.
16
+ */
17
+ readonly exactDispatch: boolean;
18
+ /** Cancellation is canonical, digest-bound, and idempotent under replay. */
19
+ readonly canonicalCancellation: boolean;
20
+ /** Buffered run events replay by execution under stable event ids. */
21
+ readonly eventReplay: boolean;
22
+ /** Status and results select one execution, not the session's latest. */
23
+ readonly executionScopedStatus: boolean;
24
+ }
25
+ /**
26
+ * The deployment backs nothing.
27
+ *
28
+ * This is the client stage, where no sandbox exists to ask, and it is also
29
+ * every answer that fails to establish a fact: no capability method, a sandbox
30
+ * that cannot answer, a `null` document, a failed request, and a document that
31
+ * leaves a required flag unset.
32
+ */
33
+ export declare const UNPROVEN_DEPLOYMENT: DeploymentCapabilitySupport;
34
+ /**
35
+ * The client stage's deployment input: this adapter's ceiling, not a fact.
36
+ *
37
+ * No sandbox exists before create, so no deployment can be asked, and the
38
+ * provider document answers a different question from the environment's — it
39
+ * states what this adapter offers against a deployment that backs it, which is
40
+ * what a caller selects a provider on. `AgentEnvironment.capabilities` carries
41
+ * the measured answer for one sandbox, and every operation an environment
42
+ * exposes follows that document, never this ceiling.
43
+ *
44
+ * The ceiling stays wide deliberately. A provider document that claimed
45
+ * nothing before create would refuse retained runs against every deployment,
46
+ * including the ones that back them, because a caller must read the provider
47
+ * document to decide whether to start one at all.
48
+ */
49
+ export declare const ADAPTER_CEILING_DEPLOYMENT: DeploymentCapabilitySupport;
50
+ /**
51
+ * Read the deployment facts out of a capability document. Every flag this
52
+ * adapter acts on is read here; the shape carries no flag it does not act on.
53
+ */
54
+ export declare function deploymentCapabilitySupport(document: SandboxRuntimeCapabilityDocument | null | undefined): DeploymentCapabilitySupport;
55
+ /**
56
+ * Establish the deployment facts for one sandbox through capability
57
+ * discovery. Every outcome but the caller's own abort resolves to a fact set.
58
+ *
59
+ * Three inputs answer without a request: a Sandbox SDK older than 0.22.0,
60
+ * which carries no `capabilities` method; a sandbox that is not running, whose
61
+ * capability route can only answer with a state error; and a `null` document,
62
+ * which is a deployment predating capability discovery or one serving a schema
63
+ * this SDK cannot read.
64
+ *
65
+ * A failed request resolves the same way. Discovery runs against a sandbox
66
+ * that a cold provision has just paid for, and a transport failure or a
67
+ * defective document is not evidence about the run operations: failing here
68
+ * would trade an unknown for the certain loss of that sandbox. The failure
69
+ * reaches the warning channel, and the environment then offers no operation
70
+ * the document did not prove.
71
+ */
72
+ export declare function readDeploymentCapabilitySupport(box: SandboxInstanceLike, options?: {
73
+ signal?: AbortSignal;
74
+ }): Promise<DeploymentCapabilitySupport>;
75
+ /**
76
+ * Whether the deployment backs the complete retained-control identity set.
77
+ * The capability schema refuses a partial retained-control block, and each
78
+ * identity rests on its own deployment fact, so they stand together: exact
79
+ * dispatch for run identity, execution-scoped status for result identity,
80
+ * event replay for event identity, and canonical cancellation for
81
+ * cancellation idempotency.
82
+ */
83
+ export declare function deploymentBacksRetainedControl(deployment: DeploymentCapabilitySupport): boolean;
@@ -0,0 +1,103 @@
1
+ import { statusFromUnknown } from "./tangle-environment-values.js";
2
+ import { awaitWithSignal } from "./tangle-contract-safety.js";
3
+ /**
4
+ * The deployment backs nothing.
5
+ *
6
+ * This is the client stage, where no sandbox exists to ask, and it is also
7
+ * every answer that fails to establish a fact: no capability method, a sandbox
8
+ * that cannot answer, a `null` document, a failed request, and a document that
9
+ * leaves a required flag unset.
10
+ */
11
+ export const UNPROVEN_DEPLOYMENT = {
12
+ exactDispatch: false,
13
+ canonicalCancellation: false,
14
+ eventReplay: false,
15
+ executionScopedStatus: false,
16
+ };
17
+ /**
18
+ * The client stage's deployment input: this adapter's ceiling, not a fact.
19
+ *
20
+ * No sandbox exists before create, so no deployment can be asked, and the
21
+ * provider document answers a different question from the environment's — it
22
+ * states what this adapter offers against a deployment that backs it, which is
23
+ * what a caller selects a provider on. `AgentEnvironment.capabilities` carries
24
+ * the measured answer for one sandbox, and every operation an environment
25
+ * exposes follows that document, never this ceiling.
26
+ *
27
+ * The ceiling stays wide deliberately. A provider document that claimed
28
+ * nothing before create would refuse retained runs against every deployment,
29
+ * including the ones that back them, because a caller must read the provider
30
+ * document to decide whether to start one at all.
31
+ */
32
+ export const ADAPTER_CEILING_DEPLOYMENT = {
33
+ exactDispatch: true,
34
+ canonicalCancellation: true,
35
+ eventReplay: true,
36
+ executionScopedStatus: true,
37
+ };
38
+ /**
39
+ * Read the deployment facts out of a capability document. Every flag this
40
+ * adapter acts on is read here; the shape carries no flag it does not act on.
41
+ */
42
+ export function deploymentCapabilitySupport(document) {
43
+ if (!document || typeof document !== "object")
44
+ return UNPROVEN_DEPLOYMENT;
45
+ return {
46
+ exactDispatch: document.dispatch?.runControlRef === true &&
47
+ document.dispatch?.executionIdOnAdmission === true,
48
+ canonicalCancellation: document.cancel?.canonicalRunCancellation === true &&
49
+ document.cancel?.digestBound === true &&
50
+ document.cancel?.idempotent === true,
51
+ eventReplay: document.runs?.eventReplay === true,
52
+ executionScopedStatus: document.runs?.executionScopedStatus === true,
53
+ };
54
+ }
55
+ /**
56
+ * Establish the deployment facts for one sandbox through capability
57
+ * discovery. Every outcome but the caller's own abort resolves to a fact set.
58
+ *
59
+ * Three inputs answer without a request: a Sandbox SDK older than 0.22.0,
60
+ * which carries no `capabilities` method; a sandbox that is not running, whose
61
+ * capability route can only answer with a state error; and a `null` document,
62
+ * which is a deployment predating capability discovery or one serving a schema
63
+ * this SDK cannot read.
64
+ *
65
+ * A failed request resolves the same way. Discovery runs against a sandbox
66
+ * that a cold provision has just paid for, and a transport failure or a
67
+ * defective document is not evidence about the run operations: failing here
68
+ * would trade an unknown for the certain loss of that sandbox. The failure
69
+ * reaches the warning channel, and the environment then offers no operation
70
+ * the document did not prove.
71
+ */
72
+ export async function readDeploymentCapabilitySupport(box, options) {
73
+ if (typeof box.capabilities !== "function")
74
+ return UNPROVEN_DEPLOYMENT;
75
+ if (statusFromUnknown(box.status) !== "running")
76
+ return UNPROVEN_DEPLOYMENT;
77
+ options?.signal?.throwIfAborted();
78
+ let document;
79
+ try {
80
+ document = await awaitWithSignal(box.capabilities(), options?.signal);
81
+ }
82
+ catch (error) {
83
+ options?.signal?.throwIfAborted();
84
+ console.warn(`Tangle capability discovery failed for sandbox ${box.id}: the deployment backs nothing`, error);
85
+ return UNPROVEN_DEPLOYMENT;
86
+ }
87
+ options?.signal?.throwIfAborted();
88
+ return deploymentCapabilitySupport(document);
89
+ }
90
+ /**
91
+ * Whether the deployment backs the complete retained-control identity set.
92
+ * The capability schema refuses a partial retained-control block, and each
93
+ * identity rests on its own deployment fact, so they stand together: exact
94
+ * dispatch for run identity, execution-scoped status for result identity,
95
+ * event replay for event identity, and canonical cancellation for
96
+ * cancellation idempotency.
97
+ */
98
+ export function deploymentBacksRetainedControl(deployment) {
99
+ return (deployment.exactDispatch &&
100
+ deployment.canonicalCancellation &&
101
+ deployment.eventReplay &&
102
+ deployment.executionScopedStatus);
103
+ }
@@ -9,5 +9,11 @@ type ExactExecutionEventStream = (options: {
9
9
  signal?: AbortSignal;
10
10
  controlRef?: AgentExactRunControlRef;
11
11
  }) => AsyncIterable<SandboxEvent>;
12
- export declare function sandboxSessionAsAgentSession(session: SandboxSessionLike, controlRef: AgentRunControlRef | undefined, provider: string, environmentId: string, dispatch?: (input: AgentTurnInput) => Promise<AgentSessionRef>, exactExecutionEvents?: ExactExecutionEventStream): AgentSession;
12
+ /**
13
+ * @param retainedControl Whether the environment's narrowed capability
14
+ * document grants retained control. Canonical cancellation is offered only
15
+ * under that grant: a `cancelRun` method the deployment does not honor is an
16
+ * action the caller selects and finds rejected on the wire.
17
+ */
18
+ export declare function sandboxSessionAsAgentSession(session: SandboxSessionLike, controlRef: AgentRunControlRef | undefined, provider: string, environmentId: string, dispatch: ((input: AgentTurnInput) => Promise<AgentSessionRef>) | undefined, exactExecutionEvents: ExactExecutionEventStream | undefined, retainedControl: boolean): AgentSession;
13
19
  export {};
@@ -8,12 +8,18 @@ import { executionBoundSessionStatus, sessionStatusFromUnknown, } from "./tangle
8
8
  import { awaitWithSignal, boundedIdentifier, } from "./tangle-contract-safety.js";
9
9
  import { assertOptionKeys } from "./tangle-environment-validation.js";
10
10
  import { hasReplayPayload, interruptExecutionAfterAbort, sessionPromptRequestDigest, } from "./tangle-environment-control.js";
11
- export function sandboxSessionAsAgentSession(session, controlRef, provider, environmentId, dispatch, exactExecutionEvents) {
11
+ /**
12
+ * @param retainedControl Whether the environment's narrowed capability
13
+ * document grants retained control. Canonical cancellation is offered only
14
+ * under that grant: a `cancelRun` method the deployment does not honor is an
15
+ * action the caller selects and finds rejected on the wire.
16
+ */
17
+ export function sandboxSessionAsAgentSession(session, controlRef, provider, environmentId, dispatch, exactExecutionEvents, retainedControl) {
12
18
  let activeControlRef = controlRef
13
19
  ? resolveRetainedSessionControlRef(controlRef, session.id, provider, environmentId)
14
20
  : undefined;
15
21
  let promptInFlight = false;
16
- const cancelRunMethod = session.cancelRun;
22
+ const cancelRunMethod = retainedControl ? session.cancelRun : undefined;
17
23
  const cancelRun = typeof cancelRunMethod === "function"
18
24
  ? async (request, options) => {
19
25
  assertOptionKeys(options, ["signal"], "Tangle exact session cancellation");
@@ -1,3 +1,22 @@
1
1
  import type { AgentEnvironment, AgentEnvironmentCapabilities } from "@tangle-network/agent-interface/environment-provider";
2
2
  import type { SandboxClientLike, SandboxInstanceLike } from "./tangle-types.js";
3
- export declare function sandboxInstanceAsEnvironment(box: SandboxInstanceLike, providerName: string, client: SandboxClientLike, declaredCapabilities: AgentEnvironmentCapabilities): AgentEnvironment;
3
+ /**
4
+ * Compose one concrete sandbox into an environment.
5
+ *
6
+ * This is the only stage that can read deployment truth, so it does: one
7
+ * `GET /capabilities` against the sandbox decides retained control, and the
8
+ * environment then exposes exactly the operations both the adapter surface
9
+ * and the deployment back. A deployment that cannot disclose a readable
10
+ * document yields no retained-control surface at all. The environment
11
+ * publishes the resulting document on `capabilities`, so a caller reads the
12
+ * answer for this sandbox rather than the provider's pre-sandbox claim.
13
+ *
14
+ * The document is measured once, here. A sandbox that is not yet running
15
+ * cannot answer, so an environment composed during provisioning claims
16
+ * nothing and keeps claiming nothing: the exposed operations and the document
17
+ * are composed together and a caller may already hold either one. Compose the
18
+ * environment again through `provider.get(id)` once the sandbox is running.
19
+ */
20
+ export declare function sandboxInstanceAsEnvironment(box: SandboxInstanceLike, providerName: string, client: SandboxClientLike, declaredCapabilities: AgentEnvironmentCapabilities, operation?: {
21
+ signal?: AbortSignal;
22
+ }): Promise<AgentEnvironment>;
@@ -1,16 +1,35 @@
1
1
  import { AgentTurnInputSchema } from "@tangle-network/agent-interface";
2
+ import { AgentEnvironmentCapabilitiesSchema } from "@tangle-network/agent-interface/environment-provider";
2
3
  import { environmentEventFromSandboxEvent } from "./tangle-events.js";
3
4
  import { executionIdFromTurnInput, promptFromTurnInput, promptOptionsFromTurnInput, } from "./tangle-prompt.js";
4
5
  import { resolveRetainedSessionControlRef } from "./tangle-session-control.js";
5
6
  import { placementInfoFromLoopPlacement, statusFromUnknown, } from "./tangle-environment-values.js";
6
7
  import { execResultFromSandboxExecResult } from "./tangle-result-values.js";
7
- import { capabilitiesForSandbox, sandboxCapabilitySupport } from "./tangle-capabilities.js";
8
+ import { capabilitiesForSandbox, frozenCapabilityDocument, sandboxCapabilitySupport, } from "./tangle-capabilities.js";
9
+ import { readDeploymentCapabilitySupport } from "./tangle-deployment-capabilities.js";
8
10
  import { awaitWithSignal, assertBoundedJson, boundedIdentifier, boundedString, } from "./tangle-contract-safety.js";
9
11
  import { assertExecOptions, assertOptionKeys, } from "./tangle-environment-validation.js";
10
12
  import { interruptExecutionAfterAbort, } from "./tangle-environment-control.js";
11
13
  import { dispatchEnvironmentRun } from "./tangle-environment-dispatch.js";
12
14
  import { sandboxSessionAsAgentSession } from "./tangle-environment-session.js";
13
- export function sandboxInstanceAsEnvironment(box, providerName, client, declaredCapabilities) {
15
+ /**
16
+ * Compose one concrete sandbox into an environment.
17
+ *
18
+ * This is the only stage that can read deployment truth, so it does: one
19
+ * `GET /capabilities` against the sandbox decides retained control, and the
20
+ * environment then exposes exactly the operations both the adapter surface
21
+ * and the deployment back. A deployment that cannot disclose a readable
22
+ * document yields no retained-control surface at all. The environment
23
+ * publishes the resulting document on `capabilities`, so a caller reads the
24
+ * answer for this sandbox rather than the provider's pre-sandbox claim.
25
+ *
26
+ * The document is measured once, here. A sandbox that is not yet running
27
+ * cannot answer, so an environment composed during provisioning claims
28
+ * nothing and keeps claiming nothing: the exposed operations and the document
29
+ * are composed together and a caller may already hold either one. Compose the
30
+ * environment again through `provider.get(id)` once the sandbox is running.
31
+ */
32
+ export async function sandboxInstanceAsEnvironment(box, providerName, client, declaredCapabilities, operation) {
14
33
  const environmentId = boundedIdentifier(box.id, "Tangle environment id");
15
34
  boundedIdentifier(providerName, "Tangle provider name");
16
35
  if (box.metadata !== undefined) {
@@ -20,7 +39,11 @@ export function sandboxInstanceAsEnvironment(box, providerName, client, declared
20
39
  assertBoundedJson(box.metadata);
21
40
  }
22
41
  const support = sandboxCapabilitySupport(box, client);
23
- const capabilities = capabilitiesForSandbox(declaredCapabilities, support);
42
+ const deployment = await readDeploymentCapabilitySupport(box, operation);
43
+ const capabilities = frozenCapabilityDocument(AgentEnvironmentCapabilitiesSchema.parse(capabilitiesForSandbox(declaredCapabilities, support, deployment)));
44
+ // The published document is the single source for what this environment
45
+ // offers, so the session surface reads its grant from there.
46
+ const retainedControl = capabilities.retainedControl !== undefined;
24
47
  const dispatch = capabilities.streaming.detach && box.dispatchPrompt
25
48
  ? dispatchEnvironmentRun(box, providerName, environmentId)
26
49
  : undefined;
@@ -37,6 +60,7 @@ export function sandboxInstanceAsEnvironment(box, providerName, client, declared
37
60
  id: environmentId,
38
61
  provider: providerName,
39
62
  ...(box.name ? { name: boundedString(box.name, "Tangle environment name") } : {}),
63
+ capabilities,
40
64
  async status(options) {
41
65
  assertOptionKeys(options, ["signal"], "Tangle environment status");
42
66
  await awaitWithSignal(box.refresh?.(options), options?.signal);
@@ -103,11 +127,12 @@ export function sandboxInstanceAsEnvironment(box, providerName, client, declared
103
127
  if (session.id !== id) {
104
128
  throw new Error("sandbox session(id) returned an unrelated session");
105
129
  }
106
- const agentSession = sandboxSessionAsAgentSession(session, resolveRetainedSessionControlRef(options?.controlRef, id, providerName, environmentId), providerName, environmentId, dispatch, exactExecutionEvents);
107
- // sessions.continue was granted from a probe-session fact; this
108
- // backstop holds every concrete session to that fact, so a client
109
- // whose sessions diverge from its probe surface fails loud here
110
- // instead of failing at the first cancellation.
130
+ const agentSession = sandboxSessionAsAgentSession(session, resolveRetainedSessionControlRef(options?.controlRef, id, providerName, environmentId), providerName, environmentId, dispatch, exactExecutionEvents, retainedControl);
131
+ // sessions.continue was granted from the probe session and the
132
+ // deployment document together; this backstop holds every
133
+ // concrete session to that grant, so a client whose sessions
134
+ // diverge from its probe surface fails loud here instead of
135
+ // failing at the first cancellation.
111
136
  if (capabilities.sessions.continue &&
112
137
  typeof agentSession.cancelRun !== "function") {
113
138
  throw new Error("Tangle retained session support requires SandboxSession.cancelRun");
@@ -72,7 +72,15 @@ export function environmentEventFromSandboxEvent(event, expected = {}) {
72
72
  if (Object.prototype.hasOwnProperty.call(data, "contextTransferReceipt")) {
73
73
  throw new Error("Tangle Sandbox emitted an unsolicited context transfer receipt");
74
74
  }
75
- const { executionId: eventExecutionId, sessionId: eventSessionId } = sandboxEventIdentity(event);
75
+ // An exact run stream is already selected by the runtime execution id.
76
+ // On that stream, session.updated carries the harness-native session id
77
+ // (for example an OpenCode session), not the runtime session id. Keep that
78
+ // value as event content while lifecycle frames remain identity-checked.
79
+ const identity = sandboxEventIdentity(event);
80
+ const eventExecutionId = identity.executionId;
81
+ const eventSessionId = expected.streamBound === true && record.type === "session.updated"
82
+ ? undefined
83
+ : identity.sessionId;
76
84
  if (expected.executionId !== undefined &&
77
85
  ((eventExecutionId === undefined && expected.streamBound !== true) ||
78
86
  (eventExecutionId !== undefined && eventExecutionId !== expected.executionId))) {
@@ -58,15 +58,32 @@ export function promptOptionsFromTurnInput(input, target) {
58
58
  ...(input.detach !== undefined ? { detach: input.detach } : {}),
59
59
  };
60
60
  }
61
+ const SANDBOX_OPTIONAL_RESULT_FIELDS = new Set([
62
+ "executionId",
63
+ "response",
64
+ "error",
65
+ "errorCode",
66
+ "toolInvocations",
67
+ "approval",
68
+ "question",
69
+ "plan",
70
+ "traceId",
71
+ "usage",
72
+ "costUsd",
73
+ ]);
61
74
  export function validatedSandboxPromptResult(result) {
62
75
  if (!result || typeof result !== "object" || Array.isArray(result)) {
63
76
  throw new Error("Tangle prompt returned no result object");
64
77
  }
65
- const record = result;
66
- if (Object.hasOwn(record, "contextTransferReceipt") &&
67
- record.contextTransferReceipt === undefined) {
78
+ const source = result;
79
+ if (Object.hasOwn(source, "contextTransferReceipt") &&
80
+ source.contextTransferReceipt === undefined) {
68
81
  throw new Error("Tangle prompt result returned a context receipt for a turn that requested no transfer");
69
82
  }
83
+ // The Sandbox SDK materializes absent optional response fields as
84
+ // `undefined`. They were absent on the JSON wire and must stay absent in the
85
+ // provider-neutral result before the strict JSON check runs.
86
+ const record = Object.fromEntries(Object.entries(source).filter(([field, value]) => value !== undefined || !SANDBOX_OPTIONAL_RESULT_FIELDS.has(field)));
70
87
  assertBoundedJson(record);
71
88
  if (typeof record.success !== "boolean") {
72
89
  throw new Error("Tangle prompt result omitted its success status");
@@ -83,7 +83,7 @@ export function createTangleProvider(options) {
83
83
  }
84
84
  try {
85
85
  input.signal?.throwIfAborted();
86
- const environment = sandboxInstanceAsEnvironment(box, providerName, options.client, declaredCapabilities);
86
+ const environment = await sandboxInstanceAsEnvironment(box, providerName, options.client, declaredCapabilities, input.signal ? { signal: input.signal } : undefined);
87
87
  input.signal?.throwIfAborted();
88
88
  return environment;
89
89
  }
@@ -115,7 +115,7 @@ export function createTangleProvider(options) {
115
115
  operation?.signal?.throwIfAborted();
116
116
  if (!box || boundedIdentifier(box.id, "Tangle environment id") !== id)
117
117
  return null;
118
- return sandboxInstanceAsEnvironment(box, providerName, options.client, declaredCapabilities);
118
+ return await sandboxInstanceAsEnvironment(box, providerName, options.client, declaredCapabilities, operation?.signal ? { signal: operation.signal } : undefined);
119
119
  },
120
120
  }
121
121
  : {}),
@@ -31,6 +31,46 @@ export interface SandboxClientLike {
31
31
  }): Promise<SandboxInstanceLike[]>;
32
32
  describePlacement?(box: SandboxInstanceLike): unknown;
33
33
  }
34
+ /**
35
+ * The `GET /capabilities` document as this adapter reads it: what the DEPLOYED
36
+ * sidecar image compiled in, not which methods the linked SDK class carries.
37
+ *
38
+ * Every capability flag this shape declares gates a claim the adapter makes,
39
+ * and the wire document's other flags are absent here because the adapter does
40
+ * not act on them yet. Every field is optional, and the document's own
41
+ * convention is that a missing flag means "unknown to that image", never
42
+ * false. The linked SDK parses a v1 wire body strictly, but this adapter reads
43
+ * any `SandboxInstanceLike`, so it never assumes a flag was validated: an
44
+ * absent field reaches the claim as unknown instead of being coerced. The
45
+ * SDK's `SandboxRuntimeCapabilities` is assignable to this shape;
46
+ * `deployment-capabilities.test.ts` pins that against the published type.
47
+ */
48
+ export interface SandboxRuntimeCapabilityDocument {
49
+ schema?: number;
50
+ agentInterface?: string;
51
+ sidecarVersion?: string;
52
+ image?: string;
53
+ dispatch?: {
54
+ /** Run requests accept a caller-supplied exact `runControlRef`. */
55
+ runControlRef?: boolean;
56
+ /** Admission echoes the executionId the request named. */
57
+ executionIdOnAdmission?: boolean;
58
+ };
59
+ cancel?: {
60
+ /** Cancellation accepts the canonical digest-bound request. */
61
+ canonicalRunCancellation?: boolean;
62
+ /** Cancellation binds to the run's request digest. */
63
+ digestBound?: boolean;
64
+ /** Replaying an operation id returns the stored acknowledgement. */
65
+ idempotent?: boolean;
66
+ };
67
+ runs?: {
68
+ /** Status and results select one execution of a session. */
69
+ executionScopedStatus?: boolean;
70
+ /** Buffered run events replay by execution. */
71
+ eventReplay?: boolean;
72
+ };
73
+ }
34
74
  export interface SandboxProcessStatusLike {
35
75
  pid: number;
36
76
  running: boolean;
@@ -106,6 +146,15 @@ export interface SandboxInstanceLike {
106
146
  }): Promise<unknown>;
107
147
  };
108
148
  process?: SandboxProcessManagerLike;
149
+ /**
150
+ * Capability discovery against the deployment behind this sandbox. Absent
151
+ * on a Sandbox SDK older than 0.22.0, which is why every call site feature-
152
+ * detects it: an older SDK cannot read deployment truth, so the adapter
153
+ * claims no retained control rather than trusting its own method surface.
154
+ * Resolves to null when the deployment cannot disclose a document this SDK
155
+ * reads; a malformed document throws.
156
+ */
157
+ capabilities?(): Promise<SandboxRuntimeCapabilityDocument | null>;
109
158
  refresh?(options?: {
110
159
  signal?: AbortSignal;
111
160
  }): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-provider-tangle",
3
- "version": "0.7.2",
3
+ "version": "0.8.0",
4
4
  "description": "AgentEnvironmentProvider adapter for Tangle sandboxes",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -37,6 +37,8 @@
37
37
  "dist/tangle-exact-process-validation.js",
38
38
  "dist/tangle-capabilities.d.ts",
39
39
  "dist/tangle-capabilities.js",
40
+ "dist/tangle-deployment-capabilities.d.ts",
41
+ "dist/tangle-deployment-capabilities.js",
40
42
  "dist/tangle-create-options.d.ts",
41
43
  "dist/tangle-create-options.js",
42
44
  "dist/tangle-environment-values.d.ts",
@@ -67,7 +69,7 @@
67
69
  "LICENSE"
68
70
  ],
69
71
  "dependencies": {
70
- "@tangle-network/agent-interface": "0.49.0"
72
+ "@tangle-network/agent-interface": "0.50.0"
71
73
  },
72
74
  "peerDependencies": {
73
75
  "@tangle-network/sandbox": ">=0.19.6 <1.0.0"
@@ -80,11 +82,11 @@
80
82
  "devDependencies": {
81
83
  "@tangle-network/agent-eval": "0.145.3",
82
84
  "@tangle-network/agent-runtime": "0.132.13",
83
- "@tangle-network/sandbox": "0.21.1",
85
+ "@tangle-network/sandbox": "0.22.0",
84
86
  "@types/node": "25.6.0",
85
87
  "typescript": "^6.0.3",
86
88
  "vitest": "^4.1.5",
87
- "@tangle-network/agent-provider-testkit": "0.6.4"
89
+ "@tangle-network/agent-provider-testkit": "0.7.0"
88
90
  },
89
91
  "scripts": {
90
92
  "build": "tsc -p tsconfig.json",