@geminixiang/mikan 1.0.0-beta.14 → 1.0.0-beta.16
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/CHANGELOG.md +45 -0
- package/README.md +33 -7
- package/dist/adapter.d.ts +1 -1
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js.map +1 -1
- package/dist/adapters/slack/response-lifecycle.js +1 -1
- package/dist/adapters/slack/response-lifecycle.js.map +1 -1
- package/dist/agent.d.ts +2 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +66 -21
- package/dist/agent.js.map +1 -1
- package/dist/execution-resolver.d.ts +2 -1
- package/dist/execution-resolver.d.ts.map +1 -1
- package/dist/execution-resolver.js +15 -2
- package/dist/execution-resolver.js.map +1 -1
- package/dist/harness/extensions/loader.d.ts +6 -0
- package/dist/harness/extensions/loader.d.ts.map +1 -1
- package/dist/harness/extensions/loader.js +24 -4
- package/dist/harness/extensions/loader.js.map +1 -1
- package/dist/harness/extensions/registry.d.ts +48 -1
- package/dist/harness/extensions/registry.d.ts.map +1 -1
- package/dist/harness/extensions/registry.js +146 -0
- package/dist/harness/extensions/registry.js.map +1 -1
- package/dist/harness/extensions/types.d.ts +123 -12
- package/dist/harness/extensions/types.d.ts.map +1 -1
- package/dist/harness/extensions/types.js.map +1 -1
- package/dist/harness/index.d.ts +3 -3
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +1 -1
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/runner.d.ts +13 -2
- package/dist/harness/runner.d.ts.map +1 -1
- package/dist/harness/runner.js +59 -16
- package/dist/harness/runner.js.map +1 -1
- package/dist/main.js +25 -15
- package/dist/main.js.map +1 -1
- package/dist/runtime/conversation-runtime.js +32 -4
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/types.d.ts +3 -1
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sandbox/identity.d.ts +1 -1
- package/dist/sandbox/identity.d.ts.map +1 -1
- package/dist/sandbox/identity.js +2 -1
- package/dist/sandbox/identity.js.map +1 -1
- package/dist/sandbox/index.d.ts +4 -3
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/index.js +5 -3
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/microvm.d.ts +17 -0
- package/dist/sandbox/microvm.d.ts.map +1 -0
- package/dist/sandbox/microvm.js +145 -0
- package/dist/sandbox/microvm.js.map +1 -0
- package/dist/sandbox/types.d.ts +8 -1
- package/dist/sandbox/types.d.ts.map +1 -1
- package/dist/sandbox/types.js.map +1 -1
- package/dist/sessions/agent-memory-file-manager.d.ts.map +1 -1
- package/dist/sessions/agent-memory-file-manager.js +0 -11
- package/dist/sessions/agent-memory-file-manager.js.map +1 -1
- package/dist/tools/generate-image.d.ts +17 -0
- package/dist/tools/generate-image.d.ts.map +1 -0
- package/dist/tools/generate-image.js +63 -0
- package/dist/tools/generate-image.js.map +1 -0
- package/dist/tools/index.d.ts +5 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +10 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/types.d.ts +19 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/vault/index.d.ts.map +1 -1
- package/dist/vault/index.js +1 -17
- package/dist/vault/index.js.map +1 -1
- package/package.json +3 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sandbox/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAA2B,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAA6B,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAA4B,MAAM,iBAAiB,CAAC;AACtF,OAAO,EAAE,YAAY,EAAsB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sandbox/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAA2B,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAA6B,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAA4B,MAAM,iBAAiB,CAAC;AACtF,OAAO,EAAE,YAAY,EAAsB,MAAM,WAAW,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAyB,MAAM,cAAc,CAAC;AAEtE,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE1E,YAAY,EACV,uBAAuB,EACvB,WAAW,EACX,UAAU,EACV,QAAQ,EACR,kBAAkB,EAClB,cAAc,EACd,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,eAAe,GAChB,CAAC;AACF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,QAAA,MAAM,eAAe,iXAOX,CAAC;AAKX,wBAAgB,kBAAkB,IAAI,SAAS,CAAC,GAAG,OAAO,eAAe,CAAC,CAEzE;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAiB5D;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAO1E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,aAAa,EACrB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAChC,QAAQ,CASV"}
|
package/dist/sandbox/index.js
CHANGED
|
@@ -3,13 +3,15 @@ import { FirecrackerExecutor, firecrackerSandboxAdapter } from "./firecracker.js
|
|
|
3
3
|
import { CloudflareSandboxExecutor, cloudflareSandboxAdapter } from "./cloudflare.js";
|
|
4
4
|
import { HostExecutor, hostSandboxAdapter } from "./host.js";
|
|
5
5
|
import { imageSandboxAdapter } from "./image.js";
|
|
6
|
+
import { MicrovmExecutor, microvmSandboxAdapter } from "./microvm.js";
|
|
6
7
|
import { SandboxError } from "./errors.js";
|
|
7
|
-
export { CloudflareSandboxExecutor, ContainerExecutor, FirecrackerExecutor, HostExecutor };
|
|
8
|
+
export { CloudflareSandboxExecutor, ContainerExecutor, FirecrackerExecutor, HostExecutor, MicrovmExecutor, };
|
|
8
9
|
export { SandboxError } from "./errors.js";
|
|
9
10
|
const sandboxAdapters = [
|
|
10
11
|
hostSandboxAdapter,
|
|
11
12
|
containerSandboxAdapter,
|
|
12
13
|
imageSandboxAdapter,
|
|
14
|
+
microvmSandboxAdapter,
|
|
13
15
|
firecrackerSandboxAdapter,
|
|
14
16
|
cloudflareSandboxAdapter,
|
|
15
17
|
];
|
|
@@ -27,7 +29,7 @@ export function parseSandboxArg(value) {
|
|
|
27
29
|
if (value.startsWith("docker:")) {
|
|
28
30
|
throw new SandboxError(`Error: '${value}' is not supported. Use 'container:<container-name>' for the shared-container mode or 'image:<image-name>' for mikan-managed per-user containers.`);
|
|
29
31
|
}
|
|
30
|
-
throw new SandboxError(`Error: Invalid sandbox type '${value}'. Use 'host', 'container:<container-name>', 'image:<image-name>', 'firecracker:<vm-id>:<host-path>', or 'cloudflare:<sandbox-id>'`);
|
|
32
|
+
throw new SandboxError(`Error: Invalid sandbox type '${value}'. Use 'host', 'container:<container-name>', 'image:<image-name>', 'microvm:default', 'firecracker:<vm-id>:<host-path>', or 'cloudflare:<sandbox-id>'`);
|
|
31
33
|
}
|
|
32
34
|
export async function validateSandbox(config) {
|
|
33
35
|
const adapter = sandboxAdapterByType.get(config.type);
|
|
@@ -37,7 +39,7 @@ export async function validateSandbox(config) {
|
|
|
37
39
|
await adapter.validate?.(config);
|
|
38
40
|
}
|
|
39
41
|
/**
|
|
40
|
-
* Create an executor that runs commands on host, in Docker, in a Firecracker VM, or through a Cloudflare sandbox bridge.
|
|
42
|
+
* Create an executor that runs commands on host, in Docker, in a microVM, in a Firecracker VM, or through a Cloudflare sandbox bridge.
|
|
41
43
|
*/
|
|
42
44
|
export function createExecutor(config, env, ensureReady) {
|
|
43
45
|
const adapter = sandboxAdapterByType.get(config.type);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sandbox/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AACtF,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAY3C,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sandbox/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AACtF,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAY3C,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,eAAe,GAChB,CAAC;AACF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,eAAe,GAAG;IACtB,kBAAkB;IAClB,uBAAuB;IACvB,mBAAmB;IACnB,qBAAqB;IACrB,yBAAyB;IACzB,wBAAwB;CAChB,CAAC;AACX,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAClC,eAAe,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CACZ,CAAC;AAEhD,MAAM,UAAU,kBAAkB;IAChC,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,YAAY,CACpB,WAAW,KAAK,mJAAmJ,CACpK,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,YAAY,CACpB,gCAAgC,KAAK,uJAAuJ,CAC7L,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAqB;IACzD,MAAM,OAAO,GAAG,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,YAAY,CAAC,oCAAoC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAqB,EACrB,GAA4B,EAC5B,WAAiC;IAEjC,MAAM,OAAO,GAAG,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,YAAY,CAAC,oCAAoC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QAC5B,MAAM,IAAI,YAAY,CAAC,oEAAoE,CAAC,CAAC;IAC/F,CAAC;IACD,OAAO,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;AAC1D,CAAC","sourcesContent":["import { ContainerExecutor, containerSandboxAdapter } from \"./container.js\";\nimport { FirecrackerExecutor, firecrackerSandboxAdapter } from \"./firecracker.js\";\nimport { CloudflareSandboxExecutor, cloudflareSandboxAdapter } from \"./cloudflare.js\";\nimport { HostExecutor, hostSandboxAdapter } from \"./host.js\";\nimport { imageSandboxAdapter } from \"./image.js\";\nimport { MicrovmExecutor, microvmSandboxAdapter } from \"./microvm.js\";\nimport { SandboxError } from \"./errors.js\";\nimport type { Executor, SandboxAdapter, SandboxConfig } from \"./types.js\";\n\nexport type {\n CloudflareSandboxConfig,\n ExecOptions,\n ExecResult,\n Executor,\n RuntimePathContext,\n SandboxAdapter,\n SandboxConfig,\n} from \"./types.js\";\nexport {\n CloudflareSandboxExecutor,\n ContainerExecutor,\n FirecrackerExecutor,\n HostExecutor,\n MicrovmExecutor,\n};\nexport { SandboxError } from \"./errors.js\";\n\nconst sandboxAdapters = [\n hostSandboxAdapter,\n containerSandboxAdapter,\n imageSandboxAdapter,\n microvmSandboxAdapter,\n firecrackerSandboxAdapter,\n cloudflareSandboxAdapter,\n] as const;\nconst sandboxAdapterByType = new Map(\n sandboxAdapters.map((adapter) => [adapter.type, adapter]),\n) as Map<SandboxConfig[\"type\"], SandboxAdapter>;\n\nexport function getSandboxAdapters(): readonly [...typeof sandboxAdapters] {\n return sandboxAdapters;\n}\n\nexport function parseSandboxArg(value: string): SandboxConfig {\n for (const adapter of sandboxAdapters) {\n const config = adapter.parse(value);\n if (config) {\n return config;\n }\n }\n\n if (value.startsWith(\"docker:\")) {\n throw new SandboxError(\n `Error: '${value}' is not supported. Use 'container:<container-name>' for the shared-container mode or 'image:<image-name>' for mikan-managed per-user containers.`,\n );\n }\n\n throw new SandboxError(\n `Error: Invalid sandbox type '${value}'. Use 'host', 'container:<container-name>', 'image:<image-name>', 'microvm:default', 'firecracker:<vm-id>:<host-path>', or 'cloudflare:<sandbox-id>'`,\n );\n}\n\nexport async function validateSandbox(config: SandboxConfig): Promise<void> {\n const adapter = sandboxAdapterByType.get(config.type);\n if (!adapter) {\n throw new SandboxError(`Error: Unsupported sandbox type '${config.type}'`);\n }\n\n await adapter.validate?.(config);\n}\n\n/**\n * Create an executor that runs commands on host, in Docker, in a microVM, in a Firecracker VM, or through a Cloudflare sandbox bridge.\n */\nexport function createExecutor(\n config: SandboxConfig,\n env?: Record<string, string>,\n ensureReady?: () => Promise<void>,\n): Executor {\n const adapter = sandboxAdapterByType.get(config.type);\n if (!adapter) {\n throw new SandboxError(`Error: Unsupported sandbox type '${config.type}'`);\n }\n if (!adapter.createExecutor) {\n throw new SandboxError(\"Error: image sandbox must resolve to a concrete container executor\");\n }\n return adapter.createExecutor(config, env, ensureReady);\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ExecOptions, ExecResult, Executor, MicrovmSandboxConfig, RuntimePathContext, SandboxAdapter } from "./types.js";
|
|
2
|
+
export declare function stopIdleMicrovms(maxIdleMs: number, now?: number): Promise<void>;
|
|
3
|
+
export declare function closeAllMicrovms(): Promise<void>;
|
|
4
|
+
export declare class MicrovmExecutor implements Executor {
|
|
5
|
+
private readonly config;
|
|
6
|
+
private readonly workspacePath;
|
|
7
|
+
private readonly sessionKey;
|
|
8
|
+
constructor(config: MicrovmSandboxConfig);
|
|
9
|
+
exec(command: string, options?: ExecOptions): Promise<ExecResult>;
|
|
10
|
+
readFile(path: string): Promise<string>;
|
|
11
|
+
writeFile(path: string, content: string): Promise<void>;
|
|
12
|
+
getWorkspacePath(): string;
|
|
13
|
+
getPathContext(hostWorkspaceRoot: string): RuntimePathContext;
|
|
14
|
+
getSandboxConfig(): MicrovmSandboxConfig;
|
|
15
|
+
}
|
|
16
|
+
export declare const microvmSandboxAdapter: SandboxAdapter<MicrovmSandboxConfig>;
|
|
17
|
+
//# sourceMappingURL=microvm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"microvm.d.ts","sourceRoot":"","sources":["../../src/sandbox/microvm.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,QAAQ,EACR,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACf,MAAM,YAAY,CAAC;AA8GpB,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAKzF;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAGtD;AAWD,qBAAa,eAAgB,YAAW,QAAQ;IAIlC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IAEpC,YAA6B,MAAM,EAAE,oBAAoB,EAIxD;IAEK,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAQtE;IAEK,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI5C;IAEK,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO5D;IAED,gBAAgB,IAAI,MAAM,CAEzB;IAED,cAAc,CAAC,iBAAiB,EAAE,MAAM,GAAG,kBAAkB,CAE5D;IAED,gBAAgB,IAAI,oBAAoB,CAEvC;CACF;AAED,eAAO,MAAM,qBAAqB,EAAE,cAAc,CAAC,oBAAoB,CAKtE,CAAC"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { dirname } from "node:path";
|
|
2
|
+
import * as log from "../log.js";
|
|
3
|
+
import { SandboxError } from "./errors.js";
|
|
4
|
+
import { createMountedRuntimePathContext } from "./path-context.js";
|
|
5
|
+
const MINIMUM_NODE_VERSION = [23, 6, 0];
|
|
6
|
+
const MIKAN_IMAGE = "mikan-sandbox:latest";
|
|
7
|
+
const sessions = new Map();
|
|
8
|
+
function parseMicrovmSandboxArg(value) {
|
|
9
|
+
if (!value.startsWith("microvm:"))
|
|
10
|
+
return undefined;
|
|
11
|
+
const profile = value.slice("microvm:".length);
|
|
12
|
+
if (!profile) {
|
|
13
|
+
throw new SandboxError("Error: microvm sandbox requires a profile (e.g., microvm:default)");
|
|
14
|
+
}
|
|
15
|
+
if (profile !== "default") {
|
|
16
|
+
throw new SandboxError(`Error: unsupported microvm profile '${profile}'. Use 'microvm:default'`);
|
|
17
|
+
}
|
|
18
|
+
return { type: "microvm", profile };
|
|
19
|
+
}
|
|
20
|
+
function assertSupportedNodeVersion() {
|
|
21
|
+
const [major = 0, minor = 0] = process.versions.node.split(".").map(Number);
|
|
22
|
+
if (major < MINIMUM_NODE_VERSION[0] || (major === MINIMUM_NODE_VERSION[0] && minor < 6)) {
|
|
23
|
+
throw new SandboxError(`Error: microvm:default requires Node.js >=23.6.0 (current: ${process.versions.node}). Other sandbox modes remain available on Node.js >=22.19.0.`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async function validateMicrovmSandbox() {
|
|
27
|
+
assertSupportedNodeVersion();
|
|
28
|
+
console.log(" Gondolin microVM enabled. Profile: default");
|
|
29
|
+
}
|
|
30
|
+
async function createVM(workspacePath) {
|
|
31
|
+
const { RealFSProvider, VM } = (await import("@earendil-works/gondolin"));
|
|
32
|
+
return VM.create({
|
|
33
|
+
sandbox: { imagePath: MIKAN_IMAGE },
|
|
34
|
+
env: { TZ: "Asia/Taipei" },
|
|
35
|
+
vfs: { mounts: { "/workspace": new RealFSProvider(workspacePath) } },
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function getSession(key, workspacePath) {
|
|
39
|
+
const existing = sessions.get(key);
|
|
40
|
+
if (existing)
|
|
41
|
+
return existing;
|
|
42
|
+
let session;
|
|
43
|
+
const vm = createVM(workspacePath).catch((error) => {
|
|
44
|
+
if (sessions.get(key) === session)
|
|
45
|
+
sessions.delete(key);
|
|
46
|
+
throw error;
|
|
47
|
+
});
|
|
48
|
+
session = { vm, activeOperations: 0, lastUsed: Date.now(), idleWaiters: [] };
|
|
49
|
+
sessions.set(key, session);
|
|
50
|
+
return session;
|
|
51
|
+
}
|
|
52
|
+
async function withVM(key, workspacePath, operation) {
|
|
53
|
+
const session = getSession(key, workspacePath);
|
|
54
|
+
session.activeOperations += 1;
|
|
55
|
+
try {
|
|
56
|
+
return await operation(await session.vm);
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
session.activeOperations -= 1;
|
|
60
|
+
session.lastUsed = Date.now();
|
|
61
|
+
if (session.activeOperations === 0) {
|
|
62
|
+
for (const resolve of session.idleWaiters.splice(0))
|
|
63
|
+
resolve();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function waitForIdle(session) {
|
|
68
|
+
if (session.activeOperations === 0)
|
|
69
|
+
return Promise.resolve();
|
|
70
|
+
return new Promise((resolve) => session.idleWaiters.push(resolve));
|
|
71
|
+
}
|
|
72
|
+
async function closeSession(key, session, waitForActiveOperations = false) {
|
|
73
|
+
if (sessions.get(key) !== session)
|
|
74
|
+
return;
|
|
75
|
+
sessions.delete(key);
|
|
76
|
+
try {
|
|
77
|
+
if (waitForActiveOperations)
|
|
78
|
+
await waitForIdle(session);
|
|
79
|
+
const vm = await session.vm;
|
|
80
|
+
await vm.close();
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
log.logWarning(`Failed to close microVM session '${key}'`, error instanceof Error ? error.message : String(error));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export async function stopIdleMicrovms(maxIdleMs, now = Date.now()) {
|
|
87
|
+
const idle = Array.from(sessions.entries()).filter(([, session]) => session.activeOperations === 0 && now - session.lastUsed >= maxIdleMs);
|
|
88
|
+
await Promise.all(idle.map(([key, session]) => closeSession(key, session)));
|
|
89
|
+
}
|
|
90
|
+
export async function closeAllMicrovms() {
|
|
91
|
+
const current = Array.from(sessions.entries());
|
|
92
|
+
await Promise.all(current.map(([key, session]) => closeSession(key, session, true)));
|
|
93
|
+
}
|
|
94
|
+
function executionSignal(options) {
|
|
95
|
+
const signals = [options?.signal];
|
|
96
|
+
if (options?.timeout && options.timeout > 0) {
|
|
97
|
+
signals.push(AbortSignal.timeout(options.timeout * 1000));
|
|
98
|
+
}
|
|
99
|
+
const active = signals.filter((signal) => signal !== undefined);
|
|
100
|
+
return active.length > 0 ? AbortSignal.any(active) : undefined;
|
|
101
|
+
}
|
|
102
|
+
export class MicrovmExecutor {
|
|
103
|
+
constructor(config) {
|
|
104
|
+
this.config = config;
|
|
105
|
+
assertSupportedNodeVersion();
|
|
106
|
+
this.workspacePath = config.workspacePath ?? process.cwd();
|
|
107
|
+
this.sessionKey = config.instanceId ?? this.workspacePath;
|
|
108
|
+
}
|
|
109
|
+
async exec(command, options) {
|
|
110
|
+
return withVM(this.sessionKey, this.workspacePath, async (vm) => {
|
|
111
|
+
const result = await vm.exec(command, {
|
|
112
|
+
cwd: "/workspace",
|
|
113
|
+
signal: executionSignal(options),
|
|
114
|
+
});
|
|
115
|
+
return { stdout: result.stdout, stderr: result.stderr, code: result.exitCode };
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
async readFile(path) {
|
|
119
|
+
return withVM(this.sessionKey, this.workspacePath, (vm) => vm.fs.readFile(path, { encoding: "utf8" }));
|
|
120
|
+
}
|
|
121
|
+
async writeFile(path, content) {
|
|
122
|
+
return withVM(this.sessionKey, this.workspacePath, async (vm) => {
|
|
123
|
+
const stage = `${path}.mikan-stage`;
|
|
124
|
+
await vm.fs.mkdir(dirname(path), { recursive: true });
|
|
125
|
+
await vm.fs.writeFile(stage, content);
|
|
126
|
+
await vm.fs.rename(stage, path);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
getWorkspacePath() {
|
|
130
|
+
return "/workspace";
|
|
131
|
+
}
|
|
132
|
+
getPathContext(hostWorkspaceRoot) {
|
|
133
|
+
return createMountedRuntimePathContext(hostWorkspaceRoot, "/workspace");
|
|
134
|
+
}
|
|
135
|
+
getSandboxConfig() {
|
|
136
|
+
return this.config;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
export const microvmSandboxAdapter = {
|
|
140
|
+
type: "microvm",
|
|
141
|
+
parse: parseMicrovmSandboxArg,
|
|
142
|
+
validate: validateMicrovmSandbox,
|
|
143
|
+
createExecutor: (config) => new MicrovmExecutor(config),
|
|
144
|
+
};
|
|
145
|
+
//# sourceMappingURL=microvm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"microvm.js","sourceRoot":"","sources":["../../src/sandbox/microvm.ts"],"names":[],"mappings":"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","sourcesContent":["import type { VM as GondolinVM } from \"@earendil-works/gondolin\";\nimport { dirname } from \"node:path\";\nimport * as log from \"../log.js\";\nimport { SandboxError } from \"./errors.js\";\nimport { createMountedRuntimePathContext } from \"./path-context.js\";\nimport type {\n ExecOptions,\n ExecResult,\n Executor,\n MicrovmSandboxConfig,\n RuntimePathContext,\n SandboxAdapter,\n} from \"./types.js\";\n\ntype GondolinModule = typeof import(\"@earendil-works/gondolin\");\ntype VM = GondolinVM;\n\ninterface MicrovmSession {\n vm: Promise<VM>;\n activeOperations: number;\n lastUsed: number;\n idleWaiters: Array<() => void>;\n}\n\nconst MINIMUM_NODE_VERSION = [23, 6, 0] as const;\nconst MIKAN_IMAGE = \"mikan-sandbox:latest\";\nconst sessions = new Map<string, MicrovmSession>();\n\nfunction parseMicrovmSandboxArg(value: string): MicrovmSandboxConfig | undefined {\n if (!value.startsWith(\"microvm:\")) return undefined;\n\n const profile = value.slice(\"microvm:\".length);\n if (!profile) {\n throw new SandboxError(\"Error: microvm sandbox requires a profile (e.g., microvm:default)\");\n }\n if (profile !== \"default\") {\n throw new SandboxError(\n `Error: unsupported microvm profile '${profile}'. Use 'microvm:default'`,\n );\n }\n return { type: \"microvm\", profile };\n}\n\nfunction assertSupportedNodeVersion(): void {\n const [major = 0, minor = 0] = process.versions.node.split(\".\").map(Number);\n if (major < MINIMUM_NODE_VERSION[0] || (major === MINIMUM_NODE_VERSION[0] && minor < 6)) {\n throw new SandboxError(\n `Error: microvm:default requires Node.js >=23.6.0 (current: ${process.versions.node}). Other sandbox modes remain available on Node.js >=22.19.0.`,\n );\n }\n}\n\nasync function validateMicrovmSandbox(): Promise<void> {\n assertSupportedNodeVersion();\n console.log(\" Gondolin microVM enabled. Profile: default\");\n}\n\nasync function createVM(workspacePath: string): Promise<VM> {\n const { RealFSProvider, VM } = (await import(\"@earendil-works/gondolin\")) as GondolinModule;\n return VM.create({\n sandbox: { imagePath: MIKAN_IMAGE },\n env: { TZ: \"Asia/Taipei\" },\n vfs: { mounts: { \"/workspace\": new RealFSProvider(workspacePath) } },\n });\n}\n\nfunction getSession(key: string, workspacePath: string): MicrovmSession {\n const existing = sessions.get(key);\n if (existing) return existing;\n\n let session: MicrovmSession;\n const vm = createVM(workspacePath).catch((error) => {\n if (sessions.get(key) === session) sessions.delete(key);\n throw error;\n });\n session = { vm, activeOperations: 0, lastUsed: Date.now(), idleWaiters: [] };\n sessions.set(key, session);\n return session;\n}\n\nasync function withVM<T>(\n key: string,\n workspacePath: string,\n operation: (vm: VM) => Promise<T>,\n): Promise<T> {\n const session = getSession(key, workspacePath);\n session.activeOperations += 1;\n try {\n return await operation(await session.vm);\n } finally {\n session.activeOperations -= 1;\n session.lastUsed = Date.now();\n if (session.activeOperations === 0) {\n for (const resolve of session.idleWaiters.splice(0)) resolve();\n }\n }\n}\n\nfunction waitForIdle(session: MicrovmSession): Promise<void> {\n if (session.activeOperations === 0) return Promise.resolve();\n return new Promise((resolve) => session.idleWaiters.push(resolve));\n}\n\nasync function closeSession(\n key: string,\n session: MicrovmSession,\n waitForActiveOperations = false,\n): Promise<void> {\n if (sessions.get(key) !== session) return;\n sessions.delete(key);\n try {\n if (waitForActiveOperations) await waitForIdle(session);\n const vm = await session.vm;\n await vm.close();\n } catch (error) {\n log.logWarning(\n `Failed to close microVM session '${key}'`,\n error instanceof Error ? error.message : String(error),\n );\n }\n}\n\nexport async function stopIdleMicrovms(maxIdleMs: number, now = Date.now()): Promise<void> {\n const idle = Array.from(sessions.entries()).filter(\n ([, session]) => session.activeOperations === 0 && now - session.lastUsed >= maxIdleMs,\n );\n await Promise.all(idle.map(([key, session]) => closeSession(key, session)));\n}\n\nexport async function closeAllMicrovms(): Promise<void> {\n const current = Array.from(sessions.entries());\n await Promise.all(current.map(([key, session]) => closeSession(key, session, true)));\n}\n\nfunction executionSignal(options?: ExecOptions): AbortSignal | undefined {\n const signals = [options?.signal];\n if (options?.timeout && options.timeout > 0) {\n signals.push(AbortSignal.timeout(options.timeout * 1000));\n }\n const active = signals.filter((signal): signal is AbortSignal => signal !== undefined);\n return active.length > 0 ? AbortSignal.any(active) : undefined;\n}\n\nexport class MicrovmExecutor implements Executor {\n private readonly workspacePath: string;\n private readonly sessionKey: string;\n\n constructor(private readonly config: MicrovmSandboxConfig) {\n assertSupportedNodeVersion();\n this.workspacePath = config.workspacePath ?? process.cwd();\n this.sessionKey = config.instanceId ?? this.workspacePath;\n }\n\n async exec(command: string, options?: ExecOptions): Promise<ExecResult> {\n return withVM(this.sessionKey, this.workspacePath, async (vm) => {\n const result = await vm.exec(command, {\n cwd: \"/workspace\",\n signal: executionSignal(options),\n });\n return { stdout: result.stdout, stderr: result.stderr, code: result.exitCode };\n });\n }\n\n async readFile(path: string): Promise<string> {\n return withVM(this.sessionKey, this.workspacePath, (vm) =>\n vm.fs.readFile(path, { encoding: \"utf8\" }),\n );\n }\n\n async writeFile(path: string, content: string): Promise<void> {\n return withVM(this.sessionKey, this.workspacePath, async (vm) => {\n const stage = `${path}.mikan-stage`;\n await vm.fs.mkdir(dirname(path), { recursive: true });\n await vm.fs.writeFile(stage, content);\n await vm.fs.rename(stage, path);\n });\n }\n\n getWorkspacePath(): string {\n return \"/workspace\";\n }\n\n getPathContext(hostWorkspaceRoot: string): RuntimePathContext {\n return createMountedRuntimePathContext(hostWorkspaceRoot, \"/workspace\");\n }\n\n getSandboxConfig(): MicrovmSandboxConfig {\n return this.config;\n }\n}\n\nexport const microvmSandboxAdapter: SandboxAdapter<MicrovmSandboxConfig> = {\n type: \"microvm\",\n parse: parseMicrovmSandboxArg,\n validate: validateMicrovmSandbox,\n createExecutor: (config) => new MicrovmExecutor(config),\n};\n"]}
|
package/dist/sandbox/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type SandboxConfig = HostSandboxConfig | ContainerSandboxConfig | ImageSandboxConfig | FirecrackerSandboxConfig | CloudflareSandboxConfig;
|
|
1
|
+
export type SandboxConfig = HostSandboxConfig | ContainerSandboxConfig | ImageSandboxConfig | MicrovmSandboxConfig | FirecrackerSandboxConfig | CloudflareSandboxConfig;
|
|
2
2
|
export interface HostSandboxConfig {
|
|
3
3
|
type: "host";
|
|
4
4
|
}
|
|
@@ -10,6 +10,13 @@ export interface ImageSandboxConfig {
|
|
|
10
10
|
type: "image";
|
|
11
11
|
image: string;
|
|
12
12
|
}
|
|
13
|
+
export interface MicrovmSandboxConfig {
|
|
14
|
+
type: "microvm";
|
|
15
|
+
profile: "default";
|
|
16
|
+
/** Local-only runtime details supplied after actor/workspace resolution. */
|
|
17
|
+
workspacePath?: string;
|
|
18
|
+
instanceId?: string;
|
|
19
|
+
}
|
|
13
20
|
export interface FirecrackerSandboxConfig {
|
|
14
21
|
type: "firecracker";
|
|
15
22
|
vmId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sandbox/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GACrB,iBAAiB,GACjB,sBAAsB,GACtB,kBAAkB,GAClB,wBAAwB,GACxB,uBAAuB,CAAC;AAE5B,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAElE;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE/D;;;;;OAKG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/E;;;;OAIG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAE3C;;OAEG;IACH,cAAc,CAAC,iBAAiB,EAAE,MAAM,GAAG,kBAAkB,CAAC;IAE9D;;OAEG;IACH,gBAAgB,IAAI,aAAa,CAAC;CACnC;AAED,MAAM,WAAW,kBAAkB;IACjC,8DAA8D;IAC9D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,yEAAyE;IACzE,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC;CACrD;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc,CAAC,OAAO,SAAS,aAAa,GAAG,aAAa;IAC3E,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACtB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,cAAc,CAAC,CACb,MAAM,EAAE,OAAO,EACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAChC,QAAQ,CAAC;CACb"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sandbox/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GACrB,iBAAiB,GACjB,sBAAsB,GACtB,kBAAkB,GAClB,oBAAoB,GACpB,wBAAwB,GACxB,uBAAuB,CAAC;AAE5B,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,SAAS,CAAC;IACnB,4EAA4E;IAC5E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAElE;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE/D;;;;;OAKG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/E;;;;OAIG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAE3C;;OAEG;IACH,cAAc,CAAC,iBAAiB,EAAE,MAAM,GAAG,kBAAkB,CAAC;IAE9D;;OAEG;IACH,gBAAgB,IAAI,aAAa,CAAC;CACnC;AAED,MAAM,WAAW,kBAAkB;IACjC,8DAA8D;IAC9D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,yEAAyE;IACzE,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC;CACrD;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc,CAAC,OAAO,SAAS,aAAa,GAAG,aAAa;IAC3E,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACtB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,cAAc,CAAC,CACb,MAAM,EAAE,OAAO,EACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAChC,QAAQ,CAAC;CACb"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sandbox/types.ts"],"names":[],"mappings":"","sourcesContent":["export type SandboxConfig =\n | HostSandboxConfig\n | ContainerSandboxConfig\n | ImageSandboxConfig\n | FirecrackerSandboxConfig\n | CloudflareSandboxConfig;\n\nexport interface HostSandboxConfig {\n type: \"host\";\n}\n\nexport interface ContainerSandboxConfig {\n type: \"container\";\n container: string;\n}\n\nexport interface ImageSandboxConfig {\n type: \"image\";\n image: string;\n}\n\nexport interface FirecrackerSandboxConfig {\n type: \"firecracker\";\n vmId: string;\n hostPath: string;\n sshUser?: string;\n sshPort?: number;\n}\n\nexport interface CloudflareSandboxConfig {\n type: \"cloudflare\";\n sandboxId: string;\n}\n\nexport interface Executor {\n /**\n * Execute a bash command.\n */\n exec(command: string, options?: ExecOptions): Promise<ExecResult>;\n\n /**\n * Read a runtime file as UTF-8 text. The executor owns the transport, so\n * file contents never pass through shell argv or extra shell parse layers.\n */\n readFile(path: string, options?: ExecOptions): Promise<string>;\n\n /**\n * Write a runtime file, creating parent directories and replacing via a\n * staging file so an aborted write never truncates the target. Like\n * readFile, transport is the executor's concern — content must survive\n * arbitrary quoting and ARG_MAX limits.\n */\n writeFile(path: string, content: string, options?: ExecOptions): Promise<void>;\n\n /**\n * Get the workspace path prefix for this executor.\n * Host: returns the actual path.\n * Container/Firecracker: returns /workspace.\n */\n getWorkspacePath(hostPath: string): string;\n\n /**\n * Return explicit host/control-plane/runtime path semantics for this executor.\n */\n getPathContext(hostWorkspaceRoot: string): RuntimePathContext;\n\n /**\n * Get the current sandbox config used by this executor.\n */\n getSandboxConfig(): SandboxConfig;\n}\n\nexport interface RuntimePathContext {\n /** Host-side workspace root used by mikan's control plane. */\n hostWorkspaceRoot: string;\n /** Workspace root as seen by bash/read/write/edit inside the runtime. */\n runtimeWorkspaceRoot: string;\n /** Translate a runtime path back to a host path when the runtime is host-backed. */\n runtimeToHostPath?: (runtimePath: string) => string;\n}\n\nexport interface ExecOptions {\n timeout?: number;\n signal?: AbortSignal;\n}\n\nexport interface ExecResult {\n stdout: string;\n stderr: string;\n code: number;\n}\n\nexport interface SandboxAdapter<TConfig extends SandboxConfig = SandboxConfig> {\n type: TConfig[\"type\"];\n parse(value: string): TConfig | undefined;\n validate?(config: TConfig): Promise<void>;\n createExecutor?(\n config: TConfig,\n env?: Record<string, string>,\n ensureReady?: () => Promise<void>,\n ): Executor;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sandbox/types.ts"],"names":[],"mappings":"","sourcesContent":["export type SandboxConfig =\n | HostSandboxConfig\n | ContainerSandboxConfig\n | ImageSandboxConfig\n | MicrovmSandboxConfig\n | FirecrackerSandboxConfig\n | CloudflareSandboxConfig;\n\nexport interface HostSandboxConfig {\n type: \"host\";\n}\n\nexport interface ContainerSandboxConfig {\n type: \"container\";\n container: string;\n}\n\nexport interface ImageSandboxConfig {\n type: \"image\";\n image: string;\n}\n\nexport interface MicrovmSandboxConfig {\n type: \"microvm\";\n profile: \"default\";\n /** Local-only runtime details supplied after actor/workspace resolution. */\n workspacePath?: string;\n instanceId?: string;\n}\n\nexport interface FirecrackerSandboxConfig {\n type: \"firecracker\";\n vmId: string;\n hostPath: string;\n sshUser?: string;\n sshPort?: number;\n}\n\nexport interface CloudflareSandboxConfig {\n type: \"cloudflare\";\n sandboxId: string;\n}\n\nexport interface Executor {\n /**\n * Execute a bash command.\n */\n exec(command: string, options?: ExecOptions): Promise<ExecResult>;\n\n /**\n * Read a runtime file as UTF-8 text. The executor owns the transport, so\n * file contents never pass through shell argv or extra shell parse layers.\n */\n readFile(path: string, options?: ExecOptions): Promise<string>;\n\n /**\n * Write a runtime file, creating parent directories and replacing via a\n * staging file so an aborted write never truncates the target. Like\n * readFile, transport is the executor's concern — content must survive\n * arbitrary quoting and ARG_MAX limits.\n */\n writeFile(path: string, content: string, options?: ExecOptions): Promise<void>;\n\n /**\n * Get the workspace path prefix for this executor.\n * Host: returns the actual path.\n * Container/Firecracker: returns /workspace.\n */\n getWorkspacePath(hostPath: string): string;\n\n /**\n * Return explicit host/control-plane/runtime path semantics for this executor.\n */\n getPathContext(hostWorkspaceRoot: string): RuntimePathContext;\n\n /**\n * Get the current sandbox config used by this executor.\n */\n getSandboxConfig(): SandboxConfig;\n}\n\nexport interface RuntimePathContext {\n /** Host-side workspace root used by mikan's control plane. */\n hostWorkspaceRoot: string;\n /** Workspace root as seen by bash/read/write/edit inside the runtime. */\n runtimeWorkspaceRoot: string;\n /** Translate a runtime path back to a host path when the runtime is host-backed. */\n runtimeToHostPath?: (runtimePath: string) => string;\n}\n\nexport interface ExecOptions {\n timeout?: number;\n signal?: AbortSignal;\n}\n\nexport interface ExecResult {\n stdout: string;\n stderr: string;\n code: number;\n}\n\nexport interface SandboxAdapter<TConfig extends SandboxConfig = SandboxConfig> {\n type: TConfig[\"type\"];\n parse(value: string): TConfig | undefined;\n validate?(config: TConfig): Promise<void>;\n createExecutor?(\n config: TConfig,\n env?: Record<string, string>,\n ensureReady?: () => Promise<void>,\n ): Executor;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-memory-file-manager.d.ts","sourceRoot":"","sources":["../../src/sessions/agent-memory-file-manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agent-memory-file-manager.d.ts","sourceRoot":"","sources":["../../src/sessions/agent-memory-file-manager.ts"],"names":[],"mappings":"AASA,OAAO,EAUL,KAAK,oBAAoB,EAE1B,MAAM,YAAY,CAAC;AAepB,YAAY,EACV,6BAA6B,EAC7B,6BAA6B,EAC7B,4BAA4B,EAC5B,uBAAuB,EACvB,8BAA8B,EAC9B,iCAAiC,EACjC,0BAA0B,GAC3B,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EACV,6BAA6B,EAC7B,6BAA6B,EAC7B,4BAA4B,EAC5B,uBAAuB,EACvB,8BAA8B,EAC9B,iCAAiC,EACjC,0BAA0B,EAC3B,MAAM,YAAY,CAAC;AAEpB,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,6BAA6B,GAAG,OAAO,CAQ1F;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,GAAG,MAAM,GAAG,IAAI,CAQ1F;AAED,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,OAAO,CAAC,CAqBlB;AAED,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IAEjC,YAAY,OAAO,GAAE,6BAAkC,EAItD;IAEK,mBAAmB,CACvB,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,oBAAoB,CAAC,CAsB/B;IAED,kBAAkB,CAAC,OAAO,EAAE,iCAAiC,GAAG,IAAI,CAUnE;IAED,YAAY,CAAC,OAAO,EAAE,uBAAuB,GAAG,MAAM,CAUrD;IAED,OAAO,CAAC,0BAA0B;IA2ClC,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,yBAAyB;CA4ClC"}
|
|
@@ -2,7 +2,6 @@ import { join } from "path";
|
|
|
2
2
|
import { isRecord, parseJsonValue, readTextFileIfExists } from "../utils/file-guards.js";
|
|
3
3
|
import { isCommandText } from "../commands/text.js";
|
|
4
4
|
import { formatHistoryLine, stripHistoryLinePrefix } from "./history-line.js";
|
|
5
|
-
import { atomicWritePrivateFile } from "../utils/fs-atomic.js";
|
|
6
5
|
import * as log from "../log.js";
|
|
7
6
|
import { isPlatformHistorySession } from "./metadata.js";
|
|
8
7
|
import { isThreadSessionKey } from "./session-key.js";
|
|
@@ -306,7 +305,6 @@ function bootstrapSessionFromLog(sessionFile, cwd, records, lastMessageId = reco
|
|
|
306
305
|
messageCount: records.length,
|
|
307
306
|
lastMessageId,
|
|
308
307
|
});
|
|
309
|
-
forceRewriteSession(sessionManager, sessionFile);
|
|
310
308
|
}
|
|
311
309
|
function syncSessionFromLog(sessionFile, cwd, records, historyWindow) {
|
|
312
310
|
if (records.length === 0)
|
|
@@ -344,15 +342,6 @@ function appendLogRecordsToSession(sessionManager, records) {
|
|
|
344
342
|
sessionManager.appendMessage(message);
|
|
345
343
|
}
|
|
346
344
|
}
|
|
347
|
-
function forceRewriteSession(sessionManager, sessionFile) {
|
|
348
|
-
const header = sessionManager.getHeader();
|
|
349
|
-
if (!header)
|
|
350
|
-
return;
|
|
351
|
-
const content = [header, ...sessionManager.getEntries()]
|
|
352
|
-
.map((entry) => JSON.stringify(entry))
|
|
353
|
-
.join("\n");
|
|
354
|
-
atomicWritePrivateFile(sessionFile, `${content}\n`);
|
|
355
|
-
}
|
|
356
345
|
function getLatestChatSyncMessageId(entries) {
|
|
357
346
|
for (let i = entries.length - 1; i >= 0; i--) {
|
|
358
347
|
const entry = entries[i];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-memory-file-manager.js","sourceRoot":"","sources":["../../src/sessions/agent-memory-file-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SessionEntry, SessionStore } from \"../harness/index.js\";\nimport { join } from \"path\";\nimport type { ConversationLogMessage } from \"../types.js\";\nimport { isRecord, parseJsonValue, readTextFileIfExists } from \"../utils/file-guards.js\";\nimport { isCommandText } from \"../commands/text.js\";\nimport { formatHistoryLine, stripHistoryLinePrefix } from \"./history-line.js\";\nimport { atomicWritePrivateFile } from \"../utils/fs-atomic.js\";\nimport * as log from \"../log.js\";\nimport { isPlatformHistorySession } from \"./metadata.js\";\nimport { isThreadSessionKey } from \"./session-key.js\";\nimport {\n createManagedSessionFile,\n createManagedSessionFileAtPath,\n extractSessionSuffix,\n getChannelSessionDir,\n getThreadSessionFile,\n openManagedSession,\n resolveChannelSessionFile,\n tryResolveCurrentSession,\n tryResolveThreadSession,\n type ResolvedSessionScope,\n type ThreadRootMessage,\n} from \"./store.js\";\n\nconst DEFAULT_RECENT_DAYS = 14;\nconst DEFAULT_MAX_TOP_LEVEL_MESSAGES = 200;\nconst CHAT_SYNC_CUSTOM_TYPE = \"mikan.chat_sync\";\nconst BIWEEKLY_ROTATION_ANCHOR = new Date(2026, 0, 4); // Sunday\nconst BIWEEKLY_MS = 14 * 24 * 60 * 60 * 1000;\n\ntype SessionAppendMessage = Parameters<SessionStore[\"appendMessage\"]>[0];\n\ninterface LogRecord {\n message: ConversationLogMessage;\n index: number;\n}\n\nexport type {\n AgentMemoryFileManagerOptions,\n HasMaterializedSessionOptions,\n RegisterThreadSessionOptions,\n ResetChatSessionOptions,\n ResolveChatSessionScopeOptions,\n SyncAgentMemoryFileManagerOptions,\n ThreadBootstrapWaitOptions,\n} from \"./types.js\";\nimport type {\n AgentMemoryFileManagerOptions,\n HasMaterializedSessionOptions,\n RegisterThreadSessionOptions,\n ResetChatSessionOptions,\n ResolveChatSessionScopeOptions,\n SyncAgentMemoryFileManagerOptions,\n ThreadBootstrapWaitOptions,\n} from \"./types.js\";\n\nexport function hasMaterializedChatSession(options: HasMaterializedSessionOptions): boolean {\n if (!isThreadSessionKey(options.sessionKey)) {\n return resolveChannelSessionFile(options.conversationDir) !== null;\n }\n return (\n tryResolveThreadSession(getThreadSessionFile(options.conversationDir, options.sessionKey)) !==\n null\n );\n}\n\nexport function registerThreadSession(options: RegisterThreadSessionOptions): string | null {\n if (!isThreadSessionKey(options.sessionKey)) return null;\n\n const threadFile = getThreadSessionFile(options.conversationDir, options.sessionKey);\n return (\n tryResolveThreadSession(threadFile) ??\n createManagedSessionFileAtPath(threadFile, options.cwd ?? options.conversationDir)\n );\n}\n\nexport async function waitForThreadSessionBootstrap(\n options: ThreadBootstrapWaitOptions,\n): Promise<boolean> {\n const {\n parentSessionKey,\n sessionKey,\n hasThreadSession,\n isParentRunning,\n sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)),\n pollMs = 100,\n } = options;\n\n if (!isThreadSessionKey(sessionKey)) return false;\n if (sessionKey === parentSessionKey) return false;\n if (hasThreadSession()) return false;\n\n let waited = false;\n while (isParentRunning() && !hasThreadSession()) {\n waited = true;\n await sleep(pollMs);\n }\n\n return waited;\n}\n\nexport class AgentMemoryFileManager {\n private readonly recentDays: number;\n private readonly maxTopLevelMessages: number;\n private readonly now: () => Date;\n\n constructor(options: AgentMemoryFileManagerOptions = {}) {\n this.recentDays = options.recentDays ?? DEFAULT_RECENT_DAYS;\n this.maxTopLevelMessages = options.maxTopLevelMessages ?? DEFAULT_MAX_TOP_LEVEL_MESSAGES;\n this.now = options.now ?? (() => new Date());\n }\n\n async resolveSessionScope(\n options: ResolveChatSessionScopeOptions,\n ): Promise<ResolvedSessionScope> {\n const cwd = options.cwd ?? options.conversationDir;\n const sessionDir = getChannelSessionDir(options.conversationDir);\n\n if (!isThreadSessionKey(options.sessionKey)) {\n const contextFile = this.resolveTopLevelSessionFile({\n conversationDir: options.conversationDir,\n sessionDir,\n cwd,\n currentMessageId: options.currentMessageId,\n rotateTopLevelSession: options.rotateTopLevelSession === true,\n });\n return { sessionDir, contextFile, threadRootMessage: null };\n }\n\n return this.resolveThreadSessionScope({\n conversationDir: options.conversationDir,\n sessionDir,\n sessionKey: options.sessionKey,\n cwd,\n currentMessageId: options.currentMessageId,\n });\n }\n\n syncSessionManager(options: SyncAgentMemoryFileManagerOptions): void {\n const records = readConversationLog(options.conversationDir);\n syncSessionManagerFromLog(\n options.sessionManager,\n selectExistingSessionSyncMessages(records, {\n sessionKey: isThreadSessionKey(options.sessionKey) ? options.sessionKey : null,\n excludeMessageId: options.currentMessageId,\n }),\n this.historyWindow(),\n );\n }\n\n resetSession(options: ResetChatSessionOptions): string {\n const cwd = options.cwd ?? options.conversationDir;\n if (isThreadSessionKey(options.sessionKey)) {\n return createManagedSessionFileAtPath(\n getThreadSessionFile(options.conversationDir, options.sessionKey),\n cwd,\n );\n }\n\n return createManagedSessionFile(getChannelSessionDir(options.conversationDir), cwd);\n }\n\n private resolveTopLevelSessionFile(options: {\n conversationDir: string;\n sessionDir: string;\n cwd: string;\n currentMessageId?: string;\n rotateTopLevelSession: boolean;\n }): string {\n const records = readConversationLog(options.conversationDir);\n const existing = tryResolveCurrentSession(options.sessionDir);\n if (existing && !isPlatformHistorySession(existing)) {\n if (!options.rotateTopLevelSession || !shouldRotateTopLevelSession(existing, this.now())) {\n syncSessionFromLog(\n existing,\n options.cwd,\n selectExistingSessionSyncMessages(records, {\n sessionKey: null,\n excludeMessageId: options.currentMessageId,\n }),\n this.historyWindow(),\n );\n return existing;\n }\n }\n\n const sessionFile = createManagedSessionFile(options.sessionDir, options.cwd);\n const bootstrapRecords = selectRecentTopLevelMessages(records, {\n recentDays: this.recentDays,\n maxMessages: this.maxTopLevelMessages,\n now: this.now(),\n excludeMessageId: options.currentMessageId,\n });\n bootstrapSessionFromLog(\n sessionFile,\n options.cwd,\n bootstrapRecords,\n latestSyncMessageId(records, {\n sessionKey: null,\n excludeMessageId: options.currentMessageId,\n }),\n );\n return sessionFile;\n }\n\n private historyWindow(): HistoryWindow {\n return { recentDays: this.recentDays, maxMessages: this.maxTopLevelMessages, now: this.now() };\n }\n\n private resolveThreadSessionScope(options: {\n conversationDir: string;\n sessionDir: string;\n sessionKey: string;\n cwd: string;\n currentMessageId?: string;\n }): ResolvedSessionScope {\n const threadFile = getThreadSessionFile(options.conversationDir, options.sessionKey);\n const threadId = extractSessionSuffix(options.sessionKey);\n const records = readConversationLog(options.conversationDir);\n const threadRootMessage = buildThreadRootSeed(findLogRecordById(records, threadId)?.message);\n const existing = tryResolveThreadSession(threadFile);\n if (existing) {\n syncSessionFromLog(\n existing,\n options.cwd,\n selectExistingSessionSyncMessages(records, {\n sessionKey: options.sessionKey,\n excludeMessageId: options.currentMessageId,\n }),\n this.historyWindow(),\n );\n return { sessionDir: options.sessionDir, contextFile: existing, threadRootMessage };\n }\n\n createManagedSessionFileAtPath(threadFile, options.cwd);\n const bootstrapRecords = selectThreadBootstrapMessages(records, threadId, {\n recentDays: this.recentDays,\n maxTopLevelMessages: this.maxTopLevelMessages,\n now: this.now(),\n excludeMessageId: options.currentMessageId,\n });\n bootstrapSessionFromLog(\n threadFile,\n options.cwd,\n bootstrapRecords,\n latestSyncMessageId(records, {\n sessionKey: options.sessionKey,\n excludeMessageId: options.currentMessageId,\n }),\n );\n\n return { sessionDir: options.sessionDir, contextFile: threadFile, threadRootMessage };\n }\n}\n\nfunction shouldRotateTopLevelSession(sessionFile: string, now: Date): boolean {\n const timestamp = readSessionTimestamp(sessionFile);\n return timestamp !== null && biweeklyBucket(timestamp) !== biweeklyBucket(now);\n}\n\nfunction readSessionTimestamp(sessionFile: string): Date | null {\n const raw = readTextFileIfExists(sessionFile);\n if (raw === undefined) return null;\n const firstLine = raw.split(\"\\n\").find((line) => line.trim());\n if (!firstLine) return null;\n try {\n const header = parseJsonValue(\n firstLine,\n (value): value is { timestamp?: unknown } => isRecord(value),\n (detail) => (detail === \"unexpected JSON shape\" ? \"expected a JSON object\" : detail),\n );\n if (typeof header.timestamp !== \"string\") return null;\n const date = new Date(header.timestamp);\n return Number.isFinite(date.getTime()) ? date : null;\n } catch {\n return null;\n }\n}\n\nfunction biweeklyBucket(date: Date): number {\n const weekStart = sundayStart(date).getTime();\n const anchor = sundayStart(BIWEEKLY_ROTATION_ANCHOR).getTime();\n return Math.floor((weekStart - anchor) / BIWEEKLY_MS);\n}\n\nfunction sundayStart(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay());\n}\n\nfunction readConversationLog(conversationDir: string): LogRecord[] {\n const logFile = join(conversationDir, \"log.jsonl\");\n const raw = readTextFileIfExists(logFile);\n if (raw === undefined) return [];\n\n const lines = raw.trim().split(\"\\n\").filter(Boolean);\n const records: LogRecord[] = [];\n for (let i = 0; i < lines.length; i++) {\n try {\n const message = parseJsonValue(\n lines[i],\n (value): value is ConversationLogMessage => isRecord(value),\n (detail) => (detail === \"unexpected JSON shape\" ? \"expected a JSON object\" : detail),\n );\n records.push({ message, index: i });\n } catch (err) {\n log.logWarning(\n `Skipping malformed log entry at ${logFile}:${i + 1}`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n return coalesceMessagingBotLogChunks(records);\n}\n\nfunction coalesceMessagingBotLogChunks(records: LogRecord[]): LogRecord[] {\n const coalesced: LogRecord[] = [];\n for (const record of records) {\n const previous = coalesced.at(-1);\n if (previous && canCoalesceMessagingBotLogChunk(previous.message, record.message)) {\n previous.message.text = `${previous.message.text ?? \"\"}${record.message.text ?? \"\"}`;\n continue;\n }\n coalesced.push({ ...record, message: { ...record.message } });\n }\n return coalesced;\n}\n\nfunction canCoalesceMessagingBotLogChunk(\n previous: ConversationLogMessage,\n current: ConversationLogMessage,\n): boolean {\n return (\n previous.isMessagingBot === true &&\n current.isMessagingBot === true &&\n !!previous.ts &&\n previous.ts === current.ts &&\n previous.threadTs === current.threadTs &&\n previous.user === current.user\n );\n}\n\nfunction findLogRecordById(records: LogRecord[], messageId: string): LogRecord | undefined {\n for (let i = records.length - 1; i >= 0; i--) {\n if (records[i].message.ts === messageId) return records[i];\n }\n return undefined;\n}\n\nfunction selectRecentTopLevelMessages(\n records: LogRecord[],\n options: {\n recentDays: number;\n maxMessages: number;\n now: Date;\n excludeMessageId?: string;\n },\n): LogRecord[] {\n return selectRecentMessages(\n records.filter((record) => isTopLevelHistoryMessage(record.message, options.excludeMessageId)),\n options,\n );\n}\n\nfunction selectRecentMessages(records: LogRecord[], options: HistoryWindow): LogRecord[] {\n const sinceMs = options.now.getTime() - options.recentDays * 24 * 60 * 60 * 1000;\n return records\n .filter((record) => isRecentHistoryMessage(record.message, sinceMs))\n .slice(-options.maxMessages);\n}\n\nfunction selectThreadBootstrapMessages(\n records: LogRecord[],\n threadId: string,\n options: {\n recentDays: number;\n maxTopLevelMessages: number;\n now: Date;\n excludeMessageId?: string;\n },\n): LogRecord[] {\n const rootRecord = findLogRecordById(records, threadId);\n const topLevelSource = rootRecord\n ? records.filter((record) => record.index <= rootRecord.index)\n : records;\n const topLevelRecords = selectRecentTopLevelMessages(topLevelSource, {\n recentDays: options.recentDays,\n maxMessages: options.maxTopLevelMessages,\n now: options.now,\n excludeMessageId: options.excludeMessageId,\n });\n const threadRecords = records.filter(\n (record) =>\n isRenderableConversationMessage(record.message, options.excludeMessageId) &&\n (record.message.ts === threadId || record.message.threadTs === threadId),\n );\n\n return dedupeAndSortRecords([...topLevelRecords, ...threadRecords]);\n}\n\nfunction isTopLevelHistoryMessage(\n message: ConversationLogMessage,\n excludeMessageId?: string,\n): boolean {\n if (!isRenderableConversationMessage(message, excludeMessageId)) return false;\n return !message.threadTs;\n}\n\nfunction isRecentHistoryMessage(message: ConversationLogMessage, sinceMs: number): boolean {\n if (!message.date) return true;\n const dateMs = new Date(message.date).getTime();\n return !Number.isFinite(dateMs) || dateMs >= sinceMs;\n}\n\nfunction selectExistingSessionSyncMessages(\n records: LogRecord[],\n options: { sessionKey: string | null; excludeMessageId?: string },\n): LogRecord[] {\n const threadId = options.sessionKey ? extractSessionSuffix(options.sessionKey) : null;\n return dedupeAndSortRecords(\n records.filter((record) => {\n if (!isRenderableConversationMessage(record.message, options.excludeMessageId)) return false;\n if (!threadId) return !record.message.threadTs;\n return record.message.ts === threadId || record.message.threadTs === threadId;\n }),\n );\n}\n\nfunction latestSyncMessageId(\n records: LogRecord[],\n options: { sessionKey: string | null; excludeMessageId?: string },\n): string | undefined {\n return selectExistingSessionSyncMessages(records, options).at(-1)?.message.ts;\n}\n\nfunction isRenderableConversationMessage(\n message: ConversationLogMessage,\n excludeMessageId?: string,\n): boolean {\n if (excludeMessageId && message.ts === excludeMessageId) return false;\n if (isChatCommandMessage(message)) return false;\n return !!message.text?.trim();\n}\n\nfunction isChatCommandMessage(message: ConversationLogMessage): boolean {\n return !message.isMessagingBot && isCommandText(message.text ?? \"\");\n}\n\nfunction dedupeAndSortRecords(records: LogRecord[]): LogRecord[] {\n const byKey = new Map<string, LogRecord>();\n for (const record of records) {\n byKey.set(record.message.ts ?? `line:${record.index}`, record);\n }\n\n return Array.from(byKey.values()).toSorted((a, b) => {\n const aTime = sortTime(a);\n const bTime = sortTime(b);\n if (aTime !== bTime) return aTime - bTime;\n return a.index - b.index;\n });\n}\n\nfunction sortTime(record: LogRecord): number {\n if (record.message.date) {\n const dateMs = new Date(record.message.date).getTime();\n if (Number.isFinite(dateMs)) return dateMs;\n }\n\n if (record.message.ts) {\n const tsMs = Number(record.message.ts) * 1000;\n if (Number.isFinite(tsMs)) return tsMs;\n }\n\n return record.index;\n}\n\nfunction bootstrapSessionFromLog(\n sessionFile: string,\n cwd: string,\n records: LogRecord[],\n lastMessageId = records.at(-1)?.message.ts,\n): void {\n if (records.length === 0 && !lastMessageId) return;\n\n const sessionManager = openManagedSession(sessionFile, cwd);\n appendLogRecordsToSession(sessionManager, records);\n sessionManager.appendCustomEntry(CHAT_SYNC_CUSTOM_TYPE, {\n source: \"log.jsonl\",\n messageCount: records.length,\n lastMessageId,\n });\n forceRewriteSession(sessionManager, sessionFile);\n}\n\ninterface HistoryWindow {\n recentDays: number;\n maxMessages: number;\n now: Date;\n}\n\nfunction syncSessionFromLog(\n sessionFile: string,\n cwd: string,\n records: LogRecord[],\n historyWindow: HistoryWindow,\n): void {\n if (records.length === 0) return;\n syncSessionManagerFromLog(openManagedSession(sessionFile, cwd), records, historyWindow);\n}\n\nfunction syncSessionManagerFromLog(\n sessionManager: SessionStore,\n records: LogRecord[],\n historyWindow: HistoryWindow,\n): void {\n if (records.length === 0) return;\n\n const existingEntries = sessionManager.getEntries();\n const lastSyncedMessageId = getLatestChatSyncMessageId(existingEntries);\n const lastSyncedIndex = lastSyncedMessageId\n ? records.findIndex((record) => record.message.ts === lastSyncedMessageId)\n : -1;\n if (lastSyncedMessageId && lastSyncedIndex === -1) return;\n\n const syncCandidates = selectRecentMessages(records.slice(lastSyncedIndex + 1), historyWindow);\n if (syncCandidates.length === 0) return;\n\n const represented = buildRepresentedMessageCounts(existingEntries);\n const newRecords = syncCandidates.filter(\n (record) => !consumeRepresentedLogMessage(record, represented),\n );\n if (newRecords.length === 0) return;\n\n appendLogRecordsToSession(sessionManager, newRecords);\n sessionManager.appendCustomEntry(CHAT_SYNC_CUSTOM_TYPE, {\n source: \"log.jsonl\",\n messageCount: newRecords.length,\n lastMessageId: syncCandidates.at(-1)?.message.ts,\n });\n}\n\nfunction appendLogRecordsToSession(sessionManager: SessionStore, records: LogRecord[]): void {\n for (const record of records) {\n const message = buildHistorySessionMessage(record.message);\n if (message) sessionManager.appendMessage(message);\n }\n}\n\nfunction forceRewriteSession(sessionManager: SessionStore, sessionFile: string): void {\n const header = sessionManager.getHeader();\n if (!header) return;\n\n const content = [header, ...sessionManager.getEntries()]\n .map((entry) => JSON.stringify(entry))\n .join(\"\\n\");\n atomicWritePrivateFile(sessionFile, `${content}\\n`);\n}\n\nfunction getLatestChatSyncMessageId(entries: SessionEntry[]): string | undefined {\n for (let i = entries.length - 1; i >= 0; i--) {\n const entry = entries[i];\n if (entry.type !== \"custom\" || entry.customType !== CHAT_SYNC_CUSTOM_TYPE) continue;\n if (!isRecord(entry.data)) return undefined;\n return typeof entry.data.lastMessageId === \"string\" ? entry.data.lastMessageId : undefined;\n }\n return undefined;\n}\n\nfunction buildRepresentedMessageCounts(entries: SessionEntry[]): Map<string, number> {\n const counts = new Map<string, number>();\n for (const entry of entries) {\n const comparable = comparableSessionMessage(entry);\n if (!comparable) continue;\n counts.set(comparable, (counts.get(comparable) ?? 0) + 1);\n }\n return counts;\n}\n\nfunction consumeRepresentedLogMessage(record: LogRecord, counts: Map<string, number>): boolean {\n const comparable = comparableLogMessage(record.message);\n if (!comparable) return false;\n\n const count = counts.get(comparable) ?? 0;\n if (count <= 0) return false;\n counts.set(comparable, count - 1);\n return true;\n}\n\nfunction comparableSessionMessage(entry: SessionEntry): string | null {\n if (entry.type !== \"message\") return null;\n const role = entry.message.role;\n if (role !== \"user\" && role !== \"assistant\") return null;\n\n const text = normalizeComparableText(getSessionMessageText(entry));\n if (!text) return null;\n return `${role}:${text}`;\n}\n\nfunction comparableLogMessage(message: ConversationLogMessage): string | null {\n const text = message.text?.trim();\n if (!text) return null;\n return `${message.isMessagingBot ? \"assistant\" : \"user\"}:${normalizeComparableText(text)}`;\n}\n\nfunction getSessionMessageText(entry: SessionEntry): string {\n if (entry.type !== \"message\" || !(\"content\" in entry.message)) return \"\";\n const content = entry.message.content;\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n return content\n .map((part) => (part.type === \"text\" && \"text\" in part ? part.text : \"\"))\n .join(\"\\n\");\n}\n\nconst normalizeComparableText = stripHistoryLinePrefix;\n\nfunction buildHistorySessionMessage(message: ConversationLogMessage): SessionAppendMessage | null {\n const text = message.text?.trim();\n if (!text) return null;\n\n const timestamp = parseMessageTimestamp(message);\n if (!message.isMessagingBot) {\n return {\n role: \"user\",\n content: [{ type: \"text\", text: formatHistoryMessage(message) }],\n ...(timestamp !== undefined ? { timestamp } : {}),\n } as SessionAppendMessage;\n }\n\n return {\n role: \"assistant\",\n content: [{ type: \"text\", text }],\n api: \"platform-history\",\n provider: \"platform-history\",\n model: \"platform-history\",\n usage: zeroUsage(),\n stopReason: \"stop\",\n ...(timestamp !== undefined ? { timestamp } : {}),\n } as SessionAppendMessage;\n}\n\nfunction buildThreadRootSeed(\n message: ConversationLogMessage | undefined,\n): ThreadRootMessage | null {\n if (!message) return null;\n return {\n text: message.text,\n userName: message.userName,\n user: message.user,\n loggedAt: message.date ? new Date(message.date).getTime() : undefined,\n isMessagingBot: message.isMessagingBot,\n };\n}\n\nfunction parseMessageTimestamp(message: ConversationLogMessage): number | undefined {\n if (message.date) {\n const dateMs = new Date(message.date).getTime();\n if (Number.isFinite(dateMs)) return dateMs;\n }\n\n if (message.ts) {\n const tsMs = Number(message.ts) * 1000;\n if (Number.isFinite(tsMs)) return tsMs;\n }\n\n return undefined;\n}\n\nfunction formatHistoryMessage(message: ConversationLogMessage): string {\n return formatHistoryLine({\n date: message.date ? new Date(message.date) : undefined,\n userName: message.userName || message.user,\n text: message.text?.trim() ?? \"\",\n });\n}\n\nfunction zeroUsage(): object {\n return {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n totalTokens: 0,\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agent-memory-file-manager.js","sourceRoot":"","sources":["../../src/sessions/agent-memory-file-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SessionEntry, SessionStore } from \"../harness/index.js\";\nimport { join } from \"path\";\nimport type { ConversationLogMessage } from \"../types.js\";\nimport { isRecord, parseJsonValue, readTextFileIfExists } from \"../utils/file-guards.js\";\nimport { isCommandText } from \"../commands/text.js\";\nimport { formatHistoryLine, stripHistoryLinePrefix } from \"./history-line.js\";\nimport * as log from \"../log.js\";\nimport { isPlatformHistorySession } from \"./metadata.js\";\nimport { isThreadSessionKey } from \"./session-key.js\";\nimport {\n createManagedSessionFile,\n createManagedSessionFileAtPath,\n extractSessionSuffix,\n getChannelSessionDir,\n getThreadSessionFile,\n openManagedSession,\n resolveChannelSessionFile,\n tryResolveCurrentSession,\n tryResolveThreadSession,\n type ResolvedSessionScope,\n type ThreadRootMessage,\n} from \"./store.js\";\n\nconst DEFAULT_RECENT_DAYS = 14;\nconst DEFAULT_MAX_TOP_LEVEL_MESSAGES = 200;\nconst CHAT_SYNC_CUSTOM_TYPE = \"mikan.chat_sync\";\nconst BIWEEKLY_ROTATION_ANCHOR = new Date(2026, 0, 4); // Sunday\nconst BIWEEKLY_MS = 14 * 24 * 60 * 60 * 1000;\n\ntype SessionAppendMessage = Parameters<SessionStore[\"appendMessage\"]>[0];\n\ninterface LogRecord {\n message: ConversationLogMessage;\n index: number;\n}\n\nexport type {\n AgentMemoryFileManagerOptions,\n HasMaterializedSessionOptions,\n RegisterThreadSessionOptions,\n ResetChatSessionOptions,\n ResolveChatSessionScopeOptions,\n SyncAgentMemoryFileManagerOptions,\n ThreadBootstrapWaitOptions,\n} from \"./types.js\";\nimport type {\n AgentMemoryFileManagerOptions,\n HasMaterializedSessionOptions,\n RegisterThreadSessionOptions,\n ResetChatSessionOptions,\n ResolveChatSessionScopeOptions,\n SyncAgentMemoryFileManagerOptions,\n ThreadBootstrapWaitOptions,\n} from \"./types.js\";\n\nexport function hasMaterializedChatSession(options: HasMaterializedSessionOptions): boolean {\n if (!isThreadSessionKey(options.sessionKey)) {\n return resolveChannelSessionFile(options.conversationDir) !== null;\n }\n return (\n tryResolveThreadSession(getThreadSessionFile(options.conversationDir, options.sessionKey)) !==\n null\n );\n}\n\nexport function registerThreadSession(options: RegisterThreadSessionOptions): string | null {\n if (!isThreadSessionKey(options.sessionKey)) return null;\n\n const threadFile = getThreadSessionFile(options.conversationDir, options.sessionKey);\n return (\n tryResolveThreadSession(threadFile) ??\n createManagedSessionFileAtPath(threadFile, options.cwd ?? options.conversationDir)\n );\n}\n\nexport async function waitForThreadSessionBootstrap(\n options: ThreadBootstrapWaitOptions,\n): Promise<boolean> {\n const {\n parentSessionKey,\n sessionKey,\n hasThreadSession,\n isParentRunning,\n sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)),\n pollMs = 100,\n } = options;\n\n if (!isThreadSessionKey(sessionKey)) return false;\n if (sessionKey === parentSessionKey) return false;\n if (hasThreadSession()) return false;\n\n let waited = false;\n while (isParentRunning() && !hasThreadSession()) {\n waited = true;\n await sleep(pollMs);\n }\n\n return waited;\n}\n\nexport class AgentMemoryFileManager {\n private readonly recentDays: number;\n private readonly maxTopLevelMessages: number;\n private readonly now: () => Date;\n\n constructor(options: AgentMemoryFileManagerOptions = {}) {\n this.recentDays = options.recentDays ?? DEFAULT_RECENT_DAYS;\n this.maxTopLevelMessages = options.maxTopLevelMessages ?? DEFAULT_MAX_TOP_LEVEL_MESSAGES;\n this.now = options.now ?? (() => new Date());\n }\n\n async resolveSessionScope(\n options: ResolveChatSessionScopeOptions,\n ): Promise<ResolvedSessionScope> {\n const cwd = options.cwd ?? options.conversationDir;\n const sessionDir = getChannelSessionDir(options.conversationDir);\n\n if (!isThreadSessionKey(options.sessionKey)) {\n const contextFile = this.resolveTopLevelSessionFile({\n conversationDir: options.conversationDir,\n sessionDir,\n cwd,\n currentMessageId: options.currentMessageId,\n rotateTopLevelSession: options.rotateTopLevelSession === true,\n });\n return { sessionDir, contextFile, threadRootMessage: null };\n }\n\n return this.resolveThreadSessionScope({\n conversationDir: options.conversationDir,\n sessionDir,\n sessionKey: options.sessionKey,\n cwd,\n currentMessageId: options.currentMessageId,\n });\n }\n\n syncSessionManager(options: SyncAgentMemoryFileManagerOptions): void {\n const records = readConversationLog(options.conversationDir);\n syncSessionManagerFromLog(\n options.sessionManager,\n selectExistingSessionSyncMessages(records, {\n sessionKey: isThreadSessionKey(options.sessionKey) ? options.sessionKey : null,\n excludeMessageId: options.currentMessageId,\n }),\n this.historyWindow(),\n );\n }\n\n resetSession(options: ResetChatSessionOptions): string {\n const cwd = options.cwd ?? options.conversationDir;\n if (isThreadSessionKey(options.sessionKey)) {\n return createManagedSessionFileAtPath(\n getThreadSessionFile(options.conversationDir, options.sessionKey),\n cwd,\n );\n }\n\n return createManagedSessionFile(getChannelSessionDir(options.conversationDir), cwd);\n }\n\n private resolveTopLevelSessionFile(options: {\n conversationDir: string;\n sessionDir: string;\n cwd: string;\n currentMessageId?: string;\n rotateTopLevelSession: boolean;\n }): string {\n const records = readConversationLog(options.conversationDir);\n const existing = tryResolveCurrentSession(options.sessionDir);\n if (existing && !isPlatformHistorySession(existing)) {\n if (!options.rotateTopLevelSession || !shouldRotateTopLevelSession(existing, this.now())) {\n syncSessionFromLog(\n existing,\n options.cwd,\n selectExistingSessionSyncMessages(records, {\n sessionKey: null,\n excludeMessageId: options.currentMessageId,\n }),\n this.historyWindow(),\n );\n return existing;\n }\n }\n\n const sessionFile = createManagedSessionFile(options.sessionDir, options.cwd);\n const bootstrapRecords = selectRecentTopLevelMessages(records, {\n recentDays: this.recentDays,\n maxMessages: this.maxTopLevelMessages,\n now: this.now(),\n excludeMessageId: options.currentMessageId,\n });\n bootstrapSessionFromLog(\n sessionFile,\n options.cwd,\n bootstrapRecords,\n latestSyncMessageId(records, {\n sessionKey: null,\n excludeMessageId: options.currentMessageId,\n }),\n );\n return sessionFile;\n }\n\n private historyWindow(): HistoryWindow {\n return { recentDays: this.recentDays, maxMessages: this.maxTopLevelMessages, now: this.now() };\n }\n\n private resolveThreadSessionScope(options: {\n conversationDir: string;\n sessionDir: string;\n sessionKey: string;\n cwd: string;\n currentMessageId?: string;\n }): ResolvedSessionScope {\n const threadFile = getThreadSessionFile(options.conversationDir, options.sessionKey);\n const threadId = extractSessionSuffix(options.sessionKey);\n const records = readConversationLog(options.conversationDir);\n const threadRootMessage = buildThreadRootSeed(findLogRecordById(records, threadId)?.message);\n const existing = tryResolveThreadSession(threadFile);\n if (existing) {\n syncSessionFromLog(\n existing,\n options.cwd,\n selectExistingSessionSyncMessages(records, {\n sessionKey: options.sessionKey,\n excludeMessageId: options.currentMessageId,\n }),\n this.historyWindow(),\n );\n return { sessionDir: options.sessionDir, contextFile: existing, threadRootMessage };\n }\n\n createManagedSessionFileAtPath(threadFile, options.cwd);\n const bootstrapRecords = selectThreadBootstrapMessages(records, threadId, {\n recentDays: this.recentDays,\n maxTopLevelMessages: this.maxTopLevelMessages,\n now: this.now(),\n excludeMessageId: options.currentMessageId,\n });\n bootstrapSessionFromLog(\n threadFile,\n options.cwd,\n bootstrapRecords,\n latestSyncMessageId(records, {\n sessionKey: options.sessionKey,\n excludeMessageId: options.currentMessageId,\n }),\n );\n\n return { sessionDir: options.sessionDir, contextFile: threadFile, threadRootMessage };\n }\n}\n\nfunction shouldRotateTopLevelSession(sessionFile: string, now: Date): boolean {\n const timestamp = readSessionTimestamp(sessionFile);\n return timestamp !== null && biweeklyBucket(timestamp) !== biweeklyBucket(now);\n}\n\nfunction readSessionTimestamp(sessionFile: string): Date | null {\n const raw = readTextFileIfExists(sessionFile);\n if (raw === undefined) return null;\n const firstLine = raw.split(\"\\n\").find((line) => line.trim());\n if (!firstLine) return null;\n try {\n const header = parseJsonValue(\n firstLine,\n (value): value is { timestamp?: unknown } => isRecord(value),\n (detail) => (detail === \"unexpected JSON shape\" ? \"expected a JSON object\" : detail),\n );\n if (typeof header.timestamp !== \"string\") return null;\n const date = new Date(header.timestamp);\n return Number.isFinite(date.getTime()) ? date : null;\n } catch {\n return null;\n }\n}\n\nfunction biweeklyBucket(date: Date): number {\n const weekStart = sundayStart(date).getTime();\n const anchor = sundayStart(BIWEEKLY_ROTATION_ANCHOR).getTime();\n return Math.floor((weekStart - anchor) / BIWEEKLY_MS);\n}\n\nfunction sundayStart(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay());\n}\n\nfunction readConversationLog(conversationDir: string): LogRecord[] {\n const logFile = join(conversationDir, \"log.jsonl\");\n const raw = readTextFileIfExists(logFile);\n if (raw === undefined) return [];\n\n const lines = raw.trim().split(\"\\n\").filter(Boolean);\n const records: LogRecord[] = [];\n for (let i = 0; i < lines.length; i++) {\n try {\n const message = parseJsonValue(\n lines[i],\n (value): value is ConversationLogMessage => isRecord(value),\n (detail) => (detail === \"unexpected JSON shape\" ? \"expected a JSON object\" : detail),\n );\n records.push({ message, index: i });\n } catch (err) {\n log.logWarning(\n `Skipping malformed log entry at ${logFile}:${i + 1}`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n return coalesceMessagingBotLogChunks(records);\n}\n\nfunction coalesceMessagingBotLogChunks(records: LogRecord[]): LogRecord[] {\n const coalesced: LogRecord[] = [];\n for (const record of records) {\n const previous = coalesced.at(-1);\n if (previous && canCoalesceMessagingBotLogChunk(previous.message, record.message)) {\n previous.message.text = `${previous.message.text ?? \"\"}${record.message.text ?? \"\"}`;\n continue;\n }\n coalesced.push({ ...record, message: { ...record.message } });\n }\n return coalesced;\n}\n\nfunction canCoalesceMessagingBotLogChunk(\n previous: ConversationLogMessage,\n current: ConversationLogMessage,\n): boolean {\n return (\n previous.isMessagingBot === true &&\n current.isMessagingBot === true &&\n !!previous.ts &&\n previous.ts === current.ts &&\n previous.threadTs === current.threadTs &&\n previous.user === current.user\n );\n}\n\nfunction findLogRecordById(records: LogRecord[], messageId: string): LogRecord | undefined {\n for (let i = records.length - 1; i >= 0; i--) {\n if (records[i].message.ts === messageId) return records[i];\n }\n return undefined;\n}\n\nfunction selectRecentTopLevelMessages(\n records: LogRecord[],\n options: {\n recentDays: number;\n maxMessages: number;\n now: Date;\n excludeMessageId?: string;\n },\n): LogRecord[] {\n return selectRecentMessages(\n records.filter((record) => isTopLevelHistoryMessage(record.message, options.excludeMessageId)),\n options,\n );\n}\n\nfunction selectRecentMessages(records: LogRecord[], options: HistoryWindow): LogRecord[] {\n const sinceMs = options.now.getTime() - options.recentDays * 24 * 60 * 60 * 1000;\n return records\n .filter((record) => isRecentHistoryMessage(record.message, sinceMs))\n .slice(-options.maxMessages);\n}\n\nfunction selectThreadBootstrapMessages(\n records: LogRecord[],\n threadId: string,\n options: {\n recentDays: number;\n maxTopLevelMessages: number;\n now: Date;\n excludeMessageId?: string;\n },\n): LogRecord[] {\n const rootRecord = findLogRecordById(records, threadId);\n const topLevelSource = rootRecord\n ? records.filter((record) => record.index <= rootRecord.index)\n : records;\n const topLevelRecords = selectRecentTopLevelMessages(topLevelSource, {\n recentDays: options.recentDays,\n maxMessages: options.maxTopLevelMessages,\n now: options.now,\n excludeMessageId: options.excludeMessageId,\n });\n const threadRecords = records.filter(\n (record) =>\n isRenderableConversationMessage(record.message, options.excludeMessageId) &&\n (record.message.ts === threadId || record.message.threadTs === threadId),\n );\n\n return dedupeAndSortRecords([...topLevelRecords, ...threadRecords]);\n}\n\nfunction isTopLevelHistoryMessage(\n message: ConversationLogMessage,\n excludeMessageId?: string,\n): boolean {\n if (!isRenderableConversationMessage(message, excludeMessageId)) return false;\n return !message.threadTs;\n}\n\nfunction isRecentHistoryMessage(message: ConversationLogMessage, sinceMs: number): boolean {\n if (!message.date) return true;\n const dateMs = new Date(message.date).getTime();\n return !Number.isFinite(dateMs) || dateMs >= sinceMs;\n}\n\nfunction selectExistingSessionSyncMessages(\n records: LogRecord[],\n options: { sessionKey: string | null; excludeMessageId?: string },\n): LogRecord[] {\n const threadId = options.sessionKey ? extractSessionSuffix(options.sessionKey) : null;\n return dedupeAndSortRecords(\n records.filter((record) => {\n if (!isRenderableConversationMessage(record.message, options.excludeMessageId)) return false;\n if (!threadId) return !record.message.threadTs;\n return record.message.ts === threadId || record.message.threadTs === threadId;\n }),\n );\n}\n\nfunction latestSyncMessageId(\n records: LogRecord[],\n options: { sessionKey: string | null; excludeMessageId?: string },\n): string | undefined {\n return selectExistingSessionSyncMessages(records, options).at(-1)?.message.ts;\n}\n\nfunction isRenderableConversationMessage(\n message: ConversationLogMessage,\n excludeMessageId?: string,\n): boolean {\n if (excludeMessageId && message.ts === excludeMessageId) return false;\n if (isChatCommandMessage(message)) return false;\n return !!message.text?.trim();\n}\n\nfunction isChatCommandMessage(message: ConversationLogMessage): boolean {\n return !message.isMessagingBot && isCommandText(message.text ?? \"\");\n}\n\nfunction dedupeAndSortRecords(records: LogRecord[]): LogRecord[] {\n const byKey = new Map<string, LogRecord>();\n for (const record of records) {\n byKey.set(record.message.ts ?? `line:${record.index}`, record);\n }\n\n return Array.from(byKey.values()).toSorted((a, b) => {\n const aTime = sortTime(a);\n const bTime = sortTime(b);\n if (aTime !== bTime) return aTime - bTime;\n return a.index - b.index;\n });\n}\n\nfunction sortTime(record: LogRecord): number {\n if (record.message.date) {\n const dateMs = new Date(record.message.date).getTime();\n if (Number.isFinite(dateMs)) return dateMs;\n }\n\n if (record.message.ts) {\n const tsMs = Number(record.message.ts) * 1000;\n if (Number.isFinite(tsMs)) return tsMs;\n }\n\n return record.index;\n}\n\nfunction bootstrapSessionFromLog(\n sessionFile: string,\n cwd: string,\n records: LogRecord[],\n lastMessageId = records.at(-1)?.message.ts,\n): void {\n if (records.length === 0 && !lastMessageId) return;\n\n const sessionManager = openManagedSession(sessionFile, cwd);\n appendLogRecordsToSession(sessionManager, records);\n sessionManager.appendCustomEntry(CHAT_SYNC_CUSTOM_TYPE, {\n source: \"log.jsonl\",\n messageCount: records.length,\n lastMessageId,\n });\n}\n\ninterface HistoryWindow {\n recentDays: number;\n maxMessages: number;\n now: Date;\n}\n\nfunction syncSessionFromLog(\n sessionFile: string,\n cwd: string,\n records: LogRecord[],\n historyWindow: HistoryWindow,\n): void {\n if (records.length === 0) return;\n syncSessionManagerFromLog(openManagedSession(sessionFile, cwd), records, historyWindow);\n}\n\nfunction syncSessionManagerFromLog(\n sessionManager: SessionStore,\n records: LogRecord[],\n historyWindow: HistoryWindow,\n): void {\n if (records.length === 0) return;\n\n const existingEntries = sessionManager.getEntries();\n const lastSyncedMessageId = getLatestChatSyncMessageId(existingEntries);\n const lastSyncedIndex = lastSyncedMessageId\n ? records.findIndex((record) => record.message.ts === lastSyncedMessageId)\n : -1;\n if (lastSyncedMessageId && lastSyncedIndex === -1) return;\n\n const syncCandidates = selectRecentMessages(records.slice(lastSyncedIndex + 1), historyWindow);\n if (syncCandidates.length === 0) return;\n\n const represented = buildRepresentedMessageCounts(existingEntries);\n const newRecords = syncCandidates.filter(\n (record) => !consumeRepresentedLogMessage(record, represented),\n );\n if (newRecords.length === 0) return;\n\n appendLogRecordsToSession(sessionManager, newRecords);\n sessionManager.appendCustomEntry(CHAT_SYNC_CUSTOM_TYPE, {\n source: \"log.jsonl\",\n messageCount: newRecords.length,\n lastMessageId: syncCandidates.at(-1)?.message.ts,\n });\n}\n\nfunction appendLogRecordsToSession(sessionManager: SessionStore, records: LogRecord[]): void {\n for (const record of records) {\n const message = buildHistorySessionMessage(record.message);\n if (message) sessionManager.appendMessage(message);\n }\n}\n\nfunction getLatestChatSyncMessageId(entries: SessionEntry[]): string | undefined {\n for (let i = entries.length - 1; i >= 0; i--) {\n const entry = entries[i];\n if (entry.type !== \"custom\" || entry.customType !== CHAT_SYNC_CUSTOM_TYPE) continue;\n if (!isRecord(entry.data)) return undefined;\n return typeof entry.data.lastMessageId === \"string\" ? entry.data.lastMessageId : undefined;\n }\n return undefined;\n}\n\nfunction buildRepresentedMessageCounts(entries: SessionEntry[]): Map<string, number> {\n const counts = new Map<string, number>();\n for (const entry of entries) {\n const comparable = comparableSessionMessage(entry);\n if (!comparable) continue;\n counts.set(comparable, (counts.get(comparable) ?? 0) + 1);\n }\n return counts;\n}\n\nfunction consumeRepresentedLogMessage(record: LogRecord, counts: Map<string, number>): boolean {\n const comparable = comparableLogMessage(record.message);\n if (!comparable) return false;\n\n const count = counts.get(comparable) ?? 0;\n if (count <= 0) return false;\n counts.set(comparable, count - 1);\n return true;\n}\n\nfunction comparableSessionMessage(entry: SessionEntry): string | null {\n if (entry.type !== \"message\") return null;\n const role = entry.message.role;\n if (role !== \"user\" && role !== \"assistant\") return null;\n\n const text = normalizeComparableText(getSessionMessageText(entry));\n if (!text) return null;\n return `${role}:${text}`;\n}\n\nfunction comparableLogMessage(message: ConversationLogMessage): string | null {\n const text = message.text?.trim();\n if (!text) return null;\n return `${message.isMessagingBot ? \"assistant\" : \"user\"}:${normalizeComparableText(text)}`;\n}\n\nfunction getSessionMessageText(entry: SessionEntry): string {\n if (entry.type !== \"message\" || !(\"content\" in entry.message)) return \"\";\n const content = entry.message.content;\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n return content\n .map((part) => (part.type === \"text\" && \"text\" in part ? part.text : \"\"))\n .join(\"\\n\");\n}\n\nconst normalizeComparableText = stripHistoryLinePrefix;\n\nfunction buildHistorySessionMessage(message: ConversationLogMessage): SessionAppendMessage | null {\n const text = message.text?.trim();\n if (!text) return null;\n\n const timestamp = parseMessageTimestamp(message);\n if (!message.isMessagingBot) {\n return {\n role: \"user\",\n content: [{ type: \"text\", text: formatHistoryMessage(message) }],\n ...(timestamp !== undefined ? { timestamp } : {}),\n } as SessionAppendMessage;\n }\n\n return {\n role: \"assistant\",\n content: [{ type: \"text\", text }],\n api: \"platform-history\",\n provider: \"platform-history\",\n model: \"platform-history\",\n usage: zeroUsage(),\n stopReason: \"stop\",\n ...(timestamp !== undefined ? { timestamp } : {}),\n } as SessionAppendMessage;\n}\n\nfunction buildThreadRootSeed(\n message: ConversationLogMessage | undefined,\n): ThreadRootMessage | null {\n if (!message) return null;\n return {\n text: message.text,\n userName: message.userName,\n user: message.user,\n loggedAt: message.date ? new Date(message.date).getTime() : undefined,\n isMessagingBot: message.isMessagingBot,\n };\n}\n\nfunction parseMessageTimestamp(message: ConversationLogMessage): number | undefined {\n if (message.date) {\n const dateMs = new Date(message.date).getTime();\n if (Number.isFinite(dateMs)) return dateMs;\n }\n\n if (message.ts) {\n const tsMs = Number(message.ts) * 1000;\n if (Number.isFinite(tsMs)) return tsMs;\n }\n\n return undefined;\n}\n\nfunction formatHistoryMessage(message: ConversationLogMessage): string {\n return formatHistoryLine({\n date: message.date ? new Date(message.date) : undefined,\n userName: message.userName || message.user,\n text: message.text?.trim() ?? \"\",\n });\n}\n\nfunction zeroUsage(): object {\n return {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n totalTokens: 0,\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n };\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AgentTool } from "@earendil-works/pi-agent-core";
|
|
2
|
+
import type { Api, Model } from "@earendil-works/pi-ai";
|
|
3
|
+
declare const schema: import("@sinclair/typebox").TObject<{
|
|
4
|
+
prompt: import("@sinclair/typebox").TString;
|
|
5
|
+
size: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
6
|
+
quality: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
7
|
+
}>;
|
|
8
|
+
export declare function createGenerateImageTool(options: {
|
|
9
|
+
model: Model<Api>;
|
|
10
|
+
getApiKey: () => Promise<string | undefined>;
|
|
11
|
+
workspaceDir: string;
|
|
12
|
+
}): {
|
|
13
|
+
tool: AgentTool<typeof schema>;
|
|
14
|
+
setUploadFunction: (fn: (filePath: string, title?: string) => Promise<void>) => void;
|
|
15
|
+
};
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=generate-image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-image.d.ts","sourceRoot":"","sources":["../../src/tools/generate-image.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAMxD,QAAA,MAAM,MAAM;;;;EAMV,CAAC;AAOH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE;IAC/C,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,SAAS,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC7C,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG;IACF,IAAI,EAAE,SAAS,CAAC,OAAO,MAAM,CAAC,CAAC;IAC/B,iBAAiB,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;CACtF,CA2DA"}
|