@tangle-network/agent-provider-tangle 0.12.3 → 0.13.1

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,11 +1,10 @@
1
1
  # @tangle-network/agent-provider-tangle
2
2
 
3
3
  Wraps `@tangle-network/sandbox` as an `AgentEnvironmentProvider`.
4
- The peer range is `>=0.23.0 <1.0.0`, and this package is developed and tested against 0.23.0.
5
- The floor is 0.23.0 because the response path needs `session.respondToInteraction`, which first shipped there.
6
- The adapter feature-detects that method, so an older SDK claims no interactions rather than failing to load.
7
- The floor stands anyway: the earlier answer path resolves the session's first outstanding question rather than the one a response names, so a response meant for one ask resolves another and reports success.
8
- This adapter never falls back to it.
4
+ The peer range is `>=0.30.1 <1.0.0`, and this package is developed and tested against 0.30.1.
5
+ The floor is 0.30.1 because interaction claims use the Sandbox backend catalog exposed by `listBackends()`.
6
+ The provider fails closed when the configured backend or its catalog entry cannot be read.
7
+ Newer SDKs may also provide `getBackend()` as a lookup over the same catalog.
9
8
 
10
9
  ```ts
11
10
  import { Sandbox } from '@tangle-network/sandbox'
@@ -1,4 +1,5 @@
1
1
  import type { AgentEnvironmentCapabilities, HarnessType } from "@tangle-network/agent-interface";
2
+ import type { BackendRegistryEntry } from "@tangle-network/sandbox";
2
3
  import type { SandboxClientLike, SandboxInstanceLike } from "./tangle-types.js";
3
4
  import type { DeploymentCapabilitySupport } from "./tangle-deployment-capabilities.js";
4
5
  import type { ResourceProfile } from "@tangle-network/agent-interface";
@@ -13,6 +14,13 @@ import { type ObservationSurfaceSupport } from "./tangle-observation.js";
13
14
  * nothing backs becomes an action the caller selects and finds missing.
14
15
  */
15
16
  export declare function defaultTangleSandboxCapabilities(harness?: HarnessType): AgentEnvironmentCapabilities;
17
+ /**
18
+ * Keep only interaction kinds the selected Sandbox backend advertises.
19
+ *
20
+ * The backend catalog is the authority for harness-specific interactions.
21
+ * An absent entry means the provider cannot prove any interaction support.
22
+ */
23
+ export declare function narrowTangleCapabilitiesToBackend(declared: AgentEnvironmentCapabilities, backend: BackendRegistryEntry | undefined): AgentEnvironmentCapabilities;
16
24
  /**
17
25
  * Adapter-surface facts that gate declared capabilities: which methods this
18
26
  * process can actually call. Every fact defaults to false when it cannot be
@@ -114,6 +114,35 @@ export function defaultTangleSandboxCapabilities(harness) {
114
114
  },
115
115
  };
116
116
  }
117
+ /**
118
+ * Keep only interaction kinds the selected Sandbox backend advertises.
119
+ *
120
+ * The backend catalog is the authority for harness-specific interactions.
121
+ * An absent entry means the provider cannot prove any interaction support.
122
+ */
123
+ export function narrowTangleCapabilitiesToBackend(declared, backend) {
124
+ if (declared.interactions === undefined || backend === undefined) {
125
+ if (declared.interactions === undefined)
126
+ return declared;
127
+ const narrowed = { ...declared };
128
+ delete narrowed.interactions;
129
+ return narrowed;
130
+ }
131
+ const supportedKinds = new Set(backend.capabilities.interactions);
132
+ const kinds = declared.interactions.kinds.filter((kind) => supportedKinds.has(kind));
133
+ if (kinds.length === 0) {
134
+ const narrowed = { ...declared };
135
+ delete narrowed.interactions;
136
+ return narrowed;
137
+ }
138
+ return {
139
+ ...declared,
140
+ interactions: {
141
+ ...declared.interactions,
142
+ kinds,
143
+ },
144
+ };
145
+ }
117
146
  // One reserved id names both probe handles; neither ever reaches the service.
118
147
  const CAPABILITY_PROBE_ID = "__tangle-capability-probe__";
119
148
  export function sandboxCapabilitySupport(box, client, requestedResources) {
@@ -1,5 +1,5 @@
1
- import type { AgentEnvironmentStatus, AgentSessionStatus, PlacementInfo } from "@tangle-network/agent-interface/environment-provider";
2
- import type { SandboxInstanceLike } from "./tangle-types.js";
1
+ import type { AgentEnvironmentCreation, AgentEnvironmentStatus, AgentSessionStatus, PlacementInfo } from "@tangle-network/agent-interface/environment-provider";
2
+ import type { SandboxCreateReceiptLike, SandboxInstanceLike } from "./tangle-types.js";
3
3
  export declare function nonEmptyString(value: unknown): string | undefined;
4
4
  export declare function optionalNonEmptyString(value: unknown, label: string): string | undefined;
5
5
  export declare function placementInfoFromLoopPlacement(placement: unknown, box: SandboxInstanceLike): PlacementInfo;
@@ -16,3 +16,9 @@ export declare function sessionStatusFromUnknown(status: unknown): AgentSessionS
16
16
  * "unknown" instead of fabricating an execution-scoped answer.
17
17
  */
18
18
  export declare function executionBoundSessionStatus(payload: unknown, executionId: string): AgentSessionStatus;
19
+ /**
20
+ * Map the platform create receipt to the environment creation verdict. An
21
+ * `unknown` outcome, a null receipt, and an SDK without receipts all leave the
22
+ * verdict absent, so a consumer cannot read them as proof of creation.
23
+ */
24
+ export declare function creationFromSandboxCreateReceipt(receipt: SandboxCreateReceiptLike | null | undefined): AgentEnvironmentCreation | undefined;
@@ -117,3 +117,24 @@ export function executionBoundSessionStatus(payload, executionId) {
117
117
  return sessionStatus;
118
118
  return "unknown";
119
119
  }
120
+ /**
121
+ * Map the platform create receipt to the environment creation verdict. An
122
+ * `unknown` outcome, a null receipt, and an SDK without receipts all leave the
123
+ * verdict absent, so a consumer cannot read them as proof of creation.
124
+ */
125
+ export function creationFromSandboxCreateReceipt(receipt) {
126
+ if (receipt === null || receipt === undefined)
127
+ return undefined;
128
+ switch (receipt.outcome) {
129
+ case "created":
130
+ return "created";
131
+ case "idempotent_replay":
132
+ return "replayed";
133
+ case "unknown":
134
+ return undefined;
135
+ default: {
136
+ const outcome = receipt.outcome;
137
+ throw new Error(`Tangle create receipt reported an unknown outcome: ${String(outcome)}`);
138
+ }
139
+ }
140
+ }
@@ -3,7 +3,7 @@ import { AgentEnvironmentCapabilitiesSchema } from "@tangle-network/agent-interf
3
3
  import { environmentEventFromSandboxEvent } from "./tangle-events.js";
4
4
  import { executionIdFromTurnInput, promptFromTurnInput, promptOptionsFromTurnInput, } from "./tangle-prompt.js";
5
5
  import { resolveRetainedSessionControlRef } from "./tangle-session-control.js";
6
- import { placementInfoFromLoopPlacement, statusFromUnknown, } from "./tangle-environment-values.js";
6
+ import { creationFromSandboxCreateReceipt, placementInfoFromLoopPlacement, statusFromUnknown, } from "./tangle-environment-values.js";
7
7
  import { execResultFromSandboxExecResult } from "./tangle-result-values.js";
8
8
  import { capabilitiesForSandbox, frozenCapabilityDocument, sandboxCapabilitySupport, } from "./tangle-capabilities.js";
9
9
  import { readDeploymentCapabilitySupport } from "./tangle-deployment-capabilities.js";
@@ -76,9 +76,11 @@ export async function sandboxInstanceAsEnvironment(box, providerName, client, de
76
76
  ...(options.signal ? { signal: options.signal } : {}),
77
77
  ...(options.controlRef ? { runControlRef: options.controlRef } : {}),
78
78
  });
79
+ const creation = creationFromSandboxCreateReceipt(box.createReceipt?.());
79
80
  return {
80
81
  id: environmentId,
81
82
  provider: providerName,
83
+ ...(creation === undefined ? {} : { creation }),
82
84
  ...(box.name ? { name: boundedString(box.name, "Tangle environment name") } : {}),
83
85
  ...(box.metadata ? { metadata: snapshotMetadata(box.metadata) } : {}),
84
86
  capabilities,
@@ -1,6 +1,6 @@
1
1
  import { AgentEnvironmentCapabilitiesSchema, createAgentEnvironmentWithIdempotency, } from "@tangle-network/agent-interface/environment-provider";
2
2
  import { createTangleExactProcessProvider, } from "./exact-process.js";
3
- import { capabilitiesForClient, defaultTangleSandboxCapabilities, } from "./tangle-capabilities.js";
3
+ import { capabilitiesForClient, defaultTangleSandboxCapabilities, narrowTangleCapabilitiesToBackend, } from "./tangle-capabilities.js";
4
4
  import { sandboxInstanceAsEnvironment } from "./tangle-environment.js";
5
5
  import { assertCreateInputShape, assertMappedCreateOptions, assertMappedSecretNames, assertNoInlineSecretValues, sandboxOptionsFromCreateInput } from "./tangle-create-options.js";
6
6
  import { statusFromUnknown } from "./tangle-environment-values.js";
@@ -25,12 +25,16 @@ export function createTangleProvider(options) {
25
25
  if (!exactProcess && configured.exactProcess) {
26
26
  throw new Error("Tangle capabilities cannot advertise exactProcess without exactProcess configuration");
27
27
  }
28
+ const backend = configured.interactions === undefined
29
+ ? undefined
30
+ : await resolveDefaultBackend(options.client, options.defaultBackend);
31
+ const narrowed = narrowTangleCapabilitiesToBackend(configured, backend);
28
32
  return exactProcess
29
33
  ? {
30
- ...configured,
34
+ ...narrowed,
31
35
  exactProcess: { egress: ["blocked", "strict"] },
32
36
  }
33
- : configured;
37
+ : narrowed;
34
38
  };
35
39
  // Provider-boundary document: client-stage facts only. It also validates
36
40
  // the configured document, so create() and get() call it before any effect.
@@ -184,6 +188,21 @@ export function createTangleProvider(options) {
184
188
  : {}),
185
189
  };
186
190
  }
191
+ async function resolveDefaultBackend(client, defaultBackend) {
192
+ if (defaultBackend === undefined)
193
+ return undefined;
194
+ try {
195
+ if (client.getBackend)
196
+ return await client.getBackend(defaultBackend);
197
+ if (!client.listBackends)
198
+ return undefined;
199
+ const catalog = await client.listBackends();
200
+ return catalog.backends.find((backend) => backend.type === defaultBackend);
201
+ }
202
+ catch {
203
+ return undefined;
204
+ }
205
+ }
187
206
  function assertProviderOperationOptions(options, label) {
188
207
  if (options === undefined)
189
208
  return;
@@ -1,6 +1,16 @@
1
- import type { BackendType, CreateSandboxOptions, ExecResult as SandboxExecResult, PromptOptions, PromptResult, SandboxEvent } from "@tangle-network/sandbox";
1
+ import type { BackendRegistryEntry, BackendRegistryResponse, BackendType, CreateSandboxOptions, ExecResult as SandboxExecResult, PromptOptions, PromptResult, SandboxEvent } from "@tangle-network/sandbox";
2
2
  import type { AgentRunCancellationAcknowledgement, AgentRunCancellationRequest, AgentExecutionPreparationReceipt, AgentInteractiveSessionControlClaim, AgentInteractiveSessionControlClaimAcknowledgement, AgentInteractiveSessionControlClaimRequest, AgentInteractiveSessionPromptAcknowledgement, AgentInteractiveSessionPromptCommand, AgentInteractiveSessionStopAcknowledgement, AgentInteractiveSessionStopCommand, AgentProfile, InputPart, InteractionRequest, InteractionResponseCommand } from "@tangle-network/agent-interface";
3
3
  import type { AgentEnvironmentCapabilities, AgentEnvironmentProvider, CreateAgentEnvironmentInput } from "@tangle-network/agent-interface/environment-provider";
4
+ /**
5
+ * The platform verdict for the create call that returned a sandbox.
6
+ * `created` means the call allocated the sandbox; `idempotent_replay` means an
7
+ * earlier call with the same idempotency key allocated it; `unknown` means the
8
+ * platform cannot prove either outcome.
9
+ */
10
+ export interface SandboxCreateReceiptLike {
11
+ outcome: "created" | "idempotent_replay" | "unknown";
12
+ idempotencyKeyApplied: boolean;
13
+ }
4
14
  export interface TangleExactProcessOptions {
5
15
  teamId?: string;
6
16
  }
@@ -20,6 +30,10 @@ export interface SandboxClientLike {
20
30
  fetch?(path: string, options?: RequestInit, fetchOptions?: {
21
31
  timeoutMs?: number;
22
32
  }): Promise<Response>;
33
+ /** Canonical backend catalog served by authenticated `/v1/backends`. */
34
+ listBackends?(): Promise<BackendRegistryResponse>;
35
+ /** Lookup over the same canonical backend catalog, when the SDK provides it. */
36
+ getBackend?(type: string): Promise<BackendRegistryEntry | undefined>;
23
37
  get?(id: string, requestOptions?: {
24
38
  signal?: AbortSignal;
25
39
  }): Promise<SandboxInstanceLike | null>;
@@ -363,6 +377,12 @@ export interface SandboxInstanceLike {
363
377
  resourceUsage?(): Promise<SandboxResourceUsageLike | null>;
364
378
  /** Interactive terminal transport. Absent on a client that cannot serve a PTY. */
365
379
  terminals?: SandboxTerminalsLike;
380
+ /**
381
+ * The platform verdict for the create call that returned this instance.
382
+ * Absent on a Sandbox SDK older than 0.30.1; null for an instance resolved
383
+ * by id or when the platform reported no receipt.
384
+ */
385
+ createReceipt?(): SandboxCreateReceiptLike | null;
366
386
  refresh?(options?: {
367
387
  signal?: AbortSignal;
368
388
  }): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-provider-tangle",
3
- "version": "0.12.3",
3
+ "version": "0.13.1",
4
4
  "description": "AgentEnvironmentProvider adapter for Tangle sandboxes",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -85,10 +85,10 @@
85
85
  "LICENSE"
86
86
  ],
87
87
  "dependencies": {
88
- "@tangle-network/agent-interface": "^1.0.1"
88
+ "@tangle-network/agent-interface": "^1.4.0"
89
89
  },
90
90
  "peerDependencies": {
91
- "@tangle-network/sandbox": ">=0.23.0 <1.0.0"
91
+ "@tangle-network/sandbox": ">=0.30.1 <1.0.0"
92
92
  },
93
93
  "peerDependenciesMeta": {
94
94
  "@tangle-network/sandbox": {
@@ -96,13 +96,13 @@
96
96
  }
97
97
  },
98
98
  "devDependencies": {
99
- "@tangle-network/agent-eval": "0.145.15",
100
- "@tangle-network/agent-runtime": "0.135.3",
101
- "@tangle-network/sandbox": "0.27.0",
99
+ "@tangle-network/agent-eval": "0.149.0",
100
+ "@tangle-network/agent-runtime": "0.142.3",
101
+ "@tangle-network/sandbox": "0.30.1",
102
102
  "@types/node": "25.6.0",
103
103
  "typescript": "^6.0.3",
104
104
  "vitest": "^4.1.5",
105
- "@tangle-network/agent-provider-testkit": "0.8.3"
105
+ "@tangle-network/agent-provider-testkit": "0.8.4"
106
106
  },
107
107
  "scripts": {
108
108
  "build": "tsc -p tsconfig.json",