UNPKG

@radcliffetech/symbolos-core

Version:

Core symbolic simulation and execution engine for Symbolos

335 lines (334 loc) 12.1 kB
it("records the correct outputId from a returned outputObject", async () => { const world = createWorld("test-output-id"); const pipelineArgs = createSymbolicObject("PipelineArgs", { params: {}, }); const steps = [ { id: "step-choice", purpose: "test output object tracking", functor: { id: "choice-functor", name: "ChoiceFunctor", method: "choose", inputType: "PipelineArgs", outputType: "WorldInstance", apply: async () => { const choice = createSymbolicObject("Choice", { id: "choice-1", rootId: "agent-123", tick: 1, }); world.artifacts.set("choice-1", choice); return { world, outputObject: choice, output: [choice], }; }, describeProvenance: () => ({ reason: "unit-test" }), }, tickAdvance: false, }, ]; const result = await runGen2WorldSimulation({ world, pipelineArgs, steps, simulatorConfig: { verbose: false }, }); const actions = Array.from(result.artifacts.values()).filter((o) => o.type === "SymbolicAction"); expect(actions.length).toBe(1); const action = actions[0]; expect(action.inputId).toBe("agent-123"); expect(action.outputId).toBe("choice-1"); expect(action.actorId).toBe("agent-123"); expect(action.transformationId).toBe("step-choice"); expect(action.instrumentId).toBe("choice-functor"); expect(action.purpose).toBe("test output object tracking"); expect(action.tick).toBe(0); }); import { createWorld, createWorldInstanceFromFrame, runGen2WorldSimulation, } from "./world-simulator"; import { describe, expect, it } from "vitest"; import { createSymbolicObject } from "../lib/object-factory"; import { forkWorld } from "./world-simulator"; it("forks a world and retains aonst pipelineArgs: Prtifacts and context", () => { const original = createWorld("fire-spread"); const obj = { id: "x", type: "Thing", createdAt: new Date().toISOString(), status: "active", }; original.artifacts.set("x", obj); const forked = forkWorld(original, { firebreak: true }); expect(forked.runId).not.toBe(original.runId); expect(forked.pipelineId).toBe("fire-spread"); expect(forked.artifacts.has("x")).toBe(true); expect(forked.context.forkedFromRunId).toBe(original.runId); expect(forked.context.pipelineArgs.params.firebreak).toBe(true); }); describe("world-simulator", () => { it("creates a new world with correct structure", () => { const world = createWorld("test-pipeline"); expect(world.tick).toBe(0); expect(world.pipelineId).toBe("test-pipeline"); expect(world.artifacts).toBeInstanceOf(Map); }); it("creates a world from frame with correct artifacts", () => { const mockFrame = { id: "frame-1", tick: 3, step: 2, runId: "abc", type: "WorldFrame", pipelineId: "mock-pipeline", createdAt: new Date().toISOString(), status: "active", members: [createSymbolicObject("MockObject", { id: "x", label: "X" })], }; const world = createWorldInstanceFromFrame({ frame: mockFrame, pipelineId: mockFrame.pipelineId, runId: mockFrame.runId, }); expect(world.tick).toBe(3); expect(world.artifacts.get("x")).toBeDefined(); expect(world.pipelineId).toBe("mock-pipeline"); }); it("runs a pipeline and stores output in artifacts", async () => { const world = createWorld("test"); const pipelineArgs = createSymbolicObject("PipelineArgs", { params: {}, }); const steps = [ { id: "step-1", purpose: "test-step", functor: { id: "mock-functor", name: "MockFunctor", method: "mock", inputType: "PipelineArgs", outputType: "MockResult", apply: async () => ({ id: "obj-1", type: "MockResult", createdAt: new Date().toISOString(), }), describeProvenance: () => ({ source: "test" }), }, }, ]; const result = await runGen2WorldSimulation({ world, pipelineArgs, steps, simulatorConfig: { verbose: false }, }); expect(result.tick).toBeGreaterThan(0); expect(result.artifacts.has("obj-1")).toBe(true); }); }); it("stores step output in context under expected key", async () => { const world = createWorld("test"); const pipelineArgs = createSymbolicObject("PipelineArgs", { params: {}, }); const steps = [ { id: "step-1", purpose: "store-context-test", functor: { id: "mock-store", name: "MockStoreFunctor", method: "mock-store", inputType: "PipelineArgs", outputType: "MockResult", apply: async () => ({ id: "mock-result", type: "MockResult", createdAt: new Date().toISOString(), }), describeProvenance: () => ({ source: "test" }), }, storeOutputAs: "Frame_t0", tickAdvance: false, }, ]; const result = await runGen2WorldSimulation({ world, pipelineArgs, steps, simulatorConfig: { verbose: false }, }); expect(result.context.Frame_t0).toBeDefined(); expect(result.context.Frame_t0).toMatchObject({ id: "mock-result" }); }); it("initializes tick, step, and artifacts correctly from frame", () => { const mockFrame = { id: "frame-x", tick: 7, step: 3, runId: "run-x", pipelineId: "pipeline-x", type: "WorldFrame", status: "active", createdAt: new Date().toISOString(), members: [ createSymbolicObject("TestObject", { id: "alpha" }), createSymbolicObject("TestObject", { id: "beta" }), ], }; const world = createWorldInstanceFromFrame({ frame: mockFrame, pipelineId: mockFrame.pipelineId, runId: mockFrame.runId, }); expect(world.tick).toBe(7); expect(world.step).toBe(3); expect(world.artifacts.size).toBe(2); expect(world.artifacts.get("alpha")?.type).toBe("TestObject"); expect(world.pipelineId).toBe("pipeline-x"); }); it("forks a world from a frame and retains pipelineId and forkedFromRunId", () => { const mockFrame = { id: "frame-a", tick: 5, step: 4, runId: "original-run", pipelineId: "mock-pipeline", type: "WorldFrame", status: "active", createdAt: new Date().toISOString(), members: [ createSymbolicObject("Thing", { id: "a" }), createSymbolicObject("Thing", { id: "b" }), ], }; const baseWorld = createWorldInstanceFromFrame({ frame: mockFrame, pipelineId: mockFrame.pipelineId, runId: mockFrame.runId, }); const forked = forkWorld(baseWorld, { firebreak: true }); expect(forked.pipelineId).toBe("mock-pipeline"); expect(forked.context.forkedFromRunId).toBe("original-run"); expect(forked.artifacts.has("a")).toBe(true); expect(forked.artifacts.has("b")).toBe(true); }); it("runs a different pipeline after forking and generates a distinct PipelineRun", async () => { const baseFrame = { id: "base-frame", tick: 2, step: 2, runId: "base-run", pipelineId: "starter-pipeline", type: "WorldFrame", status: "active", createdAt: new Date().toISOString(), members: [createSymbolicObject("BaseObject", { id: "x" })], }; const baseWorld = createWorldInstanceFromFrame({ frame: baseFrame, pipelineId: baseFrame.pipelineId, runId: baseFrame.runId, }); const forked = forkWorld(baseWorld, { alt: true }); const pipelineArgs = createSymbolicObject("PipelineArgs", { params: { alt: true, }, }); const steps = [ { id: "alt-step", purpose: "altered path", functor: { id: "alt-fn", name: "AltFunctor", method: "alt-method", inputType: "PipelineArgs", outputType: "AlteredResult", apply: async () => ({ id: "alt-result", type: "AlteredResult", createdAt: new Date().toISOString(), }), describeProvenance: () => ({ source: "fork-test" }), }, storeOutputAs: "AlteredOutput", }, ]; const result = await runGen2WorldSimulation({ world: forked, pipelineArgs, steps, simulatorConfig: { verbose: false }, }); const pipelineRuns = Array.from(result.artifacts.values()).filter((o) => o.type === "PipelineRun"); expect(pipelineRuns.length).toBe(1); expect(pipelineRuns[0].pipelineId).toBe("starter-pipeline"); expect(pipelineRuns[0].label).toMatch(/Forked Run/); }); it("creates multiple forks from a base world and runs separate pipelines", async () => { const baseFrame = { id: "frame-base", tick: 1, step: 1, runId: "original-run", pipelineId: "base-pipeline", type: "WorldFrame", status: "active", createdAt: new Date().toISOString(), members: [ createSymbolicObject("Symbol", { id: "a" }), createSymbolicObject("Symbol", { id: "b" }), ], }; const baseWorld = createWorldInstanceFromFrame({ frame: baseFrame, pipelineId: baseFrame.pipelineId, runId: baseFrame.runId, }); const results = await Promise.all(["fork-A", "fork-B", "fork-C"].map(async (label, index) => { const forked = forkWorld(baseWorld, { branch: label }); const pipelineArgs = createSymbolicObject("PipelineArgs", { params: { branch: label }, }); const steps = [ { id: `step-${label}`, purpose: `test fork ${label}`, functor: { id: `functor-${label}`, name: `Functor ${label}`, method: `method-${label}`, inputType: "PipelineArgs", outputType: "BranchResult", apply: async () => ({ id: `result-${label}`, type: "BranchResult", createdAt: new Date().toISOString(), }), describeProvenance: () => ({ source: `fork-${label}` }), }, storeOutputAs: `BranchOutput_${label}`, }, ]; const result = await runGen2WorldSimulation({ world: forked, pipelineArgs, steps, simulatorConfig: { verbose: false }, }); return result; })); expect(results.length).toBe(3); results.forEach((world, i) => { const branchResult = world.artifacts.get(`result-fork-${String.fromCharCode(65 + i)}`); expect(branchResult).toBeDefined(); expect(world.pipelineId).toBe("base-pipeline"); expect(world.context.forkedFromRunId).toBe("original-run"); }); });