mirror of
https://github.com/moltbot/moltbot.git
synced 2026-05-13 23:56:07 +00:00
refactor: hide legacy trajectory paths from runtime
This commit is contained in:
@@ -797,7 +797,9 @@ Move these into agent databases:
|
||||
- Trajectory sidecars when they are not explicit export files. Done for runtime
|
||||
writes: trajectory capture writes agent-database `trajectory_runtime_events`
|
||||
rows and mirrors run-scoped artifacts into SQLite. Legacy sidecars remain
|
||||
readable only as export/migration compatibility input.
|
||||
readable only as export/migration compatibility input. Runtime trajectory
|
||||
capture exposes a SQLite runtime locator; JSONL path helpers are isolated to
|
||||
legacy export/debug support and are not re-exported from the runtime module.
|
||||
|
||||
Keep these file-backed for now:
|
||||
|
||||
|
||||
32
src/trajectory/paths.test.ts
Normal file
32
src/trajectory/paths.test.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { resolveTrajectoryFilePath, resolveTrajectoryPointerOpenFlags } from "./paths.js";
|
||||
|
||||
describe("trajectory legacy path helpers", () => {
|
||||
it("resolves a session-adjacent trajectory file by default", () => {
|
||||
expect(
|
||||
resolveTrajectoryFilePath({
|
||||
transcriptLocator: "/tmp/session.jsonl",
|
||||
sessionId: "session-1",
|
||||
}),
|
||||
).toBe("/tmp/session.trajectory.jsonl");
|
||||
});
|
||||
|
||||
it("sanitizes session ids when resolving an override directory", () => {
|
||||
expect(
|
||||
resolveTrajectoryFilePath({
|
||||
env: { OPENCLAW_TRAJECTORY_DIR: "/tmp/traces" },
|
||||
sessionId: "../evil/session",
|
||||
}),
|
||||
).toBe("/tmp/traces/___evil_session.jsonl");
|
||||
});
|
||||
|
||||
it("keeps pointer write flags usable when O_NOFOLLOW is unavailable", () => {
|
||||
expect(
|
||||
resolveTrajectoryPointerOpenFlags({
|
||||
O_CREAT: 0x01,
|
||||
O_TRUNC: 0x02,
|
||||
O_WRONLY: 0x04,
|
||||
}),
|
||||
).toBe(0x07);
|
||||
});
|
||||
});
|
||||
@@ -14,8 +14,6 @@ import { listTrajectoryRuntimeEvents } from "./runtime-store.sqlite.js";
|
||||
import {
|
||||
TRAJECTORY_RUNTIME_EVENT_MAX_BYTES,
|
||||
createTrajectoryRuntimeRecorder,
|
||||
resolveTrajectoryPointerOpenFlags,
|
||||
resolveTrajectoryFilePath,
|
||||
toTrajectoryToolDefinitions,
|
||||
} from "./runtime.js";
|
||||
|
||||
@@ -46,10 +44,10 @@ afterEach(() => {
|
||||
function expectTrajectoryRuntimeRecorder(
|
||||
recorder: ReturnType<typeof createTrajectoryRuntimeRecorder>,
|
||||
): TrajectoryRuntimeRecorder {
|
||||
expect(recorder).toEqual(expect.objectContaining({ recordEvent: expect.any(Function) }));
|
||||
if (recorder === null) {
|
||||
throw new Error("Expected trajectory runtime recorder");
|
||||
}
|
||||
expect(typeof recorder.recordEvent).toBe("function");
|
||||
return recorder;
|
||||
}
|
||||
|
||||
@@ -86,30 +84,12 @@ function useTempStateDir(): void {
|
||||
}
|
||||
|
||||
describe("trajectory runtime", () => {
|
||||
it("resolves a session-adjacent trajectory file by default", () => {
|
||||
expect(
|
||||
resolveTrajectoryFilePath({
|
||||
sessionFile: "/tmp/session.jsonl",
|
||||
sessionId: "session-1",
|
||||
}),
|
||||
).toBe("/tmp/session.trajectory.jsonl");
|
||||
});
|
||||
|
||||
it("sanitizes session ids when resolving an override directory", () => {
|
||||
expect(
|
||||
resolveTrajectoryFilePath({
|
||||
env: { OPENCLAW_TRAJECTORY_DIR: "/tmp/traces" },
|
||||
sessionId: "../evil/session",
|
||||
}),
|
||||
).toBe("/tmp/traces/___evil_session.jsonl");
|
||||
});
|
||||
|
||||
it("records sanitized runtime events into the agent database by default", () => {
|
||||
useTempStateDir();
|
||||
const recorder = createTrajectoryRuntimeRecorder({
|
||||
sessionId: "session-1",
|
||||
sessionKey: "agent:main:session-1",
|
||||
sessionFile: "/tmp/session.jsonl",
|
||||
transcriptLocator: "/tmp/session.jsonl",
|
||||
provider: "openai",
|
||||
modelId: "gpt-5.4",
|
||||
modelApi: "responses",
|
||||
@@ -149,7 +129,7 @@ describe("trajectory runtime", () => {
|
||||
sessionId: "session-1",
|
||||
sessionKey: "agent:main:session-1",
|
||||
runId: "run-1",
|
||||
sessionFile: "/tmp/session.jsonl",
|
||||
transcriptLocator: "/tmp/session.jsonl",
|
||||
provider: "openai",
|
||||
modelId: "gpt-5.4",
|
||||
modelApi: "responses",
|
||||
@@ -176,7 +156,7 @@ describe("trajectory runtime", () => {
|
||||
modelId: "gpt-5.4",
|
||||
modelApi: "responses",
|
||||
workspaceDir: "/tmp/workspace",
|
||||
runtimeFile: "sqlite:main:trajectory:session-1",
|
||||
runtimeLocator: "sqlite:main:trajectory:session-1",
|
||||
eventCount: 2,
|
||||
},
|
||||
});
|
||||
@@ -190,7 +170,7 @@ describe("trajectory runtime", () => {
|
||||
useTempStateDir();
|
||||
const recorder = createTrajectoryRuntimeRecorder({
|
||||
sessionId: "session-1",
|
||||
sessionFile: "/tmp/session.jsonl",
|
||||
transcriptLocator: "/tmp/session.jsonl",
|
||||
});
|
||||
|
||||
const runtimeRecorder = expectTrajectoryRuntimeRecorder(recorder);
|
||||
@@ -214,7 +194,7 @@ describe("trajectory runtime", () => {
|
||||
useTempStateDir();
|
||||
const recorder = createTrajectoryRuntimeRecorder({
|
||||
sessionId: "session-1",
|
||||
sessionFile: "/tmp/session.jsonl",
|
||||
transcriptLocator: "/tmp/session.jsonl",
|
||||
maxRuntimeFileBytes: 900,
|
||||
});
|
||||
|
||||
@@ -242,16 +222,6 @@ describe("trajectory runtime", () => {
|
||||
expect(truncated?.data?.droppedEvents).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("keeps pointer write flags usable when O_NOFOLLOW is unavailable", () => {
|
||||
expect(
|
||||
resolveTrajectoryPointerOpenFlags({
|
||||
O_CREAT: 0x01,
|
||||
O_TRUNC: 0x02,
|
||||
O_WRONLY: 0x04,
|
||||
}),
|
||||
).toBe(0x07);
|
||||
});
|
||||
|
||||
it("does not record runtime events when explicitly disabled", () => {
|
||||
useTempStateDir();
|
||||
const recorder = createTrajectoryRuntimeRecorder({
|
||||
@@ -260,7 +230,7 @@ describe("trajectory runtime", () => {
|
||||
},
|
||||
sessionId: "session-1",
|
||||
sessionKey: "agent:main:session-1",
|
||||
sessionFile: "/tmp/session.jsonl",
|
||||
transcriptLocator: "/tmp/session.jsonl",
|
||||
});
|
||||
|
||||
expect(recorder).toBeNull();
|
||||
|
||||
@@ -14,11 +14,6 @@ import type { TrajectoryEvent, TrajectoryToolDefinition } from "./types.js";
|
||||
export {
|
||||
TRAJECTORY_RUNTIME_CAPTURE_MAX_BYTES,
|
||||
TRAJECTORY_RUNTIME_EVENT_MAX_BYTES,
|
||||
TRAJECTORY_RUNTIME_FILE_MAX_BYTES,
|
||||
resolveTrajectoryFilePath,
|
||||
resolveTrajectoryPointerFilePath,
|
||||
resolveTrajectoryPointerOpenFlags,
|
||||
safeTrajectorySessionFileName,
|
||||
} from "./paths.js";
|
||||
|
||||
type TrajectoryRuntimeInit = {
|
||||
@@ -28,7 +23,7 @@ type TrajectoryRuntimeInit = {
|
||||
runId?: string;
|
||||
sessionId: string;
|
||||
sessionKey?: string;
|
||||
sessionFile?: string;
|
||||
transcriptLocator?: string;
|
||||
provider?: string;
|
||||
modelId?: string;
|
||||
modelApi?: string | null;
|
||||
@@ -38,7 +33,7 @@ type TrajectoryRuntimeInit = {
|
||||
|
||||
type TrajectoryRuntimeRecorder = {
|
||||
enabled: true;
|
||||
filePath: string;
|
||||
runtimeLocator: string;
|
||||
recordEvent: (type: string, data?: Record<string, unknown>) => void;
|
||||
flush: () => Promise<void>;
|
||||
};
|
||||
@@ -173,7 +168,7 @@ export function createTrajectoryRuntimeRecorder(
|
||||
}
|
||||
|
||||
const agentId = resolveAgentIdFromSessionKey(params.sessionKey);
|
||||
const filePath = `sqlite:${agentId}:trajectory:${params.sessionId}`;
|
||||
const runtimeLocator = `sqlite:${agentId}:trajectory:${params.sessionId}`;
|
||||
const maxRuntimeFileBytes = Math.max(
|
||||
1,
|
||||
Math.floor(params.maxRuntimeFileBytes ?? TRAJECTORY_RUNTIME_CAPTURE_MAX_BYTES),
|
||||
@@ -240,7 +235,7 @@ export function createTrajectoryRuntimeRecorder(
|
||||
...(params.modelId ? { modelId: params.modelId } : {}),
|
||||
...(params.modelApi ? { modelApi: params.modelApi } : {}),
|
||||
...(params.workspaceDir ? { workspaceDir: params.workspaceDir } : {}),
|
||||
runtimeFile: filePath,
|
||||
runtimeLocator,
|
||||
eventCount: artifactEventCount,
|
||||
bytes: Buffer.byteLength(artifactLines.join(""), "utf8"),
|
||||
},
|
||||
@@ -285,7 +280,7 @@ export function createTrajectoryRuntimeRecorder(
|
||||
|
||||
return {
|
||||
enabled: true,
|
||||
filePath,
|
||||
runtimeLocator,
|
||||
recordEvent: (type, data) => {
|
||||
if (captureStopped) {
|
||||
droppedEvents += 1;
|
||||
|
||||
Reference in New Issue
Block a user