zeitlich 0.2.21 → 0.2.22
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 +70 -55
- package/dist/adapters/sandbox/daytona/index.cjs +3 -0
- package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
- package/dist/adapters/sandbox/daytona/index.d.cts +2 -1
- package/dist/adapters/sandbox/daytona/index.d.ts +2 -1
- package/dist/adapters/sandbox/daytona/index.js +3 -0
- package/dist/adapters/sandbox/daytona/index.js.map +1 -1
- package/dist/adapters/sandbox/daytona/workflow.cjs +32 -0
- package/dist/adapters/sandbox/daytona/workflow.cjs.map +1 -0
- package/dist/adapters/sandbox/daytona/workflow.d.cts +27 -0
- package/dist/adapters/sandbox/daytona/workflow.d.ts +27 -0
- package/dist/adapters/sandbox/daytona/workflow.js +30 -0
- package/dist/adapters/sandbox/daytona/workflow.js.map +1 -0
- package/dist/adapters/sandbox/inmemory/index.cjs +4 -1
- package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -1
- package/dist/adapters/sandbox/inmemory/index.d.cts +3 -2
- package/dist/adapters/sandbox/inmemory/index.d.ts +3 -2
- package/dist/adapters/sandbox/inmemory/index.js +4 -1
- package/dist/adapters/sandbox/inmemory/index.js.map +1 -1
- package/dist/adapters/sandbox/inmemory/workflow.cjs +32 -0
- package/dist/adapters/sandbox/inmemory/workflow.cjs.map +1 -0
- package/dist/adapters/sandbox/inmemory/workflow.d.cts +25 -0
- package/dist/adapters/sandbox/inmemory/workflow.d.ts +25 -0
- package/dist/adapters/sandbox/inmemory/workflow.js +30 -0
- package/dist/adapters/sandbox/inmemory/workflow.js.map +1 -0
- package/dist/adapters/sandbox/virtual/index.cjs +3 -0
- package/dist/adapters/sandbox/virtual/index.cjs.map +1 -1
- package/dist/adapters/sandbox/virtual/index.d.cts +6 -4
- package/dist/adapters/sandbox/virtual/index.d.ts +6 -4
- package/dist/adapters/sandbox/virtual/index.js +3 -0
- package/dist/adapters/sandbox/virtual/index.js.map +1 -1
- package/dist/adapters/sandbox/virtual/workflow.cjs +32 -0
- package/dist/adapters/sandbox/virtual/workflow.cjs.map +1 -0
- package/dist/adapters/sandbox/virtual/workflow.d.cts +27 -0
- package/dist/adapters/sandbox/virtual/workflow.d.ts +27 -0
- package/dist/adapters/sandbox/virtual/workflow.js +30 -0
- package/dist/adapters/sandbox/virtual/workflow.js.map +1 -0
- package/dist/adapters/thread/google-genai/index.cjs +9 -1
- package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/index.d.cts +30 -18
- package/dist/adapters/thread/google-genai/index.d.ts +30 -18
- package/dist/adapters/thread/google-genai/index.js +9 -1
- package/dist/adapters/thread/google-genai/index.js.map +1 -1
- package/dist/adapters/thread/google-genai/workflow.cjs +33 -0
- package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -0
- package/dist/adapters/thread/google-genai/workflow.d.cts +32 -0
- package/dist/adapters/thread/google-genai/workflow.d.ts +32 -0
- package/dist/adapters/thread/google-genai/workflow.js +31 -0
- package/dist/adapters/thread/google-genai/workflow.js.map +1 -0
- package/dist/adapters/thread/langchain/index.cjs +9 -1
- package/dist/adapters/thread/langchain/index.cjs.map +1 -1
- package/dist/adapters/thread/langchain/index.d.cts +26 -15
- package/dist/adapters/thread/langchain/index.d.ts +26 -15
- package/dist/adapters/thread/langchain/index.js +9 -1
- package/dist/adapters/thread/langchain/index.js.map +1 -1
- package/dist/adapters/thread/langchain/workflow.cjs +33 -0
- package/dist/adapters/thread/langchain/workflow.cjs.map +1 -0
- package/dist/adapters/thread/langchain/workflow.d.cts +32 -0
- package/dist/adapters/thread/langchain/workflow.d.ts +32 -0
- package/dist/adapters/thread/langchain/workflow.js +31 -0
- package/dist/adapters/thread/langchain/workflow.js.map +1 -0
- package/dist/index.cjs +36 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -14
- package/dist/index.d.ts +35 -14
- package/dist/index.js +38 -34
- package/dist/index.js.map +1 -1
- package/dist/queries-Bw6WEPMw.d.cts +44 -0
- package/dist/queries-C27raDaB.d.ts +44 -0
- package/dist/{queries-CHa2iv_I.d.cts → types-BJ8itUAl.d.cts} +2 -43
- package/dist/{types-BkAYmc96.d.ts → types-C5bkx6kQ.d.ts} +33 -5
- package/dist/{types-CES_30qx.d.cts → types-ClsHhtwL.d.cts} +33 -5
- package/dist/{queries-6Avfh74U.d.ts → types-ENYCKFBk.d.ts} +2 -43
- package/dist/{types-BMRzfELQ.d.cts → types-HBosetv3.d.cts} +15 -1
- package/dist/{types-BMRzfELQ.d.ts → types-HBosetv3.d.ts} +15 -1
- package/dist/workflow.cjs +4 -30
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +13 -41
- package/dist/workflow.d.ts +13 -41
- package/dist/workflow.js +6 -30
- package/dist/workflow.js.map +1 -1
- package/package.json +53 -1
- package/src/adapters/sandbox/daytona/index.ts +4 -0
- package/src/adapters/sandbox/daytona/proxy.ts +55 -0
- package/src/adapters/sandbox/e2b/filesystem.ts +147 -0
- package/src/adapters/sandbox/e2b/index.ts +159 -0
- package/src/adapters/sandbox/e2b/types.ts +23 -0
- package/src/adapters/sandbox/inmemory/index.ts +5 -1
- package/src/adapters/sandbox/inmemory/proxy.ts +53 -0
- package/src/adapters/sandbox/virtual/provider.ts +5 -1
- package/src/adapters/sandbox/virtual/proxy.ts +52 -0
- package/src/adapters/thread/google-genai/activities.ts +51 -17
- package/src/adapters/thread/google-genai/index.ts +1 -0
- package/src/adapters/thread/google-genai/proxy.ts +61 -0
- package/src/adapters/thread/langchain/activities.ts +47 -14
- package/src/adapters/thread/langchain/index.ts +1 -0
- package/src/adapters/thread/langchain/proxy.ts +61 -0
- package/src/lib/sandbox/manager.ts +40 -6
- package/src/lib/sandbox/sandbox.test.ts +12 -11
- package/src/lib/sandbox/types.ts +18 -0
- package/src/lib/session/index.ts +3 -5
- package/src/lib/session/session-edge-cases.integration.test.ts +45 -34
- package/src/lib/session/session.integration.test.ts +40 -48
- package/src/lib/session/session.ts +4 -66
- package/src/lib/session/types.ts +32 -1
- package/src/lib/subagent/define.ts +1 -1
- package/src/lib/subagent/handler.ts +9 -2
- package/src/lib/subagent/index.ts +1 -0
- package/src/lib/subagent/subagent.integration.test.ts +62 -0
- package/src/lib/subagent/types.ts +7 -2
- package/src/lib/tool-router/router-edge-cases.integration.test.ts +4 -1
- package/src/lib/tool-router/router.integration.test.ts +4 -1
- package/src/lib/workflow.test.ts +19 -10
- package/src/lib/workflow.ts +4 -1
- package/src/tools/bash/bash.test.ts +16 -7
- package/src/workflow.ts +6 -14
- package/tsup.config.ts +6 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { workflowInfo, proxyActivities } from '@temporalio/workflow';
|
|
2
|
+
|
|
3
|
+
// src/adapters/sandbox/daytona/proxy.ts
|
|
4
|
+
var ADAPTER_PREFIX = "daytona";
|
|
5
|
+
function proxyDaytonaSandboxOps(scope, options) {
|
|
6
|
+
const resolvedScope = scope ?? workflowInfo().workflowType;
|
|
7
|
+
const acts = proxyActivities(
|
|
8
|
+
options ?? {
|
|
9
|
+
startToCloseTimeout: "120s",
|
|
10
|
+
retry: {
|
|
11
|
+
maximumAttempts: 3,
|
|
12
|
+
initialInterval: "5s",
|
|
13
|
+
maximumInterval: "60s",
|
|
14
|
+
backoffCoefficient: 3
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
);
|
|
18
|
+
const prefix = `${ADAPTER_PREFIX}${resolvedScope.charAt(0).toUpperCase()}${resolvedScope.slice(1)}`;
|
|
19
|
+
const p = (key) => `${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;
|
|
20
|
+
return {
|
|
21
|
+
createSandbox: acts[p("createSandbox")],
|
|
22
|
+
destroySandbox: acts[p("destroySandbox")],
|
|
23
|
+
snapshotSandbox: acts[p("snapshotSandbox")],
|
|
24
|
+
forkSandbox: acts[p("forkSandbox")]
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { proxyDaytonaSandboxOps };
|
|
29
|
+
//# sourceMappingURL=workflow.js.map
|
|
30
|
+
//# sourceMappingURL=workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/adapters/sandbox/daytona/proxy.ts"],"names":[],"mappings":";;;AAsBA,IAAM,cAAA,GAAiB,SAAA;AAEhB,SAAS,sBAAA,CACd,OACA,OAAA,EACY;AACZ,EAAA,MAAM,aAAA,GAAgB,KAAA,IAAS,YAAA,EAAa,CAAE,YAAA;AAG9C,EAAA,MAAM,IAAA,GAAO,eAAA;AAAA,IACX,OAAA,IAAW;AAAA,MACT,mBAAA,EAAqB,MAAA;AAAA,MACrB,KAAA,EAAO;AAAA,QACL,eAAA,EAAiB,CAAA;AAAA,QACjB,eAAA,EAAiB,IAAA;AAAA,QACjB,eAAA,EAAiB,KAAA;AAAA,QACjB,kBAAA,EAAoB;AAAA;AACtB;AACF,GACF;AAEA,EAAA,MAAM,MAAA,GACJ,CAAA,EAAG,cAAc,CAAA,EAAG,cAAc,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAa,CAAA,EAAG,aAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AACpF,EAAA,MAAM,IAAI,CAAC,GAAA,KACT,CAAA,EAAG,MAAM,GAAG,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,CAAE,aAAa,CAAA,EAAG,GAAA,CAAI,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAExD,EAAA,OAAO;AAAA,IACL,aAAA,EAAe,IAAA,CAAK,CAAA,CAAE,eAAe,CAAC,CAAA;AAAA,IACtC,cAAA,EAAgB,IAAA,CAAK,CAAA,CAAE,gBAAgB,CAAC,CAAA;AAAA,IACxC,eAAA,EAAiB,IAAA,CAAK,CAAA,CAAE,iBAAiB,CAAC,CAAA;AAAA,IAC1C,WAAA,EAAa,IAAA,CAAK,CAAA,CAAE,aAAa,CAAC;AAAA,GACpC;AACF","file":"workflow.js","sourcesContent":["/**\n * Workflow-safe proxy for Daytona sandbox operations.\n *\n * Uses longer timeouts than in-memory providers since Daytona\n * sandboxes are remote and creation involves provisioning.\n *\n * Import this from `zeitlich/adapters/sandbox/daytona/workflow`\n * in your Temporal workflow files.\n *\n * By default the scope is derived from `workflowInfo().workflowType`,\n * so activities are automatically namespaced per workflow.\n *\n * @example\n * ```typescript\n * import { proxyDaytonaSandboxOps } from 'zeitlich/adapters/sandbox/daytona/workflow';\n *\n * const sandbox = proxyDaytonaSandboxOps();\n * ```\n */\nimport { proxyActivities, workflowInfo } from \"@temporalio/workflow\";\nimport type { SandboxOps } from \"../../../lib/sandbox/types\";\n\nconst ADAPTER_PREFIX = \"daytona\";\n\nexport function proxyDaytonaSandboxOps(\n scope?: string,\n options?: Parameters<typeof proxyActivities>[0]\n): SandboxOps {\n const resolvedScope = scope ?? workflowInfo().workflowType;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const acts = proxyActivities<Record<string, (...args: any[]) => any>>(\n options ?? {\n startToCloseTimeout: \"120s\",\n retry: {\n maximumAttempts: 3,\n initialInterval: \"5s\",\n maximumInterval: \"60s\",\n backoffCoefficient: 3,\n },\n }\n );\n\n const prefix =\n `${ADAPTER_PREFIX}${resolvedScope.charAt(0).toUpperCase()}${resolvedScope.slice(1)}`;\n const p = (key: string): string =>\n `${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;\n\n return {\n createSandbox: acts[p(\"createSandbox\")],\n destroySandbox: acts[p(\"destroySandbox\")],\n snapshotSandbox: acts[p(\"snapshotSandbox\")],\n forkSandbox: acts[p(\"forkSandbox\")],\n } as SandboxOps;\n}\n"]}
|
|
@@ -103,7 +103,7 @@ var InMemorySandboxProvider = class {
|
|
|
103
103
|
constructor(defaultOptions) {
|
|
104
104
|
this.defaultOptions = defaultOptions;
|
|
105
105
|
}
|
|
106
|
-
id = "
|
|
106
|
+
id = "inMemory";
|
|
107
107
|
capabilities = {
|
|
108
108
|
filesystem: true,
|
|
109
109
|
execution: true,
|
|
@@ -157,6 +157,9 @@ var InMemorySandboxProvider = class {
|
|
|
157
157
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
158
158
|
};
|
|
159
159
|
}
|
|
160
|
+
async fork(_sandboxId) {
|
|
161
|
+
throw new Error("Not implemented");
|
|
162
|
+
}
|
|
160
163
|
async restore(snapshot) {
|
|
161
164
|
const { files } = snapshot.data;
|
|
162
165
|
const initialFiles = {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/sandbox/types.ts","../../../../src/lib/thread/id.ts","../../../../src/adapters/sandbox/inmemory/index.ts"],"names":["ApplicationFailure","uuid4","Bash","InMemoryFs"],"mappings":";;;;;;;AAiKO,IAAM,oBAAA,GAAN,cAAmCA,yBAAA,CAAmB;AAAA,EAC3D,YAAY,SAAA,EAAmB;AAC7B,IAAA,KAAA,CAAM,CAAA,mBAAA,EAAsB,SAAS,CAAA,CAAA,EAAI,sBAAA,EAAwB,IAAI,CAAA;AAAA,EACvE;AACF,CAAA;ACnKA,IAAM,MAAA,GACJ,gEAAA;AAaK,SAAS,UAAA,CAAW,SAAS,EAAA,EAAY;AAC9C,EAAA,MAAM,GAAA,GAAMC,cAAA,EAAM,CAAE,OAAA,CAAQ,MAAM,EAAE,CAAA;AACpC,EAAA,IAAI,MAAA,GAAS,EAAA;AACb,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAA,EAAK;AAC/B,IAAA,MAAM,IAAA,GAAO,QAAA,CAAS,GAAA,CAAI,KAAA,CAAM,CAAA,GAAI,GAAG,CAAA,GAAI,CAAA,GAAI,CAAC,CAAA,EAAG,EAAE,CAAA;AACrD,IAAA,MAAA,IAAU,MAAA,CAAO,IAAA,GAAO,MAAA,CAAO,MAAM,CAAA;AAAA,EACvC;AACA,EAAA,OAAO,MAAA;AACT;;;ACGA,SAAS,YAAY,EAAA,EAAoC;AACvD,EAAA,MAAM,aAAA,GAAgB,GAAA;AACtB,EAAA,MAAM,gBAAgB,CAAC,IAAA,KAAyB,EAAA,CAAG,WAAA,CAAY,eAAe,IAAI,CAAA;AAElF,EAAA,OAAO;AAAA,IACL,aAAA;AAAA,IACA,UAAU,CAAC,IAAA,KAAS,GAAG,QAAA,CAAS,aAAA,CAAc,IAAI,CAAC,CAAA;AAAA,IACnD,gBAAgB,CAAC,IAAA,KAAS,GAAG,cAAA,CAAe,aAAA,CAAc,IAAI,CAAC,CAAA;AAAA,IAC/D,SAAA,EAAW,CAAC,IAAA,EAAM,OAAA,KAAY,GAAG,SAAA,CAAU,aAAA,CAAc,IAAI,CAAA,EAAG,OAAO,CAAA;AAAA,IACvE,UAAA,EAAY,CAAC,IAAA,EAAM,OAAA,KAAY,GAAG,UAAA,CAAW,aAAA,CAAc,IAAI,CAAA,EAAG,OAAO,CAAA;AAAA,IACzE,QAAQ,CAAC,IAAA,KAAS,GAAG,MAAA,CAAO,aAAA,CAAc,IAAI,CAAC,CAAA;AAAA,IAC/C,IAAA,EAAM,OAAO,IAAA,KAA4B;AACvC,MAAA,MAAM,IAAI,MAAM,EAAA,CAAG,IAAA,CAAK,aAAA,CAAc,IAAI,CAAC,CAAA;AAC3C,MAAA,OAAO;AAAA,QACL,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,aAAa,CAAA,CAAE,WAAA;AAAA,QACf,gBAAgB,CAAA,CAAE,cAAA;AAAA,QAClB,MAAM,CAAA,CAAE,IAAA;AAAA,QACR,OAAO,CAAA,CAAE;AAAA,OACX;AAAA,IACF,CAAA;AAAA,IACA,KAAA,EAAO,CAAC,IAAA,EAAM,IAAA,KAAS,GAAG,KAAA,CAAM,aAAA,CAAc,IAAI,CAAA,EAAG,IAAI,CAAA;AAAA,IACzD,SAAS,CAAC,IAAA,KAAS,GAAG,OAAA,CAAQ,aAAA,CAAc,IAAI,CAAC,CAAA;AAAA,IACjD,oBAAA,EAAsB,OAAO,IAAA,KAAiC;AAC5D,MAAA,MAAM,OAAA,GAAU,cAAc,IAAI,CAAA;AAClC,MAAA,IAAI,CAAC,GAAG,oBAAA,EAAsB;AAC5B,QAAA,MAAM,KAAA,GAAQ,MAAM,EAAA,CAAG,OAAA,CAAQ,OAAO,CAAA;AACtC,QAAA,OAAO,OAAA,CAAQ,GAAA;AAAA,UACb,KAAA,CAAM,GAAA,CAAI,OAAO,IAAA,KAAS;AACxB,YAAA,MAAM,SAAA,GAAY,EAAA,CAAG,WAAA,CAAY,OAAA,EAAS,IAAI,CAAA;AAC9C,YAAA,MAAM,CAAA,GAAI,MAAM,EAAA,CAAG,IAAA,CAAK,SAAS,CAAA;AACjC,YAAA,OAAO;AAAA,cACL,IAAA;AAAA,cACA,QAAQ,CAAA,CAAE,MAAA;AAAA,cACV,aAAa,CAAA,CAAE,WAAA;AAAA,cACf,gBAAgB,CAAA,CAAE;AAAA,aACpB;AAAA,UACF,CAAC;AAAA,SACH;AAAA,MACF;AACA,MAAA,OAAO,EAAA,CAAG,qBAAqB,OAAO,CAAA;AAAA,IACxC,CAAA;AAAA,IACA,EAAA,EAAI,CAAC,IAAA,EAAM,IAAA,KAAS,GAAG,EAAA,CAAG,aAAA,CAAc,IAAI,CAAA,EAAG,IAAI,CAAA;AAAA,IACnD,EAAA,EAAI,CAAC,GAAA,EAAK,IAAA,EAAM,IAAA,KAAS,EAAA,CAAG,EAAA,CAAG,aAAA,CAAc,GAAG,CAAA,EAAG,aAAA,CAAc,IAAI,GAAG,IAAI,CAAA;AAAA,IAC5E,EAAA,EAAI,CAAC,GAAA,EAAK,IAAA,KAAS,EAAA,CAAG,EAAA,CAAG,aAAA,CAAc,GAAG,CAAA,EAAG,aAAA,CAAc,IAAI,CAAC,CAAA;AAAA,IAChE,UAAU,CAAC,IAAA,KAAS,GAAG,QAAA,CAAS,aAAA,CAAc,IAAI,CAAC,CAAA;AAAA,IACnD,WAAA,EAAa,CAAC,IAAA,EAAM,CAAA,KAAM,GAAG,WAAA,CAAY,aAAA,CAAc,IAAI,CAAA,EAAG,CAAC;AAAA,GACjE;AACF;AAgBA,IAAM,sBAAN,MAA6C;AAAA,EAU3C,WAAA,CACW,EAAA,EACD,UAAA,EACR,OAAA,EACA;AAHS,IAAA,IAAA,CAAA,EAAA,GAAA,EAAA;AACD,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AAGR,IAAA,IAAA,CAAK,EAAA,GAAK,YAAY,UAAU,CAAA;AAChC,IAAA,IAAA,CAAK,WAAA,GAAc;AAAA,MACjB,eAAA,EAAiB,EAAE,eAAA,EAAiB,QAAA,EAAW;AAAA,MAC/C,GAAG,OAAA,EAAS;AAAA,KACd;AAAA,EACF;AAAA,EAnBS,YAAA,GAAoC;AAAA,IAC3C,UAAA,EAAY,IAAA;AAAA,IACZ,SAAA,EAAW,IAAA;AAAA,IACX,WAAA,EAAa;AAAA,GACf;AAAA,EAES,EAAA;AAAA,EACD,WAAA;AAAA,EAcR,MAAM,IAAA,CAAK,OAAA,EAAiB,QAAA,EAA6C;AACvE,IAAA,MAAM,IAAA,GAAO,IAAIC,aAAA,CAAK,EAAE,GAAG,KAAK,WAAA,EAAa,EAAA,EAAI,IAAA,CAAK,UAAA,EAAY,CAAA;AAClE,IAAA,MAAM,EAAE,UAAU,MAAA,EAAQ,MAAA,KAAW,MAAM,IAAA,CAAK,KAAK,OAAO,CAAA;AAC5D,IAAA,OAAO,EAAE,QAAA,EAAU,MAAA,EAAQ,MAAA,EAAO;AAAA,EACpC;AAAA,EAEA,MAAM,OAAA,GAAyB;AAAA,EAE/B;AAAA;AAAA,EAGA,cAAA,GAA8B;AAC5B,IAAA,OAAO,IAAA,CAAK,UAAA;AAAA,EACd;AACF,CAAA;AAMO,IAAM,0BAAN,MAAyD;AAAA,EAU9D,YAAoB,cAAA,EAAyC;AAAzC,IAAA,IAAA,CAAA,cAAA,GAAA,cAAA;AAAA,EAA0C;AAAA,EATrD,EAAA,GAAK,UAAA;AAAA,EACL,YAAA,GAAoC;AAAA,IAC3C,UAAA,EAAY,IAAA;AAAA,IACZ,SAAA,EAAW,IAAA;AAAA,IACX,WAAA,EAAa;AAAA,GACf;AAAA,EAEQ,SAAA,uBAAgB,GAAA,EAAiC;AAAA,EAIzD,MAAM,IAAI,EAAA,EAA8B;AACtC,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,EAAE,CAAA;AACrC,IAAA,IAAI,CAAC,OAAA,EAAS,MAAM,IAAI,qBAAqB,EAAE,CAAA;AAC/C,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAM,QAAQ,EAAA,EAA2B;AACvC,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,EAAE,CAAA;AACrC,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,MAAM,QAAQ,OAAA,EAAQ;AACtB,MAAA,IAAA,CAAK,SAAA,CAAU,OAAO,EAAE,CAAA;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,OAAA,EAA8D;AACzE,IAAA,MAAM,EAAA,GAAK,OAAA,EAAS,EAAA,IAAM,UAAA,EAAW;AACrC,IAAA,MAAM,eAA6B,EAAC;AAEpC,IAAA,IAAI,SAAS,YAAA,EAAc;AACzB,MAAA,KAAA,MAAW,CAAC,MAAM,OAAO,CAAA,IAAK,OAAO,OAAA,CAAQ,OAAA,CAAQ,YAAY,CAAA,EAAG;AAClE,QAAA,YAAA,CAAa,IAAI,CAAA,GAAI,OAAA;AAAA,MACvB;AAAA,IACF;AAEA,IAAA,MAAM,EAAA,GAAK,IAAIC,mBAAA,CAAW,YAAY,CAAA;AACtC,IAAA,MAAM,UAAU,IAAI,mBAAA,CAAoB,EAAA,EAAI,EAAA,EAAI,KAAK,cAAc,CAAA;AACnE,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,EAAA,EAAI,OAAO,CAAA;AAC9B,IAAA,OAAO,EAAE,OAAA,EAAQ;AAAA,EACnB;AAAA,EAEA,MAAM,SAAS,SAAA,EAA6C;AAC1D,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,SAAS,CAAA;AAC5C,IAAA,IAAI,CAAC,OAAA,EAAS,MAAM,IAAI,qBAAqB,SAAS,CAAA;AAEtD,IAAA,MAAM,EAAA,GAAK,QAAQ,cAAA,EAAe;AAClC,IAAA,MAAM,KAAA,GAAQ,GAAG,WAAA,EAAY;AAC7B,IAAA,MAAM,QAAgC,EAAC;AAEvC,IAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACrB,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,GAAO,MAAM,EAAA,CAAG,IAAA,CAAK,CAAC,CAAA;AAC5B,QAAA,IAAI,KAAK,MAAA,EAAQ;AACf,UAAA,KAAA,CAAM,CAAC,CAAA,GAAI,MAAM,EAAA,CAAG,SAAS,CAAC,CAAA;AAAA,QAChC;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAEA,IAAA,OAAO;AAAA,MACL,SAAA;AAAA,MACA,YAAY,IAAA,CAAK,EAAA;AAAA,MACjB,IAAA,EAAM,EAAE,KAAA,EAAM;AAAA,MACd,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,KACpC;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,QAAA,EAA6C;AACzD,IAAA,MAAM,EAAE,KAAA,EAAM,GAAI,QAAA,CAAS,IAAA;AAC3B,IAAA,MAAM,eAA6B,EAAC;AACpC,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,OAAO,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAG;AACnD,MAAA,YAAA,CAAa,IAAI,CAAA,GAAI,OAAA;AAAA,IACvB;AAEA,IAAA,MAAM,EAAA,GAAK,IAAIA,mBAAA,CAAW,YAAY,CAAA;AACtC,IAAA,MAAM,UAAU,IAAI,mBAAA;AAAA,MAClB,QAAA,CAAS,SAAA;AAAA,MACT,EAAA;AAAA,MACA,IAAA,CAAK;AAAA,KACP;AACA,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,CAAQ,EAAA,EAAI,OAAO,CAAA;AACtC,IAAA,OAAO,OAAA;AAAA,EACT;AACF","file":"index.cjs","sourcesContent":["// ============================================================================\n// Sandbox Filesystem\n// ============================================================================\n\nexport interface DirentEntry {\n name: string;\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n}\n\nexport interface FileStat {\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n size: number;\n mtime: Date;\n}\n\n/**\n * Provider-agnostic filesystem interface.\n *\n * Implementations that don't support a method should throw\n * {@link SandboxNotSupportedError}.\n */\nexport interface SandboxFileSystem {\n /** Base directory used when resolving relative paths. */\n readonly workspaceBase: string;\n readFile(path: string): Promise<string>;\n readFileBuffer(path: string): Promise<Uint8Array>;\n writeFile(path: string, content: string | Uint8Array): Promise<void>;\n appendFile(path: string, content: string | Uint8Array): Promise<void>;\n exists(path: string): Promise<boolean>;\n stat(path: string): Promise<FileStat>;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;\n readdir(path: string): Promise<string[]>;\n readdirWithFileTypes(path: string): Promise<DirentEntry[]>;\n rm(path: string, options?: { recursive?: boolean; force?: boolean }): Promise<void>;\n cp(src: string, dest: string, options?: { recursive?: boolean }): Promise<void>;\n mv(src: string, dest: string): Promise<void>;\n readlink(path: string): Promise<string>;\n resolvePath(base: string, path: string): string;\n}\n\n// ============================================================================\n// Execution\n// ============================================================================\n\nexport interface ExecOptions {\n timeout?: number;\n cwd?: string;\n env?: Record<string, string>;\n}\n\nexport interface ExecResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\n// ============================================================================\n// Capabilities\n// ============================================================================\n\nexport interface SandboxCapabilities {\n /** Sandbox supports filesystem operations */\n filesystem: boolean;\n /** Sandbox supports shell/command execution */\n execution: boolean;\n /** Sandbox state can be persisted and restored */\n persistence: boolean;\n}\n\n// ============================================================================\n// Sandbox\n// ============================================================================\n\nexport interface Sandbox {\n readonly id: string;\n readonly capabilities: SandboxCapabilities;\n readonly fs: SandboxFileSystem;\n\n exec(command: string, options?: ExecOptions): Promise<ExecResult>;\n destroy(): Promise<void>;\n}\n\n// ============================================================================\n// Snapshots\n// ============================================================================\n\nexport interface SandboxSnapshot {\n sandboxId: string;\n providerId: string;\n /** Provider-specific serialised state */\n data: unknown;\n createdAt: string;\n}\n\n// ============================================================================\n// Provider\n// ============================================================================\n\nexport interface SandboxCreateOptions {\n /** Preferred sandbox ID (provider may ignore) */\n id?: string;\n /** Seed the filesystem with these files */\n initialFiles?: Record<string, string | Uint8Array>;\n /** Environment variables available inside the sandbox */\n env?: Record<string, string>;\n}\n\nexport interface SandboxCreateResult {\n sandbox: Sandbox;\n /** Optional state to merge into the workflow's `AgentState` via the session. */\n stateUpdate?: Record<string, unknown>;\n}\n\nexport interface SandboxProvider<\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n TSandbox extends Sandbox = Sandbox,\n> {\n readonly id: string;\n readonly capabilities: SandboxCapabilities;\n\n create(options?: TOptions): Promise<SandboxCreateResult>;\n get(sandboxId: string): Promise<TSandbox>;\n destroy(sandboxId: string): Promise<void>;\n snapshot(sandboxId: string): Promise<SandboxSnapshot>;\n restore(snapshot: SandboxSnapshot): Promise<Sandbox>;\n}\n\n// ============================================================================\n// SandboxOps — workflow-side activity interface (like ThreadOps)\n// ============================================================================\n\nexport interface SandboxOps<\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n> {\n createSandbox(\n options?: TOptions,\n ): Promise<{ sandboxId: string; stateUpdate?: Record<string, unknown> }>;\n destroySandbox(sandboxId: string): Promise<void>;\n snapshotSandbox(sandboxId: string): Promise<SandboxSnapshot>;\n}\n\n// ============================================================================\n// Errors\n// ============================================================================\n\nimport { ApplicationFailure } from \"@temporalio/common\";\n\nexport class SandboxNotSupportedError extends ApplicationFailure {\n constructor(operation: string) {\n super(\n `Sandbox does not support: ${operation}`,\n \"SandboxNotSupportedError\",\n true,\n );\n }\n}\n\nexport class SandboxNotFoundError extends ApplicationFailure {\n constructor(sandboxId: string) {\n super(`Sandbox not found: ${sandboxId}`, \"SandboxNotFoundError\", true);\n }\n}\n","import { uuid4 } from \"@temporalio/workflow\";\n\nconst BASE62 =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\n/**\n * Generate a compact, workflow-deterministic identifier.\n *\n * Uses Temporal's `uuid4()` internally (seeded by the workflow's RNG),\n * then re-encodes the hex bytes into a base-62 alphabet for a shorter,\n * more token-efficient identifier (~3 tokens vs ~10 for a full UUID).\n *\n * Suitable for thread IDs, child workflow IDs, or any workflow-scoped identifier.\n *\n * @param length - Number of base-62 characters (default 12, ~71 bits of entropy)\n */\nexport function getShortId(length = 12): string {\n const hex = uuid4().replace(/-/g, \"\");\n let result = \"\";\n for (let i = 0; i < length; i++) {\n const byte = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n result += BASE62[byte % BASE62.length];\n }\n return result;\n}\n","import {\n Bash,\n InMemoryFs,\n type BashOptions,\n type IFileSystem,\n type InitialFiles,\n} from \"just-bash\";\nimport type {\n Sandbox,\n SandboxCapabilities,\n SandboxCreateOptions,\n SandboxCreateResult,\n SandboxFileSystem,\n SandboxProvider,\n SandboxSnapshot,\n ExecOptions,\n ExecResult,\n DirentEntry,\n FileStat,\n} from \"../../../lib/sandbox/types\";\nimport { SandboxNotFoundError } from \"../../../lib/sandbox/types\";\nimport { getShortId } from \"../../../lib/thread/id\";\n\n// ============================================================================\n// Adapter: IFileSystem → SandboxFileSystem\n// ============================================================================\n\nfunction toSandboxFs(fs: IFileSystem): SandboxFileSystem {\n const workspaceBase = \"/\";\n const normalisePath = (path: string): string => fs.resolvePath(workspaceBase, path);\n\n return {\n workspaceBase,\n readFile: (path) => fs.readFile(normalisePath(path)),\n readFileBuffer: (path) => fs.readFileBuffer(normalisePath(path)),\n writeFile: (path, content) => fs.writeFile(normalisePath(path), content),\n appendFile: (path, content) => fs.appendFile(normalisePath(path), content),\n exists: (path) => fs.exists(normalisePath(path)),\n stat: async (path): Promise<FileStat> => {\n const s = await fs.stat(normalisePath(path));\n return {\n isFile: s.isFile,\n isDirectory: s.isDirectory,\n isSymbolicLink: s.isSymbolicLink,\n size: s.size,\n mtime: s.mtime,\n };\n },\n mkdir: (path, opts) => fs.mkdir(normalisePath(path), opts),\n readdir: (path) => fs.readdir(normalisePath(path)),\n readdirWithFileTypes: async (path): Promise<DirentEntry[]> => {\n const dirPath = normalisePath(path);\n if (!fs.readdirWithFileTypes) {\n const names = await fs.readdir(dirPath);\n return Promise.all(\n names.map(async (name) => {\n const childPath = fs.resolvePath(dirPath, name);\n const s = await fs.stat(childPath);\n return {\n name,\n isFile: s.isFile,\n isDirectory: s.isDirectory,\n isSymbolicLink: s.isSymbolicLink,\n };\n })\n );\n }\n return fs.readdirWithFileTypes(dirPath);\n },\n rm: (path, opts) => fs.rm(normalisePath(path), opts),\n cp: (src, dest, opts) => fs.cp(normalisePath(src), normalisePath(dest), opts),\n mv: (src, dest) => fs.mv(normalisePath(src), normalisePath(dest)),\n readlink: (path) => fs.readlink(normalisePath(path)),\n resolvePath: (base, p) => fs.resolvePath(normalisePath(base), p),\n };\n}\n\n// ============================================================================\n// InMemorySandbox\n// ============================================================================\n\nexport interface InMemorySandboxOptions {\n /** Options forwarded to `just-bash` `Bash` (minus `fs` which is managed) */\n bashOptions?: Omit<BashOptions, \"fs\">;\n}\n\n/**\n * An in-memory {@link Sandbox} backed by `just-bash`.\n */\nexport type InMemorySandbox = Sandbox & { fs: SandboxFileSystem };\n\nclass InMemorySandboxImpl implements Sandbox {\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: true,\n };\n\n readonly fs: SandboxFileSystem;\n private bashOptions: Omit<BashOptions, \"fs\">;\n\n constructor(\n readonly id: string,\n private justBashFs: IFileSystem,\n options?: InMemorySandboxOptions\n ) {\n this.fs = toSandboxFs(justBashFs);\n this.bashOptions = {\n executionLimits: { maxStringLength: 52_428_800 },\n ...options?.bashOptions,\n };\n }\n\n async exec(command: string, _options?: ExecOptions): Promise<ExecResult> {\n const bash = new Bash({ ...this.bashOptions, fs: this.justBashFs });\n const { exitCode, stderr, stdout } = await bash.exec(command);\n return { exitCode, stdout, stderr };\n }\n\n async destroy(): Promise<void> {\n // In-memory: nothing to clean up\n }\n\n /** Expose the underlying IFileSystem for snapshot serialisation */\n _getJustBashFs(): IFileSystem {\n return this.justBashFs;\n }\n}\n\n// ============================================================================\n// InMemorySandboxProvider\n// ============================================================================\n\nexport class InMemorySandboxProvider implements SandboxProvider {\n readonly id = \"inmemory\";\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: true,\n };\n\n private sandboxes = new Map<string, InMemorySandboxImpl>();\n\n constructor(private defaultOptions?: InMemorySandboxOptions) {}\n\n async get(id: string): Promise<Sandbox> {\n const sandbox = this.sandboxes.get(id);\n if (!sandbox) throw new SandboxNotFoundError(id);\n return sandbox;\n }\n\n async destroy(id: string): Promise<void> {\n const sandbox = this.sandboxes.get(id);\n if (sandbox) {\n await sandbox.destroy();\n this.sandboxes.delete(id);\n }\n }\n\n async create(options?: SandboxCreateOptions): Promise<SandboxCreateResult> {\n const id = options?.id ?? getShortId();\n const initialFiles: InitialFiles = {};\n\n if (options?.initialFiles) {\n for (const [path, content] of Object.entries(options.initialFiles)) {\n initialFiles[path] = content;\n }\n }\n\n const fs = new InMemoryFs(initialFiles);\n const sandbox = new InMemorySandboxImpl(id, fs, this.defaultOptions);\n this.sandboxes.set(id, sandbox);\n return { sandbox };\n }\n\n async snapshot(sandboxId: string): Promise<SandboxSnapshot> {\n const sandbox = this.sandboxes.get(sandboxId);\n if (!sandbox) throw new SandboxNotFoundError(sandboxId);\n\n const fs = sandbox._getJustBashFs();\n const paths = fs.getAllPaths();\n const files: Record<string, string> = {};\n\n for (const p of paths) {\n try {\n const stat = await fs.stat(p);\n if (stat.isFile) {\n files[p] = await fs.readFile(p);\n }\n } catch {\n // skip entries that can't be read (e.g. broken symlinks)\n }\n }\n\n return {\n sandboxId,\n providerId: this.id,\n data: { files },\n createdAt: new Date().toISOString(),\n };\n }\n\n async restore(snapshot: SandboxSnapshot): Promise<Sandbox> {\n const { files } = snapshot.data as { files: Record<string, string> };\n const initialFiles: InitialFiles = {};\n for (const [path, content] of Object.entries(files)) {\n initialFiles[path] = content;\n }\n\n const fs = new InMemoryFs(initialFiles);\n const sandbox = new InMemorySandboxImpl(\n snapshot.sandboxId,\n fs,\n this.defaultOptions\n );\n this.sandboxes.set(sandbox.id, sandbox);\n return sandbox;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/sandbox/types.ts","../../../../src/lib/thread/id.ts","../../../../src/adapters/sandbox/inmemory/index.ts"],"names":["ApplicationFailure","uuid4","Bash","InMemoryFs"],"mappings":"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","file":"index.cjs","sourcesContent":["// ============================================================================\n// Sandbox Filesystem\n// ============================================================================\n\nexport interface DirentEntry {\n name: string;\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n}\n\nexport interface FileStat {\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n size: number;\n mtime: Date;\n}\n\n/**\n * Provider-agnostic filesystem interface.\n *\n * Implementations that don't support a method should throw\n * {@link SandboxNotSupportedError}.\n */\nexport interface SandboxFileSystem {\n /** Base directory used when resolving relative paths. */\n readonly workspaceBase: string;\n readFile(path: string): Promise<string>;\n readFileBuffer(path: string): Promise<Uint8Array>;\n writeFile(path: string, content: string | Uint8Array): Promise<void>;\n appendFile(path: string, content: string | Uint8Array): Promise<void>;\n exists(path: string): Promise<boolean>;\n stat(path: string): Promise<FileStat>;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;\n readdir(path: string): Promise<string[]>;\n readdirWithFileTypes(path: string): Promise<DirentEntry[]>;\n rm(path: string, options?: { recursive?: boolean; force?: boolean }): Promise<void>;\n cp(src: string, dest: string, options?: { recursive?: boolean }): Promise<void>;\n mv(src: string, dest: string): Promise<void>;\n readlink(path: string): Promise<string>;\n resolvePath(base: string, path: string): string;\n}\n\n// ============================================================================\n// Execution\n// ============================================================================\n\nexport interface ExecOptions {\n timeout?: number;\n cwd?: string;\n env?: Record<string, string>;\n}\n\nexport interface ExecResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\n// ============================================================================\n// Capabilities\n// ============================================================================\n\nexport interface SandboxCapabilities {\n /** Sandbox supports filesystem operations */\n filesystem: boolean;\n /** Sandbox supports shell/command execution */\n execution: boolean;\n /** Sandbox state can be persisted and restored */\n persistence: boolean;\n}\n\n// ============================================================================\n// Sandbox\n// ============================================================================\n\nexport interface Sandbox {\n readonly id: string;\n readonly capabilities: SandboxCapabilities;\n readonly fs: SandboxFileSystem;\n\n exec(command: string, options?: ExecOptions): Promise<ExecResult>;\n destroy(): Promise<void>;\n}\n\n// ============================================================================\n// Snapshots\n// ============================================================================\n\nexport interface SandboxSnapshot {\n sandboxId: string;\n providerId: string;\n /** Provider-specific serialised state */\n data: unknown;\n createdAt: string;\n}\n\n// ============================================================================\n// Provider\n// ============================================================================\n\nexport interface SandboxCreateOptions {\n /** Preferred sandbox ID (provider may ignore) */\n id?: string;\n /** Seed the filesystem with these files */\n initialFiles?: Record<string, string | Uint8Array>;\n /** Environment variables available inside the sandbox */\n env?: Record<string, string>;\n}\n\nexport interface SandboxCreateResult {\n sandbox: Sandbox;\n /** Optional state to merge into the workflow's `AgentState` via the session. */\n stateUpdate?: Record<string, unknown>;\n}\n\nexport interface SandboxProvider<\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n TSandbox extends Sandbox = Sandbox,\n> {\n readonly id: string;\n readonly capabilities: SandboxCapabilities;\n\n create(options?: TOptions): Promise<SandboxCreateResult>;\n get(sandboxId: string): Promise<TSandbox>;\n destroy(sandboxId: string): Promise<void>;\n snapshot(sandboxId: string): Promise<SandboxSnapshot>;\n restore(snapshot: SandboxSnapshot): Promise<Sandbox>;\n fork(sandboxId: string): Promise<Sandbox>;\n}\n\n// ============================================================================\n// SandboxOps — workflow-side activity interface (like ThreadOps)\n// ============================================================================\n\nexport interface SandboxOps<\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n> {\n createSandbox(\n options?: TOptions,\n ): Promise<{ sandboxId: string; stateUpdate?: Record<string, unknown> }>;\n destroySandbox(sandboxId: string): Promise<void>;\n snapshotSandbox(sandboxId: string): Promise<SandboxSnapshot>;\n forkSandbox(sandboxId: string): Promise<string>;\n}\n\n/**\n * Maps generic {@link SandboxOps} method names to adapter-prefixed names.\n *\n * @example\n * ```typescript\n * type InMemOps = PrefixedSandboxOps<\"inMemory\">;\n * // → { inMemoryCreateSandbox, inMemoryDestroySandbox, inMemorySnapshotSandbox }\n * ```\n */\nexport type PrefixedSandboxOps<\n TPrefix extends string,\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n> = {\n [K in keyof SandboxOps<TOptions> as `${TPrefix}${Capitalize<K & string>}`]: SandboxOps<TOptions>[K];\n};\n\n// ============================================================================\n// Errors\n// ============================================================================\n\nimport { ApplicationFailure } from \"@temporalio/common\";\n\nexport class SandboxNotSupportedError extends ApplicationFailure {\n constructor(operation: string) {\n super(\n `Sandbox does not support: ${operation}`,\n \"SandboxNotSupportedError\",\n true,\n );\n }\n}\n\nexport class SandboxNotFoundError extends ApplicationFailure {\n constructor(sandboxId: string) {\n super(`Sandbox not found: ${sandboxId}`, \"SandboxNotFoundError\", true);\n }\n}\n","import { uuid4 } from \"@temporalio/workflow\";\n\nconst BASE62 =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\n/**\n * Generate a compact, workflow-deterministic identifier.\n *\n * Uses Temporal's `uuid4()` internally (seeded by the workflow's RNG),\n * then re-encodes the hex bytes into a base-62 alphabet for a shorter,\n * more token-efficient identifier (~3 tokens vs ~10 for a full UUID).\n *\n * Suitable for thread IDs, child workflow IDs, or any workflow-scoped identifier.\n *\n * @param length - Number of base-62 characters (default 12, ~71 bits of entropy)\n */\nexport function getShortId(length = 12): string {\n const hex = uuid4().replace(/-/g, \"\");\n let result = \"\";\n for (let i = 0; i < length; i++) {\n const byte = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n result += BASE62[byte % BASE62.length];\n }\n return result;\n}\n","import {\n Bash,\n InMemoryFs,\n type BashOptions,\n type IFileSystem,\n type InitialFiles,\n} from \"just-bash\";\nimport type {\n Sandbox,\n SandboxCapabilities,\n SandboxCreateOptions,\n SandboxCreateResult,\n SandboxFileSystem,\n SandboxProvider,\n SandboxSnapshot,\n ExecOptions,\n ExecResult,\n DirentEntry,\n FileStat,\n} from \"../../../lib/sandbox/types\";\nimport { SandboxNotFoundError } from \"../../../lib/sandbox/types\";\nimport { getShortId } from \"../../../lib/thread/id\";\n\n// ============================================================================\n// Adapter: IFileSystem → SandboxFileSystem\n// ============================================================================\n\nfunction toSandboxFs(fs: IFileSystem): SandboxFileSystem {\n const workspaceBase = \"/\";\n const normalisePath = (path: string): string => fs.resolvePath(workspaceBase, path);\n\n return {\n workspaceBase,\n readFile: (path) => fs.readFile(normalisePath(path)),\n readFileBuffer: (path) => fs.readFileBuffer(normalisePath(path)),\n writeFile: (path, content) => fs.writeFile(normalisePath(path), content),\n appendFile: (path, content) => fs.appendFile(normalisePath(path), content),\n exists: (path) => fs.exists(normalisePath(path)),\n stat: async (path): Promise<FileStat> => {\n const s = await fs.stat(normalisePath(path));\n return {\n isFile: s.isFile,\n isDirectory: s.isDirectory,\n isSymbolicLink: s.isSymbolicLink,\n size: s.size,\n mtime: s.mtime,\n };\n },\n mkdir: (path, opts) => fs.mkdir(normalisePath(path), opts),\n readdir: (path) => fs.readdir(normalisePath(path)),\n readdirWithFileTypes: async (path): Promise<DirentEntry[]> => {\n const dirPath = normalisePath(path);\n if (!fs.readdirWithFileTypes) {\n const names = await fs.readdir(dirPath);\n return Promise.all(\n names.map(async (name) => {\n const childPath = fs.resolvePath(dirPath, name);\n const s = await fs.stat(childPath);\n return {\n name,\n isFile: s.isFile,\n isDirectory: s.isDirectory,\n isSymbolicLink: s.isSymbolicLink,\n };\n })\n );\n }\n return fs.readdirWithFileTypes(dirPath);\n },\n rm: (path, opts) => fs.rm(normalisePath(path), opts),\n cp: (src, dest, opts) => fs.cp(normalisePath(src), normalisePath(dest), opts),\n mv: (src, dest) => fs.mv(normalisePath(src), normalisePath(dest)),\n readlink: (path) => fs.readlink(normalisePath(path)),\n resolvePath: (base, p) => fs.resolvePath(normalisePath(base), p),\n };\n}\n\n// ============================================================================\n// InMemorySandbox\n// ============================================================================\n\nexport interface InMemorySandboxOptions {\n /** Options forwarded to `just-bash` `Bash` (minus `fs` which is managed) */\n bashOptions?: Omit<BashOptions, \"fs\">;\n}\n\n/**\n * An in-memory {@link Sandbox} backed by `just-bash`.\n */\nexport type InMemorySandbox = Sandbox & { fs: SandboxFileSystem };\n\nclass InMemorySandboxImpl implements Sandbox {\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: true,\n };\n\n readonly fs: SandboxFileSystem;\n private bashOptions: Omit<BashOptions, \"fs\">;\n\n constructor(\n readonly id: string,\n private justBashFs: IFileSystem,\n options?: InMemorySandboxOptions\n ) {\n this.fs = toSandboxFs(justBashFs);\n this.bashOptions = {\n executionLimits: { maxStringLength: 52_428_800 },\n ...options?.bashOptions,\n };\n }\n\n async exec(command: string, _options?: ExecOptions): Promise<ExecResult> {\n const bash = new Bash({ ...this.bashOptions, fs: this.justBashFs });\n const { exitCode, stderr, stdout } = await bash.exec(command);\n return { exitCode, stdout, stderr };\n }\n\n async destroy(): Promise<void> {\n // In-memory: nothing to clean up\n }\n\n /** Expose the underlying IFileSystem for snapshot serialisation */\n _getJustBashFs(): IFileSystem {\n return this.justBashFs;\n }\n}\n\n// ============================================================================\n// InMemorySandboxProvider\n// ============================================================================\n\nexport class InMemorySandboxProvider implements SandboxProvider {\n readonly id = \"inMemory\";\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: true,\n };\n\n private sandboxes = new Map<string, InMemorySandboxImpl>();\n\n constructor(private defaultOptions?: InMemorySandboxOptions) {}\n\n async get(id: string): Promise<Sandbox> {\n const sandbox = this.sandboxes.get(id);\n if (!sandbox) throw new SandboxNotFoundError(id);\n return sandbox;\n }\n\n async destroy(id: string): Promise<void> {\n const sandbox = this.sandboxes.get(id);\n if (sandbox) {\n await sandbox.destroy();\n this.sandboxes.delete(id);\n }\n }\n\n async create(options?: SandboxCreateOptions): Promise<SandboxCreateResult> {\n const id = options?.id ?? getShortId();\n const initialFiles: InitialFiles = {};\n\n if (options?.initialFiles) {\n for (const [path, content] of Object.entries(options.initialFiles)) {\n initialFiles[path] = content;\n }\n }\n\n const fs = new InMemoryFs(initialFiles);\n const sandbox = new InMemorySandboxImpl(id, fs, this.defaultOptions);\n this.sandboxes.set(id, sandbox);\n return { sandbox };\n }\n\n async snapshot(sandboxId: string): Promise<SandboxSnapshot> {\n const sandbox = this.sandboxes.get(sandboxId);\n if (!sandbox) throw new SandboxNotFoundError(sandboxId);\n\n const fs = sandbox._getJustBashFs();\n const paths = fs.getAllPaths();\n const files: Record<string, string> = {};\n\n for (const p of paths) {\n try {\n const stat = await fs.stat(p);\n if (stat.isFile) {\n files[p] = await fs.readFile(p);\n }\n } catch {\n // skip entries that can't be read (e.g. broken symlinks)\n }\n }\n\n return {\n sandboxId,\n providerId: this.id,\n data: { files },\n createdAt: new Date().toISOString(),\n };\n }\n\n async fork(_sandboxId: string): Promise<Sandbox> {\n throw new Error(\"Not implemented\");\n }\n\n async restore(snapshot: SandboxSnapshot): Promise<Sandbox> {\n const { files } = snapshot.data as { files: Record<string, string> };\n const initialFiles: InitialFiles = {};\n for (const [path, content] of Object.entries(files)) {\n initialFiles[path] = content;\n }\n\n const fs = new InMemoryFs(initialFiles);\n const sandbox = new InMemorySandboxImpl(\n snapshot.sandboxId,\n fs,\n this.defaultOptions\n );\n this.sandboxes.set(sandbox.id, sandbox);\n return sandbox;\n }\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BashOptions } from 'just-bash';
|
|
2
|
-
import { S as Sandbox, a as SandboxFileSystem, b as SandboxProvider, c as SandboxCapabilities, d as SandboxCreateOptions, e as SandboxCreateResult, f as SandboxSnapshot } from '../../../types-
|
|
2
|
+
import { S as Sandbox, a as SandboxFileSystem, b as SandboxProvider, c as SandboxCapabilities, d as SandboxCreateOptions, e as SandboxCreateResult, f as SandboxSnapshot } from '../../../types-HBosetv3.cjs';
|
|
3
3
|
import '@temporalio/common';
|
|
4
4
|
|
|
5
5
|
interface InMemorySandboxOptions {
|
|
@@ -14,7 +14,7 @@ type InMemorySandbox = Sandbox & {
|
|
|
14
14
|
};
|
|
15
15
|
declare class InMemorySandboxProvider implements SandboxProvider {
|
|
16
16
|
private defaultOptions?;
|
|
17
|
-
readonly id = "
|
|
17
|
+
readonly id = "inMemory";
|
|
18
18
|
readonly capabilities: SandboxCapabilities;
|
|
19
19
|
private sandboxes;
|
|
20
20
|
constructor(defaultOptions?: InMemorySandboxOptions | undefined);
|
|
@@ -22,6 +22,7 @@ declare class InMemorySandboxProvider implements SandboxProvider {
|
|
|
22
22
|
destroy(id: string): Promise<void>;
|
|
23
23
|
create(options?: SandboxCreateOptions): Promise<SandboxCreateResult>;
|
|
24
24
|
snapshot(sandboxId: string): Promise<SandboxSnapshot>;
|
|
25
|
+
fork(_sandboxId: string): Promise<Sandbox>;
|
|
25
26
|
restore(snapshot: SandboxSnapshot): Promise<Sandbox>;
|
|
26
27
|
}
|
|
27
28
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BashOptions } from 'just-bash';
|
|
2
|
-
import { S as Sandbox, a as SandboxFileSystem, b as SandboxProvider, c as SandboxCapabilities, d as SandboxCreateOptions, e as SandboxCreateResult, f as SandboxSnapshot } from '../../../types-
|
|
2
|
+
import { S as Sandbox, a as SandboxFileSystem, b as SandboxProvider, c as SandboxCapabilities, d as SandboxCreateOptions, e as SandboxCreateResult, f as SandboxSnapshot } from '../../../types-HBosetv3.js';
|
|
3
3
|
import '@temporalio/common';
|
|
4
4
|
|
|
5
5
|
interface InMemorySandboxOptions {
|
|
@@ -14,7 +14,7 @@ type InMemorySandbox = Sandbox & {
|
|
|
14
14
|
};
|
|
15
15
|
declare class InMemorySandboxProvider implements SandboxProvider {
|
|
16
16
|
private defaultOptions?;
|
|
17
|
-
readonly id = "
|
|
17
|
+
readonly id = "inMemory";
|
|
18
18
|
readonly capabilities: SandboxCapabilities;
|
|
19
19
|
private sandboxes;
|
|
20
20
|
constructor(defaultOptions?: InMemorySandboxOptions | undefined);
|
|
@@ -22,6 +22,7 @@ declare class InMemorySandboxProvider implements SandboxProvider {
|
|
|
22
22
|
destroy(id: string): Promise<void>;
|
|
23
23
|
create(options?: SandboxCreateOptions): Promise<SandboxCreateResult>;
|
|
24
24
|
snapshot(sandboxId: string): Promise<SandboxSnapshot>;
|
|
25
|
+
fork(_sandboxId: string): Promise<Sandbox>;
|
|
25
26
|
restore(snapshot: SandboxSnapshot): Promise<Sandbox>;
|
|
26
27
|
}
|
|
27
28
|
|
|
@@ -101,7 +101,7 @@ var InMemorySandboxProvider = class {
|
|
|
101
101
|
constructor(defaultOptions) {
|
|
102
102
|
this.defaultOptions = defaultOptions;
|
|
103
103
|
}
|
|
104
|
-
id = "
|
|
104
|
+
id = "inMemory";
|
|
105
105
|
capabilities = {
|
|
106
106
|
filesystem: true,
|
|
107
107
|
execution: true,
|
|
@@ -155,6 +155,9 @@ var InMemorySandboxProvider = class {
|
|
|
155
155
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
156
156
|
};
|
|
157
157
|
}
|
|
158
|
+
async fork(_sandboxId) {
|
|
159
|
+
throw new Error("Not implemented");
|
|
160
|
+
}
|
|
158
161
|
async restore(snapshot) {
|
|
159
162
|
const { files } = snapshot.data;
|
|
160
163
|
const initialFiles = {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/sandbox/types.ts","../../../../src/lib/thread/id.ts","../../../../src/adapters/sandbox/inmemory/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// ============================================================================\n// Sandbox Filesystem\n// ============================================================================\n\nexport interface DirentEntry {\n name: string;\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n}\n\nexport interface FileStat {\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n size: number;\n mtime: Date;\n}\n\n/**\n * Provider-agnostic filesystem interface.\n *\n * Implementations that don't support a method should throw\n * {@link SandboxNotSupportedError}.\n */\nexport interface SandboxFileSystem {\n /** Base directory used when resolving relative paths. */\n readonly workspaceBase: string;\n readFile(path: string): Promise<string>;\n readFileBuffer(path: string): Promise<Uint8Array>;\n writeFile(path: string, content: string | Uint8Array): Promise<void>;\n appendFile(path: string, content: string | Uint8Array): Promise<void>;\n exists(path: string): Promise<boolean>;\n stat(path: string): Promise<FileStat>;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;\n readdir(path: string): Promise<string[]>;\n readdirWithFileTypes(path: string): Promise<DirentEntry[]>;\n rm(path: string, options?: { recursive?: boolean; force?: boolean }): Promise<void>;\n cp(src: string, dest: string, options?: { recursive?: boolean }): Promise<void>;\n mv(src: string, dest: string): Promise<void>;\n readlink(path: string): Promise<string>;\n resolvePath(base: string, path: string): string;\n}\n\n// ============================================================================\n// Execution\n// ============================================================================\n\nexport interface ExecOptions {\n timeout?: number;\n cwd?: string;\n env?: Record<string, string>;\n}\n\nexport interface ExecResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\n// ============================================================================\n// Capabilities\n// ============================================================================\n\nexport interface SandboxCapabilities {\n /** Sandbox supports filesystem operations */\n filesystem: boolean;\n /** Sandbox supports shell/command execution */\n execution: boolean;\n /** Sandbox state can be persisted and restored */\n persistence: boolean;\n}\n\n// ============================================================================\n// Sandbox\n// ============================================================================\n\nexport interface Sandbox {\n readonly id: string;\n readonly capabilities: SandboxCapabilities;\n readonly fs: SandboxFileSystem;\n\n exec(command: string, options?: ExecOptions): Promise<ExecResult>;\n destroy(): Promise<void>;\n}\n\n// ============================================================================\n// Snapshots\n// ============================================================================\n\nexport interface SandboxSnapshot {\n sandboxId: string;\n providerId: string;\n /** Provider-specific serialised state */\n data: unknown;\n createdAt: string;\n}\n\n// ============================================================================\n// Provider\n// ============================================================================\n\nexport interface SandboxCreateOptions {\n /** Preferred sandbox ID (provider may ignore) */\n id?: string;\n /** Seed the filesystem with these files */\n initialFiles?: Record<string, string | Uint8Array>;\n /** Environment variables available inside the sandbox */\n env?: Record<string, string>;\n}\n\nexport interface SandboxCreateResult {\n sandbox: Sandbox;\n /** Optional state to merge into the workflow's `AgentState` via the session. */\n stateUpdate?: Record<string, unknown>;\n}\n\nexport interface SandboxProvider<\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n TSandbox extends Sandbox = Sandbox,\n> {\n readonly id: string;\n readonly capabilities: SandboxCapabilities;\n\n create(options?: TOptions): Promise<SandboxCreateResult>;\n get(sandboxId: string): Promise<TSandbox>;\n destroy(sandboxId: string): Promise<void>;\n snapshot(sandboxId: string): Promise<SandboxSnapshot>;\n restore(snapshot: SandboxSnapshot): Promise<Sandbox>;\n}\n\n// ============================================================================\n// SandboxOps — workflow-side activity interface (like ThreadOps)\n// ============================================================================\n\nexport interface SandboxOps<\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n> {\n createSandbox(\n options?: TOptions,\n ): Promise<{ sandboxId: string; stateUpdate?: Record<string, unknown> }>;\n destroySandbox(sandboxId: string): Promise<void>;\n snapshotSandbox(sandboxId: string): Promise<SandboxSnapshot>;\n}\n\n// ============================================================================\n// Errors\n// ============================================================================\n\nimport { ApplicationFailure } from \"@temporalio/common\";\n\nexport class SandboxNotSupportedError extends ApplicationFailure {\n constructor(operation: string) {\n super(\n `Sandbox does not support: ${operation}`,\n \"SandboxNotSupportedError\",\n true,\n );\n }\n}\n\nexport class SandboxNotFoundError extends ApplicationFailure {\n constructor(sandboxId: string) {\n super(`Sandbox not found: ${sandboxId}`, \"SandboxNotFoundError\", true);\n }\n}\n","import { uuid4 } from \"@temporalio/workflow\";\n\nconst BASE62 =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\n/**\n * Generate a compact, workflow-deterministic identifier.\n *\n * Uses Temporal's `uuid4()` internally (seeded by the workflow's RNG),\n * then re-encodes the hex bytes into a base-62 alphabet for a shorter,\n * more token-efficient identifier (~3 tokens vs ~10 for a full UUID).\n *\n * Suitable for thread IDs, child workflow IDs, or any workflow-scoped identifier.\n *\n * @param length - Number of base-62 characters (default 12, ~71 bits of entropy)\n */\nexport function getShortId(length = 12): string {\n const hex = uuid4().replace(/-/g, \"\");\n let result = \"\";\n for (let i = 0; i < length; i++) {\n const byte = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n result += BASE62[byte % BASE62.length];\n }\n return result;\n}\n","import {\n Bash,\n InMemoryFs,\n type BashOptions,\n type IFileSystem,\n type InitialFiles,\n} from \"just-bash\";\nimport type {\n Sandbox,\n SandboxCapabilities,\n SandboxCreateOptions,\n SandboxCreateResult,\n SandboxFileSystem,\n SandboxProvider,\n SandboxSnapshot,\n ExecOptions,\n ExecResult,\n DirentEntry,\n FileStat,\n} from \"../../../lib/sandbox/types\";\nimport { SandboxNotFoundError } from \"../../../lib/sandbox/types\";\nimport { getShortId } from \"../../../lib/thread/id\";\n\n// ============================================================================\n// Adapter: IFileSystem → SandboxFileSystem\n// ============================================================================\n\nfunction toSandboxFs(fs: IFileSystem): SandboxFileSystem {\n const workspaceBase = \"/\";\n const normalisePath = (path: string): string => fs.resolvePath(workspaceBase, path);\n\n return {\n workspaceBase,\n readFile: (path) => fs.readFile(normalisePath(path)),\n readFileBuffer: (path) => fs.readFileBuffer(normalisePath(path)),\n writeFile: (path, content) => fs.writeFile(normalisePath(path), content),\n appendFile: (path, content) => fs.appendFile(normalisePath(path), content),\n exists: (path) => fs.exists(normalisePath(path)),\n stat: async (path): Promise<FileStat> => {\n const s = await fs.stat(normalisePath(path));\n return {\n isFile: s.isFile,\n isDirectory: s.isDirectory,\n isSymbolicLink: s.isSymbolicLink,\n size: s.size,\n mtime: s.mtime,\n };\n },\n mkdir: (path, opts) => fs.mkdir(normalisePath(path), opts),\n readdir: (path) => fs.readdir(normalisePath(path)),\n readdirWithFileTypes: async (path): Promise<DirentEntry[]> => {\n const dirPath = normalisePath(path);\n if (!fs.readdirWithFileTypes) {\n const names = await fs.readdir(dirPath);\n return Promise.all(\n names.map(async (name) => {\n const childPath = fs.resolvePath(dirPath, name);\n const s = await fs.stat(childPath);\n return {\n name,\n isFile: s.isFile,\n isDirectory: s.isDirectory,\n isSymbolicLink: s.isSymbolicLink,\n };\n })\n );\n }\n return fs.readdirWithFileTypes(dirPath);\n },\n rm: (path, opts) => fs.rm(normalisePath(path), opts),\n cp: (src, dest, opts) => fs.cp(normalisePath(src), normalisePath(dest), opts),\n mv: (src, dest) => fs.mv(normalisePath(src), normalisePath(dest)),\n readlink: (path) => fs.readlink(normalisePath(path)),\n resolvePath: (base, p) => fs.resolvePath(normalisePath(base), p),\n };\n}\n\n// ============================================================================\n// InMemorySandbox\n// ============================================================================\n\nexport interface InMemorySandboxOptions {\n /** Options forwarded to `just-bash` `Bash` (minus `fs` which is managed) */\n bashOptions?: Omit<BashOptions, \"fs\">;\n}\n\n/**\n * An in-memory {@link Sandbox} backed by `just-bash`.\n */\nexport type InMemorySandbox = Sandbox & { fs: SandboxFileSystem };\n\nclass InMemorySandboxImpl implements Sandbox {\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: true,\n };\n\n readonly fs: SandboxFileSystem;\n private bashOptions: Omit<BashOptions, \"fs\">;\n\n constructor(\n readonly id: string,\n private justBashFs: IFileSystem,\n options?: InMemorySandboxOptions\n ) {\n this.fs = toSandboxFs(justBashFs);\n this.bashOptions = {\n executionLimits: { maxStringLength: 52_428_800 },\n ...options?.bashOptions,\n };\n }\n\n async exec(command: string, _options?: ExecOptions): Promise<ExecResult> {\n const bash = new Bash({ ...this.bashOptions, fs: this.justBashFs });\n const { exitCode, stderr, stdout } = await bash.exec(command);\n return { exitCode, stdout, stderr };\n }\n\n async destroy(): Promise<void> {\n // In-memory: nothing to clean up\n }\n\n /** Expose the underlying IFileSystem for snapshot serialisation */\n _getJustBashFs(): IFileSystem {\n return this.justBashFs;\n }\n}\n\n// ============================================================================\n// InMemorySandboxProvider\n// ============================================================================\n\nexport class InMemorySandboxProvider implements SandboxProvider {\n readonly id = \"inmemory\";\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: true,\n };\n\n private sandboxes = new Map<string, InMemorySandboxImpl>();\n\n constructor(private defaultOptions?: InMemorySandboxOptions) {}\n\n async get(id: string): Promise<Sandbox> {\n const sandbox = this.sandboxes.get(id);\n if (!sandbox) throw new SandboxNotFoundError(id);\n return sandbox;\n }\n\n async destroy(id: string): Promise<void> {\n const sandbox = this.sandboxes.get(id);\n if (sandbox) {\n await sandbox.destroy();\n this.sandboxes.delete(id);\n }\n }\n\n async create(options?: SandboxCreateOptions): Promise<SandboxCreateResult> {\n const id = options?.id ?? getShortId();\n const initialFiles: InitialFiles = {};\n\n if (options?.initialFiles) {\n for (const [path, content] of Object.entries(options.initialFiles)) {\n initialFiles[path] = content;\n }\n }\n\n const fs = new InMemoryFs(initialFiles);\n const sandbox = new InMemorySandboxImpl(id, fs, this.defaultOptions);\n this.sandboxes.set(id, sandbox);\n return { sandbox };\n }\n\n async snapshot(sandboxId: string): Promise<SandboxSnapshot> {\n const sandbox = this.sandboxes.get(sandboxId);\n if (!sandbox) throw new SandboxNotFoundError(sandboxId);\n\n const fs = sandbox._getJustBashFs();\n const paths = fs.getAllPaths();\n const files: Record<string, string> = {};\n\n for (const p of paths) {\n try {\n const stat = await fs.stat(p);\n if (stat.isFile) {\n files[p] = await fs.readFile(p);\n }\n } catch {\n // skip entries that can't be read (e.g. broken symlinks)\n }\n }\n\n return {\n sandboxId,\n providerId: this.id,\n data: { files },\n createdAt: new Date().toISOString(),\n };\n }\n\n async restore(snapshot: SandboxSnapshot): Promise<Sandbox> {\n const { files } = snapshot.data as { files: Record<string, string> };\n const initialFiles: InitialFiles = {};\n for (const [path, content] of Object.entries(files)) {\n initialFiles[path] = content;\n }\n\n const fs = new InMemoryFs(initialFiles);\n const sandbox = new InMemorySandboxImpl(\n snapshot.sandboxId,\n fs,\n this.defaultOptions\n );\n this.sandboxes.set(sandbox.id, sandbox);\n return sandbox;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/sandbox/types.ts","../../../../src/lib/thread/id.ts","../../../../src/adapters/sandbox/inmemory/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// ============================================================================\n// Sandbox Filesystem\n// ============================================================================\n\nexport interface DirentEntry {\n name: string;\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n}\n\nexport interface FileStat {\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n size: number;\n mtime: Date;\n}\n\n/**\n * Provider-agnostic filesystem interface.\n *\n * Implementations that don't support a method should throw\n * {@link SandboxNotSupportedError}.\n */\nexport interface SandboxFileSystem {\n /** Base directory used when resolving relative paths. */\n readonly workspaceBase: string;\n readFile(path: string): Promise<string>;\n readFileBuffer(path: string): Promise<Uint8Array>;\n writeFile(path: string, content: string | Uint8Array): Promise<void>;\n appendFile(path: string, content: string | Uint8Array): Promise<void>;\n exists(path: string): Promise<boolean>;\n stat(path: string): Promise<FileStat>;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;\n readdir(path: string): Promise<string[]>;\n readdirWithFileTypes(path: string): Promise<DirentEntry[]>;\n rm(path: string, options?: { recursive?: boolean; force?: boolean }): Promise<void>;\n cp(src: string, dest: string, options?: { recursive?: boolean }): Promise<void>;\n mv(src: string, dest: string): Promise<void>;\n readlink(path: string): Promise<string>;\n resolvePath(base: string, path: string): string;\n}\n\n// ============================================================================\n// Execution\n// ============================================================================\n\nexport interface ExecOptions {\n timeout?: number;\n cwd?: string;\n env?: Record<string, string>;\n}\n\nexport interface ExecResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\n// ============================================================================\n// Capabilities\n// ============================================================================\n\nexport interface SandboxCapabilities {\n /** Sandbox supports filesystem operations */\n filesystem: boolean;\n /** Sandbox supports shell/command execution */\n execution: boolean;\n /** Sandbox state can be persisted and restored */\n persistence: boolean;\n}\n\n// ============================================================================\n// Sandbox\n// ============================================================================\n\nexport interface Sandbox {\n readonly id: string;\n readonly capabilities: SandboxCapabilities;\n readonly fs: SandboxFileSystem;\n\n exec(command: string, options?: ExecOptions): Promise<ExecResult>;\n destroy(): Promise<void>;\n}\n\n// ============================================================================\n// Snapshots\n// ============================================================================\n\nexport interface SandboxSnapshot {\n sandboxId: string;\n providerId: string;\n /** Provider-specific serialised state */\n data: unknown;\n createdAt: string;\n}\n\n// ============================================================================\n// Provider\n// ============================================================================\n\nexport interface SandboxCreateOptions {\n /** Preferred sandbox ID (provider may ignore) */\n id?: string;\n /** Seed the filesystem with these files */\n initialFiles?: Record<string, string | Uint8Array>;\n /** Environment variables available inside the sandbox */\n env?: Record<string, string>;\n}\n\nexport interface SandboxCreateResult {\n sandbox: Sandbox;\n /** Optional state to merge into the workflow's `AgentState` via the session. */\n stateUpdate?: Record<string, unknown>;\n}\n\nexport interface SandboxProvider<\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n TSandbox extends Sandbox = Sandbox,\n> {\n readonly id: string;\n readonly capabilities: SandboxCapabilities;\n\n create(options?: TOptions): Promise<SandboxCreateResult>;\n get(sandboxId: string): Promise<TSandbox>;\n destroy(sandboxId: string): Promise<void>;\n snapshot(sandboxId: string): Promise<SandboxSnapshot>;\n restore(snapshot: SandboxSnapshot): Promise<Sandbox>;\n fork(sandboxId: string): Promise<Sandbox>;\n}\n\n// ============================================================================\n// SandboxOps — workflow-side activity interface (like ThreadOps)\n// ============================================================================\n\nexport interface SandboxOps<\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n> {\n createSandbox(\n options?: TOptions,\n ): Promise<{ sandboxId: string; stateUpdate?: Record<string, unknown> }>;\n destroySandbox(sandboxId: string): Promise<void>;\n snapshotSandbox(sandboxId: string): Promise<SandboxSnapshot>;\n forkSandbox(sandboxId: string): Promise<string>;\n}\n\n/**\n * Maps generic {@link SandboxOps} method names to adapter-prefixed names.\n *\n * @example\n * ```typescript\n * type InMemOps = PrefixedSandboxOps<\"inMemory\">;\n * // → { inMemoryCreateSandbox, inMemoryDestroySandbox, inMemorySnapshotSandbox }\n * ```\n */\nexport type PrefixedSandboxOps<\n TPrefix extends string,\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n> = {\n [K in keyof SandboxOps<TOptions> as `${TPrefix}${Capitalize<K & string>}`]: SandboxOps<TOptions>[K];\n};\n\n// ============================================================================\n// Errors\n// ============================================================================\n\nimport { ApplicationFailure } from \"@temporalio/common\";\n\nexport class SandboxNotSupportedError extends ApplicationFailure {\n constructor(operation: string) {\n super(\n `Sandbox does not support: ${operation}`,\n \"SandboxNotSupportedError\",\n true,\n );\n }\n}\n\nexport class SandboxNotFoundError extends ApplicationFailure {\n constructor(sandboxId: string) {\n super(`Sandbox not found: ${sandboxId}`, \"SandboxNotFoundError\", true);\n }\n}\n","import { uuid4 } from \"@temporalio/workflow\";\n\nconst BASE62 =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\n/**\n * Generate a compact, workflow-deterministic identifier.\n *\n * Uses Temporal's `uuid4()` internally (seeded by the workflow's RNG),\n * then re-encodes the hex bytes into a base-62 alphabet for a shorter,\n * more token-efficient identifier (~3 tokens vs ~10 for a full UUID).\n *\n * Suitable for thread IDs, child workflow IDs, or any workflow-scoped identifier.\n *\n * @param length - Number of base-62 characters (default 12, ~71 bits of entropy)\n */\nexport function getShortId(length = 12): string {\n const hex = uuid4().replace(/-/g, \"\");\n let result = \"\";\n for (let i = 0; i < length; i++) {\n const byte = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n result += BASE62[byte % BASE62.length];\n }\n return result;\n}\n","import {\n Bash,\n InMemoryFs,\n type BashOptions,\n type IFileSystem,\n type InitialFiles,\n} from \"just-bash\";\nimport type {\n Sandbox,\n SandboxCapabilities,\n SandboxCreateOptions,\n SandboxCreateResult,\n SandboxFileSystem,\n SandboxProvider,\n SandboxSnapshot,\n ExecOptions,\n ExecResult,\n DirentEntry,\n FileStat,\n} from \"../../../lib/sandbox/types\";\nimport { SandboxNotFoundError } from \"../../../lib/sandbox/types\";\nimport { getShortId } from \"../../../lib/thread/id\";\n\n// ============================================================================\n// Adapter: IFileSystem → SandboxFileSystem\n// ============================================================================\n\nfunction toSandboxFs(fs: IFileSystem): SandboxFileSystem {\n const workspaceBase = \"/\";\n const normalisePath = (path: string): string => fs.resolvePath(workspaceBase, path);\n\n return {\n workspaceBase,\n readFile: (path) => fs.readFile(normalisePath(path)),\n readFileBuffer: (path) => fs.readFileBuffer(normalisePath(path)),\n writeFile: (path, content) => fs.writeFile(normalisePath(path), content),\n appendFile: (path, content) => fs.appendFile(normalisePath(path), content),\n exists: (path) => fs.exists(normalisePath(path)),\n stat: async (path): Promise<FileStat> => {\n const s = await fs.stat(normalisePath(path));\n return {\n isFile: s.isFile,\n isDirectory: s.isDirectory,\n isSymbolicLink: s.isSymbolicLink,\n size: s.size,\n mtime: s.mtime,\n };\n },\n mkdir: (path, opts) => fs.mkdir(normalisePath(path), opts),\n readdir: (path) => fs.readdir(normalisePath(path)),\n readdirWithFileTypes: async (path): Promise<DirentEntry[]> => {\n const dirPath = normalisePath(path);\n if (!fs.readdirWithFileTypes) {\n const names = await fs.readdir(dirPath);\n return Promise.all(\n names.map(async (name) => {\n const childPath = fs.resolvePath(dirPath, name);\n const s = await fs.stat(childPath);\n return {\n name,\n isFile: s.isFile,\n isDirectory: s.isDirectory,\n isSymbolicLink: s.isSymbolicLink,\n };\n })\n );\n }\n return fs.readdirWithFileTypes(dirPath);\n },\n rm: (path, opts) => fs.rm(normalisePath(path), opts),\n cp: (src, dest, opts) => fs.cp(normalisePath(src), normalisePath(dest), opts),\n mv: (src, dest) => fs.mv(normalisePath(src), normalisePath(dest)),\n readlink: (path) => fs.readlink(normalisePath(path)),\n resolvePath: (base, p) => fs.resolvePath(normalisePath(base), p),\n };\n}\n\n// ============================================================================\n// InMemorySandbox\n// ============================================================================\n\nexport interface InMemorySandboxOptions {\n /** Options forwarded to `just-bash` `Bash` (minus `fs` which is managed) */\n bashOptions?: Omit<BashOptions, \"fs\">;\n}\n\n/**\n * An in-memory {@link Sandbox} backed by `just-bash`.\n */\nexport type InMemorySandbox = Sandbox & { fs: SandboxFileSystem };\n\nclass InMemorySandboxImpl implements Sandbox {\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: true,\n };\n\n readonly fs: SandboxFileSystem;\n private bashOptions: Omit<BashOptions, \"fs\">;\n\n constructor(\n readonly id: string,\n private justBashFs: IFileSystem,\n options?: InMemorySandboxOptions\n ) {\n this.fs = toSandboxFs(justBashFs);\n this.bashOptions = {\n executionLimits: { maxStringLength: 52_428_800 },\n ...options?.bashOptions,\n };\n }\n\n async exec(command: string, _options?: ExecOptions): Promise<ExecResult> {\n const bash = new Bash({ ...this.bashOptions, fs: this.justBashFs });\n const { exitCode, stderr, stdout } = await bash.exec(command);\n return { exitCode, stdout, stderr };\n }\n\n async destroy(): Promise<void> {\n // In-memory: nothing to clean up\n }\n\n /** Expose the underlying IFileSystem for snapshot serialisation */\n _getJustBashFs(): IFileSystem {\n return this.justBashFs;\n }\n}\n\n// ============================================================================\n// InMemorySandboxProvider\n// ============================================================================\n\nexport class InMemorySandboxProvider implements SandboxProvider {\n readonly id = \"inMemory\";\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: true,\n };\n\n private sandboxes = new Map<string, InMemorySandboxImpl>();\n\n constructor(private defaultOptions?: InMemorySandboxOptions) {}\n\n async get(id: string): Promise<Sandbox> {\n const sandbox = this.sandboxes.get(id);\n if (!sandbox) throw new SandboxNotFoundError(id);\n return sandbox;\n }\n\n async destroy(id: string): Promise<void> {\n const sandbox = this.sandboxes.get(id);\n if (sandbox) {\n await sandbox.destroy();\n this.sandboxes.delete(id);\n }\n }\n\n async create(options?: SandboxCreateOptions): Promise<SandboxCreateResult> {\n const id = options?.id ?? getShortId();\n const initialFiles: InitialFiles = {};\n\n if (options?.initialFiles) {\n for (const [path, content] of Object.entries(options.initialFiles)) {\n initialFiles[path] = content;\n }\n }\n\n const fs = new InMemoryFs(initialFiles);\n const sandbox = new InMemorySandboxImpl(id, fs, this.defaultOptions);\n this.sandboxes.set(id, sandbox);\n return { sandbox };\n }\n\n async snapshot(sandboxId: string): Promise<SandboxSnapshot> {\n const sandbox = this.sandboxes.get(sandboxId);\n if (!sandbox) throw new SandboxNotFoundError(sandboxId);\n\n const fs = sandbox._getJustBashFs();\n const paths = fs.getAllPaths();\n const files: Record<string, string> = {};\n\n for (const p of paths) {\n try {\n const stat = await fs.stat(p);\n if (stat.isFile) {\n files[p] = await fs.readFile(p);\n }\n } catch {\n // skip entries that can't be read (e.g. broken symlinks)\n }\n }\n\n return {\n sandboxId,\n providerId: this.id,\n data: { files },\n createdAt: new Date().toISOString(),\n };\n }\n\n async fork(_sandboxId: string): Promise<Sandbox> {\n throw new Error(\"Not implemented\");\n }\n\n async restore(snapshot: SandboxSnapshot): Promise<Sandbox> {\n const { files } = snapshot.data as { files: Record<string, string> };\n const initialFiles: InitialFiles = {};\n for (const [path, content] of Object.entries(files)) {\n initialFiles[path] = content;\n }\n\n const fs = new InMemoryFs(initialFiles);\n const sandbox = new InMemorySandboxImpl(\n snapshot.sandboxId,\n fs,\n this.defaultOptions\n );\n this.sandboxes.set(sandbox.id, sandbox);\n return sandbox;\n }\n}\n"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var workflow = require('@temporalio/workflow');
|
|
4
|
+
|
|
5
|
+
// src/adapters/sandbox/inmemory/proxy.ts
|
|
6
|
+
var ADAPTER_PREFIX = "inMemory";
|
|
7
|
+
function proxyInMemorySandboxOps(scope, options) {
|
|
8
|
+
const resolvedScope = scope ?? workflow.workflowInfo().workflowType;
|
|
9
|
+
const acts = workflow.proxyActivities(
|
|
10
|
+
options ?? {
|
|
11
|
+
startToCloseTimeout: "30s",
|
|
12
|
+
retry: {
|
|
13
|
+
maximumAttempts: 3,
|
|
14
|
+
initialInterval: "2s",
|
|
15
|
+
maximumInterval: "30s",
|
|
16
|
+
backoffCoefficient: 2
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
const prefix = `${ADAPTER_PREFIX}${resolvedScope.charAt(0).toUpperCase()}${resolvedScope.slice(1)}`;
|
|
21
|
+
const p = (key) => `${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;
|
|
22
|
+
return {
|
|
23
|
+
createSandbox: acts[p("createSandbox")],
|
|
24
|
+
destroySandbox: acts[p("destroySandbox")],
|
|
25
|
+
snapshotSandbox: acts[p("snapshotSandbox")],
|
|
26
|
+
forkSandbox: acts[p("forkSandbox")]
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
exports.proxyInMemorySandboxOps = proxyInMemorySandboxOps;
|
|
31
|
+
//# sourceMappingURL=workflow.cjs.map
|
|
32
|
+
//# sourceMappingURL=workflow.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/adapters/sandbox/inmemory/proxy.ts"],"names":["workflowInfo","proxyActivities"],"mappings":";;;;;AAoBA,IAAM,cAAA,GAAiB,UAAA;AAEhB,SAAS,uBAAA,CACd,OACA,OAAA,EACY;AACZ,EAAA,MAAM,aAAA,GAAgB,KAAA,IAASA,qBAAA,EAAa,CAAE,YAAA;AAG9C,EAAA,MAAM,IAAA,GAAOC,wBAAA;AAAA,IACX,OAAA,IAAW;AAAA,MACT,mBAAA,EAAqB,KAAA;AAAA,MACrB,KAAA,EAAO;AAAA,QACL,eAAA,EAAiB,CAAA;AAAA,QACjB,eAAA,EAAiB,IAAA;AAAA,QACjB,eAAA,EAAiB,KAAA;AAAA,QACjB,kBAAA,EAAoB;AAAA;AACtB;AACF,GACF;AAEA,EAAA,MAAM,MAAA,GACJ,CAAA,EAAG,cAAc,CAAA,EAAG,cAAc,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAa,CAAA,EAAG,aAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AACpF,EAAA,MAAM,IAAI,CAAC,GAAA,KACT,CAAA,EAAG,MAAM,GAAG,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,CAAE,aAAa,CAAA,EAAG,GAAA,CAAI,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAExD,EAAA,OAAO;AAAA,IACL,aAAA,EAAe,IAAA,CAAK,CAAA,CAAE,eAAe,CAAC,CAAA;AAAA,IACtC,cAAA,EAAgB,IAAA,CAAK,CAAA,CAAE,gBAAgB,CAAC,CAAA;AAAA,IACxC,eAAA,EAAiB,IAAA,CAAK,CAAA,CAAE,iBAAiB,CAAC,CAAA;AAAA,IAC1C,WAAA,EAAa,IAAA,CAAK,CAAA,CAAE,aAAa,CAAC;AAAA,GACpC;AACF","file":"workflow.cjs","sourcesContent":["/**\n * Workflow-safe proxy for in-memory sandbox operations.\n *\n * Import this from `zeitlich/adapters/sandbox/inmemory/workflow`\n * in your Temporal workflow files.\n *\n * By default the scope is derived from `workflowInfo().workflowType`,\n * so activities are automatically namespaced per workflow.\n *\n * @example\n * ```typescript\n * import { proxyInMemorySandboxOps } from 'zeitlich/adapters/sandbox/inmemory/workflow';\n *\n * // Auto-scoped to the current workflow name\n * const sandbox = proxyInMemorySandboxOps();\n * ```\n */\nimport { proxyActivities, workflowInfo } from \"@temporalio/workflow\";\nimport type { SandboxOps } from \"../../../lib/sandbox/types\";\n\nconst ADAPTER_PREFIX = \"inMemory\";\n\nexport function proxyInMemorySandboxOps(\n scope?: string,\n options?: Parameters<typeof proxyActivities>[0]\n): SandboxOps {\n const resolvedScope = scope ?? workflowInfo().workflowType;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const acts = proxyActivities<Record<string, (...args: any[]) => any>>(\n options ?? {\n startToCloseTimeout: \"30s\",\n retry: {\n maximumAttempts: 3,\n initialInterval: \"2s\",\n maximumInterval: \"30s\",\n backoffCoefficient: 2,\n },\n }\n );\n\n const prefix =\n `${ADAPTER_PREFIX}${resolvedScope.charAt(0).toUpperCase()}${resolvedScope.slice(1)}`;\n const p = (key: string): string =>\n `${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;\n\n return {\n createSandbox: acts[p(\"createSandbox\")],\n destroySandbox: acts[p(\"destroySandbox\")],\n snapshotSandbox: acts[p(\"snapshotSandbox\")],\n forkSandbox: acts[p(\"forkSandbox\")],\n } as SandboxOps;\n}\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { proxyActivities } from '@temporalio/workflow';
|
|
2
|
+
import { g as SandboxOps } from '../../../types-HBosetv3.cjs';
|
|
3
|
+
import '@temporalio/common';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Workflow-safe proxy for in-memory sandbox operations.
|
|
7
|
+
*
|
|
8
|
+
* Import this from `zeitlich/adapters/sandbox/inmemory/workflow`
|
|
9
|
+
* in your Temporal workflow files.
|
|
10
|
+
*
|
|
11
|
+
* By default the scope is derived from `workflowInfo().workflowType`,
|
|
12
|
+
* so activities are automatically namespaced per workflow.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { proxyInMemorySandboxOps } from 'zeitlich/adapters/sandbox/inmemory/workflow';
|
|
17
|
+
*
|
|
18
|
+
* // Auto-scoped to the current workflow name
|
|
19
|
+
* const sandbox = proxyInMemorySandboxOps();
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
declare function proxyInMemorySandboxOps(scope?: string, options?: Parameters<typeof proxyActivities>[0]): SandboxOps;
|
|
24
|
+
|
|
25
|
+
export { proxyInMemorySandboxOps };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { proxyActivities } from '@temporalio/workflow';
|
|
2
|
+
import { g as SandboxOps } from '../../../types-HBosetv3.js';
|
|
3
|
+
import '@temporalio/common';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Workflow-safe proxy for in-memory sandbox operations.
|
|
7
|
+
*
|
|
8
|
+
* Import this from `zeitlich/adapters/sandbox/inmemory/workflow`
|
|
9
|
+
* in your Temporal workflow files.
|
|
10
|
+
*
|
|
11
|
+
* By default the scope is derived from `workflowInfo().workflowType`,
|
|
12
|
+
* so activities are automatically namespaced per workflow.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { proxyInMemorySandboxOps } from 'zeitlich/adapters/sandbox/inmemory/workflow';
|
|
17
|
+
*
|
|
18
|
+
* // Auto-scoped to the current workflow name
|
|
19
|
+
* const sandbox = proxyInMemorySandboxOps();
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
declare function proxyInMemorySandboxOps(scope?: string, options?: Parameters<typeof proxyActivities>[0]): SandboxOps;
|
|
24
|
+
|
|
25
|
+
export { proxyInMemorySandboxOps };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { workflowInfo, proxyActivities } from '@temporalio/workflow';
|
|
2
|
+
|
|
3
|
+
// src/adapters/sandbox/inmemory/proxy.ts
|
|
4
|
+
var ADAPTER_PREFIX = "inMemory";
|
|
5
|
+
function proxyInMemorySandboxOps(scope, options) {
|
|
6
|
+
const resolvedScope = scope ?? workflowInfo().workflowType;
|
|
7
|
+
const acts = proxyActivities(
|
|
8
|
+
options ?? {
|
|
9
|
+
startToCloseTimeout: "30s",
|
|
10
|
+
retry: {
|
|
11
|
+
maximumAttempts: 3,
|
|
12
|
+
initialInterval: "2s",
|
|
13
|
+
maximumInterval: "30s",
|
|
14
|
+
backoffCoefficient: 2
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
);
|
|
18
|
+
const prefix = `${ADAPTER_PREFIX}${resolvedScope.charAt(0).toUpperCase()}${resolvedScope.slice(1)}`;
|
|
19
|
+
const p = (key) => `${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;
|
|
20
|
+
return {
|
|
21
|
+
createSandbox: acts[p("createSandbox")],
|
|
22
|
+
destroySandbox: acts[p("destroySandbox")],
|
|
23
|
+
snapshotSandbox: acts[p("snapshotSandbox")],
|
|
24
|
+
forkSandbox: acts[p("forkSandbox")]
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { proxyInMemorySandboxOps };
|
|
29
|
+
//# sourceMappingURL=workflow.js.map
|
|
30
|
+
//# sourceMappingURL=workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/adapters/sandbox/inmemory/proxy.ts"],"names":[],"mappings":";;;AAoBA,IAAM,cAAA,GAAiB,UAAA;AAEhB,SAAS,uBAAA,CACd,OACA,OAAA,EACY;AACZ,EAAA,MAAM,aAAA,GAAgB,KAAA,IAAS,YAAA,EAAa,CAAE,YAAA;AAG9C,EAAA,MAAM,IAAA,GAAO,eAAA;AAAA,IACX,OAAA,IAAW;AAAA,MACT,mBAAA,EAAqB,KAAA;AAAA,MACrB,KAAA,EAAO;AAAA,QACL,eAAA,EAAiB,CAAA;AAAA,QACjB,eAAA,EAAiB,IAAA;AAAA,QACjB,eAAA,EAAiB,KAAA;AAAA,QACjB,kBAAA,EAAoB;AAAA;AACtB;AACF,GACF;AAEA,EAAA,MAAM,MAAA,GACJ,CAAA,EAAG,cAAc,CAAA,EAAG,cAAc,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAa,CAAA,EAAG,aAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AACpF,EAAA,MAAM,IAAI,CAAC,GAAA,KACT,CAAA,EAAG,MAAM,GAAG,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,CAAE,aAAa,CAAA,EAAG,GAAA,CAAI,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAExD,EAAA,OAAO;AAAA,IACL,aAAA,EAAe,IAAA,CAAK,CAAA,CAAE,eAAe,CAAC,CAAA;AAAA,IACtC,cAAA,EAAgB,IAAA,CAAK,CAAA,CAAE,gBAAgB,CAAC,CAAA;AAAA,IACxC,eAAA,EAAiB,IAAA,CAAK,CAAA,CAAE,iBAAiB,CAAC,CAAA;AAAA,IAC1C,WAAA,EAAa,IAAA,CAAK,CAAA,CAAE,aAAa,CAAC;AAAA,GACpC;AACF","file":"workflow.js","sourcesContent":["/**\n * Workflow-safe proxy for in-memory sandbox operations.\n *\n * Import this from `zeitlich/adapters/sandbox/inmemory/workflow`\n * in your Temporal workflow files.\n *\n * By default the scope is derived from `workflowInfo().workflowType`,\n * so activities are automatically namespaced per workflow.\n *\n * @example\n * ```typescript\n * import { proxyInMemorySandboxOps } from 'zeitlich/adapters/sandbox/inmemory/workflow';\n *\n * // Auto-scoped to the current workflow name\n * const sandbox = proxyInMemorySandboxOps();\n * ```\n */\nimport { proxyActivities, workflowInfo } from \"@temporalio/workflow\";\nimport type { SandboxOps } from \"../../../lib/sandbox/types\";\n\nconst ADAPTER_PREFIX = \"inMemory\";\n\nexport function proxyInMemorySandboxOps(\n scope?: string,\n options?: Parameters<typeof proxyActivities>[0]\n): SandboxOps {\n const resolvedScope = scope ?? workflowInfo().workflowType;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const acts = proxyActivities<Record<string, (...args: any[]) => any>>(\n options ?? {\n startToCloseTimeout: \"30s\",\n retry: {\n maximumAttempts: 3,\n initialInterval: \"2s\",\n maximumInterval: \"30s\",\n backoffCoefficient: 2,\n },\n }\n );\n\n const prefix =\n `${ADAPTER_PREFIX}${resolvedScope.charAt(0).toUpperCase()}${resolvedScope.slice(1)}`;\n const p = (key: string): string =>\n `${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;\n\n return {\n createSandbox: acts[p(\"createSandbox\")],\n destroySandbox: acts[p(\"destroySandbox\")],\n snapshotSandbox: acts[p(\"snapshotSandbox\")],\n forkSandbox: acts[p(\"forkSandbox\")],\n } as SandboxOps;\n}\n"]}
|
|
@@ -325,6 +325,9 @@ var VirtualSandboxProvider = class {
|
|
|
325
325
|
}
|
|
326
326
|
async destroy() {
|
|
327
327
|
}
|
|
328
|
+
async fork(_sandboxId) {
|
|
329
|
+
throw new Error("Not implemented");
|
|
330
|
+
}
|
|
328
331
|
async snapshot() {
|
|
329
332
|
throw new SandboxNotSupportedError(
|
|
330
333
|
"snapshot (virtual sandbox state lives in workflow AgentState)"
|