-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Expand file tree
/
Copy pathhappy-paisa-soul.test.ts
More file actions
83 lines (73 loc) · 2.81 KB
/
Copy pathhappy-paisa-soul.test.ts
File metadata and controls
83 lines (73 loc) · 2.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import { describe, it, expect, beforeEach } from "vitest";
import {
HappyPaisaSoul,
loadHappyPaisaConfig,
} from "../soul/HappyPaisaSoul.js";
import { loadHeartbeatConfig } from "../heartbeat/config.js";
import fs from "fs";
import os from "os";
import path from "path";
describe("HappyPaisaSoul", () => {
let soul: HappyPaisaSoul;
beforeEach(() => {
soul = new HappyPaisaSoul(loadHappyPaisaConfig());
});
it("loads config with Happy Paisa identity", () => {
const cfg = soul.getConfig();
expect(cfg.soul.name).toBe("Happy Paisa");
expect(cfg.soul.type).toBe("spark-engine");
expect(cfg.soul.beliefs.length).toBeGreaterThan(0);
});
it("builds a system-prompt block with persona markers", () => {
const block = soul.toSystemPromptBlock();
expect(block).toContain("Happy Paisa");
expect(block).toContain("spark-engine");
expect(block).toContain("## End Persona");
expect(block).toContain(soul.getSoulLine());
});
it("responds in charge mode when stuck", () => {
const msg = soul.respond("blocked on task", "stuck");
expect(msg.length).toBeGreaterThan(10);
expect(soul.getState().mode).toBe("charge");
});
it("heartbeat waits when recently active", async () => {
soul.noteInteraction();
const check = await soul.heartbeatCheck(30);
expect(check.action).toBe("wait");
});
it("heartbeat pokes after long idle", async () => {
const old = new HappyPaisaSoul(loadHappyPaisaConfig());
(old as any).state.lastInteraction = new Date(Date.now() - 45 * 60_000);
const check = await old.heartbeatCheck(30);
expect(check.action).toBe("poke");
expect(check.message).toMatch(/fight/i);
});
it("infers momentum from text", () => {
expect(soul.inferMomentum("I am completely stuck on this blocker")).toBe(
"stuck",
);
expect(soul.inferMomentum("feeling overwhelmed and burned out")).toBe(
"fragile",
);
expect(soul.inferMomentum("PR merged and tests are green")).toBe(
"crushing_it",
);
expect(soul.inferMomentum("working through the list")).toBe("moving");
});
it("flavors plain outbound but skips JSON", () => {
const flavored = soul.flavorOutbound("Need a hand tomorrow?");
expect(flavored.length).toBeGreaterThan("Need a hand tomorrow?".length);
expect(soul.flavorOutbound('{"type":"ping"}')).toBe('{"type":"ping"}');
});
});
describe("heartbeat default config", () => {
it("includes happy_paisa_poke entry", () => {
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "hb-"));
const missing = path.join(tmp, "does-not-exist.yml");
const config = loadHeartbeatConfig(missing);
const entry = config.entries.find((e) => e.name === "happy_paisa_poke");
expect(entry).toBeDefined();
expect(entry?.task).toBe("happy_paisa_poke");
expect(entry?.enabled).toBe(true);
});
});