tomo-ai 0.5.11 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/cli/start.js +4 -0
- package/dist/cli/start.js.map +1 -1
- package/dist/mcp/internal-server.d.ts.map +1 -1
- package/dist/mcp/internal-server.js +2 -0
- package/dist/mcp/internal-server.js.map +1 -1
- package/dist/mcp/pet-scheduler.d.ts +10 -0
- package/dist/mcp/pet-scheduler.d.ts.map +1 -0
- package/dist/mcp/pet-scheduler.js +53 -0
- package/dist/mcp/pet-scheduler.js.map +1 -0
- package/dist/mcp/pet-store.d.ts +30 -0
- package/dist/mcp/pet-store.d.ts.map +1 -0
- package/dist/mcp/pet-store.js +153 -0
- package/dist/mcp/pet-store.js.map +1 -0
- package/dist/mcp/pet-tools.d.ts +26 -0
- package/dist/mcp/pet-tools.d.ts.map +1 -0
- package/dist/mcp/pet-tools.js +262 -0
- package/dist/mcp/pet-tools.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.6.0 (2026-05-26)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- **Virtual pet companion** (#111). Tomo now has a pet that lives at `~/.tomo/data/pet.json`. Five MCP tools on `tomo-internal` let the agent interact with it: `pet_hatch` (name and species), `pet_status` (current mood and stats), `pet_feed`, `pet_play`, and `pet_sleep`. Stats (hunger, happiness, energy, health) decay over time; affection accumulates through interactions and drives evolution through six stages: egg → baby → child → teen → adult → elder. A `PetScheduler` runs inside the tomo process and ticks every hour — no cron job setup required. When the pet needs attention (hunger, health drop, evolution), the scheduler sends a notification via `agent.sendNotification()`.
|
|
8
|
+
|
|
3
9
|
## 0.5.11 (2026-05-26)
|
|
4
10
|
|
|
5
11
|
### Bug fixes
|
package/dist/cli/start.js
CHANGED
|
@@ -46,6 +46,7 @@ async function startForeground() {
|
|
|
46
46
|
const { TelegramChannel } = await import("../channels/index.js");
|
|
47
47
|
const { config } = await import("../config.js");
|
|
48
48
|
const { CronScheduler } = await import("../cron/scheduler.js");
|
|
49
|
+
const { PetScheduler } = await import("../mcp/pet-scheduler.js");
|
|
49
50
|
// Ensure directories exist (handles upgrades where new dirs were added)
|
|
50
51
|
const { mkdirSync } = await import("node:fs");
|
|
51
52
|
mkdirSync(join(TOMO_HOME, "workspace", "tmp"), { recursive: true });
|
|
@@ -113,6 +114,7 @@ async function startForeground() {
|
|
|
113
114
|
}));
|
|
114
115
|
}
|
|
115
116
|
const scheduler = new CronScheduler(agent);
|
|
117
|
+
const petScheduler = new PetScheduler(agent);
|
|
116
118
|
// Start continuity runner if enabled
|
|
117
119
|
const { ContinuityRunner } = await import("../continuity.js");
|
|
118
120
|
const continuity = new ContinuityRunner(agent, config.city);
|
|
@@ -133,6 +135,7 @@ async function startForeground() {
|
|
|
133
135
|
versionChecker.stop();
|
|
134
136
|
rollupRunner.stop();
|
|
135
137
|
continuity.stop();
|
|
138
|
+
petScheduler.stop();
|
|
136
139
|
scheduler.stop();
|
|
137
140
|
await agent.stop();
|
|
138
141
|
try {
|
|
@@ -145,6 +148,7 @@ async function startForeground() {
|
|
|
145
148
|
process.on("SIGTERM", shutdown);
|
|
146
149
|
await agent.start();
|
|
147
150
|
scheduler.start();
|
|
151
|
+
petScheduler.start();
|
|
148
152
|
}
|
|
149
153
|
async function startDaemon() {
|
|
150
154
|
const existing = getRunningPid();
|
package/dist/cli/start.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/cli/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;AAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AAE7C,SAAS,SAAS,CAAC,GAAW;IAC5B,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,aAAa;IACpB,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3D,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,UAAU,CAAC,QAAQ,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,YAAY,CAAC;KACzB,MAAM,CAAC,kBAAkB,EAAE,yCAAyC,CAAC;KACrE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,OAAO,eAAe,EAAE,CAAC;IAC3B,CAAC;IACD,OAAO,WAAW,EAAE,CAAC;AACvB,CAAC,CAAC,CAAC;AAEL,KAAK,UAAU,eAAe;IAC5B,6EAA6E;IAC7E,2EAA2E;IAC3E,sDAAsD;IACtD,MAAM,QAAQ,GAAG,aAAa,EAAE,CAAC;IACjC,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,gCAAgC,QAAQ,yCAAyC,CAAC,CAAC;QACjG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IAC9C,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;IACjE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;IAChD,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/cli/start.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal-server.d.ts","sourceRoot":"","sources":["../../src/mcp/internal-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,8BAA8B,EAAE,MAAM,gCAAgC,CAAC;AAG/G,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"internal-server.d.ts","sourceRoot":"","sources":["../../src/mcp/internal-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,8BAA8B,EAAE,MAAM,gCAAgC,CAAC;AAG/G,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAIzC,eAAO,MAAM,sBAAsB,kBAAkB,CAAC;AAEtD;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,KAAK,GAAG,8BAA8B,CAgKxF"}
|
|
@@ -2,6 +2,7 @@ import { createSdkMcpServer, tool } from "@anthropic-ai/claude-agent-sdk";
|
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { config } from "../config.js";
|
|
4
4
|
import { buildCronTools } from "./cron-tools.js";
|
|
5
|
+
import { buildPetTools } from "./pet-tools.js";
|
|
5
6
|
export const TOMO_INTERNAL_MCP_NAME = "tomo-internal";
|
|
6
7
|
/**
|
|
7
8
|
* In-process MCP server exposing tomo-internal tools to the agent.
|
|
@@ -123,6 +124,7 @@ export function createTomoInternalMcpServer(agent) {
|
|
|
123
124
|
searchHint: "react reaction tapback latest message telegram imessage bluebubbles like love laugh",
|
|
124
125
|
}),
|
|
125
126
|
...buildCronTools(),
|
|
127
|
+
...buildPetTools(),
|
|
126
128
|
],
|
|
127
129
|
});
|
|
128
130
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal-server.js","sourceRoot":"","sources":["../../src/mcp/internal-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,IAAI,EAAuC,MAAM,gCAAgC,CAAC;AAC/G,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"internal-server.js","sourceRoot":"","sources":["../../src/mcp/internal-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pet-scheduler.d.ts","sourceRoot":"","sources":["../../src/mcp/pet-scheduler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAIzC,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,KAAK,CAA+C;gBAEhD,KAAK,EAAE,KAAK;IAIxB,KAAK,IAAI,IAAI;IAMb,IAAI,IAAI,IAAI;IAQZ,OAAO,CAAC,IAAI;CAgCb"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { PetStore } from "./pet-store.js";
|
|
2
|
+
import { log } from "../logger.js";
|
|
3
|
+
const TICK_INTERVAL_MS = 60 * 60 * 1000; // 1 hour
|
|
4
|
+
export class PetScheduler {
|
|
5
|
+
agent;
|
|
6
|
+
timer = null;
|
|
7
|
+
constructor(agent) {
|
|
8
|
+
this.agent = agent;
|
|
9
|
+
}
|
|
10
|
+
start() {
|
|
11
|
+
log.info("Pet scheduler started");
|
|
12
|
+
this.tick();
|
|
13
|
+
this.timer = setInterval(() => this.tick(), TICK_INTERVAL_MS);
|
|
14
|
+
}
|
|
15
|
+
stop() {
|
|
16
|
+
if (this.timer) {
|
|
17
|
+
clearInterval(this.timer);
|
|
18
|
+
this.timer = null;
|
|
19
|
+
}
|
|
20
|
+
log.info("Pet scheduler stopped");
|
|
21
|
+
}
|
|
22
|
+
tick() {
|
|
23
|
+
const store = new PetStore();
|
|
24
|
+
let state = store.load();
|
|
25
|
+
if (!state)
|
|
26
|
+
return;
|
|
27
|
+
const prevStage = state.stage;
|
|
28
|
+
const prevHealth = Math.round(state.health);
|
|
29
|
+
state = store.tick(state);
|
|
30
|
+
store.save(state);
|
|
31
|
+
const alerts = [];
|
|
32
|
+
if (state.stage !== prevStage) {
|
|
33
|
+
alerts.push(`✨ ${state.name} evolved into a ${state.stage}!`);
|
|
34
|
+
}
|
|
35
|
+
if (state.hunger < 20) {
|
|
36
|
+
alerts.push(`${state.name} is hungry (hunger: ${Math.round(state.hunger)})`);
|
|
37
|
+
}
|
|
38
|
+
if (Math.round(state.health) < prevHealth - 5) {
|
|
39
|
+
alerts.push(`${state.name}'s health dropped to ${Math.round(state.health)}`);
|
|
40
|
+
}
|
|
41
|
+
if (state.happiness < 20) {
|
|
42
|
+
alerts.push(`${state.name} seems very unhappy`);
|
|
43
|
+
}
|
|
44
|
+
if (alerts.length > 0) {
|
|
45
|
+
const message = alerts.join("\n");
|
|
46
|
+
log.info({ pet: state.name }, "Pet alert: %s", message);
|
|
47
|
+
this.agent.sendNotification(message).catch((err) => {
|
|
48
|
+
log.warn({ err }, "Pet scheduler: failed to send notification");
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=pet-scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pet-scheduler.js","sourceRoot":"","sources":["../../src/mcp/pet-scheduler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type PetStage = "egg" | "baby" | "child" | "teen" | "adult" | "elder";
|
|
2
|
+
export type PetMood = "sleeping" | "blissful" | "happy" | "content" | "bored" | "sad" | "miserable" | "sick" | "hungry";
|
|
3
|
+
export interface PetState {
|
|
4
|
+
name: string;
|
|
5
|
+
species: string;
|
|
6
|
+
born_at: string;
|
|
7
|
+
stage: PetStage;
|
|
8
|
+
hunger: number;
|
|
9
|
+
happiness: number;
|
|
10
|
+
energy: number;
|
|
11
|
+
health: number;
|
|
12
|
+
affection: number;
|
|
13
|
+
sleeping: boolean;
|
|
14
|
+
sleep_until: string | null;
|
|
15
|
+
last_tick: string;
|
|
16
|
+
diary: string[];
|
|
17
|
+
}
|
|
18
|
+
export declare class PetStore {
|
|
19
|
+
private petPath;
|
|
20
|
+
constructor(petPath?: string);
|
|
21
|
+
exists(): boolean;
|
|
22
|
+
load(): PetState | null;
|
|
23
|
+
save(state: PetState): void;
|
|
24
|
+
create(name: string, species: string): PetState;
|
|
25
|
+
tick(state: PetState): PetState;
|
|
26
|
+
checkEvolution(state: PetState): PetState;
|
|
27
|
+
computeMood(state: PetState): PetMood;
|
|
28
|
+
addDiary(state: PetState, entry: string): PetState;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=pet-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pet-store.d.ts","sourceRoot":"","sources":["../../src/mcp/pet-store.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAC7E,MAAM,MAAM,OAAO,GACf,UAAU,GACV,UAAU,GACV,OAAO,GACP,SAAS,GACT,OAAO,GACP,KAAK,GACL,WAAW,GACX,MAAM,GACN,QAAQ,CAAC;AAEb,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAaD,qBAAa,QAAQ;IACnB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,CAAC,EAAE,MAAM;IAI5B,MAAM,IAAI,OAAO;IAIjB,IAAI,IAAI,QAAQ,GAAG,IAAI;IASvB,IAAI,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAK3B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,QAAQ;IA4B/C,IAAI,CAAC,KAAK,EAAE,QAAQ,GAAG,QAAQ;IAmD/B,cAAc,CAAC,KAAK,EAAE,QAAQ,GAAG,QAAQ;IAgBzC,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO;IAiBrC,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ;CAInD"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
const DEFAULT_PET_PATH = path.join(os.homedir(), ".tomo", "data", "pet.json");
|
|
5
|
+
const STAGE_ORDER = ["egg", "baby", "child", "teen", "adult", "elder"];
|
|
6
|
+
// Thresholds to reach this stage (affection points + minimum age)
|
|
7
|
+
const STAGE_THRESHOLDS = {
|
|
8
|
+
baby: { affection: 1, ageMs: 0 },
|
|
9
|
+
child: { affection: 20, ageMs: 1 * 24 * 60 * 60 * 1000 },
|
|
10
|
+
teen: { affection: 60, ageMs: 3 * 24 * 60 * 60 * 1000 },
|
|
11
|
+
adult: { affection: 150, ageMs: 7 * 24 * 60 * 60 * 1000 },
|
|
12
|
+
elder: { affection: 0, ageMs: 30 * 24 * 60 * 60 * 1000 },
|
|
13
|
+
};
|
|
14
|
+
export class PetStore {
|
|
15
|
+
petPath;
|
|
16
|
+
constructor(petPath) {
|
|
17
|
+
this.petPath = petPath ?? DEFAULT_PET_PATH;
|
|
18
|
+
}
|
|
19
|
+
exists() {
|
|
20
|
+
return fs.existsSync(this.petPath);
|
|
21
|
+
}
|
|
22
|
+
load() {
|
|
23
|
+
if (!this.exists())
|
|
24
|
+
return null;
|
|
25
|
+
try {
|
|
26
|
+
return JSON.parse(fs.readFileSync(this.petPath, "utf-8"));
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
save(state) {
|
|
33
|
+
fs.mkdirSync(path.dirname(this.petPath), { recursive: true });
|
|
34
|
+
fs.writeFileSync(this.petPath, JSON.stringify(state, null, 2), "utf-8");
|
|
35
|
+
}
|
|
36
|
+
create(name, species) {
|
|
37
|
+
const now = new Date().toISOString();
|
|
38
|
+
const state = {
|
|
39
|
+
name,
|
|
40
|
+
species,
|
|
41
|
+
born_at: now,
|
|
42
|
+
stage: "baby",
|
|
43
|
+
hunger: 80,
|
|
44
|
+
happiness: 70,
|
|
45
|
+
energy: 90,
|
|
46
|
+
health: 100,
|
|
47
|
+
affection: 1,
|
|
48
|
+
sleeping: false,
|
|
49
|
+
sleep_until: null,
|
|
50
|
+
last_tick: now,
|
|
51
|
+
diary: [`${name} hatched!`],
|
|
52
|
+
};
|
|
53
|
+
this.save(state);
|
|
54
|
+
return state;
|
|
55
|
+
}
|
|
56
|
+
// Apply time-based decay since last_tick. Skips if < 6 minutes elapsed.
|
|
57
|
+
//
|
|
58
|
+
// Time is split correctly for two offline-gap cases:
|
|
59
|
+
// 1. Sleep expired mid-interval: slept hours get energy recovery, remaining
|
|
60
|
+
// awake hours get hunger/happiness/energy decay.
|
|
61
|
+
// 2. Starvation started mid-interval: health penalty only covers the time
|
|
62
|
+
// actually spent at hunger=0, not the full elapsed window.
|
|
63
|
+
tick(state) {
|
|
64
|
+
const now = Date.now();
|
|
65
|
+
const last = new Date(state.last_tick).getTime();
|
|
66
|
+
const elapsedHours = (now - last) / (1000 * 60 * 60);
|
|
67
|
+
if (elapsedHours < 0.1)
|
|
68
|
+
return this.checkEvolution(state);
|
|
69
|
+
let awakeHours;
|
|
70
|
+
if (state.sleeping) {
|
|
71
|
+
if (state.sleep_until && now >= new Date(state.sleep_until).getTime()) {
|
|
72
|
+
// Sleep expired during the interval — split into slept + awake portions.
|
|
73
|
+
const sleptHours = Math.max(0, (new Date(state.sleep_until).getTime() - last) / (1000 * 60 * 60));
|
|
74
|
+
awakeHours = elapsedHours - sleptHours;
|
|
75
|
+
state.energy = Math.min(100, state.energy + sleptHours * 15);
|
|
76
|
+
state.sleeping = false;
|
|
77
|
+
state.sleep_until = null;
|
|
78
|
+
state = this.addDiary(state, `${state.name} woke up refreshed.`);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
// Still sleeping for the entire interval.
|
|
82
|
+
state.energy = Math.min(100, state.energy + elapsedHours * 15);
|
|
83
|
+
awakeHours = 0;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
awakeHours = elapsedHours;
|
|
88
|
+
}
|
|
89
|
+
if (awakeHours > 0) {
|
|
90
|
+
const hungerBefore = state.hunger;
|
|
91
|
+
state.hunger = Math.max(0, state.hunger - awakeHours * 5);
|
|
92
|
+
state.happiness = Math.max(0, state.happiness - awakeHours * 3);
|
|
93
|
+
state.energy = Math.max(0, state.energy - awakeHours * 4);
|
|
94
|
+
// Health: penalize only for the time actually spent at hunger=0.
|
|
95
|
+
// If hunger was > 0 at the start, starvation began after hungerBefore/5 hours.
|
|
96
|
+
const starvingHours = hungerBefore > 0
|
|
97
|
+
? Math.max(0, awakeHours - hungerBefore / 5)
|
|
98
|
+
: awakeHours;
|
|
99
|
+
if (starvingHours > 0) {
|
|
100
|
+
state.health = Math.max(0, state.health - starvingHours * 8);
|
|
101
|
+
}
|
|
102
|
+
else if (state.hunger > 60 && state.health < 100) {
|
|
103
|
+
state.health = Math.min(100, state.health + awakeHours * 2);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
state.last_tick = new Date().toISOString();
|
|
107
|
+
return this.checkEvolution(state);
|
|
108
|
+
}
|
|
109
|
+
// Check whether the pet qualifies for the next stage and apply if so.
|
|
110
|
+
checkEvolution(state) {
|
|
111
|
+
const currentIdx = STAGE_ORDER.indexOf(state.stage);
|
|
112
|
+
if (currentIdx >= STAGE_ORDER.length - 1)
|
|
113
|
+
return state;
|
|
114
|
+
const nextStage = STAGE_ORDER[currentIdx + 1];
|
|
115
|
+
const threshold = STAGE_THRESHOLDS[nextStage];
|
|
116
|
+
if (!threshold)
|
|
117
|
+
return state;
|
|
118
|
+
const ageMs = Date.now() - new Date(state.born_at).getTime();
|
|
119
|
+
if (state.affection >= threshold.affection && ageMs >= threshold.ageMs) {
|
|
120
|
+
state.stage = nextStage;
|
|
121
|
+
state = this.addDiary(state, `✨ ${state.name} evolved into a ${nextStage}!`);
|
|
122
|
+
}
|
|
123
|
+
return state;
|
|
124
|
+
}
|
|
125
|
+
computeMood(state) {
|
|
126
|
+
if (state.sleeping)
|
|
127
|
+
return "sleeping";
|
|
128
|
+
if (state.health < 40)
|
|
129
|
+
return "sick";
|
|
130
|
+
if (state.hunger < 20)
|
|
131
|
+
return "hungry";
|
|
132
|
+
const score = state.hunger * 0.35 +
|
|
133
|
+
state.happiness * 0.35 +
|
|
134
|
+
state.energy * 0.20 +
|
|
135
|
+
state.health * 0.10;
|
|
136
|
+
if (score >= 90)
|
|
137
|
+
return "blissful";
|
|
138
|
+
if (score >= 70)
|
|
139
|
+
return "happy";
|
|
140
|
+
if (score >= 50)
|
|
141
|
+
return "content";
|
|
142
|
+
if (score >= 35)
|
|
143
|
+
return "bored";
|
|
144
|
+
if (score >= 20)
|
|
145
|
+
return "sad";
|
|
146
|
+
return "miserable";
|
|
147
|
+
}
|
|
148
|
+
addDiary(state, entry) {
|
|
149
|
+
state.diary = [entry, ...state.diary].slice(0, 10);
|
|
150
|
+
return state;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=pet-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pet-store.js","sourceRoot":"","sources":["../../src/mcp/pet-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* MCP tools for the virtual pet companion system.
|
|
4
|
+
*
|
|
5
|
+
* State is persisted in ~/.tomo/data/pet.json. Each tool call loads fresh
|
|
6
|
+
* state from disk, applies a tick (time-based decay), runs its action, then
|
|
7
|
+
* saves — the file is always the single source of truth.
|
|
8
|
+
*
|
|
9
|
+
* Time-based decay runs automatically via PetScheduler (started in startForeground),
|
|
10
|
+
* not through these MCP tools — the agent only interacts with the pet on user request.
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildPetTools(petPath?: string): (import("@anthropic-ai/claude-agent-sdk").SdkMcpToolDefinition<{}> | import("@anthropic-ai/claude-agent-sdk").SdkMcpToolDefinition<{
|
|
13
|
+
name: z.ZodString;
|
|
14
|
+
species: z.ZodOptional<z.ZodString>;
|
|
15
|
+
}> | import("@anthropic-ai/claude-agent-sdk").SdkMcpToolDefinition<{
|
|
16
|
+
treat: z.ZodOptional<z.ZodBoolean>;
|
|
17
|
+
}> | import("@anthropic-ai/claude-agent-sdk").SdkMcpToolDefinition<{
|
|
18
|
+
activity: z.ZodOptional<z.ZodString>;
|
|
19
|
+
}> | import("@anthropic-ai/claude-agent-sdk").SdkMcpToolDefinition<{
|
|
20
|
+
action: z.ZodEnum<{
|
|
21
|
+
sleep: "sleep";
|
|
22
|
+
wake: "wake";
|
|
23
|
+
}>;
|
|
24
|
+
hours: z.ZodOptional<z.ZodNumber>;
|
|
25
|
+
}>)[];
|
|
26
|
+
//# sourceMappingURL=pet-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pet-tools.d.ts","sourceRoot":"","sources":["../../src/mcp/pet-tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM;;;;;;;;;;;;;MAoT7C"}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { tool } from "@anthropic-ai/claude-agent-sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { PetStore } from "./pet-store.js";
|
|
4
|
+
/**
|
|
5
|
+
* MCP tools for the virtual pet companion system.
|
|
6
|
+
*
|
|
7
|
+
* State is persisted in ~/.tomo/data/pet.json. Each tool call loads fresh
|
|
8
|
+
* state from disk, applies a tick (time-based decay), runs its action, then
|
|
9
|
+
* saves — the file is always the single source of truth.
|
|
10
|
+
*
|
|
11
|
+
* Time-based decay runs automatically via PetScheduler (started in startForeground),
|
|
12
|
+
* not through these MCP tools — the agent only interacts with the pet on user request.
|
|
13
|
+
*/
|
|
14
|
+
export function buildPetTools(petPath) {
|
|
15
|
+
return [
|
|
16
|
+
tool("pet_status", [
|
|
17
|
+
"Check on your virtual companion's current state.",
|
|
18
|
+
"",
|
|
19
|
+
"Returns name, stage, mood, all stats, and the last few diary entries.",
|
|
20
|
+
"Also applies any time-based stat decay since the last interaction.",
|
|
21
|
+
"",
|
|
22
|
+
"Call at the start of any pet-related conversation to get fresh state.",
|
|
23
|
+
"The mood field reflects how the pet is feeling — let it color your personality.",
|
|
24
|
+
].join("\n"), {}, async () => {
|
|
25
|
+
const store = new PetStore(petPath);
|
|
26
|
+
let state = store.load();
|
|
27
|
+
if (!state) {
|
|
28
|
+
return {
|
|
29
|
+
content: [{
|
|
30
|
+
type: "text",
|
|
31
|
+
text: "No pet found. Use pet_hatch to bring one into the world.",
|
|
32
|
+
}],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
state = store.tick(state);
|
|
36
|
+
store.save(state);
|
|
37
|
+
const ageMs = Date.now() - new Date(state.born_at).getTime();
|
|
38
|
+
const ageDays = Math.floor(ageMs / (1000 * 60 * 60 * 24));
|
|
39
|
+
const mood = store.computeMood(state);
|
|
40
|
+
return {
|
|
41
|
+
content: [{
|
|
42
|
+
type: "text",
|
|
43
|
+
text: JSON.stringify({
|
|
44
|
+
name: state.name,
|
|
45
|
+
species: state.species,
|
|
46
|
+
stage: state.stage,
|
|
47
|
+
age_days: ageDays,
|
|
48
|
+
mood,
|
|
49
|
+
stats: {
|
|
50
|
+
hunger: Math.round(state.hunger),
|
|
51
|
+
happiness: Math.round(state.happiness),
|
|
52
|
+
energy: Math.round(state.energy),
|
|
53
|
+
health: Math.round(state.health),
|
|
54
|
+
affection: state.affection,
|
|
55
|
+
},
|
|
56
|
+
sleeping: state.sleeping,
|
|
57
|
+
sleep_until: state.sleep_until,
|
|
58
|
+
recent_diary: state.diary.slice(0, 3),
|
|
59
|
+
}, null, 2),
|
|
60
|
+
}],
|
|
61
|
+
};
|
|
62
|
+
}, {
|
|
63
|
+
searchHint: "pet companion status check mood stats hunger happiness energy health diary",
|
|
64
|
+
}),
|
|
65
|
+
tool("pet_hatch", [
|
|
66
|
+
"Bring a new pet companion into the world.",
|
|
67
|
+
"",
|
|
68
|
+
"Give it a name and optionally a species. Replaces any existing pet.",
|
|
69
|
+
].join("\n"), {
|
|
70
|
+
name: z.string().min(1).max(30).describe("The pet's name."),
|
|
71
|
+
species: z.string().max(50).optional().describe("Optional species (e.g. 'cloud fox', 'pixel rabbit', 'tiny dragon'). Defaults to 'mystery creature'."),
|
|
72
|
+
}, async ({ name, species }) => {
|
|
73
|
+
const store = new PetStore(petPath);
|
|
74
|
+
const state = store.create(name, species ?? "mystery creature");
|
|
75
|
+
return {
|
|
76
|
+
content: [{
|
|
77
|
+
type: "text",
|
|
78
|
+
text: `${name} the ${state.species} has hatched! Say hello to your new companion.`,
|
|
79
|
+
}],
|
|
80
|
+
};
|
|
81
|
+
}, {
|
|
82
|
+
searchHint: "pet hatch create new companion name species",
|
|
83
|
+
}),
|
|
84
|
+
tool("pet_feed", [
|
|
85
|
+
"Feed your companion.",
|
|
86
|
+
"",
|
|
87
|
+
"Restores hunger and gives a small happiness boost.",
|
|
88
|
+
"Pass treat=true for a bigger happiness boost (costs some energy).",
|
|
89
|
+
"Best when hunger is below 50. Overfeeding above 90 has no extra effect.",
|
|
90
|
+
].join("\n"), {
|
|
91
|
+
treat: z.boolean().optional().describe("Give a special treat instead of regular food. Bigger happiness boost but costs energy."),
|
|
92
|
+
}, async ({ treat }) => {
|
|
93
|
+
const store = new PetStore(petPath);
|
|
94
|
+
let state = store.load();
|
|
95
|
+
if (!state) {
|
|
96
|
+
return {
|
|
97
|
+
content: [{ type: "text", text: "No pet to feed. Use pet_hatch first." }],
|
|
98
|
+
isError: true,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
state = store.tick(state);
|
|
102
|
+
if (state.sleeping) {
|
|
103
|
+
return {
|
|
104
|
+
content: [{
|
|
105
|
+
type: "text",
|
|
106
|
+
text: `${state.name} is sleeping. Better not wake them just to eat.`,
|
|
107
|
+
}],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
const wasHungry = state.hunger < 30;
|
|
111
|
+
state.hunger = Math.min(100, state.hunger + (treat ? 15 : 25));
|
|
112
|
+
state.happiness = Math.min(100, state.happiness + (treat ? 15 : 5));
|
|
113
|
+
if (treat)
|
|
114
|
+
state.energy = Math.max(0, state.energy - 5);
|
|
115
|
+
state.affection += 1;
|
|
116
|
+
const entry = treat
|
|
117
|
+
? `${state.name} gobbled up a treat with delight!`
|
|
118
|
+
: wasHungry
|
|
119
|
+
? `${state.name} was so hungry — devoured the food gratefully.`
|
|
120
|
+
: `${state.name} ate contentedly.`;
|
|
121
|
+
state = store.addDiary(state, entry);
|
|
122
|
+
state = store.checkEvolution(state);
|
|
123
|
+
store.save(state);
|
|
124
|
+
return {
|
|
125
|
+
content: [{
|
|
126
|
+
type: "text",
|
|
127
|
+
text: JSON.stringify({
|
|
128
|
+
event: treat ? "fed (treat)" : "fed",
|
|
129
|
+
hunger: Math.round(state.hunger),
|
|
130
|
+
happiness: Math.round(state.happiness),
|
|
131
|
+
mood: store.computeMood(state),
|
|
132
|
+
diary: entry,
|
|
133
|
+
}, null, 2),
|
|
134
|
+
}],
|
|
135
|
+
};
|
|
136
|
+
}, {
|
|
137
|
+
searchHint: "pet feed food eat hunger treat",
|
|
138
|
+
}),
|
|
139
|
+
tool("pet_play", [
|
|
140
|
+
"Play with your companion.",
|
|
141
|
+
"",
|
|
142
|
+
"Boosts happiness and deepens your bond (affection += 2).",
|
|
143
|
+
"Costs energy and some hunger. Best when energy > 40.",
|
|
144
|
+
"Each play session builds toward the next evolution stage.",
|
|
145
|
+
"",
|
|
146
|
+
"Optionally describe what you're doing together.",
|
|
147
|
+
].join("\n"), {
|
|
148
|
+
activity: z.string().max(60).optional().describe("What you're doing together (e.g. 'fetch', 'stargazing', 'telling stories')."),
|
|
149
|
+
}, async ({ activity }) => {
|
|
150
|
+
const store = new PetStore(petPath);
|
|
151
|
+
let state = store.load();
|
|
152
|
+
if (!state) {
|
|
153
|
+
return {
|
|
154
|
+
content: [{ type: "text", text: "No pet to play with. Use pet_hatch first." }],
|
|
155
|
+
isError: true,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
state = store.tick(state);
|
|
159
|
+
if (state.sleeping) {
|
|
160
|
+
return {
|
|
161
|
+
content: [{ type: "text", text: `${state.name} is sleeping. Let them rest.` }],
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
if (state.energy < 15) {
|
|
165
|
+
return {
|
|
166
|
+
content: [{
|
|
167
|
+
type: "text",
|
|
168
|
+
text: `${state.name} is too tired to play right now. Try letting them sleep first.`,
|
|
169
|
+
}],
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
const act = activity ?? "played together";
|
|
173
|
+
const prevStage = state.stage;
|
|
174
|
+
state.happiness = Math.min(100, state.happiness + 20);
|
|
175
|
+
state.energy = Math.max(0, state.energy - 15);
|
|
176
|
+
state.hunger = Math.max(0, state.hunger - 8);
|
|
177
|
+
state.affection += 2;
|
|
178
|
+
const entry = `${state.name} ${act} — pure joy.`;
|
|
179
|
+
state = store.addDiary(state, entry);
|
|
180
|
+
state = store.checkEvolution(state);
|
|
181
|
+
store.save(state);
|
|
182
|
+
const evolved = state.stage !== prevStage;
|
|
183
|
+
return {
|
|
184
|
+
content: [{
|
|
185
|
+
type: "text",
|
|
186
|
+
text: JSON.stringify({
|
|
187
|
+
event: act,
|
|
188
|
+
happiness: Math.round(state.happiness),
|
|
189
|
+
energy: Math.round(state.energy),
|
|
190
|
+
affection: state.affection,
|
|
191
|
+
mood: store.computeMood(state),
|
|
192
|
+
...(evolved ? { evolution: `Evolved to ${state.stage}!` } : {}),
|
|
193
|
+
diary: entry,
|
|
194
|
+
}, null, 2),
|
|
195
|
+
}],
|
|
196
|
+
};
|
|
197
|
+
}, {
|
|
198
|
+
searchHint: "pet play activity fun happiness bond affection",
|
|
199
|
+
}),
|
|
200
|
+
tool("pet_sleep", [
|
|
201
|
+
"Put your companion to sleep or wake them up.",
|
|
202
|
+
"",
|
|
203
|
+
"Sleep restores energy over time (15 pts/hr). You can set how long they sleep;",
|
|
204
|
+
"they wake automatically after. Waking early preserves whatever energy was gained.",
|
|
205
|
+
].join("\n"), {
|
|
206
|
+
action: z.enum(["sleep", "wake"]).describe("'sleep' to put them down, 'wake' to wake early."),
|
|
207
|
+
hours: z.number().min(0.5).max(12).optional().describe("How many hours to sleep. Defaults to 4."),
|
|
208
|
+
}, async ({ action, hours }) => {
|
|
209
|
+
const store = new PetStore(petPath);
|
|
210
|
+
let state = store.load();
|
|
211
|
+
if (!state) {
|
|
212
|
+
return {
|
|
213
|
+
content: [{ type: "text", text: "No pet. Use pet_hatch first." }],
|
|
214
|
+
isError: true,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
state = store.tick(state);
|
|
218
|
+
if (action === "sleep") {
|
|
219
|
+
if (state.sleeping) {
|
|
220
|
+
return {
|
|
221
|
+
content: [{ type: "text", text: `${state.name} is already sleeping.` }],
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
const sleepHours = hours ?? 4;
|
|
225
|
+
state.sleeping = true;
|
|
226
|
+
state.sleep_until = new Date(Date.now() + sleepHours * 60 * 60 * 1000).toISOString();
|
|
227
|
+
state = store.addDiary(state, `${state.name} curled up for a ${sleepHours}h nap.`);
|
|
228
|
+
store.save(state);
|
|
229
|
+
return {
|
|
230
|
+
content: [{
|
|
231
|
+
type: "text",
|
|
232
|
+
text: `${state.name} is sleeping until ${new Date(state.sleep_until).toLocaleTimeString()}.`,
|
|
233
|
+
}],
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
if (!state.sleeping) {
|
|
238
|
+
return {
|
|
239
|
+
content: [{ type: "text", text: `${state.name} is already awake.` }],
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
state.sleeping = false;
|
|
243
|
+
state.sleep_until = null;
|
|
244
|
+
state = store.addDiary(state, `${state.name} woke up early — a bit groggy.`);
|
|
245
|
+
store.save(state);
|
|
246
|
+
return {
|
|
247
|
+
content: [{
|
|
248
|
+
type: "text",
|
|
249
|
+
text: JSON.stringify({
|
|
250
|
+
event: "woke up",
|
|
251
|
+
energy: Math.round(state.energy),
|
|
252
|
+
mood: store.computeMood(state),
|
|
253
|
+
}, null, 2),
|
|
254
|
+
}],
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
}, {
|
|
258
|
+
searchHint: "pet sleep wake rest energy nap",
|
|
259
|
+
}),
|
|
260
|
+
];
|
|
261
|
+
}
|
|
262
|
+
//# sourceMappingURL=pet-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pet-tools.js","sourceRoot":"","sources":["../../src/mcp/pet-tools.ts"],"names":[],"mappings":"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"}
|