@opengeni/runtime 3.0.0-canary.0 → 3.0.1-canary.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/{chunk-46BFUGFL.js → chunk-FQM5VV5D.js} +243 -49
- package/dist/chunk-FQM5VV5D.js.map +1 -0
- package/dist/{chunk-46VVJC6K.js → chunk-KBYDX5N6.js} +21 -11
- package/dist/chunk-KBYDX5N6.js.map +1 -0
- package/dist/index.js +6 -2
- package/dist/operational-instructions.d.ts +1 -1
- package/dist/sandbox/index.d.ts +1 -0
- package/dist/sandbox/index.js +5 -1
- package/dist/sandbox/materialization-verification-error.d.ts +27 -0
- package/dist/sandbox/providers/modal-command-control.d.ts +6 -0
- package/dist/sandbox/providers/modal-command-session.d.ts +1 -0
- package/dist/sandbox/providers/modal-materialization-verification.d.ts +7 -0
- package/dist/sandbox/routing/routing-session.d.ts +4 -0
- package/dist/workspace-tool-gateway.js +2 -2
- package/package.json +11 -11
- package/src/bundled_default_skills/opengeni-help/SKILL.md +103 -0
- package/src/index.ts +9 -4
- package/src/operational-instructions.ts +2 -0
- package/src/sandbox/index.ts +6 -0
- package/src/sandbox/materialization-verification-error.ts +65 -0
- package/src/sandbox/providers/modal-command-control.ts +49 -4
- package/src/sandbox/providers/modal-command-session.ts +4 -0
- package/src/sandbox/providers/modal-materialization-verification.ts +122 -0
- package/src/sandbox/routing/routing-session.ts +75 -10
- package/dist/chunk-46BFUGFL.js.map +0 -1
- package/dist/chunk-46VVJC6K.js.map +0 -1
|
@@ -15860,6 +15860,36 @@ function admittedProviderCommandHandle() {
|
|
|
15860
15860
|
return admission.getStore();
|
|
15861
15861
|
}
|
|
15862
15862
|
|
|
15863
|
+
// src/sandbox/materialization-verification-error.ts
|
|
15864
|
+
var EXPLANATIONS = {
|
|
15865
|
+
path_not_visible: "the provider could not see the destination path",
|
|
15866
|
+
command_failed: "the visibility-check command exited unsuccessfully",
|
|
15867
|
+
command_pending: "the visibility-check command was still running; path visibility is unconfirmed",
|
|
15868
|
+
invalid_response: "the visibility check returned no valid success confirmation",
|
|
15869
|
+
command_error: "the provider could not complete the visibility-check command"
|
|
15870
|
+
};
|
|
15871
|
+
var SandboxMaterializationVerificationError = class extends Error {
|
|
15872
|
+
constructor(diagnostic, options) {
|
|
15873
|
+
super(
|
|
15874
|
+
`Sandbox materialization verification failed: ${EXPLANATIONS[diagnostic.reason]}: ${diagnostic.path}`,
|
|
15875
|
+
options
|
|
15876
|
+
);
|
|
15877
|
+
this.diagnostic = diagnostic;
|
|
15878
|
+
this.name = "SandboxMaterializationVerificationError";
|
|
15879
|
+
}
|
|
15880
|
+
code = "sandbox_materialization_verification_failed";
|
|
15881
|
+
};
|
|
15882
|
+
var providerDiagnostics = /* @__PURE__ */ new WeakMap();
|
|
15883
|
+
function retainMaterializationVerificationDiagnostic(error, diagnostic) {
|
|
15884
|
+
if (error !== null && (typeof error === "object" || typeof error === "function")) {
|
|
15885
|
+
providerDiagnostics.set(error, diagnostic);
|
|
15886
|
+
}
|
|
15887
|
+
}
|
|
15888
|
+
function materializationVerificationDiagnostic(error) {
|
|
15889
|
+
if (error instanceof SandboxMaterializationVerificationError) return error.diagnostic;
|
|
15890
|
+
return error !== null && (typeof error === "object" || typeof error === "function") ? providerDiagnostics.get(error) : void 0;
|
|
15891
|
+
}
|
|
15892
|
+
|
|
15863
15893
|
// src/sandbox/routing/routing-session.ts
|
|
15864
15894
|
import { CAPABILITY_DESCRIPTORS as CAPABILITY_DESCRIPTORS2 } from "@opengeni/contracts";
|
|
15865
15895
|
|
|
@@ -17305,11 +17335,13 @@ var RoutingSandboxSession = class {
|
|
|
17305
17335
|
async invokeProviderOperation(op, backend, fn, onCaptureWait) {
|
|
17306
17336
|
const startedAt = performance.now();
|
|
17307
17337
|
let outcome = "failed";
|
|
17338
|
+
let materializationFailureReason;
|
|
17308
17339
|
try {
|
|
17309
17340
|
const result = await withSandboxProviderOperation(backend.session, fn, onCaptureWait);
|
|
17310
17341
|
outcome = "ok";
|
|
17311
17342
|
return result;
|
|
17312
17343
|
} catch (error) {
|
|
17344
|
+
materializationFailureReason = materializationVerificationDiagnostic(error)?.reason;
|
|
17313
17345
|
if ((op === "readFile" || op === "listDir" || op === "pathExists" || op === "viewImage") && isDefinitePathNotFoundError(error)) {
|
|
17314
17346
|
outcome = "not_found";
|
|
17315
17347
|
}
|
|
@@ -17320,7 +17352,8 @@ var RoutingSandboxSession = class {
|
|
|
17320
17352
|
backend: backend.kind,
|
|
17321
17353
|
op,
|
|
17322
17354
|
outcome,
|
|
17323
|
-
durationMs: Math.max(0, performance.now() - startedAt)
|
|
17355
|
+
durationMs: Math.max(0, performance.now() - startedAt),
|
|
17356
|
+
...materializationFailureReason ? { materializationFailureReason } : {}
|
|
17324
17357
|
});
|
|
17325
17358
|
} catch {
|
|
17326
17359
|
}
|
|
@@ -17793,6 +17826,9 @@ var RoutingSandboxSession = class {
|
|
|
17793
17826
|
};
|
|
17794
17827
|
var MATERIALIZED_PATH_MARKER = "__OPENGENI_MATERIALIZED_PATH_VISIBLE__";
|
|
17795
17828
|
async function assertProviderCanSeeMaterializedPath(session, path) {
|
|
17829
|
+
if (session.verifyMaterializedPath) {
|
|
17830
|
+
return session.verifyMaterializedPath(path, providerManifestRoot(session) ?? "/workspace");
|
|
17831
|
+
}
|
|
17796
17832
|
const command = `test -e ${shellSingleQuote(path)} && printf %s ${shellSingleQuote(
|
|
17797
17833
|
MATERIALIZED_PATH_MARKER
|
|
17798
17834
|
)}`;
|
|
@@ -17804,18 +17840,56 @@ async function assertProviderCanSeeMaterializedPath(session, path) {
|
|
|
17804
17840
|
tty: false
|
|
17805
17841
|
};
|
|
17806
17842
|
let output;
|
|
17807
|
-
|
|
17808
|
-
|
|
17809
|
-
} else if (session.exec) {
|
|
17810
|
-
output = formatExecResult(await session.exec(args));
|
|
17811
|
-
} else {
|
|
17843
|
+
let result;
|
|
17844
|
+
if (!session.execCommand && !session.exec) {
|
|
17812
17845
|
throw new RoutingUnsupportedError("materializeEntry.verify", "unknown");
|
|
17813
17846
|
}
|
|
17814
|
-
|
|
17815
|
-
|
|
17816
|
-
|
|
17817
|
-
|
|
17847
|
+
try {
|
|
17848
|
+
result = session.execCommand ? await session.execCommand(args) : await session.exec(args);
|
|
17849
|
+
} catch (cause) {
|
|
17850
|
+
retainMaterializationVerificationDiagnostic(cause, {
|
|
17851
|
+
reason: "command_error",
|
|
17852
|
+
path,
|
|
17853
|
+
workdir: args.workdir,
|
|
17854
|
+
command,
|
|
17855
|
+
output: null,
|
|
17856
|
+
exitCode: null,
|
|
17857
|
+
providerSessionId: null,
|
|
17858
|
+
causeMessage: cause instanceof Error ? cause.message : String(cause)
|
|
17859
|
+
});
|
|
17860
|
+
throw cause;
|
|
17861
|
+
}
|
|
17862
|
+
try {
|
|
17863
|
+
output = formatExecResult(result);
|
|
17864
|
+
} catch (cause) {
|
|
17865
|
+
const record = result && typeof result === "object" ? result : {};
|
|
17866
|
+
const returnedOutput = [record.output, record.stderr, record.stdout].filter((value) => typeof value === "string").join("\n");
|
|
17867
|
+
throw new SandboxMaterializationVerificationError({
|
|
17868
|
+
reason: "invalid_response",
|
|
17869
|
+
path,
|
|
17870
|
+
workdir: args.workdir,
|
|
17871
|
+
command,
|
|
17872
|
+
output: returnedOutput || null,
|
|
17873
|
+
exitCode: null,
|
|
17874
|
+
providerSessionId: null,
|
|
17875
|
+
causeMessage: cause instanceof Error ? cause.message : String(cause)
|
|
17876
|
+
});
|
|
17877
|
+
}
|
|
17878
|
+
const status = parseExecResponseBanner(output);
|
|
17879
|
+
const markerPresent = stripExecBanner(output).includes(MATERIALIZED_PATH_MARKER);
|
|
17880
|
+
if (markerPresent && (status.kind === "absent" || status.kind === "exited" && status.exitCode === 0)) {
|
|
17881
|
+
return;
|
|
17818
17882
|
}
|
|
17883
|
+
const reason = status.kind === "running" ? "command_pending" : status.kind === "exited" && status.exitCode === 1 ? "path_not_visible" : status.kind === "exited" && status.exitCode !== 0 ? "command_failed" : "invalid_response";
|
|
17884
|
+
throw new SandboxMaterializationVerificationError({
|
|
17885
|
+
reason,
|
|
17886
|
+
path,
|
|
17887
|
+
workdir: args.workdir,
|
|
17888
|
+
command,
|
|
17889
|
+
output,
|
|
17890
|
+
exitCode: status.kind === "exited" ? status.exitCode : null,
|
|
17891
|
+
providerSessionId: status.kind === "running" ? status.sessionId : null
|
|
17892
|
+
});
|
|
17819
17893
|
}
|
|
17820
17894
|
function providerManifestRoot(session) {
|
|
17821
17895
|
const root = session.state?.manifest?.root;
|
|
@@ -21793,6 +21867,96 @@ function parseUnifiedPatch(patch) {
|
|
|
21793
21867
|
|
|
21794
21868
|
// src/sandbox/providers/modal-command-session.ts
|
|
21795
21869
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
21870
|
+
|
|
21871
|
+
// src/sandbox/providers/modal-materialization-verification.ts
|
|
21872
|
+
var MARKER = "__OPENGENI_MATERIALIZED_PATH_VISIBLE__";
|
|
21873
|
+
var OUTPUT_LIMIT = 16 * 1024;
|
|
21874
|
+
async function verifyModalMaterializedPath(control, path, workdir, pending, observationTimeoutMs = 3e4) {
|
|
21875
|
+
const quote = (value) => `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
21876
|
+
const command = `test -e ${quote(path)} && printf %s ${quote(MARKER)}`;
|
|
21877
|
+
const cancellation = new AbortController();
|
|
21878
|
+
const deadlineReason = new Error("Materialization visibility observation deadline exceeded");
|
|
21879
|
+
let providerCommand;
|
|
21880
|
+
let stdout = "";
|
|
21881
|
+
let stderr = "";
|
|
21882
|
+
const diagnostic = (reason, exitCode = null) => ({
|
|
21883
|
+
reason,
|
|
21884
|
+
path,
|
|
21885
|
+
workdir,
|
|
21886
|
+
command,
|
|
21887
|
+
output: (stdout + stderr).slice(0, OUTPUT_LIMIT),
|
|
21888
|
+
exitCode,
|
|
21889
|
+
providerSessionId: null,
|
|
21890
|
+
...providerCommand ? {
|
|
21891
|
+
providerExecution: {
|
|
21892
|
+
sandboxId: providerCommand.sandboxId,
|
|
21893
|
+
taskId: providerCommand.taskId,
|
|
21894
|
+
execId: providerCommand.execId
|
|
21895
|
+
}
|
|
21896
|
+
} : {}
|
|
21897
|
+
});
|
|
21898
|
+
const timer = setTimeout(() => {
|
|
21899
|
+
cancellation.abort(deadlineReason);
|
|
21900
|
+
}, observationTimeoutMs);
|
|
21901
|
+
timer.unref();
|
|
21902
|
+
pending.add(cancellation);
|
|
21903
|
+
try {
|
|
21904
|
+
providerCommand = await control.start(
|
|
21905
|
+
{ cmd: command, workdir, shell: "sh", login: false, tty: false },
|
|
21906
|
+
cancellation.signal
|
|
21907
|
+
);
|
|
21908
|
+
for (; ; ) {
|
|
21909
|
+
cancellation.signal.throwIfAborted();
|
|
21910
|
+
const page = await control.readProbe(providerCommand, 1e3, cancellation);
|
|
21911
|
+
cancellation.signal.throwIfAborted();
|
|
21912
|
+
if (page.command.sandboxId !== providerCommand.sandboxId || page.command.taskId !== providerCommand.taskId || page.command.execId !== providerCommand.execId) {
|
|
21913
|
+
throw new SandboxMaterializationVerificationError(diagnostic("invalid_response"));
|
|
21914
|
+
}
|
|
21915
|
+
providerCommand = page.command;
|
|
21916
|
+
for (const chunk of page.chunks) {
|
|
21917
|
+
if (chunk.stream === "stdout") stdout += chunk.text;
|
|
21918
|
+
else stderr += chunk.text;
|
|
21919
|
+
}
|
|
21920
|
+
if (stdout.length + stderr.length > OUTPUT_LIMIT) {
|
|
21921
|
+
throw new SandboxMaterializationVerificationError(diagnostic("invalid_response"));
|
|
21922
|
+
}
|
|
21923
|
+
if (page.exitCode === null) {
|
|
21924
|
+
await new Promise((resolve6) => setImmediate(resolve6));
|
|
21925
|
+
continue;
|
|
21926
|
+
}
|
|
21927
|
+
if (page.exitCode === 0 && stdout === MARKER) return;
|
|
21928
|
+
throw new SandboxMaterializationVerificationError(
|
|
21929
|
+
diagnostic(
|
|
21930
|
+
page.exitCode === 1 ? "path_not_visible" : page.exitCode === 0 ? "invalid_response" : "command_failed",
|
|
21931
|
+
page.exitCode
|
|
21932
|
+
)
|
|
21933
|
+
);
|
|
21934
|
+
}
|
|
21935
|
+
} catch (error) {
|
|
21936
|
+
if (cancellation.signal.reason === deadlineReason) {
|
|
21937
|
+
throw new SandboxMaterializationVerificationError(
|
|
21938
|
+
{
|
|
21939
|
+
...diagnostic("command_pending"),
|
|
21940
|
+
causeMessage: "Observation deadline exceeded; provider process completion is unconfirmed"
|
|
21941
|
+
},
|
|
21942
|
+
{ cause: error }
|
|
21943
|
+
);
|
|
21944
|
+
}
|
|
21945
|
+
if (!(error instanceof SandboxMaterializationVerificationError)) {
|
|
21946
|
+
retainMaterializationVerificationDiagnostic(error, {
|
|
21947
|
+
...diagnostic("command_error"),
|
|
21948
|
+
causeMessage: error instanceof Error ? error.message : String(error)
|
|
21949
|
+
});
|
|
21950
|
+
}
|
|
21951
|
+
throw error;
|
|
21952
|
+
} finally {
|
|
21953
|
+
cancellation.abort(new Error("Materialization visibility observation finished"));
|
|
21954
|
+
clearTimeout(timer);
|
|
21955
|
+
pending.delete(cancellation);
|
|
21956
|
+
}
|
|
21957
|
+
}
|
|
21958
|
+
|
|
21959
|
+
// src/sandbox/providers/modal-command-session.ts
|
|
21796
21960
|
function sameExecution(a, b) {
|
|
21797
21961
|
return a.sandboxId === b.sandboxId && a.taskId === b.taskId && a.execId === b.execId && Boolean(a.pty) === Boolean(b.pty);
|
|
21798
21962
|
}
|
|
@@ -21802,6 +21966,7 @@ function installModalCommandSession(session, control) {
|
|
|
21802
21966
|
const originalWrite = session.writeStdin?.bind(session);
|
|
21803
21967
|
const cancelLegacyStart = session.cancelPendingExecCommand?.bind(session);
|
|
21804
21968
|
const pendingStarts = /* @__PURE__ */ new Set();
|
|
21969
|
+
session.verifyMaterializedPath = (path, workdir) => verifyModalMaterializedPath(control, path, workdir, pendingStarts);
|
|
21805
21970
|
const entries = /* @__PURE__ */ new Map();
|
|
21806
21971
|
const setupHandles = /* @__PURE__ */ new Map();
|
|
21807
21972
|
let nextSetupHandle = MAX_PROVIDER_COMMAND_HANDLE + 1;
|
|
@@ -22074,49 +22239,76 @@ var ModalCommandControl = class _ModalCommandControl {
|
|
|
22074
22239
|
};
|
|
22075
22240
|
}
|
|
22076
22241
|
async read(command, yieldTimeMs, signal) {
|
|
22242
|
+
return this.readOutput(command, yieldTimeMs, signal);
|
|
22243
|
+
}
|
|
22244
|
+
/** Fixed internal probes own their cancellation controller and must drain
|
|
22245
|
+
* both reads before relinquishing the surrounding provider-operation gate.
|
|
22246
|
+
* Retained-command readers keep their existing signal/receipt contract.
|
|
22247
|
+
*/
|
|
22248
|
+
async readProbe(command, yieldTimeMs, cancellation) {
|
|
22249
|
+
return this.readOutput(
|
|
22250
|
+
command,
|
|
22251
|
+
yieldTimeMs,
|
|
22252
|
+
cancellation.signal,
|
|
22253
|
+
(error) => cancellation.abort(error)
|
|
22254
|
+
);
|
|
22255
|
+
}
|
|
22256
|
+
async readOutput(command, yieldTimeMs, signal, cancelSiblings) {
|
|
22077
22257
|
signal?.throwIfAborted();
|
|
22078
22258
|
this.assertIdentity(command);
|
|
22079
22259
|
const next = structuredClone(command);
|
|
22080
|
-
|
|
22081
|
-
|
|
22082
|
-
|
|
22083
|
-
|
|
22084
|
-
|
|
22085
|
-
|
|
22086
|
-
|
|
22087
|
-
|
|
22088
|
-
|
|
22089
|
-
|
|
22090
|
-
|
|
22091
|
-
|
|
22092
|
-
|
|
22093
|
-
|
|
22094
|
-
|
|
22095
|
-
|
|
22096
|
-
|
|
22097
|
-
|
|
22098
|
-
|
|
22099
|
-
|
|
22100
|
-
|
|
22101
|
-
|
|
22102
|
-
|
|
22103
|
-
|
|
22104
|
-
|
|
22105
|
-
|
|
22106
|
-
|
|
22107
|
-
|
|
22108
|
-
|
|
22109
|
-
|
|
22110
|
-
|
|
22111
|
-
|
|
22112
|
-
|
|
22113
|
-
|
|
22114
|
-
|
|
22115
|
-
|
|
22116
|
-
|
|
22117
|
-
|
|
22260
|
+
let failure;
|
|
22261
|
+
const reads = ["stdout", "stderr"].map(async (stream) => {
|
|
22262
|
+
const cursor = command.streams[stream];
|
|
22263
|
+
if (cursor.exitCode !== null) return null;
|
|
22264
|
+
const descriptor = stream === "stdout" ? 1 : 2;
|
|
22265
|
+
for await (const batch of this.client.containerExecGetOutput(
|
|
22266
|
+
{
|
|
22267
|
+
execId: command.execId,
|
|
22268
|
+
timeout: Math.max(0, yieldTimeMs) / 1e3,
|
|
22269
|
+
lastBatchIndex: cursor.batchIndex,
|
|
22270
|
+
fileDescriptor: descriptor,
|
|
22271
|
+
getRawBytes: true
|
|
22272
|
+
},
|
|
22273
|
+
signal ? { signal } : void 0
|
|
22274
|
+
)) {
|
|
22275
|
+
if (batch.batchIndex <= cursor.batchIndex) continue;
|
|
22276
|
+
if (!Number.isSafeInteger(batch.batchIndex))
|
|
22277
|
+
throw new Error("Invalid Modal output cursor");
|
|
22278
|
+
const terminal = batch.exitCode !== void 0;
|
|
22279
|
+
if (terminal && !Number.isSafeInteger(batch.exitCode))
|
|
22280
|
+
throw new Error("Invalid Modal exit status");
|
|
22281
|
+
const decoded = decodePage(
|
|
22282
|
+
cursor.utf8Remainder,
|
|
22283
|
+
batch.items.filter((item) => item.fileDescriptor === descriptor).map((item) => item.messageBytes),
|
|
22284
|
+
terminal
|
|
22285
|
+
);
|
|
22286
|
+
next.streams[stream] = {
|
|
22287
|
+
batchIndex: batch.batchIndex,
|
|
22288
|
+
utf8Remainder: decoded.remainder,
|
|
22289
|
+
exitCode: terminal ? batch.exitCode : null
|
|
22290
|
+
};
|
|
22291
|
+
return {
|
|
22292
|
+
stream,
|
|
22293
|
+
chunkId: `modal:${command.execId}:${stream}:${cursor.batchIndex}:${batch.batchIndex}`,
|
|
22294
|
+
text: decoded.text
|
|
22295
|
+
};
|
|
22296
|
+
}
|
|
22297
|
+
return null;
|
|
22298
|
+
}).map(
|
|
22299
|
+
(read) => !cancelSiblings ? read : read.catch((error) => {
|
|
22300
|
+
failure ??= { error };
|
|
22301
|
+
cancelSiblings(error);
|
|
22302
|
+
throw error;
|
|
22118
22303
|
})
|
|
22119
22304
|
);
|
|
22305
|
+
const pages = cancelSiblings ? await Promise.allSettled(reads).then((results) => {
|
|
22306
|
+
if (failure) throw failure.error;
|
|
22307
|
+
return results.map((result) => {
|
|
22308
|
+
if (result.status === "rejected") throw result.reason;
|
|
22309
|
+
return result.value;
|
|
22310
|
+
});
|
|
22311
|
+
}) : await Promise.all(reads);
|
|
22120
22312
|
const stdoutExit = next.streams.stdout.exitCode;
|
|
22121
22313
|
const stderrExit = next.streams.stderr.exitCode;
|
|
22122
22314
|
if (stdoutExit !== null && stderrExit !== null && stdoutExit !== stderrExit)
|
|
@@ -37040,6 +37232,8 @@ export {
|
|
|
37040
37232
|
parseExecBannerSessionId,
|
|
37041
37233
|
parseExecBannerExitCode,
|
|
37042
37234
|
isExecSessionLostBanner,
|
|
37235
|
+
SandboxMaterializationVerificationError,
|
|
37236
|
+
materializationVerificationDiagnostic,
|
|
37043
37237
|
normalizeConnectedMachineWorkspaceRoot,
|
|
37044
37238
|
isWindowsConnectedMachinePath,
|
|
37045
37239
|
isConnectedMachineAbsolutePath,
|
|
@@ -37293,4 +37487,4 @@ export {
|
|
|
37293
37487
|
collectSandboxEnvironment2 as collectSandboxEnvironment,
|
|
37294
37488
|
parseExposedPorts2 as parseExposedPorts
|
|
37295
37489
|
};
|
|
37296
|
-
//# sourceMappingURL=chunk-
|
|
37490
|
+
//# sourceMappingURL=chunk-FQM5VV5D.js.map
|