mirror of
https://github.com/sortedcord/omnia.git
synced 2026-07-22 12:02:49 +05:30
refactor: Remove serializer and polymorphed forms from AttributableObject AC in favor of generic helper function
1. Decoupled Attributes Serialization:
• Removed all serialize() methods from AttributableObject
(attribute.ts), WorldState (world.ts), and Entity (entity.ts).
• Implemented a standalone, uncoupled function
serializeAttributes(attributes: Attribute[]): string in attribute.ts.
This function receives an array of attributes and outputs their
formatted
representation.
2. System Objective Serializer:
• Implemented serializeObjectiveWorldState(worldState:
WorldState): string in world.ts for system LLMs that need objective
reality dumps (e.g. validators and intent decoders). It manually
retrieves and formats attributes using serializeAttributes()
alongside class-specific fields like locationId .
3. System prompt updates:
• Updated LLMValidator (llm-validator.ts), TimeDeltaGenerator
(delta.ts), and IntentDecoder (intent-decoder.ts) to use the new
standalone serializeObjectiveWorldState(worldState) helper imported
from @omnia/core .
4. Unit Tests (Tier 1):
• Updated core.test.ts to verify serializeAttributes and
serializeObjectiveWorldState utilities directly.
This commit is contained in:
@@ -112,14 +112,14 @@ export abstract class AttributableObject implements IAttribute {
|
||||
attr.hasAccess(viewerId),
|
||||
);
|
||||
}
|
||||
|
||||
serialize(): string {
|
||||
const lines: string[] = [];
|
||||
for (const [name, attr] of this.attributes.entries()) {
|
||||
const aclList = Array.from(attr.getAllowedEntities());
|
||||
const aclStr = aclList.length > 0 ? ` (Visible to: ${aclList.join(", ")})` : "";
|
||||
lines.push(`* ${name}: ${attr.getValue()} (Visibility: ${attr.getVisibility()})${aclStr}`);
|
||||
}
|
||||
return lines.join("\n");
|
||||
}
|
||||
}
|
||||
|
||||
export function serializeAttributes(attributes: Attribute[]): string {
|
||||
const lines: string[] = [];
|
||||
for (const attr of attributes) {
|
||||
const aclList = Array.from(attr.getAllowedEntities());
|
||||
const aclStr = aclList.length > 0 ? ` (Visible to: ${aclList.join(", ")})` : "";
|
||||
lines.push(`* ${attr.name}: ${attr.getValue()} (Visibility: ${attr.getVisibility()})${aclStr}`);
|
||||
}
|
||||
return lines.join("\n");
|
||||
}
|
||||
|
||||
@@ -7,16 +7,4 @@ export class Entity extends AttributableObject {
|
||||
super(id);
|
||||
this.locationId = locationId ?? null;
|
||||
}
|
||||
|
||||
override serialize(): string {
|
||||
const lines: string[] = [];
|
||||
if (this.locationId) {
|
||||
lines.push(`* Location ID: ${this.locationId}`);
|
||||
}
|
||||
const selfSerialized = super.serialize();
|
||||
if (selfSerialized) {
|
||||
lines.push(selfSerialized);
|
||||
}
|
||||
return lines.join("\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AttributableObject } from "./attribute.js";
|
||||
import { AttributableObject, serializeAttributes } from "./attribute.js";
|
||||
import { Entity } from "./entity.js";
|
||||
import { WorldClock } from "./clock.js";
|
||||
|
||||
@@ -27,33 +27,40 @@ export class WorldState extends AttributableObject {
|
||||
getEntity(id: string): Entity | undefined {
|
||||
return this.entities.get(id);
|
||||
}
|
||||
|
||||
override serialize(): string {
|
||||
const lines: string[] = [];
|
||||
|
||||
// 1. Serialize self attributes (world attributes)
|
||||
const selfSerialized = super.serialize();
|
||||
if (selfSerialized) {
|
||||
lines.push("World Attributes:");
|
||||
lines.push(selfSerialized.split("\n").map(l => " " + l).join("\n"));
|
||||
}
|
||||
|
||||
// 2. Serialize entities
|
||||
lines.push("Entities:");
|
||||
if (this.entities.size > 0) {
|
||||
for (const entity of this.entities.values()) {
|
||||
lines.push(` - Entity [ID: ${entity.id}]:`);
|
||||
const entitySerialized = entity.serialize();
|
||||
if (entitySerialized) {
|
||||
lines.push(entitySerialized.split("\n").map(l => " " + l).join("\n"));
|
||||
} else {
|
||||
lines.push(" * (No attributes)");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lines.push(" (No entities)");
|
||||
}
|
||||
|
||||
return lines.join("\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Objective world state serializer for system LLM tasks.
|
||||
* Bypasses epistemic privacy bounds for system/physics validation.
|
||||
*/
|
||||
export function serializeObjectiveWorldState(worldState: WorldState): string {
|
||||
const lines: string[] = [];
|
||||
|
||||
// Serialize world attributes
|
||||
if (worldState.attributes.size > 0) {
|
||||
lines.push("World Attributes:");
|
||||
const worldAttrsStr = serializeAttributes(Array.from(worldState.attributes.values()));
|
||||
lines.push(worldAttrsStr.split("\n").map(l => " " + l).join("\n"));
|
||||
}
|
||||
|
||||
// Serialize entities and their attributes
|
||||
lines.push("Entities:");
|
||||
if (worldState.entities.size > 0) {
|
||||
for (const entity of worldState.entities.values()) {
|
||||
lines.push(` - Entity [ID: ${entity.id}]:`);
|
||||
if (entity.locationId) {
|
||||
lines.push(` * Location ID: ${entity.locationId}`);
|
||||
}
|
||||
if (entity.attributes.size > 0) {
|
||||
const entityAttrsStr = serializeAttributes(Array.from(entity.attributes.values()));
|
||||
lines.push(entityAttrsStr.split("\n").map(l => " " + l).join("\n"));
|
||||
} else {
|
||||
lines.push(" * (No attributes)");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lines.push(" (No entities)");
|
||||
}
|
||||
|
||||
return lines.join("\n");
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import {
|
||||
WorldClock,
|
||||
WorldState,
|
||||
SQLiteRepository,
|
||||
serializeAttributes,
|
||||
serializeObjectiveWorldState,
|
||||
} from "@omnia/core";
|
||||
|
||||
// A concrete implementation of AttributableObject for testing
|
||||
@@ -171,18 +173,18 @@ describe("SQLiteRepository Unit Tests (Tier 1)", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("Serializer Unit Tests (Tier 1)", () => {
|
||||
test("AttributableObject serialization", () => {
|
||||
describe("Serializer & serializeObjectiveWorldState Unit Tests (Tier 1)", () => {
|
||||
test("serializeAttributes utility", () => {
|
||||
const obj = new MockAttributable("obj-1");
|
||||
obj.addAttribute("health", "100", AttributeVisibility.PUBLIC);
|
||||
obj.addAttribute("secret", "key-123", AttributeVisibility.PRIVATE, new Set(["alice"]));
|
||||
|
||||
const result = obj.serialize();
|
||||
const result = serializeAttributes(Array.from(obj.attributes.values()));
|
||||
expect(result).toContain("* health: 100 (Visibility: PUBLIC)");
|
||||
expect(result).toContain("* secret: key-123 (Visibility: PRIVATE) (Visible to: alice)");
|
||||
});
|
||||
|
||||
test("WorldState serialization", () => {
|
||||
test("serializeObjectiveWorldState utility", () => {
|
||||
const world = new WorldState("world-1");
|
||||
world.addAttribute("gravity", "9.8", AttributeVisibility.PUBLIC);
|
||||
|
||||
@@ -193,7 +195,7 @@ describe("Serializer Unit Tests (Tier 1)", () => {
|
||||
const bob = new Entity("bob"); // no attributes
|
||||
world.addEntity(bob);
|
||||
|
||||
const result = world.serialize();
|
||||
const result = serializeObjectiveWorldState(world);
|
||||
expect(result).toContain("World Attributes:");
|
||||
expect(result).toContain(" * gravity: 9.8 (Visibility: PUBLIC)");
|
||||
expect(result).toContain("Entities:");
|
||||
|
||||
Reference in New Issue
Block a user