@tangle-network/agent-provider-tangle 0.12.2 → 0.12.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tangle-provider.js +71 -63
- package/package.json +3 -3
package/dist/tangle-provider.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AgentEnvironmentCapabilitiesSchema } from "@tangle-network/agent-interface/environment-provider";
|
|
1
|
+
import { AgentEnvironmentCapabilitiesSchema, createAgentEnvironmentWithIdempotency, } from "@tangle-network/agent-interface/environment-provider";
|
|
2
2
|
import { createTangleExactProcessProvider, } from "./exact-process.js";
|
|
3
3
|
import { capabilitiesForClient, defaultTangleSandboxCapabilities, } from "./tangle-capabilities.js";
|
|
4
4
|
import { sandboxInstanceAsEnvironment } from "./tangle-environment.js";
|
|
@@ -36,74 +36,82 @@ export function createTangleProvider(options) {
|
|
|
36
36
|
// the configured document, so create() and get() call it before any effect.
|
|
37
37
|
const narrowedProviderCapabilities = (declared) => AgentEnvironmentCapabilitiesSchema.parse(capabilitiesForClient(declared, options.client));
|
|
38
38
|
const resolveCapabilities = async () => narrowedProviderCapabilities(await resolveDeclaredCapabilities());
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
39
|
+
const createRecords = new Map();
|
|
40
|
+
const createEnvironment = async (input) => {
|
|
41
|
+
assertCreateInputShape(input);
|
|
42
|
+
input.signal?.throwIfAborted();
|
|
43
|
+
assertNoInlineSecretValues(input);
|
|
44
|
+
if (input.providerOptions && Object.keys(input.providerOptions).length > 0) {
|
|
45
|
+
throw new Error("Tangle create providerOptions are not supported");
|
|
46
|
+
}
|
|
47
|
+
// The sandbox stage narrows from the declared document, not the
|
|
48
|
+
// provider-boundary one: the client stage cannot observe box-scoped
|
|
49
|
+
// facts, so measured instance facts must decide them per sandbox.
|
|
50
|
+
const declaredCapabilities = await resolveDeclaredCapabilities();
|
|
51
|
+
narrowedProviderCapabilities(declaredCapabilities);
|
|
52
|
+
const createOptions = options.mapCreateInput?.(input) ??
|
|
53
|
+
sandboxOptionsFromCreateInput(input, options.defaultBackend ?? "opencode");
|
|
54
|
+
assertMappedCreateOptions(createOptions);
|
|
55
|
+
if (input.idempotencyKey !== undefined &&
|
|
56
|
+
createOptions.idempotencyKey !== input.idempotencyKey) {
|
|
57
|
+
throw new Error("Tangle mapped create options must preserve input idempotencyKey");
|
|
58
|
+
}
|
|
59
|
+
assertMappedSecretNames(createOptions);
|
|
60
|
+
input.signal?.throwIfAborted();
|
|
61
|
+
const createPromise = options.client.create(createOptions, input.signal ? { signal: input.signal } : undefined);
|
|
62
|
+
let box;
|
|
63
|
+
try {
|
|
64
|
+
box = await awaitWithSignal(createPromise, input.signal);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
if (input.signal?.aborted) {
|
|
68
|
+
void createPromise
|
|
69
|
+
.then(async (lateBox) => {
|
|
70
|
+
if (!lateBox.delete) {
|
|
71
|
+
attachCleanupHandle(error, lateBox);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
await lateBox.delete();
|
|
76
|
+
}
|
|
77
|
+
catch (cleanupError) {
|
|
78
|
+
attachCleanupHandle(error, lateBox, cleanupError);
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
.catch((lateError) => attachCleanupHandle(error, undefined, lateError));
|
|
50
82
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const declaredCapabilities = await resolveDeclaredCapabilities();
|
|
55
|
-
narrowedProviderCapabilities(declaredCapabilities);
|
|
56
|
-
const createOptions = options.mapCreateInput?.(input) ??
|
|
57
|
-
sandboxOptionsFromCreateInput(input, options.defaultBackend ?? "opencode");
|
|
58
|
-
assertMappedCreateOptions(createOptions);
|
|
59
|
-
assertMappedSecretNames(createOptions);
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
60
86
|
input.signal?.throwIfAborted();
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (!lateBox.delete) {
|
|
71
|
-
attachCleanupHandle(error, lateBox);
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
try {
|
|
75
|
-
await lateBox.delete();
|
|
76
|
-
}
|
|
77
|
-
catch (cleanupError) {
|
|
78
|
-
attachCleanupHandle(error, lateBox, cleanupError);
|
|
79
|
-
}
|
|
80
|
-
})
|
|
81
|
-
.catch((lateError) => attachCleanupHandle(error, undefined, lateError));
|
|
82
|
-
}
|
|
83
|
-
throw error;
|
|
87
|
+
const requestedResources = requestedResourceProfile(input.resources);
|
|
88
|
+
const environment = await sandboxInstanceAsEnvironment(box, providerName, options.client, declaredCapabilities, input.signal ? { signal: input.signal } : undefined, requestedResources === undefined ? undefined : { resources: requestedResources });
|
|
89
|
+
input.signal?.throwIfAborted();
|
|
90
|
+
return environment;
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
if (!box.delete) {
|
|
94
|
+
const baseError = error instanceof Error ? error : new Error(String(error));
|
|
95
|
+
throw Object.assign(baseError, { cleanupHandle: box });
|
|
84
96
|
}
|
|
85
97
|
try {
|
|
86
|
-
|
|
87
|
-
const requestedResources = requestedResourceProfile(input.resources);
|
|
88
|
-
const environment = await sandboxInstanceAsEnvironment(box, providerName, options.client, declaredCapabilities, input.signal ? { signal: input.signal } : undefined, requestedResources === undefined ? undefined : { resources: requestedResources });
|
|
89
|
-
input.signal?.throwIfAborted();
|
|
90
|
-
return environment;
|
|
98
|
+
await box.delete();
|
|
91
99
|
}
|
|
92
|
-
catch (
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
try {
|
|
98
|
-
await box.delete();
|
|
99
|
-
}
|
|
100
|
-
catch (cleanupError) {
|
|
101
|
-
const combined = new AggregateError([error, cleanupError], "Tangle environment validation and cleanup both failed");
|
|
102
|
-
attachCleanupHandle(combined, box, cleanupError);
|
|
103
|
-
throw combined;
|
|
104
|
-
}
|
|
105
|
-
throw error;
|
|
100
|
+
catch (cleanupError) {
|
|
101
|
+
const combined = new AggregateError([error, cleanupError], "Tangle environment validation and cleanup both failed");
|
|
102
|
+
attachCleanupHandle(combined, box, cleanupError);
|
|
103
|
+
throw combined;
|
|
106
104
|
}
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
return {
|
|
109
|
+
name: providerName,
|
|
110
|
+
...(exactProcess ? { exactProcess } : {}),
|
|
111
|
+
capabilities: resolveCapabilities,
|
|
112
|
+
...(options.validateProfile ? { validateProfile: options.validateProfile } : {}),
|
|
113
|
+
create(input) {
|
|
114
|
+
return createAgentEnvironmentWithIdempotency(createRecords, input, () => createEnvironment(input));
|
|
107
115
|
},
|
|
108
116
|
...(options.client.get
|
|
109
117
|
? {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/agent-provider-tangle",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.3",
|
|
4
4
|
"description": "AgentEnvironmentProvider adapter for Tangle sandboxes",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
"LICENSE"
|
|
86
86
|
],
|
|
87
87
|
"dependencies": {
|
|
88
|
-
"@tangle-network/agent-interface": "^1.0.
|
|
88
|
+
"@tangle-network/agent-interface": "^1.0.1"
|
|
89
89
|
},
|
|
90
90
|
"peerDependencies": {
|
|
91
91
|
"@tangle-network/sandbox": ">=0.23.0 <1.0.0"
|
|
@@ -102,7 +102,7 @@
|
|
|
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.
|
|
105
|
+
"@tangle-network/agent-provider-testkit": "0.8.3"
|
|
106
106
|
},
|
|
107
107
|
"scripts": {
|
|
108
108
|
"build": "tsc -p tsconfig.json",
|