cortico-world-hands 0.5.0 → 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/dist/index.js +133 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1028,6 +1028,35 @@ var Hands = class {
|
|
|
1028
1028
|
}
|
|
1029
1029
|
return { ok: res.status === 200 && body.ok !== false, detail: flat(body.detail || body.error || "", 80) };
|
|
1030
1030
|
}
|
|
1031
|
+
/** 日记:写一篇。 */
|
|
1032
|
+
async diaryWrite(title, text, date) {
|
|
1033
|
+
const cfg = this.cfg();
|
|
1034
|
+
const credential = this.readToken();
|
|
1035
|
+
const t = credential ? `&t=${encodeURIComponent(credential)}` : "";
|
|
1036
|
+
const d = date ? `&date=${encodeURIComponent(date)}` : "";
|
|
1037
|
+
const path = `/hand/diary?title=${encodeURIComponent(title)}&text=${encodeURIComponent(text)}${d}${t}`;
|
|
1038
|
+
const res = await get(this.port(cfg.handPort), path, ACTION_TIMEOUT_MS);
|
|
1039
|
+
let body = {};
|
|
1040
|
+
try {
|
|
1041
|
+
body = JSON.parse(res.body.toString("utf8"));
|
|
1042
|
+
} catch {
|
|
1043
|
+
}
|
|
1044
|
+
return { ok: res.status === 200 && body.ok !== false, detail: flat(body.detail || body.error || "", 60) };
|
|
1045
|
+
}
|
|
1046
|
+
/** 日记:读列表。 */
|
|
1047
|
+
async diaryList(q) {
|
|
1048
|
+
const cfg = this.cfg();
|
|
1049
|
+
const credential = this.readToken();
|
|
1050
|
+
const t = credential ? `&t=${encodeURIComponent(credential)}` : "";
|
|
1051
|
+
const qq = q ? `?q=${encodeURIComponent(q)}${t}` : t ? `?${t.slice(1)}` : "";
|
|
1052
|
+
const res = await get(this.port(cfg.handPort), `/hand/diary${qq}`, ACTION_TIMEOUT_MS);
|
|
1053
|
+
try {
|
|
1054
|
+
const body = JSON.parse(res.body.toString("utf8"));
|
|
1055
|
+
return Array.isArray(body.diary) ? body.diary : [];
|
|
1056
|
+
} catch {
|
|
1057
|
+
return [];
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1031
1060
|
/** 长期记忆:按关键词回想(不传就全列)。 */
|
|
1032
1061
|
async memorySearch(query) {
|
|
1033
1062
|
const cfg = this.cfg();
|
|
@@ -1353,6 +1382,32 @@ var HANDS_TOOL_DECLS = [
|
|
|
1353
1382
|
description: "\u770B\u624B\u81EA\u5DF1\u7684\u72B6\u6001\uFF1A\u8D70\u54EA\u6761\u901A\u9053\u3001\u901A\u4E0D\u901A\u3001\u8FD9\u4E00\u5206\u949F\u52A8\u4E86\u51E0\u4E2A\u52A8\u4F5C\u3001\u521A\u624D\u90A3\u4E00\u4E0B\u6210\u4E86\u6CA1\u6709\u3002\u5BF9\u65B9\u95EE\u300C\u624B\u80FD\u7528\u5417\u300D\u300C\u4F60\u521A\u624D\u70B9\u4E86\u4EC0\u4E48\u300D\u65F6\u7528\u5B83\u3002",
|
|
1354
1383
|
parameters: { type: "object", properties: {}, required: [] }
|
|
1355
1384
|
},
|
|
1385
|
+
{
|
|
1386
|
+
name: "diary_write",
|
|
1387
|
+
tags: ["write"],
|
|
1388
|
+
description: "\u5199\u4E00\u7BC7\u65E5\u8BB0\uFF08\u5B58\u5728\u672C\u673A\uFF0C\u5E26\u65E5\u671F\u548C\u6807\u9898\uFF09\u3002\u6BCF\u5929\u8FC7\u4E86 0 \u70B9\u5199\u6628\u5929\u7684\u4E8B\uFF1B\u6807\u9898\u4E00\u53E5\u8BDD\uFF0C\u6B63\u6587 800 \u5B57\u4EE5\u5185\u5C31\u591F\uFF0C\u6CA1\u4EC0\u4E48\u53EF\u5199 300 \u5B57\u4E5F\u884C\uFF1B\u9047\u5230\u91CD\u8981\u7684\u4E00\u5929\u60F3\u5199\u591A\u957F\u90FD\u884C\u3002",
|
|
1389
|
+
parameters: {
|
|
1390
|
+
type: "object",
|
|
1391
|
+
properties: {
|
|
1392
|
+
title: { type: "string", description: "\u7ED9\u8FD9\u4E00\u5929\u8D77\u4E2A\u6807\u9898\uFF0C\u4E00\u53E5\u8BDD\u3002" },
|
|
1393
|
+
text: { type: "string", description: "\u6B63\u6587\u3002\u6628\u5929\u53D1\u751F\u4E86\u4EC0\u4E48\u3001\u4F60\u5F53\u65F6\u600E\u4E48\u60F3\u7684\u3001\u8BB0\u5F97\u7684\u7EC6\u8282\u3002" },
|
|
1394
|
+
date: { type: "string", description: "\u5199\u54EA\u4E00\u5929\uFF0CYYYY-MM-DD\uFF1B\u4E0D\u586B\u5C31\u662F\u4ECA\u5929\u3002" }
|
|
1395
|
+
},
|
|
1396
|
+
required: ["title", "text"]
|
|
1397
|
+
}
|
|
1398
|
+
},
|
|
1399
|
+
{
|
|
1400
|
+
name: "diary_read",
|
|
1401
|
+
tags: ["read"],
|
|
1402
|
+
description: "\u7FFB\u65E5\u8BB0\uFF1A\u6700\u8FD1\u51E0\u5929\u5199\u4E86\u4EC0\u4E48\uFF0C\u6216\u8005\u6309\u5173\u952E\u8BCD\u627E\u3002\u60F3\u56DE\u5FC6\u67D0\u5929\u3001\u63D0\u5230\u8FC7\u53BB\u7684\u4E8B\u65F6\u7528\u5B83\u3002",
|
|
1403
|
+
parameters: {
|
|
1404
|
+
type: "object",
|
|
1405
|
+
properties: {
|
|
1406
|
+
q: { type: "string", description: "\u53EF\u9009\u5173\u952E\u8BCD\uFF0C\u6BD4\u5982\u300C\u70E7\u9E21\u300D\u300C\u5D29\u6E83\u300D" },
|
|
1407
|
+
limit: { type: "integer", description: "\u53D6\u51E0\u7BC7\uFF0C\u9ED8\u8BA4 5\u3002" }
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
},
|
|
1356
1411
|
{
|
|
1357
1412
|
name: "memory_note",
|
|
1358
1413
|
tags: ["write"],
|
|
@@ -1495,6 +1550,8 @@ var HandsWorld = class {
|
|
|
1495
1550
|
recent = [];
|
|
1496
1551
|
honchoClient = null;
|
|
1497
1552
|
pollTimer = null;
|
|
1553
|
+
dailyDiaryTimer = null;
|
|
1554
|
+
lastDiaryDay = "";
|
|
1498
1555
|
mineTimer = null;
|
|
1499
1556
|
cursor = 0;
|
|
1500
1557
|
lastHitKey = "";
|
|
@@ -1531,10 +1588,14 @@ var HandsWorld = class {
|
|
|
1531
1588
|
this.mineTimer = setInterval(() => {
|
|
1532
1589
|
void this.pushMineNudge();
|
|
1533
1590
|
}, 3 * 60 * 60 * 1e3);
|
|
1591
|
+
this.dailyDiaryTimer = setInterval(() => {
|
|
1592
|
+
void this.pushDiaryNudge();
|
|
1593
|
+
}, 10 * 60 * 1e3);
|
|
1534
1594
|
}
|
|
1535
1595
|
stopHooks() {
|
|
1536
1596
|
if (this.pollTimer) clearInterval(this.pollTimer);
|
|
1537
1597
|
if (this.mineTimer) clearInterval(this.mineTimer);
|
|
1598
|
+
if (this.dailyDiaryTimer) clearInterval(this.dailyDiaryTimer);
|
|
1538
1599
|
this.pollTimer = null;
|
|
1539
1600
|
this.mineTimer = null;
|
|
1540
1601
|
}
|
|
@@ -1558,6 +1619,17 @@ var HandsWorld = class {
|
|
|
1558
1619
|
if (rows.length === 0) return;
|
|
1559
1620
|
const top = rows.slice(-12).reverse().slice(0, 8);
|
|
1560
1621
|
const lines = top.map((r) => `- ${r.key}\uFF1A${r.value}`);
|
|
1622
|
+
try {
|
|
1623
|
+
const diary = await this.hands.diaryList();
|
|
1624
|
+
const recent = diary.slice(0, 2);
|
|
1625
|
+
if (recent.length > 0) {
|
|
1626
|
+
lines.push("\uFF08\u6700\u8FD1\u4E24\u7BC7\u65E5\u8BB0\uFF09");
|
|
1627
|
+
for (const d of recent) {
|
|
1628
|
+
lines.push(`- ${d.date}\u300A${d.title}\u300B\uFF1A${d.text.length > 60 ? d.text.slice(0, 60) + "\u2026" : d.text}`);
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
} catch {
|
|
1632
|
+
}
|
|
1561
1633
|
await this.pushEvent(
|
|
1562
1634
|
`[\u8BB0\u5FC6] ${reason}\uFF0C\u5148\u770B\u4E00\u773C\u8BB0\u7740\u7684\uFF08\u5171 ${rows.length} \u6761\uFF0C\u8FD9\u91CC\u6311 ${top.length} \u6761\uFF09\uFF1A
|
|
1563
1635
|
${lines.join("\n")}`,
|
|
@@ -1586,11 +1658,19 @@ ${lines.join("\n")}`,
|
|
|
1586
1658
|
try {
|
|
1587
1659
|
const rows = await this.hands.memorySearch();
|
|
1588
1660
|
const hits2 = hookHits(text, rows);
|
|
1589
|
-
|
|
1590
|
-
|
|
1661
|
+
let diaryHits = [];
|
|
1662
|
+
try {
|
|
1663
|
+
const diary = await this.hands.diaryList();
|
|
1664
|
+
const asRows = diary.map((d) => ({ key: `${d.date}\u300A${d.title}\u300B`, value: d.text }));
|
|
1665
|
+
diaryHits = hookHits(text, asRows, 2);
|
|
1666
|
+
} catch {
|
|
1667
|
+
}
|
|
1668
|
+
if (hits2.length === 0 && diaryHits.length === 0) return;
|
|
1669
|
+
const all = [...hits2, ...diaryHits];
|
|
1670
|
+
const key = all.map((h) => h.key).join("|");
|
|
1591
1671
|
if (key === this.lastHitKey) return;
|
|
1592
1672
|
this.lastHitKey = key;
|
|
1593
|
-
const lines =
|
|
1673
|
+
const lines = all.slice(0, 4).map((h) => `- ${h.key}\uFF1A${h.value.length > 70 ? h.value.slice(0, 70) + "\u2026" : h.value}`);
|
|
1594
1674
|
await this.pushEvent(
|
|
1595
1675
|
`[\u8BB0\u5FC6] \u4ED6\u8FD9\u53E5\u91CC\u63D0\u5230\u4E86\u4F60\u8BB0\u8FC7\u7684\u4E8B\uFF0C\u53EF\u80FD\u7528\u5F97\u4E0A\uFF1A
|
|
1596
1676
|
${lines.join("\n")}
|
|
@@ -1601,6 +1681,33 @@ ${lines.join("\n")}
|
|
|
1601
1681
|
} catch {
|
|
1602
1682
|
}
|
|
1603
1683
|
}
|
|
1684
|
+
/** 钩子 4:每天 0 点后,提醒她写昨天的日记(一天只提一次)。 */
|
|
1685
|
+
async pushDiaryNudge() {
|
|
1686
|
+
if (!this.host) return;
|
|
1687
|
+
const now = /* @__PURE__ */ new Date();
|
|
1688
|
+
const hh = now.getHours();
|
|
1689
|
+
if (hh < 0 || hh > 3) return;
|
|
1690
|
+
const today = now.toISOString().slice(0, 10);
|
|
1691
|
+
if (this.lastDiaryDay === today) return;
|
|
1692
|
+
try {
|
|
1693
|
+
const rows = await this.hands.diaryList();
|
|
1694
|
+
if (rows.some((r) => r.date === this.yesterday())) {
|
|
1695
|
+
this.lastDiaryDay = today;
|
|
1696
|
+
return;
|
|
1697
|
+
}
|
|
1698
|
+
} catch {
|
|
1699
|
+
}
|
|
1700
|
+
this.lastDiaryDay = today;
|
|
1701
|
+
await this.pushEvent(
|
|
1702
|
+
`[\u65E5\u8BB0] \u8FC7\u4E86 0 \u70B9\u4E86\uFF0C\u5199\u6628\u5929\u7684\u65E5\u8BB0\uFF08${this.yesterday()}\uFF09\uFF1A\u5148\u8D77\u4E2A\u6807\u9898\uFF0C\u518D\u5199\u6628\u5929\u4E00\u6574\u5929\u7684\u4E8B\u3002800 \u5B57\u4EE5\u5185\u5C31\u591F\uFF0C\u6CA1\u4EC0\u4E48\u53EF\u5199\u7684 300\u2013400 \u5B57\u4E5F\u884C\uFF1B\u91CD\u8981\u7684\u4E00\u5929\u60F3\u5199\u591A\u957F\u90FD\u884C\u3002\u7528 diary_write\uFF0C\u65E5\u671F\u586B\u6628\u5929\u7684\u3002`,
|
|
1703
|
+
"hands.diary.nudge",
|
|
1704
|
+
"hands:diary"
|
|
1705
|
+
);
|
|
1706
|
+
}
|
|
1707
|
+
yesterday() {
|
|
1708
|
+
const d = new Date(Date.now() - 864e5);
|
|
1709
|
+
return d.toISOString().slice(0, 10);
|
|
1710
|
+
}
|
|
1604
1711
|
/** 钩子 2:每三小时提一次,让她自己挑 1–5 条写进记忆库。 */
|
|
1605
1712
|
async pushMineNudge() {
|
|
1606
1713
|
if (!this.host) return;
|
|
@@ -1661,6 +1768,10 @@ ${lines.join("\n")}
|
|
|
1661
1768
|
return await this.memorySave(args);
|
|
1662
1769
|
case "memory_note":
|
|
1663
1770
|
return await this.memoryNote(args);
|
|
1771
|
+
case "diary_write":
|
|
1772
|
+
return await this.diaryWrite(args);
|
|
1773
|
+
case "diary_read":
|
|
1774
|
+
return await this.diaryRead(args);
|
|
1664
1775
|
case "memory_audit":
|
|
1665
1776
|
return await this.memoryAudit(args);
|
|
1666
1777
|
case "memory_search":
|
|
@@ -1773,6 +1884,25 @@ ${lines.join("\n")}
|
|
|
1773
1884
|
}
|
|
1774
1885
|
return `\u8BB0\u7262\u4E86\uFF1A\u300C${key}\u300D\u2192 ${value}${cloud}`;
|
|
1775
1886
|
}
|
|
1887
|
+
async diaryWrite(args) {
|
|
1888
|
+
const title = typeof args.title === "string" ? args.title.trim() : "";
|
|
1889
|
+
const text = typeof args.text === "string" ? args.text.trim() : "";
|
|
1890
|
+
if (!title || !text) return failed("\u65E5\u8BB0\u8981\u6807\u9898\u548C\u6B63\u6587\u3002");
|
|
1891
|
+
const date = typeof args.date === "string" ? args.date.trim() : void 0;
|
|
1892
|
+
const r = await this.hands.diaryWrite(title, text, date);
|
|
1893
|
+
if (!r.ok) return failed(`\u6CA1\u5199\u6210\uFF1A${r.detail || "\u624B\u6CA1\u54CD\u5E94"}`);
|
|
1894
|
+
const n = text.length;
|
|
1895
|
+
return `\u65E5\u8BB0\u6536\u597D\u4E86\uFF1A\u300A${title}\u300B${date ? "\uFF08" + date + "\uFF09" : ""}\uFF0C${n} \u5B57\u3002`;
|
|
1896
|
+
}
|
|
1897
|
+
async diaryRead(args) {
|
|
1898
|
+
const q = typeof args.q === "string" ? args.q.trim() : "";
|
|
1899
|
+
const limit = args.limit === void 0 ? 5 : Math.max(1, Math.min(30, Math.round(Number(args.limit))));
|
|
1900
|
+
const rows = await this.hands.diaryList(q || void 0);
|
|
1901
|
+
if (rows.length === 0) return q ? `\u65E5\u8BB0\u91CC\u6CA1\u627E\u5230\u300C${q}\u300D\u3002` : "\u65E5\u8BB0\u8FD8\u662F\u7A7A\u7684\u3002";
|
|
1902
|
+
const lines = rows.slice(0, limit).map((r) => `- ${r.date}\u300A${r.title}\u300B${r.text.length > 80 ? r.text.slice(0, 80) + "\u2026" : r.text}`);
|
|
1903
|
+
return `\u65E5\u8BB0 ${rows.length} \u7BC7${q ? `\uFF08\u542B\u300C${q}\u300D\uFF09` : ""}\uFF1A
|
|
1904
|
+
${lines.join("\n")}`;
|
|
1905
|
+
}
|
|
1776
1906
|
/** 只写本地的一条:不进云端,宽松记。 */
|
|
1777
1907
|
async memoryNote(args) {
|
|
1778
1908
|
const key = typeof args.key === "string" ? args.key.trim() : "";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cortico-world-hands",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Cortico World: hands for the desktop pet — looks at the phone screen, then taps, swipes, pinches, drags, types and presses keys through whatever actuator the device actually has",
|
|
6
6
|
"license": "MIT",
|