feat: Implemented primitive intent pipline (closes #7)

This commit is contained in:
2026-07-06 22:43:09 +05:30
parent 72b87c40bc
commit f7177b619b
11 changed files with 388 additions and 8 deletions

View File

@@ -0,0 +1,123 @@
import { describe, test, expect } from "vitest";
import { WorldState, Entity } from "@omnia/core";
import { MockLLMProvider } from "@omnia/llm";
import { IntentDecoder, IntentSequence } from "@omnia/intent";
describe("IntentDecoder Unit Tests (Tier 1)", () => {
test("decodes prose with a single action intent", async () => {
const world = new WorldState("world-1");
const alice = new Entity("alice");
world.addEntity(alice);
const mockResponse: IntentSequence = {
intents: [
{
type: "action",
originalText: "Alice opened the chest.",
description: "Open the wooden chest.",
actorId: "alice",
targetIds: [],
},
],
};
const llm = new MockLLMProvider([mockResponse]);
const decoder = new IntentDecoder(llm);
const result = await decoder.decode(world, "alice", "Alice opened the chest.");
expect(result.intents).toHaveLength(1);
expect(result.intents[0].type).toBe("action");
expect(result.intents[0].actorId).toBe("alice");
expect(result.intents[0].targetIds).toEqual([]);
});
test("decodes prose with a single dialogue intent", async () => {
const world = new WorldState("world-1");
const alice = new Entity("alice");
const bob = new Entity("bob");
world.addEntity(alice);
world.addEntity(bob);
const mockResponse: IntentSequence = {
intents: [
{
type: "dialogue",
originalText: '"Do you have the key?" Alice asked Bob.',
description: "Alice asks Bob if he has the key.",
actorId: "alice",
targetIds: ["bob"],
},
],
};
const llm = new MockLLMProvider([mockResponse]);
const decoder = new IntentDecoder(llm);
const result = await decoder.decode(
world,
"alice",
'"Do you have the key?" Alice asked Bob.',
);
expect(result.intents).toHaveLength(1);
expect(result.intents[0].type).toBe("dialogue");
expect(result.intents[0].targetIds).toEqual(["bob"]);
});
test("decodes prose with mixed dialogue and action intents", async () => {
const world = new WorldState("world-1");
const alice = new Entity("alice");
const bob = new Entity("bob");
world.addEntity(alice);
world.addEntity(bob);
const mockResponse: IntentSequence = {
intents: [
{
type: "dialogue",
originalText: '"Cover me," Alice whispered to Bob.',
description: "Alice whispers to Bob requesting cover.",
actorId: "alice",
targetIds: ["bob"],
},
{
type: "action",
originalText: "She crept towards the door and pulled the handle.",
description: "Creep towards the door and pull the handle.",
actorId: "alice",
targetIds: [],
},
],
};
const llm = new MockLLMProvider([mockResponse]);
const decoder = new IntentDecoder(llm);
const result = await decoder.decode(
world,
"alice",
'"Cover me," Alice whispered to Bob. She crept towards the door and pulled the handle.',
);
expect(result.intents).toHaveLength(2);
expect(result.intents[0].type).toBe("dialogue");
expect(result.intents[0].targetIds).toEqual(["bob"]);
expect(result.intents[1].type).toBe("action");
expect(result.intents[1].actorId).toBe("alice");
});
test("throws on LLM failure", async () => {
const world = new WorldState("world-1");
const alice = new Entity("alice");
world.addEntity(alice);
// MockLLMProvider with empty queue will return { success: false }
const llm = new MockLLMProvider([]);
const decoder = new IntentDecoder(llm);
await expect(
decoder.decode(world, "alice", "Alice ran away."),
).rejects.toThrow("Intent decoding failed");
});
});