@tangle-network/sandbox 0.33.1 → 0.34.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/dist/agent/index.d.ts +3 -3
- package/dist/agent/index.js +2 -2
- package/dist/{agent-run-outcome-BgM41pA9.d.ts → agent-run-outcome-BypNL3kD.d.ts} +1 -1
- package/dist/{browser-interactive-control-controller-B476gcui.d.ts → browser-interactive-control-controller-lRfzpg9t.d.ts} +1 -1
- package/dist/{client-AKnQpK_p.js → client-BENlXKO9.js} +1 -1
- package/dist/{client-CkHBDGjY.d.ts → client-DmTp9UWk.d.ts} +3 -3
- package/dist/core.d.ts +3 -3
- package/dist/core.js +2 -2
- package/dist/{index-kbHbIst7.d.ts → index-DiJ3NxHB.d.ts} +2 -2
- package/dist/index.d.ts +8 -8
- package/dist/index.js +4 -4
- package/dist/interactive-control.d.ts +1 -1
- package/dist/runtime.d.ts +2 -2
- package/dist/{sandbox-xlgsnrL5.d.ts → sandbox-DDuB6WXs.d.ts} +102 -7
- package/dist/{sandbox-sU-uwrYh.js → sandbox-Dg4nXKd9.js} +538 -13
- package/dist/tangle/index.d.ts +1 -1
- package/dist/tangle/index.js +1 -1
- package/dist/{tangle-C85FdpsD.js → tangle-DeKTFfoQ.js} +1 -1
- package/dist/{terminal-stream-4KNJ6SmL.d.ts → terminal-stream-5GNLCsms.d.ts} +15 -1
- package/dist/{types-CSVMTw4A.d.ts → types-ltmlQ9Y1.d.ts} +19 -3
- package/package.json +4 -4
|
@@ -2,7 +2,7 @@ import { a as uploadChunked, c as encodePromptForWire, d as applyRequestedModel,
|
|
|
2
2
|
import { a as NetworkError, c as QuotaError, d as StateError, f as TimeoutError, l as SandboxError, m as parseErrorResponse, n as CapabilityError, o as NotFoundError, p as ValidationError, t as AuthError, u as ServerError } from "./errors-C6kn-3zt.js";
|
|
3
3
|
import { c as createInteractiveControlHolderId, d as interactiveSessionControlReleaseResponseSchema, f as interactiveSessionStatusResponseSchema, i as createBrowserInteractiveSessionControlTransport, o as InteractiveSessionControlController, r as browserInteractiveTerminalEndpoint, s as assertInteractiveSessionRef, u as interactiveSessionControlClaimResponseSchema } from "./browser-interactive-control-controller-wXQ7W5pT.js";
|
|
4
4
|
import { n as combineAbortSignals, t as awaitWithAbort } from "./abort-signal-si1WMfJb.js";
|
|
5
|
-
import { AgentExactRunControlRefSchema, AgentInteractiveSessionAttachSchema, AgentInteractiveSessionControlClaimAcknowledgementSchema, AgentInteractiveSessionControlClaimRequestSchema, AgentInteractiveSessionControlClaimSchema, AgentInteractiveSessionPromptAcknowledgementSchema, AgentInteractiveSessionPromptCommandSchema, AgentInteractiveSessionRefSchema, AgentInteractiveSessionStartSchema, AgentInteractiveSessionStopAcknowledgementSchema, AgentInteractiveSessionStopCommandSchema, AgentRunCancellationAcknowledgementSchema, AgentRunCancellationRequestSchema, InteractionAcknowledgementSchema, InteractionBindingSchema, InteractionRequestSchema, InteractionResponseCommandSchema, InteractionResponseSchema, agentInteractiveSessionControlClaimAcknowledgementMatchesRequest, agentInteractiveSessionControlClaimIsNewer, agentInteractiveSessionControlClaimMatchesRef, agentInteractiveSessionPromptAcknowledgementMatchesCommand, agentInteractiveSessionPromptRequestDigest, agentInteractiveSessionRefMatchesStart, agentInteractiveSessionStatusMatchesRef, agentInteractiveSessionStopAcknowledgementMatchesCommand, agentRunCancellationAcknowledgementMatchesRequest, canonicalCandidateDigest, exactAgentInteractiveSessionStart, sha256DigestSchema } from "@tangle-network/agent-interface";
|
|
5
|
+
import { AgentExactRunControlRefSchema, AgentInteractiveSessionAttachSchema, AgentInteractiveSessionControlClaimAcknowledgementSchema, AgentInteractiveSessionControlClaimRequestSchema, AgentInteractiveSessionControlClaimSchema, AgentInteractiveSessionPromptAcknowledgementSchema, AgentInteractiveSessionPromptCommandSchema, AgentInteractiveSessionRefSchema, AgentInteractiveSessionStartSchema, AgentInteractiveSessionStopAcknowledgementSchema, AgentInteractiveSessionStopCommandSchema, AgentRunCancellationAcknowledgementSchema, AgentRunCancellationRequestSchema, InteractionAcknowledgementSchema, InteractionBindingSchema, InteractionRequestSchema, InteractionResponseCommandSchema, InteractionResponseSchema, TerminalInputSchema, TerminalOutputEventSchema, TerminalReplayWindowSchema, TerminalResizeSchema, TerminalSessionRefSchema, agentInteractiveSessionControlClaimAcknowledgementMatchesRequest, agentInteractiveSessionControlClaimIsNewer, agentInteractiveSessionControlClaimMatchesRef, agentInteractiveSessionPromptAcknowledgementMatchesCommand, agentInteractiveSessionPromptRequestDigest, agentInteractiveSessionRefMatchesStart, agentInteractiveSessionStatusMatchesRef, agentInteractiveSessionStopAcknowledgementMatchesCommand, agentRunCancellationAcknowledgementMatchesRequest, canonicalCandidateDigest, exactAgentInteractiveSessionStart, sha256DigestSchema, terminalSessionUsable } from "@tangle-network/agent-interface";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import { AgentInteractiveSessionControlClaimSchema as AgentInteractiveSessionControlClaimSchema$1, AgentInteractiveSessionPromptAcknowledgementSchema as AgentInteractiveSessionPromptAcknowledgementSchema$1, AgentInteractiveSessionRefSchema as AgentInteractiveSessionRefSchema$1, AgentInteractiveSessionStatusSchema, AgentInteractiveSessionStopAcknowledgementSchema as AgentInteractiveSessionStopAcknowledgementSchema$1 } from "@tangle-network/agent-interface/environment-interactive-control";
|
|
8
8
|
import { readTokenCostUsd, readTokenUsage } from "@tangle-network/agent-core";
|
|
@@ -1369,7 +1369,21 @@ const terminalReadyMessageSchema = z.object({
|
|
|
1369
1369
|
connectionId: z.string(),
|
|
1370
1370
|
sessionId: z.string(),
|
|
1371
1371
|
restored: z.boolean(),
|
|
1372
|
-
detachTimeoutMs: z.number().int().positive()
|
|
1372
|
+
detachTimeoutMs: z.number().int().positive(),
|
|
1373
|
+
/** Exact viewer count held by the runtime for this connection. */
|
|
1374
|
+
attachCount: z.number().int().positive().optional(),
|
|
1375
|
+
/** Server-issued output cursor window for exact interactive terminals. */
|
|
1376
|
+
cursors: z.object({
|
|
1377
|
+
earliest: z.number().int().nonnegative(),
|
|
1378
|
+
latest: z.number().int().nonnegative()
|
|
1379
|
+
}).optional()
|
|
1380
|
+
});
|
|
1381
|
+
/** One sequenced output frame for an exact interactive terminal. */
|
|
1382
|
+
const terminalOutputMessageSchema = z.object({
|
|
1383
|
+
type: z.literal("output"),
|
|
1384
|
+
seq: z.number().int().positive(),
|
|
1385
|
+
/** Base64-encoded UTF-8 bytes from the retained terminal event. */
|
|
1386
|
+
data: z.string().min(1)
|
|
1373
1387
|
});
|
|
1374
1388
|
const terminalExitMessageSchema = z.object({
|
|
1375
1389
|
type: z.literal("exit"),
|
|
@@ -1387,6 +1401,7 @@ const terminalErrorMessageSchema = z.object({
|
|
|
1387
1401
|
});
|
|
1388
1402
|
const terminalServerMessageSchema = z.union([
|
|
1389
1403
|
terminalReadyMessageSchema,
|
|
1404
|
+
terminalOutputMessageSchema,
|
|
1390
1405
|
terminalExitMessageSchema,
|
|
1391
1406
|
terminalRenewedMessageSchema,
|
|
1392
1407
|
terminalErrorMessageSchema
|
|
@@ -1412,7 +1427,9 @@ const terminalServerMessageSchema = z.union([
|
|
|
1412
1427
|
* Subsequent input and resize frames carry only their operation fields; the
|
|
1413
1428
|
* server binds authority to the init for the socket lifetime.
|
|
1414
1429
|
* server → client (TEXT JSON):
|
|
1415
|
-
* ready {connectionId, sessionId, restored, detachTimeoutMs
|
|
1430
|
+
* ready {connectionId, sessionId, restored, detachTimeoutMs,
|
|
1431
|
+
* attachCount?, cursors?}
|
|
1432
|
+
* output {seq, data} — exact interactive output as base64 UTF-8 bytes
|
|
1416
1433
|
* exit {exitCode?, exitSignal?}
|
|
1417
1434
|
* error {code, message}
|
|
1418
1435
|
* rec / rec.done — recording tee frames for the platform's session
|
|
@@ -1528,6 +1545,19 @@ function toWebSocketUrl(url) {
|
|
|
1528
1545
|
function assertDimension(name, value) {
|
|
1529
1546
|
if (!Number.isInteger(value) || value < 1 || value > 4096) throw new TerminalStreamError(`${name} must be an integer in [1, ${TERMINAL_WS_MAX_DIMENSION}], got ${value}`, "INVALID_DIMENSION");
|
|
1530
1547
|
}
|
|
1548
|
+
/** Decode the sidecar's base64 output frame without a Node-only dependency. */
|
|
1549
|
+
function decodeBase64(value) {
|
|
1550
|
+
if (!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(value)) throw new TerminalStreamError("Terminal output frame is not valid base64", "INVALID_FRAME");
|
|
1551
|
+
let binary;
|
|
1552
|
+
try {
|
|
1553
|
+
binary = atob(value);
|
|
1554
|
+
} catch {
|
|
1555
|
+
throw new TerminalStreamError("Terminal output frame is not valid base64", "INVALID_FRAME");
|
|
1556
|
+
}
|
|
1557
|
+
const bytes = new Uint8Array(binary.length);
|
|
1558
|
+
for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index);
|
|
1559
|
+
return bytes;
|
|
1560
|
+
}
|
|
1531
1561
|
function normalizeInteractiveSessionIdentity(incarnationId, control) {
|
|
1532
1562
|
if (incarnationId === void 0 && control === void 0) return void 0;
|
|
1533
1563
|
if (typeof incarnationId !== "string" || incarnationId.length === 0 || incarnationId.trim() !== incarnationId) throw new TerminalStreamError("Interactive terminal attach requires an exact incarnationId", "INVALID_INTERACTIVE_IDENTITY");
|
|
@@ -1729,7 +1759,7 @@ var TerminalStream = class TerminalStream {
|
|
|
1729
1759
|
}
|
|
1730
1760
|
const message = decoded;
|
|
1731
1761
|
if (message.type === "rec" || message.type === "rec.done") return;
|
|
1732
|
-
if (message.type !== "ready" && message.type !== "exit" && message.type !== "renewed" && message.type !== "error") return;
|
|
1762
|
+
if (message.type !== "ready" && message.type !== "output" && message.type !== "exit" && message.type !== "renewed" && message.type !== "error") return;
|
|
1733
1763
|
const parsed = terminalServerMessageSchema.safeParse(message);
|
|
1734
1764
|
if (!parsed.success) {
|
|
1735
1765
|
failProtocolFrame();
|
|
@@ -1741,13 +1771,27 @@ var TerminalStream = class TerminalStream {
|
|
|
1741
1771
|
connectionId: parsed.data.connectionId,
|
|
1742
1772
|
sessionId: parsed.data.sessionId,
|
|
1743
1773
|
restored: parsed.data.restored,
|
|
1744
|
-
detachTimeoutMs: parsed.data.detachTimeoutMs
|
|
1774
|
+
detachTimeoutMs: parsed.data.detachTimeoutMs,
|
|
1775
|
+
...parsed.data.attachCount === void 0 ? {} : { attachCount: parsed.data.attachCount },
|
|
1776
|
+
...parsed.data.cursors === void 0 ? {} : { cursors: parsed.data.cursors }
|
|
1745
1777
|
};
|
|
1746
1778
|
this.readyInfo = info;
|
|
1747
1779
|
connectPhase.succeed();
|
|
1748
1780
|
this.handlers.onReady?.(info);
|
|
1749
1781
|
return;
|
|
1750
1782
|
}
|
|
1783
|
+
case "output":
|
|
1784
|
+
try {
|
|
1785
|
+
const bytes = decodeBase64(parsed.data.data);
|
|
1786
|
+
this.handlers.onOutput?.(parsed.data.seq, bytes);
|
|
1787
|
+
if (this.handlers.onOutput === void 0) this.handlers.onData?.(bytes);
|
|
1788
|
+
} catch (error) {
|
|
1789
|
+
const protocolError = error instanceof TerminalStreamError ? error : new TerminalStreamError("Terminal output frame is not valid base64", "INVALID_FRAME");
|
|
1790
|
+
if (!connectPhase.settled()) connectPhase.fail(protocolError);
|
|
1791
|
+
else this.handlers.onError?.(protocolError);
|
|
1792
|
+
if (this.ws.readyState === WebSocket.OPEN) this.ws.close(1e3, "invalid terminal output");
|
|
1793
|
+
}
|
|
1794
|
+
return;
|
|
1751
1795
|
case "exit":
|
|
1752
1796
|
this.handlers.onExit?.({
|
|
1753
1797
|
exitCode: parsed.data.exitCode,
|
|
@@ -2014,6 +2058,397 @@ var BrowserInteractiveSessionController = class extends InteractiveSessionContro
|
|
|
2014
2058
|
}
|
|
2015
2059
|
};
|
|
2016
2060
|
//#endregion
|
|
2061
|
+
//#region src/interactive-terminal-session.ts
|
|
2062
|
+
const MAX_RETAINED_TERMINAL_FRAMES = 4096;
|
|
2063
|
+
const MAX_RETAINED_TERMINAL_BYTES = 8 * 1024 * 1024;
|
|
2064
|
+
const terminalTextEncoder = new TextEncoder();
|
|
2065
|
+
/**
|
|
2066
|
+
* Bounded ordered terminal frames backed by server-issued output sequences.
|
|
2067
|
+
*
|
|
2068
|
+
* The server cursor is never replaced with a client counter. A reconnecting
|
|
2069
|
+
* handle therefore exposes the same output identity after process restart.
|
|
2070
|
+
*/
|
|
2071
|
+
var InteractiveTerminalFrameLog = class {
|
|
2072
|
+
entries = [];
|
|
2073
|
+
entryStartIndex = 0;
|
|
2074
|
+
retainedStartOrdinal = 1;
|
|
2075
|
+
outputEntries = [];
|
|
2076
|
+
outputEntryStartIndex = 0;
|
|
2077
|
+
lastOrdinal = 0;
|
|
2078
|
+
retainedBytes = 0;
|
|
2079
|
+
latestOutputSeq = 0;
|
|
2080
|
+
lastSeenOutputSeq = 0;
|
|
2081
|
+
earliestOutputSeq = 0;
|
|
2082
|
+
evictedOutputOrdinal = 0;
|
|
2083
|
+
ended = false;
|
|
2084
|
+
waiters = /* @__PURE__ */ new Set();
|
|
2085
|
+
configure(window) {
|
|
2086
|
+
const exactWindow = TerminalReplayWindowSchema.parse(window);
|
|
2087
|
+
if (exactWindow.latest < exactWindow.earliest) throw new Error("Terminal replay cursor window is reversed");
|
|
2088
|
+
this.earliestOutputSeq = exactWindow.earliest;
|
|
2089
|
+
this.latestOutputSeq = exactWindow.latest;
|
|
2090
|
+
this.lastSeenOutputSeq = exactWindow.earliest;
|
|
2091
|
+
}
|
|
2092
|
+
append(event) {
|
|
2093
|
+
const exactEvent = this.validateEvent(event);
|
|
2094
|
+
if (exactEvent.type === "output") {
|
|
2095
|
+
if (exactEvent.seq <= this.lastSeenOutputSeq) throw new Error("Terminal output sequence is not strictly increasing");
|
|
2096
|
+
this.lastSeenOutputSeq = exactEvent.seq;
|
|
2097
|
+
this.latestOutputSeq = Math.max(this.latestOutputSeq, exactEvent.seq);
|
|
2098
|
+
}
|
|
2099
|
+
const ordinal = ++this.lastOrdinal;
|
|
2100
|
+
if (this.activeEntryCount() === 0) this.retainedStartOrdinal = ordinal;
|
|
2101
|
+
const entry = {
|
|
2102
|
+
ordinal,
|
|
2103
|
+
event: exactEvent
|
|
2104
|
+
};
|
|
2105
|
+
this.entries.push(entry);
|
|
2106
|
+
if (exactEvent.type === "output") this.outputEntries.push({
|
|
2107
|
+
ordinal,
|
|
2108
|
+
seq: exactEvent.seq
|
|
2109
|
+
});
|
|
2110
|
+
this.retainedBytes += this.eventBytes(exactEvent);
|
|
2111
|
+
this.trim();
|
|
2112
|
+
this.wake();
|
|
2113
|
+
}
|
|
2114
|
+
end() {
|
|
2115
|
+
this.ended = true;
|
|
2116
|
+
this.wake();
|
|
2117
|
+
}
|
|
2118
|
+
get cursors() {
|
|
2119
|
+
return {
|
|
2120
|
+
earliest: this.earliestOutputSeq,
|
|
2121
|
+
latest: this.latestOutputSeq
|
|
2122
|
+
};
|
|
2123
|
+
}
|
|
2124
|
+
async *read(since, signal) {
|
|
2125
|
+
signal?.throwIfAborted();
|
|
2126
|
+
const cursor = since ?? this.earliestOutputSeq;
|
|
2127
|
+
this.assertCursor(cursor);
|
|
2128
|
+
let ordinal = this.ordinalForCursor(cursor);
|
|
2129
|
+
let outputCursor = cursor;
|
|
2130
|
+
while (true) {
|
|
2131
|
+
signal?.throwIfAborted();
|
|
2132
|
+
if (this.evictedOutputOrdinal > ordinal) throw new Error("Terminal output was evicted before this consumer could read it");
|
|
2133
|
+
const entryIndex = this.indexAfterOrdinal(ordinal);
|
|
2134
|
+
const entry = this.entries[this.entryStartIndex + entryIndex];
|
|
2135
|
+
if (entry !== void 0) {
|
|
2136
|
+
ordinal = entry.ordinal;
|
|
2137
|
+
if (entry.event.type === "output" && entry.event.seq <= outputCursor) continue;
|
|
2138
|
+
if (entry.event.type === "output") outputCursor = entry.event.seq;
|
|
2139
|
+
yield entry.event;
|
|
2140
|
+
signal?.throwIfAborted();
|
|
2141
|
+
continue;
|
|
2142
|
+
}
|
|
2143
|
+
if (this.ended) return;
|
|
2144
|
+
await this.waitForFrames(signal);
|
|
2145
|
+
}
|
|
2146
|
+
}
|
|
2147
|
+
validateEvent(event) {
|
|
2148
|
+
return TerminalOutputEventSchema.parse(event);
|
|
2149
|
+
}
|
|
2150
|
+
eventBytes(event) {
|
|
2151
|
+
return event.type === "output" ? terminalTextEncoder.encode(event.data).byteLength : 64;
|
|
2152
|
+
}
|
|
2153
|
+
trim() {
|
|
2154
|
+
while (this.activeEntryCount() > MAX_RETAINED_TERMINAL_FRAMES || this.retainedBytes > MAX_RETAINED_TERMINAL_BYTES && this.activeEntryCount() > 1) {
|
|
2155
|
+
const dropped = this.entries[this.entryStartIndex];
|
|
2156
|
+
if (dropped === void 0) return;
|
|
2157
|
+
this.entryStartIndex += 1;
|
|
2158
|
+
this.retainedBytes -= this.eventBytes(dropped.event);
|
|
2159
|
+
if (dropped.event.type === "output") {
|
|
2160
|
+
this.earliestOutputSeq = Math.max(this.earliestOutputSeq, dropped.event.seq);
|
|
2161
|
+
this.evictedOutputOrdinal = dropped.ordinal;
|
|
2162
|
+
}
|
|
2163
|
+
}
|
|
2164
|
+
this.retainedStartOrdinal = this.entries[this.entryStartIndex]?.ordinal ?? this.lastOrdinal + 1;
|
|
2165
|
+
while (this.outputEntries[this.outputEntryStartIndex] !== void 0 && this.outputEntries[this.outputEntryStartIndex].ordinal < this.retainedStartOrdinal) this.outputEntryStartIndex += 1;
|
|
2166
|
+
this.compactRetainedEntries();
|
|
2167
|
+
}
|
|
2168
|
+
assertCursor(cursor) {
|
|
2169
|
+
if (!Number.isSafeInteger(cursor) || cursor < 0) throw new Error("Terminal replay cursor must be a non-negative integer");
|
|
2170
|
+
const { earliest, latest } = this.cursors;
|
|
2171
|
+
if (cursor < earliest) throw new Error(`Terminal replay cursor ${cursor} is older than ${earliest}`);
|
|
2172
|
+
if (cursor > latest) throw new Error(`Terminal replay cursor ${cursor} is ahead of ${latest}`);
|
|
2173
|
+
}
|
|
2174
|
+
ordinalForCursor(cursor) {
|
|
2175
|
+
let low = this.outputEntryStartIndex;
|
|
2176
|
+
let high = this.outputEntries.length - 1;
|
|
2177
|
+
let matchingOrdinal;
|
|
2178
|
+
while (low <= high) {
|
|
2179
|
+
const middle = low + Math.floor((high - low) / 2);
|
|
2180
|
+
const candidate = this.outputEntries[middle];
|
|
2181
|
+
if (candidate === void 0) break;
|
|
2182
|
+
if (candidate.seq <= cursor) {
|
|
2183
|
+
matchingOrdinal = candidate.ordinal;
|
|
2184
|
+
low = middle + 1;
|
|
2185
|
+
} else high = middle - 1;
|
|
2186
|
+
}
|
|
2187
|
+
if (matchingOrdinal !== void 0) return matchingOrdinal;
|
|
2188
|
+
if (cursor === this.earliestOutputSeq) return this.evictedOutputOrdinal;
|
|
2189
|
+
if (cursor <= this.latestOutputSeq) return this.lastOrdinal;
|
|
2190
|
+
throw new Error("Terminal replay cursor is not retained");
|
|
2191
|
+
}
|
|
2192
|
+
activeEntryCount() {
|
|
2193
|
+
return this.entries.length - this.entryStartIndex;
|
|
2194
|
+
}
|
|
2195
|
+
indexAfterOrdinal(ordinal) {
|
|
2196
|
+
const first = this.entries[this.entryStartIndex];
|
|
2197
|
+
if (first === void 0 || ordinal < first.ordinal) return 0;
|
|
2198
|
+
const last = this.entries[this.entries.length - 1];
|
|
2199
|
+
if (last === void 0 || ordinal >= last.ordinal) return this.activeEntryCount();
|
|
2200
|
+
return ordinal - first.ordinal + 1;
|
|
2201
|
+
}
|
|
2202
|
+
compactRetainedEntries() {
|
|
2203
|
+
if (this.entryStartIndex > 1024 && this.entryStartIndex * 2 >= this.entries.length) {
|
|
2204
|
+
this.entries = this.entries.slice(this.entryStartIndex);
|
|
2205
|
+
this.entryStartIndex = 0;
|
|
2206
|
+
}
|
|
2207
|
+
if (this.outputEntryStartIndex > 1024 && this.outputEntryStartIndex * 2 >= this.outputEntries.length) {
|
|
2208
|
+
this.outputEntries = this.outputEntries.slice(this.outputEntryStartIndex);
|
|
2209
|
+
this.outputEntryStartIndex = 0;
|
|
2210
|
+
}
|
|
2211
|
+
}
|
|
2212
|
+
waitForFrames(signal) {
|
|
2213
|
+
return new Promise((resolve, reject) => {
|
|
2214
|
+
let settled = false;
|
|
2215
|
+
const wake = () => {
|
|
2216
|
+
if (settled) return;
|
|
2217
|
+
settled = true;
|
|
2218
|
+
signal?.removeEventListener("abort", onAbort);
|
|
2219
|
+
this.waiters.delete(wake);
|
|
2220
|
+
resolve();
|
|
2221
|
+
};
|
|
2222
|
+
const onAbort = () => {
|
|
2223
|
+
if (settled) return;
|
|
2224
|
+
settled = true;
|
|
2225
|
+
this.waiters.delete(wake);
|
|
2226
|
+
reject(signal?.reason instanceof Error ? signal.reason : new DOMException("Terminal event read was aborted", "AbortError"));
|
|
2227
|
+
};
|
|
2228
|
+
this.waiters.add(wake);
|
|
2229
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
2230
|
+
if (signal?.aborted) onAbort();
|
|
2231
|
+
});
|
|
2232
|
+
}
|
|
2233
|
+
wake() {
|
|
2234
|
+
for (const waiter of [...this.waiters]) waiter();
|
|
2235
|
+
}
|
|
2236
|
+
};
|
|
2237
|
+
/** Create a capture that preserves output sequence and UTF-8 boundaries. */
|
|
2238
|
+
function createInteractiveTerminalCapture() {
|
|
2239
|
+
const log = new InteractiveTerminalFrameLog();
|
|
2240
|
+
const decoder = new TextDecoder();
|
|
2241
|
+
let ready;
|
|
2242
|
+
let failure;
|
|
2243
|
+
const exit = { seen: false };
|
|
2244
|
+
let explicitClose = false;
|
|
2245
|
+
const fail = (error) => {
|
|
2246
|
+
failure ??= error;
|
|
2247
|
+
log.append({
|
|
2248
|
+
type: "error",
|
|
2249
|
+
message: error.message
|
|
2250
|
+
});
|
|
2251
|
+
log.end();
|
|
2252
|
+
};
|
|
2253
|
+
return {
|
|
2254
|
+
handlers: {
|
|
2255
|
+
onReady: (info) => {
|
|
2256
|
+
ready = info;
|
|
2257
|
+
if (info.cursors === void 0) {
|
|
2258
|
+
fail(/* @__PURE__ */ new Error("Exact terminal ready message has no replay cursors"));
|
|
2259
|
+
return;
|
|
2260
|
+
}
|
|
2261
|
+
try {
|
|
2262
|
+
log.configure(info.cursors);
|
|
2263
|
+
log.append({ type: "ready" });
|
|
2264
|
+
} catch (error) {
|
|
2265
|
+
fail(error instanceof Error ? error : new Error(String(error)));
|
|
2266
|
+
}
|
|
2267
|
+
},
|
|
2268
|
+
onOutput: (seq, bytes) => {
|
|
2269
|
+
try {
|
|
2270
|
+
log.append({
|
|
2271
|
+
type: "output",
|
|
2272
|
+
seq,
|
|
2273
|
+
data: decoder.decode(bytes)
|
|
2274
|
+
});
|
|
2275
|
+
} catch (error) {
|
|
2276
|
+
fail(error instanceof Error ? error : new Error(String(error)));
|
|
2277
|
+
}
|
|
2278
|
+
},
|
|
2279
|
+
onData: () => {
|
|
2280
|
+
fail(/* @__PURE__ */ new Error("Exact terminal transport returned unsequenced binary output"));
|
|
2281
|
+
},
|
|
2282
|
+
onExit: (info) => {
|
|
2283
|
+
try {
|
|
2284
|
+
exit.seen = true;
|
|
2285
|
+
exit.exitCode = info.exitCode;
|
|
2286
|
+
exit.exitSignal = info.exitSignal;
|
|
2287
|
+
log.append({
|
|
2288
|
+
type: "exit",
|
|
2289
|
+
...info.exitCode === void 0 ? {} : { exitCode: info.exitCode },
|
|
2290
|
+
...info.exitSignal === void 0 ? {} : { exitSignal: info.exitSignal }
|
|
2291
|
+
});
|
|
2292
|
+
log.end();
|
|
2293
|
+
} catch (error) {
|
|
2294
|
+
fail(error instanceof Error ? error : new Error(String(error)));
|
|
2295
|
+
}
|
|
2296
|
+
},
|
|
2297
|
+
onError: (error) => fail(error),
|
|
2298
|
+
onClose: (code, reason) => {
|
|
2299
|
+
try {
|
|
2300
|
+
if (exit.seen || explicitClose || failure !== void 0) {
|
|
2301
|
+
log.end();
|
|
2302
|
+
return;
|
|
2303
|
+
}
|
|
2304
|
+
fail(/* @__PURE__ */ new Error(`Terminal connection closed before the process exited (code ${code}${reason ? `: ${reason}` : ""})`));
|
|
2305
|
+
} catch (error) {
|
|
2306
|
+
fail(error instanceof Error ? error : new Error(String(error)));
|
|
2307
|
+
}
|
|
2308
|
+
}
|
|
2309
|
+
},
|
|
2310
|
+
log,
|
|
2311
|
+
markExplicitClose: () => {
|
|
2312
|
+
explicitClose = true;
|
|
2313
|
+
},
|
|
2314
|
+
flushOutput: () => {},
|
|
2315
|
+
get ready() {
|
|
2316
|
+
return ready;
|
|
2317
|
+
},
|
|
2318
|
+
get failure() {
|
|
2319
|
+
return failure;
|
|
2320
|
+
},
|
|
2321
|
+
exit
|
|
2322
|
+
};
|
|
2323
|
+
}
|
|
2324
|
+
/** Build the provider-neutral ref from server metadata and exact authority. */
|
|
2325
|
+
function createInteractiveTerminalSession(options) {
|
|
2326
|
+
const { stream, capture, metadata, ref, parentExecutionId, control } = options;
|
|
2327
|
+
const ready = capture.ready ?? stream.ready;
|
|
2328
|
+
const cursors = ready.cursors;
|
|
2329
|
+
if (cursors === void 0) throw new Error("Exact terminal ready message has no replay cursors");
|
|
2330
|
+
if (capture.failure !== void 0) throw capture.failure;
|
|
2331
|
+
if (!agentInteractiveSessionControlClaimMatchesRef(ref, control)) throw new Error("Exact terminal control claim is not bound");
|
|
2332
|
+
if (ready.attachCount === void 0) throw new Error("Exact terminal ready message has no attach count");
|
|
2333
|
+
if (metadata.sessionId !== ready.sessionId) throw new Error("Terminal metadata does not match the attached session");
|
|
2334
|
+
if (metadata.connectionId !== void 0 && metadata.connectionId !== ready.connectionId) throw new Error("Terminal metadata does not match the attached connection");
|
|
2335
|
+
const required = {
|
|
2336
|
+
name: metadata.name,
|
|
2337
|
+
shell: metadata.shell,
|
|
2338
|
+
cwd: metadata.cwd,
|
|
2339
|
+
cols: metadata.cols,
|
|
2340
|
+
rows: metadata.rows,
|
|
2341
|
+
createdAt: metadata.createdAt,
|
|
2342
|
+
lastActivityAt: metadata.lastActivityAt,
|
|
2343
|
+
isRunning: metadata.isRunning
|
|
2344
|
+
};
|
|
2345
|
+
if (typeof required.name !== "string" || typeof required.shell !== "string" || typeof required.cwd !== "string" || !Number.isSafeInteger(required.cols) || !Number.isSafeInteger(required.rows) || typeof required.createdAt !== "string" || typeof required.lastActivityAt !== "string" || typeof required.isRunning !== "boolean") throw new Error("Terminal metadata omits required provider facts");
|
|
2346
|
+
const terminalRef = TerminalSessionRefSchema.parse({
|
|
2347
|
+
terminalSessionId: ready.sessionId,
|
|
2348
|
+
parentExecutionId,
|
|
2349
|
+
name: required.name,
|
|
2350
|
+
shell: required.shell,
|
|
2351
|
+
...metadata.command === void 0 ? {} : { command: metadata.command },
|
|
2352
|
+
cwd: required.cwd,
|
|
2353
|
+
cols: required.cols,
|
|
2354
|
+
rows: required.rows,
|
|
2355
|
+
connectionId: ready.connectionId,
|
|
2356
|
+
createdAt: required.createdAt,
|
|
2357
|
+
lastActivityAt: required.lastActivityAt,
|
|
2358
|
+
expiresAt: control.expiresAt,
|
|
2359
|
+
isRunning: required.isRunning,
|
|
2360
|
+
...metadata.exitCode === void 0 ? {} : { exitCode: metadata.exitCode },
|
|
2361
|
+
...metadata.exitSignal === void 0 ? {} : { exitSignal: metadata.exitSignal },
|
|
2362
|
+
attachCount: ready.attachCount
|
|
2363
|
+
});
|
|
2364
|
+
if (ref.run.executionId !== parentExecutionId || ref.run.sessionId !== metadata.sessionId) throw new Error("Interactive terminal ref does not match its parent execution");
|
|
2365
|
+
return new InteractiveTerminalSessionImpl(terminalRef, cursors, control, stream, capture.log, capture, capture.exit);
|
|
2366
|
+
}
|
|
2367
|
+
var InteractiveTerminalSessionImpl = class {
|
|
2368
|
+
detached = false;
|
|
2369
|
+
constructor(initialRef, initialCursors, control, stream, log, capture, exit = void 0) {
|
|
2370
|
+
this.initialRef = initialRef;
|
|
2371
|
+
this.initialCursors = initialCursors;
|
|
2372
|
+
this.control = control;
|
|
2373
|
+
this.stream = stream;
|
|
2374
|
+
this.log = log;
|
|
2375
|
+
this.capture = capture;
|
|
2376
|
+
this.exit = exit;
|
|
2377
|
+
}
|
|
2378
|
+
get ref() {
|
|
2379
|
+
return TerminalSessionRefSchema.parse({
|
|
2380
|
+
...this.initialRef,
|
|
2381
|
+
isRunning: this.initialRef.isRunning && !(this.exit?.seen ?? false),
|
|
2382
|
+
...this.exit?.exitCode === void 0 ? {} : { exitCode: this.exit.exitCode },
|
|
2383
|
+
...this.exit?.exitSignal === void 0 ? {} : { exitSignal: this.exit.exitSignal }
|
|
2384
|
+
});
|
|
2385
|
+
}
|
|
2386
|
+
get cursors() {
|
|
2387
|
+
return this.log.cursors.latest === 0 && this.initialCursors.latest > 0 ? this.initialCursors : this.log.cursors;
|
|
2388
|
+
}
|
|
2389
|
+
async input(input, options) {
|
|
2390
|
+
const exactInput = TerminalInputSchema.parse(input);
|
|
2391
|
+
this.assertWritable(options);
|
|
2392
|
+
this.stream.write(exactInput.data);
|
|
2393
|
+
}
|
|
2394
|
+
async resize(resize, options) {
|
|
2395
|
+
const exactResize = TerminalResizeSchema.parse(resize);
|
|
2396
|
+
this.assertWritable(options);
|
|
2397
|
+
this.capture.flushOutput();
|
|
2398
|
+
this.stream.resize(exactResize.cols, exactResize.rows);
|
|
2399
|
+
this.log.append({
|
|
2400
|
+
type: "resize",
|
|
2401
|
+
cols: exactResize.cols,
|
|
2402
|
+
rows: exactResize.rows
|
|
2403
|
+
});
|
|
2404
|
+
}
|
|
2405
|
+
async detach(options) {
|
|
2406
|
+
options?.signal?.throwIfAborted();
|
|
2407
|
+
if (!this.detached) {
|
|
2408
|
+
this.capture.markExplicitClose();
|
|
2409
|
+
this.capture.flushOutput();
|
|
2410
|
+
await this.stream.close();
|
|
2411
|
+
this.detached = true;
|
|
2412
|
+
this.log.end();
|
|
2413
|
+
}
|
|
2414
|
+
return {
|
|
2415
|
+
status: "detached",
|
|
2416
|
+
terminalSessionId: this.initialRef.terminalSessionId,
|
|
2417
|
+
connectionId: this.initialRef.connectionId
|
|
2418
|
+
};
|
|
2419
|
+
}
|
|
2420
|
+
async close(options) {
|
|
2421
|
+
options?.signal?.throwIfAborted();
|
|
2422
|
+
if (!this.detached) {
|
|
2423
|
+
this.capture.markExplicitClose();
|
|
2424
|
+
this.capture.flushOutput();
|
|
2425
|
+
await this.stream.close();
|
|
2426
|
+
this.detached = true;
|
|
2427
|
+
this.log.end();
|
|
2428
|
+
}
|
|
2429
|
+
if (this.exit?.seen) return {
|
|
2430
|
+
status: "closed",
|
|
2431
|
+
terminalSessionId: this.initialRef.terminalSessionId,
|
|
2432
|
+
...this.exit.exitCode === void 0 ? {} : { exitCode: this.exit.exitCode },
|
|
2433
|
+
...this.exit.exitSignal === void 0 ? {} : { exitSignal: this.exit.exitSignal }
|
|
2434
|
+
};
|
|
2435
|
+
return {
|
|
2436
|
+
status: "unknown",
|
|
2437
|
+
terminalSessionId: this.initialRef.terminalSessionId,
|
|
2438
|
+
message: "The terminal connection closed, but only the interactive stop operation can prove process termination.",
|
|
2439
|
+
retryable: false
|
|
2440
|
+
};
|
|
2441
|
+
}
|
|
2442
|
+
events(options) {
|
|
2443
|
+
return this.log.read(options?.since, options?.signal);
|
|
2444
|
+
}
|
|
2445
|
+
assertWritable(options) {
|
|
2446
|
+
options?.signal?.throwIfAborted();
|
|
2447
|
+
if (this.detached) throw new Error("Terminal connection is detached");
|
|
2448
|
+
if (!terminalSessionUsable(this.ref, (/* @__PURE__ */ new Date()).toISOString()) || this.exit?.seen) throw new Error("Terminal connection is no longer writable");
|
|
2449
|
+
}
|
|
2450
|
+
};
|
|
2451
|
+
//#endregion
|
|
2017
2452
|
//#region src/interactive.ts
|
|
2018
2453
|
/**
|
|
2019
2454
|
* Exact native coding-agent sessions on the public SDK.
|
|
@@ -2042,7 +2477,7 @@ function createInteractiveSessionController(host, sessionId, ref, holderId) {
|
|
|
2042
2477
|
* Handle for one exact interactive harness session.
|
|
2043
2478
|
*
|
|
2044
2479
|
* `start()` binds the returned ref and control for prompt and stop commands.
|
|
2045
|
-
* Attach
|
|
2480
|
+
* Attach claims fresh control unless the caller supplies an exact active claim.
|
|
2046
2481
|
*/
|
|
2047
2482
|
var InteractiveSessionHandle = class {
|
|
2048
2483
|
ref;
|
|
@@ -2050,6 +2485,8 @@ var InteractiveSessionHandle = class {
|
|
|
2050
2485
|
attachHolderId = createInteractiveControlHolderId("sdk");
|
|
2051
2486
|
attachController;
|
|
2052
2487
|
attachInFlight;
|
|
2488
|
+
agentTerminalAttachInFlight;
|
|
2489
|
+
agentTerminalAttachDigest;
|
|
2053
2490
|
constructor(host, sessionId, options = {}) {
|
|
2054
2491
|
this.host = host;
|
|
2055
2492
|
this.sessionId = sessionId;
|
|
@@ -2104,19 +2541,44 @@ var InteractiveSessionHandle = class {
|
|
|
2104
2541
|
}
|
|
2105
2542
|
attach(request = {}, options) {
|
|
2106
2543
|
options?.signal?.throwIfAborted();
|
|
2107
|
-
|
|
2544
|
+
const suppliedRequest = request;
|
|
2545
|
+
const explicitControl = suppliedRequest.control !== void 0;
|
|
2546
|
+
if (this.attachInFlight !== void 0) {
|
|
2547
|
+
if (explicitControl) throw new Error(`Interactive session ${this.sessionId} cannot attach with an exact control while another attach is in flight`);
|
|
2548
|
+
return awaitWithAbort(this.attachInFlight, options?.signal);
|
|
2549
|
+
}
|
|
2108
2550
|
const ref = this.requireRef();
|
|
2109
2551
|
let controller = this.attachController;
|
|
2110
2552
|
if (controller === void 0) {
|
|
2111
2553
|
controller = createInteractiveSessionController(this.host, this.sessionId, ref, this.attachHolderId);
|
|
2112
2554
|
this.attachController = controller;
|
|
2113
2555
|
}
|
|
2114
|
-
|
|
2115
|
-
|
|
2556
|
+
let exactIdentity;
|
|
2557
|
+
let attachRequest = suppliedRequest;
|
|
2558
|
+
if (explicitControl) {
|
|
2559
|
+
const { control, handlers, ...wireRequest } = suppliedRequest;
|
|
2560
|
+
const exactAttach = AgentInteractiveSessionAttachSchema.parse({
|
|
2561
|
+
...wireRequest,
|
|
2562
|
+
control
|
|
2563
|
+
});
|
|
2564
|
+
if (!agentInteractiveSessionControlClaimMatchesRef(ref, exactAttach.control)) throw new Error(`Interactive session ${this.sessionId} attach is bound to a different exact control claim`);
|
|
2565
|
+
assertActiveInteractiveControlClaim(exactAttach.control);
|
|
2566
|
+
exactIdentity = {
|
|
2567
|
+
ref,
|
|
2568
|
+
control: exactAttach.control
|
|
2569
|
+
};
|
|
2570
|
+
attachRequest = {
|
|
2571
|
+
...wireRequest,
|
|
2572
|
+
...handlers === void 0 ? {} : { handlers }
|
|
2573
|
+
};
|
|
2574
|
+
}
|
|
2575
|
+
const operation = (async () => {
|
|
2576
|
+
const identity = exactIdentity === void 0 ? await controller.resolve(options) : exactIdentity;
|
|
2577
|
+
const stream = await controller.attachWithIdentity(identity, attachRequest, options);
|
|
2116
2578
|
this.ref = identity.ref;
|
|
2117
2579
|
this.control = identity.control;
|
|
2118
2580
|
return stream;
|
|
2119
|
-
});
|
|
2581
|
+
})();
|
|
2120
2582
|
let tracked;
|
|
2121
2583
|
tracked = operation.finally(() => {
|
|
2122
2584
|
if (this.attachInFlight === tracked) this.attachInFlight = void 0;
|
|
@@ -2124,6 +2586,54 @@ var InteractiveSessionHandle = class {
|
|
|
2124
2586
|
this.attachInFlight = tracked;
|
|
2125
2587
|
return tracked;
|
|
2126
2588
|
}
|
|
2589
|
+
/** Attach the native terminal with server-issued replay identity. */
|
|
2590
|
+
attachAgentTerminal(request, options) {
|
|
2591
|
+
options?.signal?.throwIfAborted();
|
|
2592
|
+
const binding = this.requireBinding();
|
|
2593
|
+
const exactRequest = AgentInteractiveSessionAttachSchema.parse(request);
|
|
2594
|
+
if (!agentInteractiveSessionControlClaimMatchesRef(binding.ref, exactRequest.control) || canonicalCandidateDigest(exactRequest.control) !== canonicalCandidateDigest(binding.control)) throw new Error(`Interactive session ${this.sessionId} terminal attach is bound to a different active control claim`);
|
|
2595
|
+
const requestDigest = canonicalCandidateDigest(exactRequest);
|
|
2596
|
+
if (this.agentTerminalAttachInFlight !== void 0) {
|
|
2597
|
+
if (this.agentTerminalAttachDigest !== requestDigest) throw new Error(`Interactive session ${this.sessionId} cannot attach with a different terminal request while another attach is in flight`);
|
|
2598
|
+
return awaitWithAbort(this.agentTerminalAttachInFlight, options?.signal);
|
|
2599
|
+
}
|
|
2600
|
+
const capture = createInteractiveTerminalCapture();
|
|
2601
|
+
const operation = (async () => {
|
|
2602
|
+
const stream = await this.attach({
|
|
2603
|
+
...exactRequest,
|
|
2604
|
+
handlers: capture.handlers
|
|
2605
|
+
}, options);
|
|
2606
|
+
try {
|
|
2607
|
+
if (capture.failure !== void 0) throw capture.failure;
|
|
2608
|
+
const ready = capture.ready ?? stream.ready;
|
|
2609
|
+
const metadataReader = this.host._interactiveTerminalInfo;
|
|
2610
|
+
if (metadataReader === void 0) throw new Error("Sandbox runtime exposes no exact interactive terminal metadata");
|
|
2611
|
+
const metadata = options === void 0 ? await metadataReader(this.sessionId, ready.sessionId) : await metadataReader(this.sessionId, ready.sessionId, options);
|
|
2612
|
+
if (metadata === null) throw new Error(`Interactive terminal ${ready.sessionId} metadata is unavailable`);
|
|
2613
|
+
return createInteractiveTerminalSession({
|
|
2614
|
+
stream,
|
|
2615
|
+
capture,
|
|
2616
|
+
metadata,
|
|
2617
|
+
ref: binding.ref,
|
|
2618
|
+
parentExecutionId: binding.ref.run.executionId,
|
|
2619
|
+
control: binding.control
|
|
2620
|
+
});
|
|
2621
|
+
} catch (error) {
|
|
2622
|
+
await stream.close().catch(() => {});
|
|
2623
|
+
throw error;
|
|
2624
|
+
}
|
|
2625
|
+
})();
|
|
2626
|
+
let tracked;
|
|
2627
|
+
tracked = operation.finally(() => {
|
|
2628
|
+
if (this.agentTerminalAttachInFlight === tracked) {
|
|
2629
|
+
this.agentTerminalAttachInFlight = void 0;
|
|
2630
|
+
this.agentTerminalAttachDigest = void 0;
|
|
2631
|
+
}
|
|
2632
|
+
});
|
|
2633
|
+
this.agentTerminalAttachInFlight = tracked;
|
|
2634
|
+
this.agentTerminalAttachDigest = requestDigest;
|
|
2635
|
+
return awaitWithAbort(tracked, options?.signal);
|
|
2636
|
+
}
|
|
2127
2637
|
status(options) {
|
|
2128
2638
|
options?.signal?.throwIfAborted();
|
|
2129
2639
|
const ref = this.requireRef();
|
|
@@ -2170,6 +2680,10 @@ var InteractiveSessionHandle = class {
|
|
|
2170
2680
|
});
|
|
2171
2681
|
}
|
|
2172
2682
|
};
|
|
2683
|
+
function assertActiveInteractiveControlClaim(control) {
|
|
2684
|
+
const expiresAt = Date.parse(control.expiresAt);
|
|
2685
|
+
if (!Number.isFinite(expiresAt) || expiresAt <= Date.now()) throw new Error("Interactive control claim is stale");
|
|
2686
|
+
}
|
|
2173
2687
|
//#endregion
|
|
2174
2688
|
//#region src/session.ts
|
|
2175
2689
|
/**
|
|
@@ -2691,9 +3205,12 @@ function normalizeSandboxCreateReceipt(raw) {
|
|
|
2691
3205
|
const record = raw;
|
|
2692
3206
|
const idempotencyKeyApplied = record.idempotencyKeyApplied;
|
|
2693
3207
|
if (typeof idempotencyKeyApplied !== "boolean") return null;
|
|
3208
|
+
const outcome = SANDBOX_CREATE_OUTCOMES.includes(record.outcome) ? record.outcome : "unknown";
|
|
3209
|
+
const injectedSecrets = Array.isArray(record.injectedSecrets) ? record.injectedSecrets.filter((name) => typeof name === "string") : void 0;
|
|
2694
3210
|
return {
|
|
2695
|
-
outcome
|
|
2696
|
-
idempotencyKeyApplied
|
|
3211
|
+
outcome,
|
|
3212
|
+
idempotencyKeyApplied,
|
|
3213
|
+
...injectedSecrets ? { injectedSecrets } : {}
|
|
2697
3214
|
};
|
|
2698
3215
|
}
|
|
2699
3216
|
/**
|
|
@@ -7163,6 +7680,14 @@ var SandboxInstance = class SandboxInstance {
|
|
|
7163
7680
|
async _attachInteractive(id, ref, request, options, reconnectAuthority) {
|
|
7164
7681
|
return this.interactiveTerminalOperations._attachInteractive(id, ref, request, options, reconnectAuthority);
|
|
7165
7682
|
}
|
|
7683
|
+
/** @internal — read exact terminal facts from the runtime-owned manager. */
|
|
7684
|
+
async _interactiveTerminalInfo(id, terminalId, options) {
|
|
7685
|
+
options?.signal?.throwIfAborted();
|
|
7686
|
+
if (id !== this.id) throw new ValidationError("Interactive terminal metadata request does not belong to this sandbox");
|
|
7687
|
+
const metadata = await this.runtime.terminals.get(terminalId);
|
|
7688
|
+
options?.signal?.throwIfAborted();
|
|
7689
|
+
return metadata;
|
|
7690
|
+
}
|
|
7166
7691
|
/** @internal — delegated to the native interactive operations module. */
|
|
7167
7692
|
async _attachTerminal(connectionId, options = {}) {
|
|
7168
7693
|
return this.interactiveTerminalOperations._attachTerminal(connectionId, options);
|
|
@@ -7411,4 +7936,4 @@ function quoteForShell(value) {
|
|
|
7411
7936
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
7412
7937
|
}
|
|
7413
7938
|
//#endregion
|
|
7414
|
-
export {
|
|
7939
|
+
export { toOtelJson as A, collectAgentResponseText as C, buildTraceExportPayload as D, normalizeConnection as E, exportTraceBundle as O, collectAgentFinalMessageText as S, isToolBearingEvent as T, TerminalStream as _, WorkspaceImages as a, requestInteractiveSessionToken as b, SandboxTaskSession as c, agentInteractiveSessionPromptRequestDigest as d, InteractiveTerminalFrameLog as f, InteractiveSessionController as g, BrowserInteractiveSessionController as h, normalizeStartupDiagnostics as i, otelTraceIdForTangleTrace as k, SandboxSession as l, createInteractiveTerminalSession as m, createSandboxInstanceFromResponse as n, GPU_LEASE_PROVIDER_NAMES as o, createInteractiveTerminalCapture as p, normalizeSandboxCreateReceipt as r, MAX_EGRESS_DENIALS_LIMIT as s, SandboxInstance as t, InteractiveSessionHandle as u, TerminalStreamError as v, getSandboxEventText as w, applySandboxEventText as x, TERMINAL_WS_ECHO_SUBPROTOCOL as y };
|
package/dist/tangle/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as TANGLE_JOBS_CONTRACT, c as AgentSandboxBlueprintAbi, d as SandboxCreateParamTypes, f as SandboxCreateResponseParamTypes, i as TANGLE_CHAIN_ID, l as ITangleJobsAbi, n as JOB_SANDBOX_CREATE, o as TANGLE_MAINNET_RPC, p as SandboxIdParamTypes, r as JOB_SANDBOX_DELETE, s as TangleSandboxClientConfig, t as TangleSandboxClient, u as JsonResponseParamTypes } from "../index-
|
|
1
|
+
import { a as TANGLE_JOBS_CONTRACT, c as AgentSandboxBlueprintAbi, d as SandboxCreateParamTypes, f as SandboxCreateResponseParamTypes, i as TANGLE_CHAIN_ID, l as ITangleJobsAbi, n as JOB_SANDBOX_CREATE, o as TANGLE_MAINNET_RPC, p as SandboxIdParamTypes, r as JOB_SANDBOX_DELETE, s as TangleSandboxClientConfig, t as TangleSandboxClient, u as JsonResponseParamTypes } from "../index-DiJ3NxHB.js";
|
|
2
2
|
export { AgentSandboxBlueprintAbi, ITangleJobsAbi, JOB_SANDBOX_CREATE, JOB_SANDBOX_DELETE, JsonResponseParamTypes, SandboxCreateParamTypes, SandboxCreateResponseParamTypes, SandboxIdParamTypes, TANGLE_CHAIN_ID, TANGLE_JOBS_CONTRACT, TANGLE_MAINNET_RPC, TangleSandboxClient, TangleSandboxClientConfig };
|